LOGIN / SIGN UP
2 Author: Claes Nästén
Date: Thu May 07 22:30:11 +0200 2009
Subject: A not so beautiful patch for making session shutdown work ok.
    With this logging out from Gnome also shuts down pekwm successfully, and
    it's possible to start it by setting the window manager gconf value.
    
    In the future file descriptors probably should be possible to match with
    event handlers or similar to simplify this logic.

src/WindowManager.cc
 
143 @@ -143,6 +143,22 @@
143 break;
144 }
145 }
146
147 /**
148 * Handler setting ice connections
149 */
150 static void
151 iceWatch(IceConn ice_conn, IcePointer data,
152 Bool opening, IcePointer *watch_data)
153 {
154 if (opening) {
155 WindowManager::instance()->setIceConn(ice_conn);
156 WindowManager::instance()->setIceFd(IceConnectionNumber(ice_conn));
157 } else {
158 WindowManager::instance()->setIceConn(0);
159 WindowManager::instance()->setIceFd(0);
160 }
161 }
162
163 } // extern "C"
164
...  
178 @@ -162,6 +178,7 @@
178
179 // Setup window manager
180 _instance = new WindowManager(command_line, config_file);
181
182 if (_instance->setupDisplay(replace)) {
183 _instance->scanWindows();
184 Frame::resetFrameIDs();
...  
223 @@ -206,6 +223,7 @@
223 #endif // HARBOUR
224 _cmd_dialog(0), _search_dialog(0),
225 _status_window(0), _workspace_indicator(0),
226 _max_fd(0), _dpy_fd(0), _ice_fd(0), _ice_conn(0),
227 _command_line(command_line),
228 _startup(false), _shutdown(false), _reload(false),
229 _allow_grouping(true), _hint_wo(0), _root_wo(0)
...  
385 @@ -367,6 +385,8 @@
385
386 // Setup screen, init atoms and claim the display.
387 _screen = new PScreen(dpy, _config->isHonourRandr());
388 _dpy_fd = ConnectionNumber(dpy);
389 _max_fd = _dpy_fd + 1;
390
391 Atoms::init();
392
...  
796 @@ -776,8 +796,13 @@
796 WindowManager::doEventLoop(void)
797 {
798 XEvent ev;
799 bool is_xevent, is_icevent;
800 Timer<ActionPerformed>::timed_event_list events;
801
802 #ifdef HAVE_SESSION
803 IceAddConnectionWatch(iceWatch, NULL);
804 #endif // HAVE_SESSION
805
806 while (! _shutdown && ! is_signal_int_term) {
807 // Handle timeouts
808 if (is_signal_alrm) {
...  
823 @@ -798,8 +823,13 @@
823 doReload();
824 }
825
826 // Wait for IO
827 waitIO(is_xevent, is_icevent);
828
829 // Get next event, drop event handling if none was given
805 if (_screen->getNextEvent(ev)) {
831 if (is_xevent) {
832 XNextEvent(_screen->getDpy(), &ev);
833
834 switch (ev.type) {
835 case MapRequest:
836 handleMapRequestEvent(&ev.xmaprequest);
...  
916 @@ -886,6 +916,55 @@
916 break;
917 }
918 }
919
920 #ifdef HAVE_SESSION
921 if (is_icevent) {
922 Bool dummy_b;
923 // Process messages, might not
924 IceProcessMessages(_ice_conn, NULL, &dummy_b);
925 }
926 #endif // HAVE_SESSION
927 }
928
929 #ifdef HAVE_SESSION
930 IceRemoveConnectionWatch(iceWatch, NULL);
931 #endif // HAVE_SESSION
932 }
933
934 /**
935 * Wait for data from connections.
936 */
937 void
938 WindowManager::waitIO(bool &is_xevent, bool &is_iceevent)
939 {
940 is_xevent = is_iceevent = false;
941
942 if (XPending(PScreen::instance()->getDpy()) > 0) {
943 is_xevent = true;
944 return;
945 }
946
947 // Make sure to flush X11 connection before starting to wait or
948 // else we might end up waiting here forever.
949 XFlush(_screen->getDpy());
950
951 int ret;
952 fd_set rfds;
953
954 FD_ZERO(&rfds);
955 FD_SET(_dpy_fd, &rfds);
956 #ifdef HAVE_SESSION
957 if (_ice_fd) {
958 FD_SET(_ice_fd, &rfds);
959 }
960 #endif // HAVE_SESSION
961
962 ret = select(_max_fd, &rfds, 0, 0, 0);
963 if (ret > 0) {
964 is_xevent = FD_ISSET(_dpy_fd, &rfds);
965 #ifdef HAVE_SESSION
966 is_iceevent = FD_ISSET(_ice_fd, &rfds);
967 #endif // HAVE_SESSION
968 }
969 }
970
...  

src/WindowManager.hh
 
27 @@ -27,11 +27,14 @@
27 #include <list>
28 #include <map>
29
30 #ifdef HAVE_XRANDR
31 extern "C" {
32 #ifdef HAVE_XRANDR
33 #include <X11/extensions/Xrandr.h>
34 }
35 #endif // HAVE_XRANDR
36 #ifdef HAVE_SESSION
37 #include <X11/ICE/ICElib.h>
38 #endif // HAVE_SESSION
39 }
40
41 class ActionHandler;
42 class AutoProperties;
...  
83 @@ -80,6 +83,12 @@
83 /**< Return shutdown flag, set to tru to shutdown window manager. */
84 bool *getShutdownFlag(void) { return &_shutdown; }
85
86 void setIceConn(IceConn ice_conn) { _ice_conn = ice_conn; }
87 void setIceFd(int ice_fd) {
88 _ice_fd = ice_fd;
89 _max_fd = std::max(_dpy_fd, _ice_fd) + 1;
90 }
91
92 // get "base" classes
93 inline PScreen *getScreen(void) const { return _screen; }
94 inline Config *getConfig(void) const { return _config; }
...  
186 @@ -177,6 +186,8 @@
186 void scanWindows(void);
187 void execStartFile(void);
188
189 void waitIO(bool &is_xevent, bool &is_iceevent);
190
191 void doReload(void);
192 void doReloadConfig(void);
193 void doReloadTheme(void);
...  
278 @@ -267,6 +278,13 @@
278 static const unsigned int MENU_NAMES_RESERVED_COUNT;
279 #endif // MENUS
280
281 int _max_fd; /**< Max file descriptor to select on. */
282 int _dpy_fd; /**< Display file descriptor. */
283 #ifdef HAVE_SESSION
284 int _ice_fd; /**< ICE file descriptor.*/
285 IceConn _ice_conn; /**< Connection to ICE. */
286 #endif // HAVE_SESSION
287
288 std::string _command_line, _restart_command;
289 bool _startup; //!< Indicates startup status.
290 bool _shutdown; //!< Set to wheter we want to shutdown.
...