mirror of
https://github.com/edeproject/ede.git
synced 2023-08-10 21:13:03 +03:00
Support for X quitting
This commit is contained in:
parent
e0e54f2ece
commit
377538f2e3
@ -26,6 +26,7 @@
|
|||||||
#include "Splash.h"
|
#include "Splash.h"
|
||||||
#include "Logout.h"
|
#include "Logout.h"
|
||||||
#include "Xsm.h"
|
#include "Xsm.h"
|
||||||
|
#include "Xshutdown.h"
|
||||||
|
|
||||||
EDELIB_NS_USING(Config)
|
EDELIB_NS_USING(Config)
|
||||||
EDELIB_NS_USING(Resource)
|
EDELIB_NS_USING(Resource)
|
||||||
@ -220,7 +221,11 @@ int EvokeService::handle(const XEvent* xev) {
|
|||||||
int dw = DisplayWidth(fl_display, fl_screen);
|
int dw = DisplayWidth(fl_display, fl_screen);
|
||||||
int dh = DisplayHeight(fl_display, fl_screen);
|
int dh = DisplayHeight(fl_display, fl_screen);
|
||||||
|
|
||||||
logout_dialog_show(dw, dh, LOGOUT_OPT_SHUTDOWN | LOGOUT_OPT_RESTART);
|
int ret = logout_dialog_show(dw, dh, LOGOUT_OPT_SHUTDOWN | LOGOUT_OPT_RESTART);
|
||||||
|
if(ret != -1) {
|
||||||
|
x_shutdown();
|
||||||
|
stop();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -18,7 +18,8 @@ SOURCE = evoke.cpp
|
|||||||
Splash.cpp
|
Splash.cpp
|
||||||
Xsm.cpp
|
Xsm.cpp
|
||||||
Logout.cpp
|
Logout.cpp
|
||||||
Autostart.cpp ;
|
Autostart.cpp
|
||||||
|
Xshutdown.cpp ;
|
||||||
|
|
||||||
CONFIG = ede-settings.conf
|
CONFIG = ede-settings.conf
|
||||||
ede-startup.conf ;
|
ede-startup.conf ;
|
||||||
|
129
evoke/Xshutdown.cpp
Normal file
129
evoke/Xshutdown.cpp
Normal file
@ -0,0 +1,129 @@
|
|||||||
|
/*
|
||||||
|
* $Id$
|
||||||
|
*
|
||||||
|
* Evoke, head honcho of everything
|
||||||
|
* Part of Equinox Desktop Environment (EDE).
|
||||||
|
* Copyright (c) 2007-2009 EDE Authors.
|
||||||
|
*
|
||||||
|
* This program is licensed under terms of the
|
||||||
|
* GNU General Public License version 2 or newer.
|
||||||
|
* See COPYING for details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <FL/x.H>
|
||||||
|
#include "Xshutdown.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This is re-implementation of XmuClientWindow() so I don't have to link code with libXmu.
|
||||||
|
* XmuClientWindow() will return parent window of given window; this is used so we don't
|
||||||
|
* send delete message to some button or else, but it's parent.
|
||||||
|
*/
|
||||||
|
static Window mu_try_children(Display* dpy, Window win, Atom wm_state) {
|
||||||
|
Atom real;
|
||||||
|
Window root, parent;
|
||||||
|
Window* children = 0;
|
||||||
|
Window ret = 0;
|
||||||
|
unsigned int nchildren;
|
||||||
|
unsigned char* prop;
|
||||||
|
unsigned long n, extra;
|
||||||
|
int format;
|
||||||
|
|
||||||
|
if(!XQueryTree(dpy, win, &root, &parent, &children, &nchildren))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
for(unsigned int i = 0; (i < nchildren) && !ret; i++) {
|
||||||
|
prop = NULL;
|
||||||
|
XGetWindowProperty(dpy, children[i], wm_state, 0, 0, False, AnyPropertyType,
|
||||||
|
&real, &format, &n, &extra, (unsigned char**)&prop);
|
||||||
|
if(prop)
|
||||||
|
XFree(prop);
|
||||||
|
if(real)
|
||||||
|
ret = children[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
for(unsigned int i = 0; (i < nchildren) && !ret; i++)
|
||||||
|
ret = mu_try_children(dpy, win, wm_state);
|
||||||
|
|
||||||
|
if(children)
|
||||||
|
XFree(children);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Window mu_client_window(Display* dpy, Window win, Atom wm_state) {
|
||||||
|
Atom real;
|
||||||
|
int format;
|
||||||
|
unsigned long n, extra;
|
||||||
|
unsigned char* prop;
|
||||||
|
int status = XGetWindowProperty(dpy, win, wm_state, 0, 0, False, AnyPropertyType,
|
||||||
|
&real, &format, &n, &extra, (unsigned char**)&prop);
|
||||||
|
if(prop)
|
||||||
|
XFree(prop);
|
||||||
|
|
||||||
|
if(status != Success)
|
||||||
|
return win;
|
||||||
|
|
||||||
|
if(real)
|
||||||
|
return win;
|
||||||
|
|
||||||
|
Window w = mu_try_children(dpy, win, wm_state);
|
||||||
|
if(!w)
|
||||||
|
w = win;
|
||||||
|
|
||||||
|
return w;
|
||||||
|
}
|
||||||
|
|
||||||
|
void x_shutdown(void) {
|
||||||
|
Window dummy, *wins;
|
||||||
|
Window root = RootWindow(fl_display, fl_screen);
|
||||||
|
unsigned int n;
|
||||||
|
|
||||||
|
if(!XQueryTree(fl_display, root, &dummy, &dummy, &wins, &n))
|
||||||
|
return;
|
||||||
|
|
||||||
|
Atom wm_protocols = XInternAtom(fl_display, "WM_PROTOCOLS", False);
|
||||||
|
Atom wm_delete_window = XInternAtom(fl_display, "WM_DELETE_WINDOW", False);
|
||||||
|
Atom wm_state = XInternAtom(fl_display, "WM_STATE", False);
|
||||||
|
XWindowAttributes attr;
|
||||||
|
XEvent ev;
|
||||||
|
|
||||||
|
for(unsigned int i = 0; i < n; i++) {
|
||||||
|
if(XGetWindowAttributes(fl_display, wins[i], &attr) && (attr.map_state == IsViewable))
|
||||||
|
wins[i] = mu_client_window(fl_display, wins[i], wm_state);
|
||||||
|
else
|
||||||
|
wins[i] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Hm... probably we should first quit known processes started by us
|
||||||
|
* then rest of the X familly
|
||||||
|
*/
|
||||||
|
for(unsigned int i = 0; i < n; i++) {
|
||||||
|
if(wins[i]) {
|
||||||
|
/* FIXME: check WM_PROTOCOLS before sending WM_DELETE_WINDOW ??? */
|
||||||
|
memset(&ev, 0, sizeof(ev));
|
||||||
|
ev.xclient.type = ClientMessage;
|
||||||
|
ev.xclient.window = wins[i];
|
||||||
|
ev.xclient.message_type = wm_protocols;
|
||||||
|
ev.xclient.format = 32;
|
||||||
|
ev.xclient.data.l[0] = (long)wm_delete_window;
|
||||||
|
ev.xclient.data.l[1] = CurrentTime;
|
||||||
|
XSendEvent(fl_display, wins[i], False, 0L, &ev);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
XSync(fl_display, False);
|
||||||
|
sleep(1);
|
||||||
|
|
||||||
|
/* kill remaining windows */
|
||||||
|
for(unsigned int i = 0; i < n; i++) {
|
||||||
|
if(wins[i]) {
|
||||||
|
XKillClient(fl_display, wins[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
XSync(fl_display, False);
|
||||||
|
XFree(wins);
|
||||||
|
}
|
||||||
|
|
18
evoke/Xshutdown.h
Normal file
18
evoke/Xshutdown.h
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
/*
|
||||||
|
* $Id$
|
||||||
|
*
|
||||||
|
* Evoke, head honcho of everything
|
||||||
|
* Part of Equinox Desktop Environment (EDE).
|
||||||
|
* Copyright (c) 2007-2009 EDE Authors.
|
||||||
|
*
|
||||||
|
* This program is licensed under terms of the
|
||||||
|
* GNU General Public License version 2 or newer.
|
||||||
|
* See COPYING for details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __XSHUTDOWN_H__
|
||||||
|
#define __XSHUTDOWN_H__
|
||||||
|
|
||||||
|
void x_shutdown(void);
|
||||||
|
|
||||||
|
#endif
|
Loading…
Reference in New Issue
Block a user