window: Add a target workspace for raise_and_make_recent

The shell might raise and make windows recent for another workspace when
an app gets activated on another workspace. Making the windows only
recent on the current workspace thus results in inconsistent focus when
another window of the same app is closed.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3315>
This commit is contained in:
Sebastian Wick 2023-10-06 12:58:22 +02:00
parent 13d9edc687
commit 9a6ddd2dff
2 changed files with 33 additions and 8 deletions

View File

@ -4556,11 +4556,19 @@ meta_window_transient_can_focus (MetaWindow *window)
}
static void
meta_window_make_most_recent (MetaWindow *window)
meta_window_make_most_recent (MetaWindow *window,
MetaWorkspace *target_workspace)
{
MetaWorkspaceManager *workspace_manager = window->display->workspace_manager;
GList *l;
/**
* Marks the window as the most recently used window on a specific workspace.
* If the window exists on all workspaces, it will become the most recently
* used sticky window on all other workspaces. This ensures proper tracking
* among windows on all workspaces while not overriding MRU for other windows.
*/
for (l = workspace_manager->workspaces; l != NULL; l = l->next)
{
MetaWorkspace *workspace = l->data;
@ -4572,16 +4580,19 @@ meta_window_make_most_recent (MetaWindow *window)
/*
* Move to the front of the MRU list if the window is on the
* active workspace or was explicitly made sticky
* target_workspace or was explicitly made sticky
*/
if (workspace == workspace_manager->active_workspace ||
window->on_all_workspaces_requested)
if (workspace == target_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;
}
/* Not sticky and not on the target workspace: we're done here */
if (!window->on_all_workspaces)
continue;
/* Otherwise move it before other sticky windows */
for (link = workspace->mru_list; link; link = link->next)
{
@ -4679,7 +4690,7 @@ meta_window_focus (MetaWindow *window,
if (workspace_manager->active_workspace &&
meta_window_located_on_workspace (window,
workspace_manager->active_workspace))
meta_window_make_most_recent (window);
meta_window_make_most_recent (window, workspace_manager->active_workspace);
backend = backend_from_window (window);
stage = CLUTTER_STAGE (meta_backend_get_stage (backend));
@ -5026,13 +5037,26 @@ meta_window_raise (MetaWindow *window)
g_signal_emit (window, window_signals[RAISED], 0);
}
/**
* meta_window_raise_and_make_recent_on_workspace:
* @window: a #MetaWindow
* @workspace: the #MetaWorkspace to raise and make it most recent on
*
* Raises a window and marks it as the most recently used window on the
* workspace @target_workspace. If the window exists on all workspaces, it will
* become the most recently used sticky window on all other workspaces. This
* ensures proper tracking among windows on all workspaces while not overriding
* MRU for other windows.
*/
void
meta_window_raise_and_make_recent (MetaWindow *window)
meta_window_raise_and_make_recent_on_workspace (MetaWindow *window,
MetaWorkspace *workspace)
{
g_return_if_fail (META_IS_WINDOW (window));
g_return_if_fail (META_IS_WORKSPACE (workspace));
meta_window_raise (window);
meta_window_make_most_recent (window);
meta_window_make_most_recent (window, workspace);
}
void

View File

@ -314,7 +314,8 @@ void meta_window_lower_with_transients (MetaWindow *window,
uint32_t timestamp);
META_EXPORT
void meta_window_raise_and_make_recent (MetaWindow *window);
void meta_window_raise_and_make_recent_on_workspace (MetaWindow *window,
MetaWorkspace *workspace);
META_EXPORT
const char *meta_window_get_title (MetaWindow *window);