From aa21156ced504964f5809b1a219542927b7402c3 Mon Sep 17 00:00:00 2001 From: Uli Schlachter Date: Wed, 27 Feb 2019 10:20:22 +0100 Subject: [PATCH] Make sure we always flush after xcb_ungrab_server() Between xcb_grab_server() and xcb_ungrab_server(), XCB's output buffer might fill up. Thus, the GrabServer request might already have been sent to the server, but the following UngrabServer request could end up in XCB's output buffer. There, it might sit around for quite a while and cause problems. Since we cannot detect when XCB's output buffer fills up, we just always flush after generating an UngrabServer request. Very-likely-Fixes: https://github.com/awesomeWM/awesome/issues/2697 Signed-off-by: Uli Schlachter --- awesome.c | 6 ++---- common/xutil.h | 14 ++++++++++++++ objects/client.c | 6 +++--- root.c | 3 +-- 4 files changed, 20 insertions(+), 9 deletions(-) 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);