diff options
author | Gary Wong <gtw@gnu.org> | 2009-09-10 11:05:23 -0600 |
---|---|---|
committer | Gary Wong <gtw@gnu.org> | 2009-09-10 11:05:23 -0600 |
commit | d4d66325598a872099c946de60855f991c588142 (patch) | |
tree | 2fb00b50050fcdcdbeeee65cb31057674891184e | |
parent | 354413b0f7026c11f9e70b14f7e828d06a1f4772 (diff) |
Be careful to catch all events when starting up and shutting down.
-rw-r--r-- | ChangeLog | 7 | ||||
-rw-r--r-- | gwm.c | 58 | ||||
-rw-r--r-- | root.c | 2 | ||||
-rw-r--r-- | root.h | 3 |
4 files changed, 61 insertions, 9 deletions
@@ -1,3 +1,10 @@ +2009-09-10 Gary Wong <gtw@gnu.org> + + * gwm.c (setup_display): Make sure the root event mask change is + atomic with the query of its children. + (shutdown_display): Process any remaining MapRequest, + ConfigureRequest or CirculateRequest events before closing. + 2009-09-09 Gary Wong <gtw@gnu.org> * actions.c (action_window_list_menu): Insert windows into the @@ -2016,15 +2016,22 @@ static void setup_display( void ) { /* Send StructureNotify ClientMessage (ICCCM 2.0, section 2.8). */ msg.window = screens[ i ]->root; msg.data.data32[ 1 ] = gwm_screens[ i ].wm_atom; - /* FIXME Make the SubstructureNotify/SubstructureRedirect atomic - with respect to the QueryTree below. */ xcb_send_event( c, FALSE, screens[ i ]->root, XCB_EVENT_MASK_STRUCTURE_NOTIFY, (char *) &msg ); + /* Querying the list of children of the root must be atomic with + respect to both our SubstructureNotify and SubstructureRedirect + event masks taking effect, so grab the server for a moment. */ + xcb_grab_server( c ); + cookies[ i ] = xcb_change_window_attributes_checked( c, screens[ i ]->root, XCB_CW_EVENT_MASK, &n ); + tree_cookies[ i ] = xcb_query_tree( c, screens[ i ]->root ); + + xcb_ungrab_server( c ); + values[ 0 ] = 0; xcb_change_property( c, XCB_PROP_MODE_REPLACE, screens[ i ]->root, atoms[ ATOM__NET_CURRENT_DESKTOP ], CARDINAL, 32, @@ -2065,8 +2072,6 @@ static void setup_display( void ) { xcb_change_property( c, XCB_PROP_MODE_REPLACE, screens[ i ]->root, atoms[ ATOM__NET_WORKAREA ], CARDINAL, 32, 4, values ); - - tree_cookies[ i ] = xcb_query_tree( c, screens[ i ]->root ); } xcb_set_input_focus( c, XCB_INPUT_FOCUS_NONE, XCB_INPUT_FOCUS_POINTER_ROOT, @@ -2405,7 +2410,8 @@ static void shutdown_display( void ) { uint32_t n; xcb_intern_atom_cookie_t cookie; union callback_param cp; - + xcb_generic_event_t *ev; + for( i = 0; i < num_screens; i++ ) { xcb_window_t w = screens[ i ]->root | STACK_END; @@ -2465,9 +2471,45 @@ static void shutdown_display( void ) { sync_with_callback( cookie.sequence ); - /* FIXME We must handle any MapRequest (and perhaps ConfigureRequest - and CirculateRequest) the server might have sent us before it - changed our root event masks. */ + /* We have now received all events that preceded our change to the + root event masks, and we won't be getting any more redirected + requests. Run through the event queue one last time, and handle + any that are still waiting. */ + while( ( ev = xcb_poll_for_event( c ) ) ) { +#if DEBUG + if( flag_debug && ev ) + show_event( ev ); +#endif + + switch( ev->response_type ) { + case 0: /* Error */ + show_error( (xcb_generic_error_t *) ev ); + break; + + case XCB_MAP_REQUEST: + xcb_map_window( c, ( ( xcb_map_request_event_t *) ev )->window ); + break; + + case XCB_CONFIGURE_REQUEST: + withdrawn_configure_request( NULL, + (xcb_configure_request_event_t *) ev ); + break; + + case XCB_CIRCULATE_REQUEST: + root_circulate_request( NULL, + (xcb_circulate_request_event_t *) ev ); + break; + + default: + /* Do nothing. We're about to go away. Even client messages + such as WM_CHANGE_STATE should be ignored; all windows have + been forced into the Normal state whether they like it or + not. */ + break; + } + + free( ev ); + } xcb_disconnect( c ); #if DEBUG @@ -144,7 +144,7 @@ static void root_configure_notify( struct gwm_window *window, ev->above_sibling : window->w | STACK_END ); } -static void root_circulate_request( struct gwm_window *window, +extern void root_circulate_request( struct gwm_window *window, xcb_circulate_request_event_t *ev ) { uint32_t value = ev->place == XCB_PLACE_ON_TOP ? XCB_STACK_MODE_ABOVE : @@ -1,6 +1,9 @@ #ifndef ROOT_H #define ROOT_H +extern void root_circulate_request( struct gwm_window *window, + xcb_circulate_request_event_t *ev ); + extern const event_handler root_handlers[]; #endif |