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: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2909>
This commit is contained in:
Sebastian Wick 2023-03-10 21:33:47 +01:00
parent 3bbff537d9
commit 87bd574598

View File

@ -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);
}
}