From 4a79e7b7779297db9a622523953a6f207fe38cde Mon Sep 17 00:00:00 2001 From: Maxim Solovyov Date: Thu, 1 Feb 2024 07:13:16 +0300 Subject: [PATCH] render: fix binding the root background pixmap in case of depth mismatch fix the same issue in the legacy backends, see the previous commit for details. this commit also removes the x_validate_pixmap function because it was used only in the get_root_tile function and the fix pretty much implies and embeds it. --- src/render.c | 20 +++++++++++++------- src/x.c | 21 --------------------- src/x.h | 2 -- 3 files changed, 13 insertions(+), 30 deletions(-) diff --git a/src/render.c b/src/render.c index fadd8335..371a9be7 100644 --- a/src/render.c +++ b/src/render.c @@ -604,20 +604,27 @@ static bool get_root_tile(session_t *ps) { bool fill = false; xcb_pixmap_t pixmap = x_get_root_back_pixmap(&ps->c, ps->atoms); - // Make sure the pixmap we got is valid - if (pixmap && !x_validate_pixmap(&ps->c, pixmap)) { - pixmap = XCB_NONE; + xcb_get_geometry_reply_t *r; + if (pixmap) { + r = xcb_get_geometry_reply(ps->c.c, xcb_get_geometry(ps->c.c, pixmap), NULL); } // Create a pixmap if there isn't any - if (!pixmap) { + xcb_visualid_t visual; + if (!pixmap || !r) { pixmap = x_create_pixmap(&ps->c, (uint8_t)ps->c.screen_info->root_depth, 1, 1); if (pixmap == XCB_NONE) { log_error("Failed to create pixmaps for root tile."); return false; } + visual = ps->c.screen_info->root_visual; fill = true; + } else { + visual = r->depth == ps->c.screen_info->root_depth + ? ps->c.screen_info->root_visual + : x_get_visual_for_depth(&ps->c, r->depth); + free(r); } // Create Picture @@ -625,7 +632,7 @@ static bool get_root_tile(session_t *ps) { .repeat = true, }; ps->root_tile_paint.pict = x_create_picture_with_visual_and_pixmap( - &ps->c, ps->c.screen_info->root_visual, pixmap, XCB_RENDER_CP_REPEAT, &pa); + &ps->c, visual, pixmap, XCB_RENDER_CP_REPEAT, &pa); // Fill pixmap if needed if (fill) { @@ -646,8 +653,7 @@ static bool get_root_tile(session_t *ps) { ps->root_tile_paint.pixmap = pixmap; #ifdef CONFIG_OPENGL if (BKEND_GLX == ps->o.backend) { - return paint_bind_tex(ps, &ps->root_tile_paint, 0, 0, true, 0, - ps->c.screen_info->root_visual, false); + return paint_bind_tex(ps, &ps->root_tile_paint, 0, 0, true, 0, visual, false); } #endif diff --git a/src/x.c b/src/x.c index c4de9113..d48ae96b 100644 --- a/src/x.c +++ b/src/x.c @@ -704,27 +704,6 @@ xcb_pixmap_t x_create_pixmap(struct x_connection *c, uint8_t depth, int width, i return XCB_NONE; } -/** - * Validate a pixmap. - * - * Detect whether the pixmap is valid with XGetGeometry. Well, maybe there - * are better ways. - */ -bool x_validate_pixmap(struct x_connection *c, xcb_pixmap_t pixmap) { - if (pixmap == XCB_NONE) { - return false; - } - - auto r = xcb_get_geometry_reply(c->c, xcb_get_geometry(c->c, pixmap), NULL); - if (!r) { - return false; - } - - bool ret = r->width && r->height; - free(r); - return ret; -} - /// We don't use the _XSETROOT_ID root window property as a source of the background /// pixmap because it most likely points to a dummy pixmap used to keep the colormap /// associated with the background pixmap alive but we listen for it's changes and update diff --git a/src/x.h b/src/x.h index fe443137..f320e869 100644 --- a/src/x.h +++ b/src/x.h @@ -356,8 +356,6 @@ const char *x_strerror(xcb_generic_error_t *e); xcb_pixmap_t x_create_pixmap(struct x_connection *, uint8_t depth, int width, int height); -bool x_validate_pixmap(struct x_connection *, xcb_pixmap_t pxmap); - /** * Free a winprop_t. *