detach scene buffer before all pixman image replacements

Call wlr_scene_buffer_set_buffer(NULL) before freeing the old pixman
image in every resize path (client configure, frame configure,
workspace badge, balloon). This ensures the scene graph never holds
a dangling reference to freed pixel data.
This commit is contained in:
lkn 2026-06-23 21:42:00 +02:00
parent 711ff08b57
commit 7f6a7b66d1
3 changed files with 12 additions and 9 deletions

View File

@ -27,7 +27,8 @@ wl_workspace_badge_render(WScreen *scr, WNativeWindow badge_win,
/* Resize pixman buffer if needed */
if (width > 0 && height > 0 && (width != fb->width || height != fb->height)) {
W_UnregisterBacking(fb->id);
if (fb->scene_buf)
wlr_scene_buffer_set_buffer(fb->scene_buf, NULL);
pixman_image_unref(fb->image);
fb->image = pixman_image_create_bits(PIXMAN_a8r8g8b8, width, height, NULL, 0);
if (!fb->image) return NULL;
@ -35,7 +36,8 @@ wl_workspace_badge_render(WScreen *scr, WNativeWindow badge_win,
fb->height = height;
fb->base.width = width;
fb->base.height = height;
W_RegisterBacking(fb->id, fb->image);
if (fb->scene_buf)
wlr_scene_buffer_set_dest_size(fb->scene_buf, width, height);
}
/* Build shape mask: draw white text at 5x5 offsets on black.

View File

@ -515,6 +515,8 @@ wl_frame_configure(WNativeWindow win, int x, int y, int width, int height)
/* Resize: reallocate the pixman image if dimensions changed. */
if (width > 0 && height > 0 && (width != fb->width || height != fb->height)) {
if (fb->scene_buf)
wlr_scene_buffer_set_buffer(fb->scene_buf, NULL);
if (fb->image)
pixman_image_unref(fb->image);
fb->image = pixman_image_create_bits(PIXMAN_a8r8g8b8,
@ -523,9 +525,6 @@ wl_frame_configure(WNativeWindow win, int x, int y, int width, int height)
fb->height = height;
fb->base.width = width;
fb->base.height = height;
/* Notify scene graph of new size — required for hit-testing.
* wlroots caches buffer dimensions; without this, clicks beyond
* the old size would miss this scene_buf. */
if (fb->scene_buf)
wlr_scene_buffer_set_dest_size(fb->scene_buf, width, height);
}

View File

@ -277,14 +277,14 @@ void wl_window_resize(WNativeWindow win, int w, int h)
}
struct wl_frame_buf *fb = frame_buf_find(win);
if (fb && w > 0 && h > 0 && (w != fb->width || h != fb->height)) {
if (fb->scene_buf)
wlr_scene_buffer_set_buffer(fb->scene_buf, NULL);
pixman_image_unref(fb->image);
fb->image = pixman_image_create_bits(PIXMAN_a8r8g8b8, w, h, NULL, 0);
fb->width = w;
fb->height = h;
fb->base.width = w;
fb->base.height = h;
W_RegisterBacking(fb->id, fb->image);
/* Update scene graph's cached buffer size for hit-testing. */
if (fb->scene_buf)
wlr_scene_buffer_set_dest_size(fb->scene_buf, w, h);
}
@ -635,14 +635,16 @@ void wl_balloon_show(WScreen *scr, void *bal_ptr)
/* Resize pixman buffer if needed */
if (bw != fb->width || bh != fb->height) {
W_UnregisterBacking(fb->id);
if (fb->scene_buf)
wlr_scene_buffer_set_buffer(fb->scene_buf, NULL);
pixman_image_unref(fb->image);
fb->image = pixman_image_create_bits(PIXMAN_a8r8g8b8, bw, bh, NULL, 0);
fb->width = bw;
fb->height = bh;
fb->base.width = bw;
fb->base.height = bh;
W_RegisterBacking(fb->id, fb->image);
if (fb->scene_buf)
wlr_scene_buffer_set_dest_size(fb->scene_buf, bw, bh);
}
/* Fill pale yellow background */