wayland: hide resizebar when window is shaded

On Wayland, scene buffer nodes are independently composited and not
clipped to their parent frame bounds. When shading collapses the frame
to titlebar height, the resizebar scene node remained visible because
nothing disabled it.

Two changes:

1. wl_frame_paint: skip resizebar rendering and disable both the
   resizebar own scene node and the main frame scene buffer when the
   frame height is <= the titlebar height (shaded). Re-enable both
   when unshaded.

2. actions.c: call wm_backend->frame_paint() after wFrameWindowResize
   in both wShadeWindow and wUnshadeWindow. This triggers the scene
   graph update on Wayland and is a harmless decoration refresh on X11.
This commit is contained in:
lkn 2026-05-14 21:35:50 +02:00
parent 42e07acc4f
commit 34ed9fc1b2
2 changed files with 20 additions and 2 deletions

View File

@ -261,6 +261,10 @@ void wShadeWindow(WWindow *wwin)
/* for the client it's just like iconification */
wFrameWindowResize(wwin->frame, wwin->frame->core->width, wwin->frame->top_width - 1);
/* Repaint frame so the resizebar scene node is hidden (Wayland) or
* decorations are refreshed at the new size (X11). */
wm_backend->frame_paint(wwin->frame);
wwin->client.y = wwin->frame_y - wwin->client.height + wwin->frame->top_width;
wWindowSynthConfigureNotify(wwin);
@ -296,6 +300,10 @@ void wUnshadeWindow(WWindow *wwin)
wFrameWindowResize(wwin->frame, wwin->frame->core->width,
wwin->frame->top_width + wwin->client.height + wwin->frame->bottom_width);
/* Repaint frame so the resizebar scene node is restored (Wayland) or
* decorations are refreshed at the new size (X11). */
wm_backend->frame_paint(wwin->frame);
wwin->client.y = wwin->frame_y + wwin->frame->top_width;
wWindowSynthConfigureNotify(wwin);

View File

@ -4124,7 +4124,10 @@ wl_frame_paint(struct WFrameWindow *fwin)
}
/* --- Resizebar --- */
if (fwin->resizebar && fwin->bottom_width > 0) {
/* Skip resizebar when frame is shaded (height ≤ titlebar). */
bool show_resizebar = fwin->resizebar && fwin->bottom_width > 0
&& total_h > (int)fwin->top_width;
if (show_resizebar) {
int rb_y = total_h - fwin->bottom_width;
int rb_w = total_w;
int rb_h = fwin->bottom_width;
@ -4165,9 +4168,16 @@ wl_frame_paint(struct WFrameWindow *fwin)
}
}
/* Hide the resizebar's own scene node when shaded. */
if (fwin->resizebar) {
struct wl_frame_buf *rb_fb = frame_buf_find(fwin->resizebar->window);
if (rb_fb && rb_fb->scene_buf)
wlr_scene_node_set_enabled(&rb_fb->scene_buf->node, show_resizebar);
}
/* Commit the buffer to the scene graph only if it has content (resizebar). */
if (fb->scene_buf) {
if (fwin->resizebar && fwin->bottom_width > 0)
if (show_resizebar)
wlr_scene_buffer_set_buffer(fb->scene_buf, &fb->base);
else
wlr_scene_node_set_enabled(&fb->scene_buf->node, false);