From 340a60927e4f1b20ca15596023e814b6948b832e Mon Sep 17 00:00:00 2001 From: lkn Date: Sun, 7 Jun 2026 15:44:22 +0200 Subject: [PATCH] wire W_ViewSceneNodeSetEnabledFn in WINGs client path via recycle/remap In WINGs client mode (e.g. WPrefs), W_ViewSceneNodeSetEnabledFn was never set because the compositor-side wl_backend.c does not run in the client process. When popup close calls wl_unmap, the function pointer was NULL, so the scene node was never disabled and the popup remained visible. Fix: during W_WLClientInit, if W_ViewSceneNodeSetEnabledFn is still NULL (unset by compositor), set it to wl_client_scene_node_set_enabled which calls recycle (destroy xdg_toplevel + wl_surface) on disable and remap (recreate from scratch) on enable. This ensures the client-side popup lifecycle correctly removes and recreates the surface, eliminating stale pixels without depending on compositor-side function pointers. --- WINGs/wclient_wl.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/WINGs/wclient_wl.c b/WINGs/wclient_wl.c index 37a0424..b790439 100644 --- a/WINGs/wclient_wl.c +++ b/WINGs/wclient_wl.c @@ -645,6 +645,15 @@ wl_client_toplevel_remap(WNativeWindow id) wl_client_toplevel_remap_locked(top); } +void +wl_client_scene_node_set_enabled(unsigned long id, int enabled) +{ + if (enabled) + wl_client_toplevel_remap((WNativeWindow)id); + else + wl_client_toplevel_recycle((WNativeWindow)id); +} + void W_WLClientSetMinMaxSize(W_View *view) { @@ -1388,6 +1397,17 @@ W_WLClientInit(struct W_Screen *scrPtr, const char *display) W_WLClientToplevelRealizeFn = wl_client_toplevel_realize; W_WLClientToplevelResizeFn = wl_client_toplevel_resize; W_WLClientToplevelDestroyFn = wl_client_toplevel_destroy; + /* Wire up scene-node enable/disable for client toplevels. + * When running as a client (e.g. WPrefs), the compositor-side + * function pointer is not available, so we use recycle/remap + * to destroy/recreate the wl_surface instead. */ + extern void (*W_ViewSceneNodeSetEnabledFn)(unsigned long id, int enabled); + if (!W_ViewSceneNodeSetEnabledFn) { + extern void wl_client_toplevel_recycle(WNativeWindow); + extern void wl_client_toplevel_remap(WNativeWindow); + W_ViewSceneNodeSetEnabledFn = + wl_client_scene_node_set_enabled; + } { extern void (*W_ViewCommitBackingFn)(unsigned long id); extern void (*W_ViewDestroyBackingFn)(unsigned long id);