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
This commit is contained in:
Alexander Mikhaylenko 2019-10-12 23:55:26 +05:00 committed by Alexander Mikhaylenko
parent 697b84e80e
commit 03514bb31a
3 changed files with 47 additions and 2 deletions

View File

@ -704,6 +704,8 @@ void meta_window_get_session_geometry (MetaWindow *window,
void meta_window_update_unfocused_button_grabs (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, void meta_window_set_focused_internal (MetaWindow *window,
gboolean focused); gboolean focused);

View File

@ -251,6 +251,10 @@ prefs_changed_callback (MetaPreference pref,
meta_window_recalc_features (window); meta_window_recalc_features (window);
meta_window_queue (window, META_QUEUE_MOVE_RESIZE); meta_window_queue (window, META_QUEUE_MOVE_RESIZE);
} }
else if (pref == META_PREF_FOCUS_MODE)
{
meta_window_appears_focused_changed (window);
}
} }
static void 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 /* queue a move_resize since changing workspaces may change
* the relevant struts * the relevant struts
*/ */
@ -5171,7 +5178,7 @@ meta_window_change_workspace_by_index (MetaWindow *window,
meta_window_change_workspace (window, workspace); meta_window_change_workspace (window, workspace);
} }
static void void
meta_window_appears_focused_changed (MetaWindow *window) meta_window_appears_focused_changed (MetaWindow *window)
{ {
set_net_wm_state (window); set_net_wm_state (window);
@ -7255,7 +7262,17 @@ meta_window_get_frame (MetaWindow *window)
gboolean gboolean
meta_window_appears_focused (MetaWindow *window) 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 gboolean

View File

@ -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 void
meta_workspace_add_window (MetaWorkspace *workspace, meta_workspace_add_window (MetaWorkspace *workspace,
MetaWindow *window) MetaWindow *window)
{ {
MetaWorkspaceManager *manager = workspace->display->workspace_manager;
COGL_TRACE_BEGIN_SCOPED (MetaWorkspaceAddWindow, COGL_TRACE_BEGIN_SCOPED (MetaWorkspaceAddWindow,
"Workspace (add window)"); "Workspace (add window)");
@ -385,6 +402,9 @@ meta_workspace_add_window (MetaWorkspace *workspace,
meta_workspace_invalidate_work_area (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_signal_emit (workspace, signals[WINDOW_ADDED], 0, window);
g_object_notify_by_pspec (G_OBJECT (workspace), obj_props[PROP_N_WINDOWS]); g_object_notify_by_pspec (G_OBJECT (workspace), obj_props[PROP_N_WINDOWS]);
} }
@ -393,6 +413,8 @@ void
meta_workspace_remove_window (MetaWorkspace *workspace, meta_workspace_remove_window (MetaWorkspace *workspace,
MetaWindow *window) MetaWindow *window)
{ {
MetaWorkspaceManager *manager = workspace->display->workspace_manager;
COGL_TRACE_BEGIN_SCOPED (MetaWorkspaceRemoveWindow, COGL_TRACE_BEGIN_SCOPED (MetaWorkspaceRemoveWindow,
"Workspace (remove window)"); "Workspace (remove window)");
@ -409,6 +431,9 @@ meta_workspace_remove_window (MetaWorkspace *workspace,
meta_workspace_invalidate_work_area (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_signal_emit (workspace, signals[WINDOW_REMOVED], 0, window);
g_object_notify (G_OBJECT (workspace), "n-windows"); g_object_notify (G_OBJECT (workspace), "n-windows");
} }
@ -657,6 +682,7 @@ meta_workspace_activate_with_focus (MetaWorkspace *workspace,
if (focus_this) if (focus_this)
{ {
meta_window_activate (focus_this, timestamp); meta_window_activate (focus_this, timestamp);
workspace_default_focus_changed (workspace, focus_this);
} }
else if (move_window) else if (move_window)
{ {