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:
parent
777a5229eb
commit
8d77acc349
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Reference in New Issue