From 8d77acc349f76463ece7b201a529066fbb9bd9b7 Mon Sep 17 00:00:00 2001 From: Window Maker Date: Sun, 24 May 2026 16:17:06 +0200 Subject: [PATCH] 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) --- WINGs/wrender_wl.c | 5 +++-- WINGs/wview_wl.c | 4 ++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/WINGs/wrender_wl.c b/WINGs/wrender_wl.c index 431fa57..ba33e72 100644 --- a/WINGs/wrender_wl.c +++ b/WINGs/wrender_wl.c @@ -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); } } diff --git a/WINGs/wview_wl.c b/WINGs/wview_wl.c index 732cf64..28aa5be 100644 --- a/WINGs/wview_wl.c +++ b/WINGs/wview_wl.c @@ -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;