From 03514bb31a6df8a2ba19181420c13c00a35d5424 Mon Sep 17 00:00:00 2001 From: Alexander Mikhaylenko Date: Sat, 12 Oct 2019 23:55:26 +0500 Subject: [PATCH] window: Make default focus window on each workspace appear focused Makes workspace transitions in gnome-shell look more seamless, since both outgoing and incoming workspace have focused windows. This is only done for click focus mode, since it's not known which window would be focused for the other modes. https://gitlab.gnome.org/GNOME/mutter/merge_requests/850 --- src/core/window-private.h | 2 ++ src/core/window.c | 21 +++++++++++++++++++-- src/core/workspace.c | 26 ++++++++++++++++++++++++++ 3 files changed, 47 insertions(+), 2 deletions(-) diff --git a/src/core/window-private.h b/src/core/window-private.h index ed5d8059b..12123e2d2 100644 --- a/src/core/window-private.h +++ b/src/core/window-private.h @@ -704,6 +704,8 @@ void meta_window_get_session_geometry (MetaWindow *window, void meta_window_update_unfocused_button_grabs (MetaWindow *window); +void meta_window_appears_focused_changed (MetaWindow *window); + void meta_window_set_focused_internal (MetaWindow *window, gboolean focused); diff --git a/src/core/window.c b/src/core/window.c index c660a3b0c..550762e6d 100644 --- a/src/core/window.c +++ b/src/core/window.c @@ -251,6 +251,10 @@ prefs_changed_callback (MetaPreference pref, meta_window_recalc_features (window); meta_window_queue (window, META_QUEUE_MOVE_RESIZE); } + else if (pref == META_PREF_FOCUS_MODE) + { + meta_window_appears_focused_changed (window); + } } static void @@ -4872,6 +4876,9 @@ set_workspace_state (MetaWindow *window, } } + if (!window->constructing) + meta_window_appears_focused_changed (window); + /* queue a move_resize since changing workspaces may change * the relevant struts */ @@ -5171,7 +5178,7 @@ meta_window_change_workspace_by_index (MetaWindow *window, meta_window_change_workspace (window, workspace); } -static void +void meta_window_appears_focused_changed (MetaWindow *window) { set_net_wm_state (window); @@ -7255,7 +7262,17 @@ meta_window_get_frame (MetaWindow *window) gboolean meta_window_appears_focused (MetaWindow *window) { - return window->has_focus || (window->attached_focus_window != NULL); + MetaWorkspaceManager *workspace_manager; + MetaWorkspace *workspace; + MetaWindow *default_window = NULL; + + workspace_manager = window->display->workspace_manager; + workspace = meta_window_get_workspace (window); + + if (workspace && workspace != workspace_manager->active_workspace) + default_window = meta_workspace_get_default_focus_window (workspace); + + return window->has_focus || (window->attached_focus_window != NULL) || (window == default_window); } gboolean diff --git a/src/core/workspace.c b/src/core/workspace.c index 16b21ec19..75b74707d 100644 --- a/src/core/workspace.c +++ b/src/core/workspace.c @@ -365,10 +365,27 @@ meta_workspace_remove (MetaWorkspace *workspace) */ } +static void +workspace_default_focus_changed (MetaWorkspace *workspace, + MetaWindow *not_this_one) +{ + GSList *windows, *l; + + windows = meta_display_list_windows (workspace->display, META_LIST_DEFAULT); + for (l = windows; l; l = l->next) { + MetaWindow *window = META_WINDOW (l->data); + + if (meta_window_located_on_workspace (window, workspace) && window != not_this_one) + meta_window_appears_focused_changed (window); + } +} + void meta_workspace_add_window (MetaWorkspace *workspace, MetaWindow *window) { + MetaWorkspaceManager *manager = workspace->display->workspace_manager; + COGL_TRACE_BEGIN_SCOPED (MetaWorkspaceAddWindow, "Workspace (add window)"); @@ -385,6 +402,9 @@ meta_workspace_add_window (MetaWorkspace *workspace, meta_workspace_invalidate_work_area (workspace); } + if (workspace != manager->active_workspace) + workspace_default_focus_changed (workspace, window); + g_signal_emit (workspace, signals[WINDOW_ADDED], 0, window); g_object_notify_by_pspec (G_OBJECT (workspace), obj_props[PROP_N_WINDOWS]); } @@ -393,6 +413,8 @@ void meta_workspace_remove_window (MetaWorkspace *workspace, MetaWindow *window) { + MetaWorkspaceManager *manager = workspace->display->workspace_manager; + COGL_TRACE_BEGIN_SCOPED (MetaWorkspaceRemoveWindow, "Workspace (remove window)"); @@ -409,6 +431,9 @@ meta_workspace_remove_window (MetaWorkspace *workspace, meta_workspace_invalidate_work_area (workspace); } + if (workspace != manager->active_workspace) + workspace_default_focus_changed (workspace, window); + g_signal_emit (workspace, signals[WINDOW_REMOVED], 0, window); g_object_notify (G_OBJECT (workspace), "n-windows"); } @@ -657,6 +682,7 @@ meta_workspace_activate_with_focus (MetaWorkspace *workspace, if (focus_this) { meta_window_activate (focus_this, timestamp); + workspace_default_focus_changed (workspace, focus_this); } else if (move_window) {