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).
This commit is contained in:
lkn 2026-06-24 19:00:28 +02:00
parent 144b089dff
commit 0c295dcf09
1 changed files with 8 additions and 7 deletions

View File

@ -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_node_set_enabled(&fb->scene_buf->node, true);
}
if (wl_state.output)