From 87bd574598539196ae102cfdb294957993519e74 Mon Sep 17 00:00:00 2001 From: Sebastian Wick Date: Fri, 10 Mar 2023 21:33:47 +0100 Subject: [PATCH] core/window: Change MRU behavior for windows on secondary output Current behavior pushes a window which receives focus to the start of the MRU list on every workspace it is on. By focusing a sticky window the default focus on all other workspaces changes as well. This is fine for sticky windows explicitly marked as sticky by the user but if a window is on a secondary output and workspaces are only on the primary output the behavior is unexpected. Instead we want the window to be the default focus only on the current workspace but also keep those windows in a relative MRU order to each other on all workspaces. Closes: https://gitlab.gnome.org/GNOME/mutter/-/issues/2681 Fixes: 058981dc1 ("workspace: Focus the default window only if no window is focused") Part-of: --- src/core/window.c | 34 +++++++++++++++++++++++++++++----- 1 file changed, 29 insertions(+), 5 deletions(-) diff --git a/src/core/window.c b/src/core/window.c index 46d44ea4b..28dda785e 100644 --- a/src/core/window.c +++ b/src/core/window.c @@ -4575,14 +4575,38 @@ meta_window_make_most_recent (MetaWindow *window) for (l = workspace_manager->workspaces; l != NULL; l = l->next) { MetaWorkspace *workspace = l->data; - GList *link; + GList *self, *link; - link = g_list_find (workspace->mru_list, window); - if (!link) + self = g_list_find (workspace->mru_list, window); + if (!self) continue; - workspace->mru_list = g_list_delete_link (workspace->mru_list, link); - workspace->mru_list = g_list_prepend (workspace->mru_list, window); + /* + * Move to the front of the MRU list if the window is on the + * active workspace or was explicitly made sticky + */ + if (workspace == workspace_manager->active_workspace || + window->on_all_workspaces_requested) + { + workspace->mru_list = g_list_delete_link (workspace->mru_list, self); + workspace->mru_list = g_list_prepend (workspace->mru_list, window); + continue; + } + + /* Otherwise move it before other sticky windows */ + for (link = workspace->mru_list; link; link = link->next) + { + MetaWindow *mru_window = link->data; + + if (mru_window->workspace == NULL) + break; + } + + if (link == self) + continue; + + workspace->mru_list = g_list_delete_link (workspace->mru_list, self); + workspace->mru_list = g_list_insert_before (workspace->mru_list, link, window); } }