From 0c295dcf098a6fa9d532138ef3fd4926adb521cb Mon Sep 17 00:00:00 2001 From: lkn Date: Wed, 24 Jun 2026 19:00:28 +0200 Subject: [PATCH] wayland: fix shade crash and titlebar visibility when shaded Two issues with window shading: 1. wShadeWindow resizes the frame to top_width-1 tall. wl_frame_paint used the unclamped fwin->top_width as titlebar blit height, writing one row past the pixman buffer. Heap corruption detected by glibc on next free (RReleaseImage) caused SIGABRT. Fix: clamp tb_h to total_h. 2. The parent frame scene_buf was only enabled when show_resizebar was true. When the titlebar child buffer is too narrow (falls back to drawing into the parent), the shaded frame had its scene_buf disabled and the titlebar was invisible. Fix: always commit and enable the parent scene_buf (cleared to transparent, so unused areas are safe). --- src/backend/wayland/wl_framebuf.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/backend/wayland/wl_framebuf.c b/src/backend/wayland/wl_framebuf.c index 3c67c95..9127bbf 100644 --- a/src/backend/wayland/wl_framebuf.c +++ b/src/backend/wayland/wl_framebuf.c @@ -593,6 +593,8 @@ wl_frame_paint(struct WFrameWindow *fwin) pixman_image_t *tb_img = tb_fb ? tb_fb->image : fb->image; int tb_w = total_w; /* always full frame width */ int tb_h = fwin->top_width; + if (tb_h > total_h) + tb_h = total_h; /* In Wayland we composite buttons into the titlebar buffer, so * the titlebar must be full-width and positioned at the frame origin @@ -805,14 +807,13 @@ wl_frame_paint(struct WFrameWindow *fwin) wlr_scene_node_set_enabled(&rb_fb->scene_buf->node, show_resizebar); } - /* Commit the buffer to the scene graph only if it has content (resizebar). */ + /* Always commit the parent frame buffer — it holds the resizebar + * pixels (when unshaded) and/or the titlebar fallback (when the + * titlebar child is too narrow). The buffer is cleared to transparent + * at the top of this function so unused areas won't obscure anything. */ if (fb->scene_buf) { - if (show_resizebar) { - wlr_scene_node_set_enabled(&fb->scene_buf->node, true); - wlr_scene_buffer_set_buffer_with_damage(fb->scene_buf, &fb->base, NULL); - } else { - wlr_scene_node_set_enabled(&fb->scene_buf->node, false); - } + wlr_scene_buffer_set_buffer_with_damage(fb->scene_buf, &fb->base, NULL); + wlr_scene_node_set_enabled(&fb->scene_buf->node, true); } if (wl_state.output)