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: also enable the parent scene_buf
   when the titlebar was drawn into it (no titlebar child found).
This commit is contained in:
lkn 2026-06-24 19:55:22 +02:00
parent d8b10988d0
commit e6acdbf0f1
2 changed files with 14 additions and 7 deletions

View File

@ -812,13 +812,16 @@ wl_frame_paint(struct WFrameWindow *fwin)
wlr_scene_node_set_enabled(&rb_fb->scene_buf->node, show_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. */
/* Commit the parent frame buffer when it has visible content:
* resizebar pixels (unshaded) or titlebar fallback (when the titlebar
* child buffer is too narrow and we drew into the parent instead). */
if (fb->scene_buf) {
wlr_scene_buffer_set_buffer_with_damage(fb->scene_buf, &fb->base, NULL);
wlr_scene_node_set_enabled(&fb->scene_buf->node, true);
if (show_resizebar || !fwin->titlebar || !frame_buf_find(fwin->titlebar->window)) {
wlr_scene_buffer_set_buffer_with_damage(fb->scene_buf, &fb->base, NULL);
wlr_scene_node_set_enabled(&fb->scene_buf->node, true);
} else {
wlr_scene_node_set_enabled(&fb->scene_buf->node, false);
}
}
if (wl_state.output)

View File

@ -329,7 +329,11 @@ void wl_noop_client_send_event(WNativeWindow win, void *d) { (void)win; (void)d;
void wl_noop_window_get_colormap(WNativeWindow win, unsigned long *c) { (void)win; (void)c; }
WNativeWindow wl_noop_pointer_query_window(WNativeWindow root) { (void)root; return WNATIVE_NONE; }
void wl_noop_dialog_paint_icon(unsigned long d, void *b, void *p, WScreen *s,
int x, int y, int w, int h) { (void)d;(void)b;(void)p;(void)s;(void)x;(void)y;(void)w;(void)h; }const char *wl_noop_keysym_to_string(unsigned long ks) { (void)ks; return ""; }int wl_noop_window_get_command(WNativeWindow win, char ***a, int *c) { (void)win; (void)a; *c=0; return 0; }
int x, int y, int w, int h) { (void)d;(void)b;(void)p;(void)s;(void)x;(void)y;(void)w;(void)h; }const char *wl_noop_keysym_to_string(unsigned long ks) {
static char buf[64];
xkb_keysym_get_name((xkb_keysym_t)ks, buf, sizeof(buf));
return buf;
}int wl_noop_window_get_command(WNativeWindow win, char ***a, int *c) { (void)win; (void)a; *c=0; return 0; }
int wl_noop_netwm_process_client_message(WMEvent *e) { (void)e; return 0; }
int wl_noop_xdnd_process_client_message(WMEvent *e) { (void)e; return 0; }
void wl_noop_xdnd_process_selection(WMEvent *e) { (void)e; }