From 7e21ae259a1440eb5888efe47f883bf63a53a65d Mon Sep 17 00:00:00 2001 From: Window Maker Date: Sun, 24 May 2026 15:55:12 +0200 Subject: [PATCH] WINGs/wrender_wl: composite up to toplevel after pixmap_copy to view On X11, painting to a window pixmap (via XCopyArea in the DOUBLE_BUFFER path) makes content immediately visible because the X server handles display. On Wayland, writing to a view's backing pixman image has no effect until it's composited up through the parent chain to the toplevel surface and committed. When render_wl_pixmap_copy detects the destination is a registered view backing (ID in 0x10000000-0x2FFFFFFF range), it now walks up the parent chain compositing each view into its parent, then commits the toplevel. This makes widget paint operations (labels, buttons, frames) immediately visible without requiring a full wl_redisplay cycle. --- WINGs/wrender_wl.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/WINGs/wrender_wl.c b/WINGs/wrender_wl.c index 5406de8..431fa57 100644 --- a/WINGs/wrender_wl.c +++ b/WINGs/wrender_wl.c @@ -54,6 +54,9 @@ render_wl_pixmap_free(void *rctx, WMDrawable pm) pixman_image_unref((pixman_image_t *)pm); } +extern W_View *W_GetViewForWindow(WNativeWindow id); +extern void (*W_ViewCommitBackingFn)(unsigned long id); + static void render_wl_pixmap_copy(void *rctx, WMDrawable src, WMDrawable dst, int sx, int sy, unsigned int w, unsigned int h, int dx, int dy) @@ -64,6 +67,26 @@ render_wl_pixmap_copy(void *rctx, WMDrawable src, WMDrawable dst, if (!d) return; pixman_image_composite32(PIXMAN_OP_SRC, s, NULL, d, sx, sy, 0, 0, dx, dy, w, h); + + /* If dst is a view backing (DOUBLE_BUFFER copy-to-window), composite + * 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) { + 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) { + pixman_image_composite32(PIXMAN_OP_OVER, vs, NULL, pd, + 0, 0, 0, 0, + view->pos.x, view->pos.y, + view->size.width, view->size.height); + } + view = view->parent; + } + /* Commit the toplevel surface */ + if (view && W_ViewCommitBackingFn) + W_ViewCommitBackingFn((unsigned long)view->window); + } } static inline pixman_color_t