window: Add raise_and_make_recent() method

After !2489, the active workspace's MRU list is now used to pick
the next focus window instead of the stack order.

This list is currently only updated on focus, which can lead to
surprising behavior when closing a window after activating its
ShellApp in the shell.

That is because raising a window (as part of shell_app_activate())
will only change the stacking order, so when closing the active
app window, the focus will switch to whatever had focus before the
app was activated, not the app's next window.

In order to allow gnome-shell to address this, add a new
raise_and_make_recent() method that also adjust the MRU order.

https://gitlab.gnome.org/GNOME/mutter/-/issues/2540

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2866>
This commit is contained in:
Florian Müllner 2023-02-23 19:57:43 +01:00 committed by Marge Bot
parent 79f5059df7
commit e74573e165
2 changed files with 32 additions and 16 deletions

View File

@ -4571,6 +4571,25 @@ meta_window_transient_can_focus (MetaWindow *window)
return TRUE; return TRUE;
} }
static void
meta_window_make_most_recent (MetaWindow *window) {
MetaWorkspaceManager *workspace_manager = window->display->workspace_manager;
GList *l;
for (l = workspace_manager->workspaces; l != NULL; l = l->next)
{
MetaWorkspace *workspace = l->data;
GList *link;
link = g_list_find (workspace->mru_list, window);
if (!link)
continue;
workspace->mru_list = g_list_delete_link (workspace->mru_list, link);
workspace->mru_list = g_list_prepend (workspace->mru_list, window);
}
}
/* XXX META_EFFECT_FOCUS */ /* XXX META_EFFECT_FOCUS */
void void
meta_window_focus (MetaWindow *window, meta_window_focus (MetaWindow *window,
@ -4651,22 +4670,7 @@ meta_window_focus (MetaWindow *window,
if (workspace_manager->active_workspace && if (workspace_manager->active_workspace &&
meta_window_located_on_workspace (window, meta_window_located_on_workspace (window,
workspace_manager->active_workspace)) workspace_manager->active_workspace))
{ meta_window_make_most_recent (window);
GList *l;
for (l = workspace_manager->workspaces; l != NULL; l = l->next)
{
MetaWorkspace *workspace = l->data;
GList *link;
link = g_list_find (workspace->mru_list, window);
if (!link)
continue;
workspace->mru_list = g_list_delete_link (workspace->mru_list, link);
workspace->mru_list = g_list_prepend (workspace->mru_list, window);
}
}
backend = backend_from_window (window); backend = backend_from_window (window);
stage = CLUTTER_STAGE (meta_backend_get_stage (backend)); stage = CLUTTER_STAGE (meta_backend_get_stage (backend));
@ -5013,6 +5017,15 @@ meta_window_raise (MetaWindow *window)
g_signal_emit (window, window_signals[RAISED], 0); g_signal_emit (window, window_signals[RAISED], 0);
} }
void
meta_window_raise_and_make_recent (MetaWindow *window)
{
g_return_if_fail (META_IS_WINDOW (window));
meta_window_raise (window);
meta_window_make_most_recent (window);
}
void void
meta_window_lower (MetaWindow *window) meta_window_lower (MetaWindow *window)
{ {

View File

@ -315,6 +315,9 @@ META_EXPORT
void meta_window_lower_with_transients (MetaWindow *window, void meta_window_lower_with_transients (MetaWindow *window,
uint32_t timestamp); uint32_t timestamp);
META_EXPORT
void meta_window_raise_and_make_recent (MetaWindow *window);
META_EXPORT META_EXPORT
const char *meta_window_get_title (MetaWindow *window); const char *meta_window_get_title (MetaWindow *window);