WINGs/wayland: prevent infinite redisplay recursion during resize

The font prefs panel crashed because wl_resize called wl_redisplay
while already inside a redisplay. This caused expose handlers to
trigger more resizes, creating unbounded recursion and memory growth
(backing images growing to 1024+ pixels wide). Skip the redisplay
from wl_resize when wl_redisplay_depth > 0 — the ongoing parent
redisplay will composite the resized child at its new size.
This commit is contained in:
Window Maker 2026-05-25 13:19:39 +02:00
parent 4a6c5330a3
commit ef98cc3c64
2 changed files with 1565 additions and 18 deletions

View File

@ -365,7 +365,10 @@ static void wl_resize(void *vctx, W_View *view, unsigned int w, unsigned int h)
cev._view_target = view->parent;
WMHandleEvent(&cev);
}
wl_redisplay(vctx, view);
/* Only redisplay if not already inside a redisplay (prevents
* infinite recursion when expose handlers trigger resizes). */
if (wl_redisplay_depth == 0)
wl_redisplay(vctx, view);
}
}
@ -478,6 +481,19 @@ static void wl_redisplay(void *vctx, W_View *view)
if (view->parent && view->size.width > 0 && view->size.height > 0) {
pixman_image_t *src = (pixman_image_t *)W_GetViewBacking(view->window);
pixman_image_t *dst = (pixman_image_t *)W_GetViewBacking(view->parent->window);
if (!src || !dst || !pixman_image_get_data(src) || !pixman_image_get_data(dst)) {
wwarning("wl_redisplay: BAD composite view=0x%lx size=%dx%d src=%p dst=%p"
" src_data=%p dst_data=%p src_dim=%dx%d dst_dim=%dx%d",
(unsigned long)view->window,
view->size.width, view->size.height,
(void*)src, (void*)dst,
src ? (void*)pixman_image_get_data(src) : NULL,
dst ? (void*)pixman_image_get_data(dst) : NULL,
src ? pixman_image_get_width(src) : 0,
src ? pixman_image_get_height(src) : 0,
dst ? pixman_image_get_width(dst) : 0,
dst ? pixman_image_get_height(dst) : 0);
}
if (src && dst && pixman_image_get_data(src) && pixman_image_get_data(dst)) {
int sw = pixman_image_get_width(src);
int sh = pixman_image_get_height(src);
@ -488,10 +504,13 @@ static void wl_redisplay(void *vctx, W_View *view)
/* Clip to destination bounds */
if (view->pos.x + cw > dw) cw = dw - view->pos.x;
if (view->pos.y + ch > dh) ch = dh - view->pos.y;
if (cw > 0 && ch > 0 && view->pos.x >= 0 && view->pos.y >= 0)
if (cw > 0 && ch > 0 && view->pos.x >= 0 && view->pos.y >= 0) {
fprintf(stderr, "COMPOSITE view=0x%lx pos=%d,%d cw=%d ch=%d sw=%d sh=%d dw=%d dh=%d\n",
(unsigned long)view->window, view->pos.x, view->pos.y, cw, ch, sw, sh, dw, dh);
pixman_image_composite32(PIXMAN_OP_OVER, src, NULL, dst,
0, 0, 0, 0,
view->pos.x, view->pos.y, cw, ch);
}
}
}

1560
wprefs.log

File diff suppressed because it is too large Load Diff