Review the use of XFlush and xcb_flush

Replace most of XFlush with xcb_flush.

Also, in a lot of places, XFlush is used as if it is XSync. Replace
those cases by using xcb's _checked version of functions and
xcb_request_check.

Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
This commit is contained in:
Yuxuan Shui 2019-02-07 00:41:24 +00:00
parent 856ad4b230
commit 22bc79369e
No known key found for this signature in database
GPG Key ID: 37C999F617EA1A47
3 changed files with 41 additions and 23 deletions

View File

@ -805,8 +805,13 @@ map_win(session_t *ps, xcb_window_t id) {
// Unmap overlay window if it got mapped but we are currently not // Unmap overlay window if it got mapped but we are currently not
// in redirected state. // in redirected state.
if (ps->overlay && id == ps->overlay && !ps->redirected) { if (ps->overlay && id == ps->overlay && !ps->redirected) {
xcb_unmap_window(ps->c, ps->overlay); auto e = xcb_request_check(ps->c, xcb_unmap_window(ps->c, ps->overlay));
XFlush(ps->dpy); if (e) {
log_error("Failed to unmap the overlay window");
free(e);
}
// We don't track the overlay window, so we can return
return;
} }
win *w = find_win(ps, id); win *w = find_win(ps, id);
@ -835,8 +840,8 @@ map_win(session_t *ps, xcb_window_t id) {
xcb_shape_select_input(ps->c, id, 1); xcb_shape_select_input(ps->c, id, 1);
} }
// Make sure the XSelectInput() requests are sent // Make sure the select input requests are sent
XFlush(ps->dpy); x_sync(ps->c);
// Update window mode here to check for ARGB windows // Update window mode here to check for ARGB windows
win_determine_mode(ps, w); win_determine_mode(ps, w);
@ -845,8 +850,7 @@ map_win(session_t *ps, xcb_window_t id) {
// window should have been prepared at this point // window should have been prepared at this point
if (!w->client_win) { if (!w->client_win) {
win_recheck_client(ps, w); win_recheck_client(ps, w);
} } else {
else {
// Re-mark client window here // Re-mark client window here
win_mark_client(ps, w, w->client_win); win_mark_client(ps, w, w->client_win);
} }
@ -2329,9 +2333,13 @@ handle_queued_x_events(EV_P_ ev_prepare *w, int revents) {
ev_handle(ps, ev); ev_handle(ps, ev);
free(ev); free(ev);
}; };
// Flush because if we go into sleep when there is still
// requests in the outgoing buffer, they will not be sent
// for an indefinite amount of time.
// Use XFlush here too, we might still use some Xlib functions
// because OpenGL.
XFlush(ps->dpy); XFlush(ps->dpy);
xcb_flush(ps->c); xcb_flush(ps->c);
int err = xcb_connection_has_error(ps->c); int err = xcb_connection_has_error(ps->c);
if (err) { if (err) {
log_fatal("X11 server connection broke (error %d)", err); log_fatal("X11 server connection broke (error %d)", err);
@ -2695,12 +2703,16 @@ session_init(session_t *ps_old, int argc, char **argv) {
// Start listening to events on root earlier to catch all possible // Start listening to events on root earlier to catch all possible
// root geometry changes // root geometry changes
xcb_change_window_attributes(ps->c, ps->root, XCB_CW_EVENT_MASK, (const uint32_t[]) { auto e = xcb_request_check(
XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY ps->c, xcb_change_window_attributes_checked(
| XCB_EVENT_MASK_EXPOSURE ps->c, ps->root, XCB_CW_EVENT_MASK,
| XCB_EVENT_MASK_STRUCTURE_NOTIFY (const uint32_t[]){XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY |
| XCB_EVENT_MASK_PROPERTY_CHANGE }); XCB_EVENT_MASK_EXPOSURE | XCB_EVENT_MASK_STRUCTURE_NOTIFY |
XFlush(ps->dpy); XCB_EVENT_MASK_PROPERTY_CHANGE}));
if (e) {
log_error("Failed to setup root window event mask");
free(e);
}
ps->root_width = DisplayWidth(ps->dpy, ps->scr); ps->root_width = DisplayWidth(ps->dpy, ps->scr);
ps->root_height = DisplayHeight(ps->dpy, ps->scr); ps->root_height = DisplayHeight(ps->dpy, ps->scr);
@ -2858,7 +2870,7 @@ session_init(session_t *ps_old, int argc, char **argv) {
if (ps->o.xrender_sync_fence) { if (ps->o.xrender_sync_fence) {
ps->sync_fence = xcb_generate_id(ps->c); ps->sync_fence = xcb_generate_id(ps->c);
auto e = xcb_request_check(ps->c, xcb_sync_create_fence(ps->c, ps->root, ps->sync_fence, 0)); e = xcb_request_check(ps->c, xcb_sync_create_fence(ps->c, ps->root, ps->sync_fence, 0));
if (e) { if (e) {
log_error("Failed to create a XSync fence. xrender-sync-fence will be disabled"); log_error("Failed to create a XSync fence. xrender-sync-fence will be disabled");
ps->o.xrender_sync_fence = false; ps->o.xrender_sync_fence = false;
@ -3020,9 +3032,11 @@ session_init(session_t *ps_old, int argc, char **argv) {
recheck_focus(ps); recheck_focus(ps);
} }
xcb_ungrab_server(ps->c); e = xcb_request_check(ps->c, xcb_ungrab_server(ps->c));
// ALWAYS flush after xcb_ungrab_server()! if (e) {
XFlush(ps->dpy); log_error("Failed to ungrad server");
free(e);
}
// Fork to background, if asked // Fork to background, if asked
if (ps->o.fork_after_register) { if (ps->o.fork_after_register) {

View File

@ -972,6 +972,7 @@ void paint_all(session_t *ps, win *const t, bool ignore_damage) {
// Wait for VBlank. We could do it aggressively (send the painting // Wait for VBlank. We could do it aggressively (send the painting
// request and XFlush() on VBlank) or conservatively (send the request // request and XFlush() on VBlank) or conservatively (send the request
// only on VBlank). // only on VBlank).
// TODO Investigate and potentially remove this option
if (!ps->o.vsync_aggressive) if (!ps->o.vsync_aggressive)
vsync_wait(ps); vsync_wait(ps);
@ -1038,7 +1039,7 @@ void paint_all(session_t *ps, win *const t, bool ignore_damage) {
if (ps->o.vsync_aggressive) if (ps->o.vsync_aggressive)
vsync_wait(ps); vsync_wait(ps);
xcb_flush(ps->c); x_sync(ps->c);
#ifdef CONFIG_OPENGL #ifdef CONFIG_OPENGL
if (glx_has_context(ps)) { if (glx_has_context(ps)) {

View File

@ -650,11 +650,14 @@ void win_mark_client(session_t *ps, win *w, xcb_window_t client) {
if (w->a.map_state != XCB_MAP_STATE_VIEWABLE) if (w->a.map_state != XCB_MAP_STATE_VIEWABLE)
return; return;
xcb_change_window_attributes(ps->c, client, XCB_CW_EVENT_MASK, auto e = xcb_request_check(
(const uint32_t[]) { determine_evmask(ps, client, WIN_EVMODE_CLIENT) }); ps->c, xcb_change_window_attributes(
ps->c, client, XCB_CW_EVENT_MASK,
// Make sure the XSelectInput() requests are sent (const uint32_t[]){determine_evmask(ps, client, WIN_EVMODE_CLIENT)}));
XFlush(ps->dpy); if (e) {
log_error("Failed to change event mask of window %#010x", client);
free(e);
}
win_upd_wintype(ps, w); win_upd_wintype(ps, w);