WINGs: guard against destroyed views in redisplay and composite-up

When a button click triggers changeSection which destroys widgets
(nameL, versionL, statusL) and then maps new ones, the recursive
wl_redisplay and the composite-up in render_wl_pixmap_copy could
encounter views marked alreadyDead or with freed backings.

Add alreadyDead checks to:
- wl_redisplay entry (skip dead views)
- wl_redisplay child iteration (skip dead children)
- render_wl_pixmap_copy composite-up loop (stop at dead views)
This commit is contained in:
Window Maker 2026-05-24 16:17:06 +02:00
parent 777a5229eb
commit 8d77acc349
2 changed files with 5 additions and 4 deletions

View File

@ -72,7 +72,8 @@ render_wl_pixmap_copy(void *rctx, WMDrawable src, WMDrawable dst,
* up through the parent chain so the change becomes visible. */
if ((unsigned long)dst >= 0x10000000 && (unsigned long)dst < 0x30000000) {
W_View *view = W_GetViewForWindow((WNativeWindow)(unsigned long)dst);
while (view && view->parent) {
if (view && view->flags.alreadyDead) return;
while (view && view->parent && !view->flags.alreadyDead) {
pixman_image_t *vs = (pixman_image_t *)W_GetViewBacking(view->window);
pixman_image_t *pd = (pixman_image_t *)W_GetViewBacking(view->parent->window);
if (vs && pd) {
@ -84,7 +85,7 @@ render_wl_pixmap_copy(void *rctx, WMDrawable src, WMDrawable dst,
view = view->parent;
}
/* Commit the toplevel surface */
if (view && W_ViewCommitBackingFn)
if (view && !view->flags.alreadyDead && W_ViewCommitBackingFn)
W_ViewCommitBackingFn((unsigned long)view->window);
}
}

View File

@ -384,7 +384,7 @@ static void wl_redisplay(void *vctx, W_View *view)
(void)vctx;
if (!view->flags.mapped)
if (!view->flags.mapped || view->flags.alreadyDead)
return;
/* Fill background color */
@ -417,7 +417,7 @@ static void wl_redisplay(void *vctx, W_View *view)
/* Re-composite all mapped children into this view's backing */
W_View *child = view->childrenList;
while (child) {
if (child->flags.mapped && child->flags.realized) {
if (child->flags.mapped && child->flags.realized && !child->flags.alreadyDead) {
wl_redisplay(vctx, child);
}
child = child->nextSister;