From 34ed9fc1b25af18660df2b7c692fe4cc20370c6c Mon Sep 17 00:00:00 2001 From: lkn Date: Thu, 14 May 2026 21:35:50 +0200 Subject: [PATCH] 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. --- src/actions.c | 8 ++++++++ src/backend/wayland/wl_backend.c | 14 ++++++++++++-- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/src/actions.c b/src/actions.c index 9dec494..d125d85 100644 --- a/src/actions.c +++ b/src/actions.c @@ -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); diff --git a/src/backend/wayland/wl_backend.c b/src/backend/wayland/wl_backend.c index 2e9b4c5..e1db0f3 100644 --- a/src/backend/wayland/wl_backend.c +++ b/src/backend/wayland/wl_backend.c @@ -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);