From 1229f15a8e77b9d9753305fcd5491c8462050e16 Mon Sep 17 00:00:00 2001 From: lkn Date: Sun, 7 Jun 2026 17:25:19 +0200 Subject: [PATCH] wl_client_view_unmap: replace buffer with 1x1 transparent instead of NULL to avoid xdg unmap NULL-buffer unmap requires a configure/ack cycle before the next real buffer commit. The compositor may not send a configure event for a NULL unmap, leaving the surface stuck at configured=0 on reopen. Fix: replace the popup buffer with a 1x1 transparent buffer on close. This hides the popup visually without triggering an xdg unmap. The surface stays configured and alive. On reopen, resizeMenu (now always called in popUpMenu) creates a correct-size buffer via wl_client_toplevel_resize. wl_redisplay then paints into the new buffer and commits immediately. No configure/ack cycle needed. --- WINGs/wclient_wl.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/WINGs/wclient_wl.c b/WINGs/wclient_wl.c index e8aeb4f..52fb8e4 100644 --- a/WINGs/wclient_wl.c +++ b/WINGs/wclient_wl.c @@ -574,12 +574,19 @@ wl_client_view_unmap(WNativeWindow id) { WLClientToplevel *top = wlc_top_find(id); if (!top || !top->surface) return; - /* Attach NULL + commit to hide the surface. The xdg_surface - * stays configured after the first configure/ack, so subsequent - * commits do not need a new configure event. */ - wl_surface_attach(top->surface, NULL, 0, 0); + /* Replace the popup buffer with a 1x1 transparent buffer. This + * hides the popup visually without triggering an xdg unmap, so + * no configure/ack cycle is needed on reopen. The surface stays + * configured and alive. On reopen, resizeMenu creates a new + * correct-size buffer via wl_client_toplevel_resize. */ + WLClientShmBuffer *old = top->buf; + top->buf = wlclient_create_shm_buffer(top->ctx, 1, 1); + if (!top->buf) { top->buf = old; return; } + if (old) wlclient_destroy_shm_buffer(old); + W_SetViewBacking(top->view->window, top->buf->image); + wl_surface_attach(top->surface, top->buf->wl_buf, 0, 0); + wl_surface_damage_buffer(top->surface, 0, 0, 1, 1); wl_surface_commit(top->surface); - top->configured = 0; top->mapped = 0; if (top->ctx && top->ctx->display) wl_display_flush(top->ctx->display);