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:
parent
4a6c5330a3
commit
ef98cc3c64
|
|
@ -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
1560
wprefs.log
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue