fix popup reopen: shrink view size on 1x1 unmap; fix cascade commit target

Two concrete bugs fixed:

1. Popup reopen with 1x1 buffer: W_ResizeView returns early when view size
matches requested size. After 1x1 unmap, view->size.width/height was still the
original correct size, so resizeMenu never triggered wl_client_toplevel_resize.
Fix: set view size to 1x1 after replacing the buffer.

2. Selected item not updating button display: render_wl_pixmap_copy cascade
walks up to rootView (no WLClientToplevel) and commits it (no-op). After
paintPopUpButton, the mainAppView backing is updated but never committed.
Fix: when the cascade reaches rootView, fall back to committing the first
topLevel child that has a client backing.
This commit is contained in:
lkn 2026-06-07 17:32:44 +02:00
parent 1229f15a8e
commit 874f9b1ae0
3 changed files with 26 additions and 3 deletions

1
.gitignore vendored
View File

@ -97,3 +97,4 @@ src/wmaker-popup-v1-server-protocol.h
# User scratch
+cmd
/*Errors

View File

@ -584,6 +584,12 @@ wl_client_view_unmap(WNativeWindow id)
if (!top->buf) { top->buf = old; return; }
if (old) wlclient_destroy_shm_buffer(old);
W_SetViewBacking(top->view->window, top->buf->image);
/* Shrink the view size to 1x1 so W_ResizeView in resizeMenu detects
* a mismatch on reopen and actually resizes the buffer. Without this,
* W_ResizeView returns early (view already has the correct size from
* the first open) and wl_client_toplevel_resize is never called. */
top->view->size.width = 1;
top->view->size.height = 1;
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);

View File

@ -85,9 +85,25 @@ render_wl_pixmap_copy(void *rctx, WMDrawable src, WMDrawable dst,
}
view = view->parent;
}
/* Commit the toplevel surface */
if (view && !view->flags.alreadyDead && W_ViewCommitBackingFn)
W_ViewCommitBackingFn((unsigned long)view->window);
/* 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;
}
}
}
}
}