From a1d9fdf9f109e5f229f85992563ee254f6ff4d1c Mon Sep 17 00:00:00 2001 From: Window Maker Date: Sat, 23 May 2026 22:07:41 +0200 Subject: [PATCH] wayland: fix orphan menu titlebars at startup MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Top-level frame trees were enabled by default at creation. When framewin.c then called wm_backend->window_map_raised(titlebar) at frame creation time (necessary for X11 decoration semantics), the titlebar's scene_buf became enabled. Combined with the always-enabled tree, this made the titlebar visually rendered at the frame's default spawn position — even for menus and dialogs that had not been logically mapped yet. The visible orphan reflected whichever submenu titlebar was painted last (e.g. 'Multimedia'). Fix: top-level frame trees now start DISABLED. wl_window_map and wl_window_map_raised explicitly enable the tree when called on a top-level frame_buf. This matches X11 semantics where a child window is only visible if its parent window is mapped. Decoration children (titlebar, buttons) being individually 'mapped' no longer produces orphan visibility because the parent frame's tree gates their visibility. --- src/backend/wayland/wl_backend.c | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/src/backend/wayland/wl_backend.c b/src/backend/wayland/wl_backend.c index 5cfa8ad..352f7d8 100644 --- a/src/backend/wayland/wl_backend.c +++ b/src/backend/wayland/wl_backend.c @@ -4193,7 +4193,13 @@ wl_frame_create_toplevel(WScreen *scr, wlr_scene_node_set_position(&fb->scene_buf->node, 0, 0); wlr_scene_node_set_enabled(&fb->scene_buf->node, false); } - wlr_scene_node_set_enabled(&fb->tree->node, true); + /* Tree starts disabled — wl_window_map enables it when the + * frame is logically mapped. Without this, decoration + * children (titlebar, buttons) of unmapped menus/dialogs + * appear as orphans because window_map_raised on those + * children enables their scene_bufs while the frame itself + * has not been mapped. */ + wlr_scene_node_set_enabled(&fb->tree->node, false); } } @@ -4462,8 +4468,9 @@ wl_frame_paint(struct WFrameWindow *fwin) } /* Commit titlebar buffer */ - if (tb_fb && tb_fb->scene_buf) + if (tb_fb && tb_fb->scene_buf) { wlr_scene_buffer_set_buffer(tb_fb->scene_buf, &tb_fb->base); + } } /* --- Titlebar buttons --- */ @@ -6496,10 +6503,13 @@ wl_window_map_raised(WNativeWindow win) struct wl_frame_buf *fb = frame_buf_find(win); if (fb && fb->scene_buf) { wlr_scene_node_set_enabled(&fb->scene_buf->node, true); - if (fb->tree) + if (fb->tree) { + /* Top-level frame: enable tree (decoration children become visible). */ + wlr_scene_node_set_enabled(&fb->tree->node, true); wlr_scene_node_raise_to_top(&fb->tree->node); - else + } else { wlr_scene_node_raise_to_top(&fb->scene_buf->node); + } return; } } @@ -8597,7 +8607,7 @@ static void wl_menu_paint_entry(WMenu *menu, int index, int selected) for (int col = 0; col < w && col < fb->width; col++) dst[(y + h - 1) * stride + col] = dark; - wlr_scene_buffer_set_buffer(fb->scene_buf, &fb->base); + wlr_scene_buffer_set_buffer_with_damage(fb->scene_buf, &fb->base, NULL); } static void wl_menu_draw_frame(WScreen *scr, WNativeWindow win, int y, int w, int h, int type) @@ -8628,7 +8638,7 @@ static void wl_menu_draw_frame(WScreen *scr, WNativeWindow win, int y, int w, in dst[y * stride + col] = light; (void)scr; (void)type; - wlr_scene_buffer_set_buffer(fb->scene_buf, &fb->base); + wlr_scene_buffer_set_buffer_with_damage(fb->scene_buf, &fb->base, NULL); } static void wl_noop_draw_bevel(WNativeWindow d, unsigned int width, unsigned int height,