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.
This commit is contained in:
lkn 2026-06-07 17:25:19 +02:00
parent 93d69639dc
commit 1229f15a8e
1 changed files with 12 additions and 5 deletions

View File

@ -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);