From 7bdb78287cca11e98e5d71c3be805e66d790a3e7 Mon Sep 17 00:00:00 2001 From: Yuxuan Shui Date: Sat, 22 Jun 2024 16:26:47 +0100 Subject: [PATCH] core: fix root window event mask Calling wm_import_incomplete with the root window overwrites its event mask, causing some required events not being generated for us, which causes rendering issues when screen resolution is changed. Set the root event masks after wm_import_incomplete. Fixes #1277 Signed-off-by: Yuxuan Shui --- src/picom.c | 43 ++++++++++++++++++++++++++----------------- 1 file changed, 26 insertions(+), 17 deletions(-) diff --git a/src/picom.c b/src/picom.c index 4302b4afc4..f1b3f642e1 100644 --- a/src/picom.c +++ b/src/picom.c @@ -2145,6 +2145,7 @@ static session_t *session_init(int argc, char **argv, Display *dpy, // Allocate a session and copy default values into it session_t *ps = cmalloc(session_t); + xcb_generic_error_t *e = NULL; *ps = s_def; ps->loop = EV_DEFAULT; pixman_region32_init(&ps->screen_reg); @@ -2156,26 +2157,9 @@ static session_t *session_init(int argc, char **argv, Display *dpy, // Use the same Display across reset, primarily for resource leak checking x_connection_init(&ps->c, dpy); - // We store width/height from screen_info instead using them directly because they - // can change, see configure_root(). - ps->root_width = ps->c.screen_info->width_in_pixels; - ps->root_height = ps->c.screen_info->height_in_pixels; const xcb_query_extension_reply_t *ext_info; - // Start listening to events on root earlier to catch all possible - // root geometry changes - auto e = xcb_request_check( - ps->c.c, xcb_change_window_attributes_checked( - ps->c.c, ps->c.screen_info->root, XCB_CW_EVENT_MASK, - (const uint32_t[]){XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY | - XCB_EVENT_MASK_EXPOSURE | XCB_EVENT_MASK_STRUCTURE_NOTIFY | - XCB_EVENT_MASK_PROPERTY_CHANGE})); - if (e) { - log_error_x_error(e, "Failed to setup root window event mask"); - free(e); - } - xcb_prefetch_extension_data(ps->c.c, &xcb_render_id); xcb_prefetch_extension_data(ps->c.c, &xcb_composite_id); xcb_prefetch_extension_data(ps->c.c, &xcb_damage_id); @@ -2554,6 +2538,31 @@ static session_t *session_init(int argc, char **argv, Display *dpy, ps->wm = wm_new(); wm_import_incomplete(ps->wm, ps->c.screen_info->root, XCB_NONE); + // wm_import_incomplete will set event masks on the root window, but its event + // mask is missing things we need, so we need to set it again. + e = xcb_request_check( + ps->c.c, xcb_change_window_attributes_checked( + ps->c.c, ps->c.screen_info->root, XCB_CW_EVENT_MASK, + (const uint32_t[]){XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY | + XCB_EVENT_MASK_EXPOSURE | XCB_EVENT_MASK_STRUCTURE_NOTIFY | + XCB_EVENT_MASK_PROPERTY_CHANGE})); + if (e) { + log_error_x_error(e, "Failed to setup root window event mask"); + free(e); + } + + // Query the size of the root window. We need the size information before any + // window can be managed. + auto r = XCB_AWAIT(xcb_get_geometry, ps->c.c, ps->c.screen_info->root); + if (!r) { + log_fatal("Failed to get geometry of the root window"); + goto err; + } + ps->root_width = r->width; + ps->root_height = r->height; + free(r); + rebuild_screen_reg(ps); + e = xcb_request_check(ps->c.c, xcb_grab_server_checked(ps->c.c)); if (e) { log_fatal_x_error(e, "Failed to grab X server");