From bf76b3842b92922b8d3fa23a105d9e9b1aad521c Mon Sep 17 00:00:00 2001 From: Uli Schlachter Date: Wed, 19 Oct 2011 15:11:11 +0200 Subject: [PATCH] Ungrab the server before parsing the config This moves the loading of the rc.lua and managing of pre-existing clients to after we ungrab the server during startup. To make sure we have no races with clients which start up parallel to awesome, we do the QueryTree for all the clients that we have to manage before the ungrab, but start managing the clients only after the ungrab. This means that we have already selected our event mask on the root window in scan() and thus received an UnmapNotify event when we reparent windows into a frame window. This has the effect that we immediately unmanage the client again, whoops. To fix this, we grab the server again and remove our event mask on the root window again while we reparent. This should hopefully fix all cases where we deadlock during startup because pulseaudio wants to talk to the X server, but is being ignored because we have the server grabbed while at the same time we are waiting for pulseaudio. Signed-off-by: Uli Schlachter --- awesome.c | 31 +++++++++++++++---------------- objects/client.c | 26 ++++++++++++++++++++++++++ 2 files changed, 41 insertions(+), 16 deletions(-) diff --git a/awesome.c b/awesome.c index 26598bf77..58dc4e353 100644 --- a/awesome.c +++ b/awesome.c @@ -80,20 +80,15 @@ awesome_atexit(bool restart) /** Scan X to find windows to manage. */ static void -scan(void) +scan(xcb_query_tree_cookie_t tree_c) { int i, tree_c_len; - xcb_query_tree_cookie_t tree_c; xcb_query_tree_reply_t *tree_r; xcb_window_t *wins = NULL; xcb_get_window_attributes_reply_t *attr_r; xcb_get_geometry_reply_t *geom_r; long state; - /* Get the window tree associated to this screen */ - tree_c = xcb_query_tree_unchecked(globalconf.connection, - globalconf.screen->root); - tree_r = xcb_query_tree_reply(globalconf.connection, tree_c, NULL); @@ -321,6 +316,7 @@ main(int argc, char **argv) xdgHandle xdg; bool no_argb = false; xcb_generic_event_t *event; + xcb_query_tree_cookie_t tree_c; static struct option long_options[] = { { "help", 0, NULL, 'h' }, @@ -541,6 +537,18 @@ main(int argc, char **argv) (const uint32_t[]) { globalconf.screen->black_pixel, globalconf.screen->white_pixel }); xcb_destroy_window(globalconf.connection, tmp_win); + /* Get the window tree associated to this screen */ + tree_c = xcb_query_tree_unchecked(globalconf.connection, + globalconf.screen->root); + + xcb_change_window_attributes(globalconf.connection, + globalconf.screen->root, + XCB_CW_EVENT_MASK, + ROOT_WINDOW_EVENT_MASK); + + /* we will receive events, stop grabbing server */ + xcb_ungrab_server(globalconf.connection); + /* Parse and run configuration file */ if (!luaA_parserc(&xdg, confpath, true)) fatal("couldn't find any rc file"); @@ -550,17 +558,8 @@ main(int argc, char **argv) xdgWipeHandle(&xdg); /* scan existing windows */ - scan(); + scan(tree_c); - { - xcb_change_window_attributes(globalconf.connection, - globalconf.screen->root, - XCB_CW_EVENT_MASK, - ROOT_WINDOW_EVENT_MASK); - } - - /* we will receive events, stop grabbing server */ - xcb_ungrab_server(globalconf.connection); xcb_flush(globalconf.connection); /* main event loop */ diff --git a/objects/client.c b/objects/client.c index f7a740336..e7c26ea5d 100644 --- a/objects/client.c +++ b/objects/client.c @@ -433,9 +433,35 @@ client_manage(xcb_window_t w, xcb_get_geometry_reply_t *wgeom, bool startup) FRAME_SELECT_INPUT_EVENT_MASK, globalconf.default_cmap }); + + if (startup) + { + /* The client is already mapped, thus we must be sure that we don't send + * ourselves an UnmapNotify due to the xcb_reparent_window(). + * + * Grab the server to make sure we don't lose any events. + */ + uint32_t no_event[] = { 0 }; + xcb_grab_server(globalconf.connection); + + xcb_change_window_attributes(globalconf.connection, + globalconf.screen->root, + XCB_CW_EVENT_MASK, + no_event); + } + xcb_reparent_window(globalconf.connection, w, c->frame_window, 0, 0); xcb_map_window(globalconf.connection, w); + if (startup) + { + xcb_change_window_attributes(globalconf.connection, + globalconf.screen->root, + XCB_CW_EVENT_MASK, + ROOT_WINDOW_EVENT_MASK); + xcb_ungrab_server(globalconf.connection); + } + /* Do this now so that we don't get any events for the above * (Else, reparent could cause an UnmapNotify) */ xcb_change_window_attributes(globalconf.connection, w, XCB_CW_EVENT_MASK, select_input_val);