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 <psychon@znc.in>
This commit is contained in:
Uli Schlachter 2019-02-27 10:20:22 +01:00
parent 2d2dba0d80
commit aa21156ced
4 changed files with 20 additions and 9 deletions

View File

@ -345,8 +345,7 @@ acquire_timestamp(void)
atom, type, 8, 0, ""); atom, type, 8, 0, "");
xcb_change_window_attributes(globalconf.connection, win, xcb_change_window_attributes(globalconf.connection, win,
XCB_CW_EVENT_MASK, (uint32_t[]) { 0 }); XCB_CW_EVENT_MASK, (uint32_t[]) { 0 });
xcb_ungrab_server(globalconf.connection); xutil_ungrab_server(globalconf.connection);
xcb_flush(globalconf.connection);
/* Now wait for the event */ /* Now wait for the event */
while((event = xcb_wait_for_event(globalconf.connection))) while((event = xcb_wait_for_event(globalconf.connection)))
@ -882,8 +881,7 @@ main(int argc, char **argv)
ROOT_WINDOW_EVENT_MASK); ROOT_WINDOW_EVENT_MASK);
/* we will receive events, stop grabbing server */ /* we will receive events, stop grabbing server */
xcb_ungrab_server(globalconf.connection); xutil_ungrab_server(globalconf.connection);
xcb_flush(globalconf.connection);
/* get the current wallpaper, from now on we are informed when it changes */ /* get the current wallpaper, from now on we are informed when it changes */
root_update_wallpaper(); root_update_wallpaper();

View File

@ -54,6 +54,20 @@ xutil_get_text_property_from_reply(xcb_get_property_reply_t *reply)
return NULL; 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 *); uint16_t xutil_key_mask_fromstr(const char *);
void xutil_key_mask_tostr(uint16_t, const char **, size_t *); void xutil_key_mask_tostr(uint16_t, const char **, size_t *);

View File

@ -1241,7 +1241,7 @@ client_restore_enterleave_events(void)
check(globalconf.pending_enter_leave_begin.sequence != 0); check(globalconf.pending_enter_leave_begin.sequence != 0);
pair.begin = globalconf.pending_enter_leave_begin; pair.begin = globalconf.pending_enter_leave_begin;
pair.end = xcb_no_operation(globalconf.connection); pair.end = xcb_no_operation(globalconf.connection);
xcb_ungrab_server(globalconf.connection); xutil_ungrab_server(globalconf.connection);
globalconf.pending_enter_leave_begin.sequence = 0; globalconf.pending_enter_leave_begin.sequence = 0;
sequence_pair_array_append(&globalconf.ignore_enter_leave_events, pair); 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, globalconf.screen->root,
XCB_CW_EVENT_MASK, XCB_CW_EVENT_MASK,
ROOT_WINDOW_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 /* Do this now so that we don't get any events for the above
* (Else, reparent could cause an UnmapNotify) */ * (Else, reparent could cause an UnmapNotify) */
@ -1978,7 +1978,7 @@ client_set_minimized(lua_State *L, int cidx, bool s)
c->window, c->window,
XCB_CW_EVENT_MASK, XCB_CW_EVENT_MASK,
client_select_input_val); client_select_input_val);
xcb_ungrab_server(globalconf.connection); xutil_ungrab_server(globalconf.connection);
} }
else else
{ {

3
root.c
View File

@ -124,8 +124,7 @@ root_set_wallpaper(cairo_pattern_t *pattern)
globalconf.screen->root, globalconf.screen->root,
XCB_CW_EVENT_MASK, XCB_CW_EVENT_MASK,
ROOT_WINDOW_EVENT_MASK); ROOT_WINDOW_EVENT_MASK);
xcb_ungrab_server(globalconf.connection); xutil_ungrab_server(globalconf.connection);
xcb_flush(globalconf.connection);
/* Make sure our pixmap is not destroyed when we disconnect. */ /* Make sure our pixmap is not destroyed when we disconnect. */
xcb_set_close_down_mode(c, XCB_CLOSE_DOWN_RETAIN_PERMANENT); xcb_set_close_down_mode(c, XCB_CLOSE_DOWN_RETAIN_PERMANENT);