From 79fbb611e019583c87158aec1879dd952a5d0c99 Mon Sep 17 00:00:00 2001 From: John Lindgren Date: Fri, 7 Nov 2025 22:38:32 -0500 Subject: [PATCH] view: less hacky support for minimize-before-map The previous "minimal fix" (5148c2aa3140) worked but was a bit of a hack, as it basically un-minimized and then immediately minimized the view again at map. It's not actually too difficult to make the map handlers aware of minimized views, eliminating the need for the hack. Note: this depends on the previous commit ("xwayland: connect commit and surface_destroy handlers together") otherwise the xwayland map handler registers the commit handler twice, leading to a crash. --- src/foreign-toplevel/foreign.c | 1 - src/view-impl-common.c | 5 ++++- src/view.c | 13 +------------ src/xdg.c | 16 ++++++++++++---- src/xwayland.c | 11 +++++++++-- 5 files changed, 26 insertions(+), 20 deletions(-) diff --git a/src/foreign-toplevel/foreign.c b/src/foreign-toplevel/foreign.c index 14563431..4290ffd0 100644 --- a/src/foreign-toplevel/foreign.c +++ b/src/foreign-toplevel/foreign.c @@ -18,7 +18,6 @@ struct foreign_toplevel * foreign_toplevel_create(struct view *view) { assert(view); - assert(view->mapped); struct foreign_toplevel *toplevel = znew(*toplevel); wlr_foreign_toplevel_init(&toplevel->wlr_toplevel, view); diff --git a/src/view-impl-common.c b/src/view-impl-common.c index 21590588..8cb4d80f 100644 --- a/src/view-impl-common.c +++ b/src/view-impl-common.c @@ -10,7 +10,10 @@ void view_impl_map(struct view *view) { - desktop_focus_view(view, /*raise*/ true); + /* Leave minimized, if minimized before map */ + if (!view->minimized) { + desktop_focus_view(view, /*raise*/ true); + } if (!view->been_mapped) { window_rules_apply(view, LAB_WINDOW_RULE_EVENT_ON_FIRST_MAP); } diff --git a/src/view.c b/src/view.c index 45e9fc45..efad9d83 100644 --- a/src/view.c +++ b/src/view.c @@ -2458,18 +2458,7 @@ static void handle_map(struct wl_listener *listener, void *data) { struct view *view = wl_container_of(listener, view, mappable.map); - if (view->minimized) { - /* - * The view->impl functions do not directly support - * mapping a view while minimized. Instead, mark it as - * not minimized, map it, and then minimize it again. - */ - view->minimized = false; - view->impl->map(view); - view_minimize(view, true); - } else { - view->impl->map(view); - } + view->impl->map(view); } static void diff --git a/src/xdg.c b/src/xdg.c index 83ab9bb9..363d7019 100644 --- a/src/xdg.c +++ b/src/xdg.c @@ -781,8 +781,6 @@ xdg_toplevel_view_map(struct view *view) return; } - view->mapped = true; - /* * An output should have been chosen when the surface was first * created, but take one more opportunity to assign an output if not. @@ -790,8 +788,16 @@ xdg_toplevel_view_map(struct view *view) if (!view->output) { view_set_output(view, output_nearest_to_cursor(view->server)); } - struct wlr_xdg_surface *xdg_surface = xdg_surface_from_view(view); - wlr_scene_node_set_enabled(&view->scene_tree->node, true); + + /* + * For initially minimized views, we do not set view->mapped + * nor enable the scene node. All other map logic (positioning, + * creating foreign toplevel, etc.) happens as normal. + */ + if (!view->minimized) { + view->mapped = true; + wlr_scene_node_set_enabled(&view->scene_tree->node, true); + } if (!view->foreign_toplevel) { init_foreign_toplevel(view); @@ -813,6 +819,8 @@ xdg_toplevel_view_map(struct view *view) * dimensions remain zero until handle_commit(). */ if (wlr_box_empty(&view->pending)) { + struct wlr_xdg_surface *xdg_surface = + xdg_surface_from_view(view); view->pending.width = xdg_surface->geometry.width; view->pending.height = xdg_surface->geometry.height; } diff --git a/src/xwayland.c b/src/xwayland.c index 1a1cc9b0..ac30941f 100644 --- a/src/xwayland.c +++ b/src/xwayland.c @@ -832,8 +832,15 @@ xwayland_view_map(struct view *view) */ handle_map_request(&xwayland_view->map_request, NULL); - view->mapped = true; - wlr_scene_node_set_enabled(&view->scene_tree->node, true); + /* + * For initially minimized views, we do not set view->mapped + * nor enable the scene node. All other map logic (positioning, + * creating foreign toplevel, etc.) happens as normal. + */ + if (!view->minimized) { + view->mapped = true; + wlr_scene_node_set_enabled(&view->scene_tree->node, true); + } if (view->surface != xwayland_surface->surface) { set_surface(view, xwayland_surface->surface);