view: avoid repeated focus changes unminimizing parent/child views

When unminimizing a group of N parent/child views, we currently end up
triggering N focus changes (as well as O(N^2) surface restackings) due
to calling desktop_focus_view() for each view in turn.

Since desktop_focus_view() already raises all sibling views together
via view_move_to_front(), let's make view_minimize() call it only once
at the very end, once all views are visible.

Test cases:
- Audacious with floating plugin views (XWayland)
- xfce4-terminal with About dialog (xdg-shell)

v2: also avoid repeated focus changes when minimizing
This commit is contained in:
John Lindgren 2026-01-16 00:59:39 -05:00 committed by Johan Malm
parent 7d7ece21d9
commit cd291fe051
2 changed files with 49 additions and 28 deletions

View file

@ -11,6 +11,11 @@ view_impl_map(struct view *view)
{
view_update_visibility(view);
/* 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);
}
@ -41,6 +46,19 @@ view_impl_unmap(struct view *view)
{
view_update_visibility(view);
/*
* When exiting an xwayland application with multiple views
* mapped, a race condition can occur: after the topmost view
* is unmapped, the next view under it is offered focus, but is
* also unmapped before accepting focus (so server->active_view
* remains NULL). To avoid being left with no active view at
* all, check for that case also.
*/
struct server *server = view->server;
if (view == server->active_view || !server->active_view) {
desktop_focus_topmost_view(server);
}
/*
* Destroy the foreign toplevel handle so the unmapped view
* doesn't show up in panels and the like.