From a3413a840266bc178cf2b01fc87ca92357ef9cc8 Mon Sep 17 00:00:00 2001 From: lkn Date: Sun, 21 Jun 2026 17:55:35 +0200 Subject: [PATCH] WINGs/wayland: commit correct topLevel view after child widget repaint MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The upward compositing walk in render_wl_pixmap_copy, render_wl_fill_rect, and wl_draw_string traverses from the repainted widget to the root view. Previously, the commit at the end targeted the root view or searched its direct children for a topLevel — this found the main window instead of the dialog containing the widget that actually changed. Fix: track the topLevel ancestor during the upward walk and commit that specific view. This ensures dialog widgets (buttons, lists) have their visual feedback rendered to the correct scene_buf. --- WINGs/wfont_wl.c | 9 +++++++-- WINGs/wrender_wl.c | 35 +++++++++++++++-------------------- 2 files changed, 22 insertions(+), 22 deletions(-) diff --git a/WINGs/wfont_wl.c b/WINGs/wfont_wl.c index 679432e..636a2ef 100644 --- a/WINGs/wfont_wl.c +++ b/WINGs/wfont_wl.c @@ -190,7 +190,10 @@ wl_draw_string(void *sctx, void *handle, WMDrawable d, && (unsigned long)d < 0x30000000) { W_View *v = W_GetViewForWindow((WNativeWindow)(unsigned long)d); if (v && !v->flags.alreadyDead) { + W_View *topLevel = NULL; while (v && v->parent && !v->flags.alreadyDead) { + if (v->flags.topLevel) + topLevel = v; pixman_image_t *vs = (pixman_image_t *)W_GetViewBacking(v->window); pixman_image_t *pd = (pixman_image_t *)W_GetViewBacking(v->parent->window); if (vs && pd) @@ -200,8 +203,10 @@ wl_draw_string(void *sctx, void *handle, WMDrawable d, v->size.width, v->size.height); v = v->parent; } - if (v && !v->flags.alreadyDead && W_ViewCommitBackingFn) - W_ViewCommitBackingFn((unsigned long)v->window); + if (v && v->flags.topLevel) + topLevel = v; + if (topLevel && !topLevel->flags.alreadyDead && W_ViewCommitBackingFn) + W_ViewCommitBackingFn((unsigned long)topLevel->window); } } } diff --git a/WINGs/wrender_wl.c b/WINGs/wrender_wl.c index 5b462a3..86a0ed1 100644 --- a/WINGs/wrender_wl.c +++ b/WINGs/wrender_wl.c @@ -74,7 +74,10 @@ render_wl_pixmap_copy(void *rctx, WMDrawable src, WMDrawable dst, if ((unsigned long)dst >= 0x10000000 && (unsigned long)dst < 0x30000000) { W_View *view = W_GetViewForWindow((WNativeWindow)(unsigned long)dst); if (view && view->flags.alreadyDead) return; + W_View *topLevel = NULL; while (view && view->parent && !view->flags.alreadyDead) { + if (view->flags.topLevel) + topLevel = view; 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) { @@ -85,24 +88,11 @@ render_wl_pixmap_copy(void *rctx, WMDrawable src, WMDrawable dst, } view = view->parent; } - /* Commit the toplevel surface. If the cascade walked up to a - * root view that has no client backing, commit the nearest - * topLevel child instead. */ - if (view && !view->flags.alreadyDead && W_ViewCommitBackingFn) { - /* Check if the topmost parent is committable */ - if (view->flags.topLevel) { - W_ViewCommitBackingFn((unsigned long)view->window); - } else { - /* Walk down to find a topLevel child that has a backing */ - W_View *top = view->childrenList; - while (top) { - if (top->flags.topLevel && top->flags.realized) { - W_ViewCommitBackingFn((unsigned long)top->window); - break; - } - top = top->nextSister; - } - } + /* Also check the final view (root might be topLevel) */ + if (view && view->flags.topLevel) + topLevel = view; + if (topLevel && !topLevel->flags.alreadyDead && W_ViewCommitBackingFn) { + W_ViewCommitBackingFn((unsigned long)topLevel->window); } } } @@ -182,7 +172,10 @@ render_wl_fill_rect(void *rctx, WMDrawable d, WMColor *color, && (unsigned long)d < 0x30000000) { W_View *v = W_GetViewForWindow((WNativeWindow)(unsigned long)d); if (v && !v->flags.alreadyDead) { + W_View *topLevel = NULL; while (v && v->parent && !v->flags.alreadyDead) { + if (v->flags.topLevel) + topLevel = v; pixman_image_t *vs = W_GetViewBacking(v->window); pixman_image_t *pd = W_GetViewBacking(v->parent->window); if (vs && pd) @@ -192,8 +185,10 @@ render_wl_fill_rect(void *rctx, WMDrawable d, WMColor *color, v->size.width, v->size.height); v = v->parent; } - if (v && !v->flags.alreadyDead && W_ViewCommitBackingFn) - W_ViewCommitBackingFn((unsigned long)v->window); + if (v && v->flags.topLevel) + topLevel = v; + if (topLevel && !topLevel->flags.alreadyDead && W_ViewCommitBackingFn) + W_ViewCommitBackingFn((unsigned long)topLevel->window); } } }