From 9a6ddd2dff96881e1ce5b59bce3f3d688f5aebbf Mon Sep 17 00:00:00 2001 From: Sebastian Wick Date: Fri, 6 Oct 2023 12:58:22 +0200 Subject: [PATCH] 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: --- src/core/window.c | 38 +++++++++++++++++++++++++++++++------- src/meta/window.h | 3 ++- 2 files changed, 33 insertions(+), 8 deletions(-) diff --git a/src/core/window.c b/src/core/window.c index 408fe20ac..01e8e5770 100644 --- a/src/core/window.c +++ b/src/core/window.c @@ -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 diff --git a/src/meta/window.h b/src/meta/window.h index 42fedfadd..127160e78 100644 --- a/src/meta/window.h +++ b/src/meta/window.h @@ -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);