diff --git a/awesome.c b/awesome.c index 4063a490e..bc73e337d 100644 --- a/awesome.c +++ b/awesome.c @@ -345,8 +345,7 @@ acquire_timestamp(void) atom, type, 8, 0, ""); xcb_change_window_attributes(globalconf.connection, win, XCB_CW_EVENT_MASK, (uint32_t[]) { 0 }); - xcb_ungrab_server(globalconf.connection); - xcb_flush(globalconf.connection); + xutil_ungrab_server(globalconf.connection); /* Now wait for the event */ while((event = xcb_wait_for_event(globalconf.connection))) @@ -882,8 +881,7 @@ main(int argc, char **argv) ROOT_WINDOW_EVENT_MASK); /* we will receive events, stop grabbing server */ - xcb_ungrab_server(globalconf.connection); - xcb_flush(globalconf.connection); + xutil_ungrab_server(globalconf.connection); /* get the current wallpaper, from now on we are informed when it changes */ root_update_wallpaper(); diff --git a/common/xutil.h b/common/xutil.h index 5ee3b08de..81820f255 100644 --- a/common/xutil.h +++ b/common/xutil.h @@ -54,6 +54,20 @@ xutil_get_text_property_from_reply(xcb_get_property_reply_t *reply) return NULL; } +static inline void +xutil_ungrab_server(xcb_connection_t *connection) +{ + /* XCB's output buffer might have filled up between the GrabServer request + * and now. Thus, the GrabServer might already have been sent and the + * following UngrabServer would sit around in the output buffer for an + * indeterminate time and might cause problems. We cannot detect this + * situation, so just always flush directly after UngrabServer. + */ + xcb_ungrab_server(connection); + xcb_flush(connection); +} +#define xcb_ungrab_server do_not_use_xcb_ungrab_server_directly + uint16_t xutil_key_mask_fromstr(const char *); void xutil_key_mask_tostr(uint16_t, const char **, size_t *); diff --git a/objects/client.c b/objects/client.c index f00f586d8..f38e1626b 100644 --- a/objects/client.c +++ b/objects/client.c @@ -1241,7 +1241,7 @@ client_restore_enterleave_events(void) check(globalconf.pending_enter_leave_begin.sequence != 0); pair.begin = globalconf.pending_enter_leave_begin; pair.end = xcb_no_operation(globalconf.connection); - xcb_ungrab_server(globalconf.connection); + xutil_ungrab_server(globalconf.connection); globalconf.pending_enter_leave_begin.sequence = 0; sequence_pair_array_append(&globalconf.ignore_enter_leave_events, pair); } @@ -1587,7 +1587,7 @@ client_manage(xcb_window_t w, xcb_get_geometry_reply_t *wgeom, xcb_get_window_at globalconf.screen->root, XCB_CW_EVENT_MASK, ROOT_WINDOW_EVENT_MASK); - xcb_ungrab_server(globalconf.connection); + xutil_ungrab_server(globalconf.connection); /* Do this now so that we don't get any events for the above * (Else, reparent could cause an UnmapNotify) */ @@ -1978,7 +1978,7 @@ client_set_minimized(lua_State *L, int cidx, bool s) c->window, XCB_CW_EVENT_MASK, client_select_input_val); - xcb_ungrab_server(globalconf.connection); + xutil_ungrab_server(globalconf.connection); } else { diff --git a/root.c b/root.c index ac5bb38b9..bc649c40a 100644 --- a/root.c +++ b/root.c @@ -124,8 +124,7 @@ root_set_wallpaper(cairo_pattern_t *pattern) globalconf.screen->root, XCB_CW_EVENT_MASK, ROOT_WINDOW_EVENT_MASK); - xcb_ungrab_server(globalconf.connection); - xcb_flush(globalconf.connection); + xutil_ungrab_server(globalconf.connection); /* Make sure our pixmap is not destroyed when we disconnect. */ xcb_set_close_down_mode(c, XCB_CLOSE_DOWN_RETAIN_PERMANENT);