mirror of
https://github.com/brl/mutter.git
synced 2024-11-27 10:30:47 -05:00
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. Track the state and recompute it when it changes, to avoid redrawing the windows needlessly. Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/850>
This commit is contained in:
parent
7afefbbb61
commit
ed391eb06b
@ -382,6 +382,9 @@ struct _MetaWindow
|
||||
/* TRUE iff window == window->display->focus_window */
|
||||
guint has_focus : 1;
|
||||
|
||||
/* TRUE if window appears focused at the moment */
|
||||
guint appears_focused : 1;
|
||||
|
||||
/* Have we placed this window? */
|
||||
guint placed : 1;
|
||||
|
||||
@ -717,6 +720,8 @@ void meta_window_get_session_geometry (MetaWindow *window,
|
||||
|
||||
void meta_window_update_unfocused_button_grabs (MetaWindow *window);
|
||||
|
||||
void meta_window_update_appears_focused (MetaWindow *window);
|
||||
|
||||
void meta_window_set_focused_internal (MetaWindow *window,
|
||||
gboolean focused);
|
||||
|
||||
|
@ -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_update_appears_focused (window);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
@ -402,7 +406,7 @@ meta_window_get_property(GObject *object,
|
||||
g_value_set_string (value, win->mutter_hints);
|
||||
break;
|
||||
case PROP_APPEARS_FOCUSED:
|
||||
g_value_set_boolean (value, meta_window_appears_focused (win));
|
||||
g_value_set_boolean (value, win->appears_focused);
|
||||
break;
|
||||
case PROP_WM_CLASS:
|
||||
g_value_set_string (value, win->res_class);
|
||||
@ -1514,7 +1518,7 @@ meta_window_unmanage (MetaWindow *window,
|
||||
* on what gets focused, maintaining sloppy focus
|
||||
* invariants.
|
||||
*/
|
||||
if (meta_window_appears_focused (window))
|
||||
if (window->appears_focused)
|
||||
meta_window_propagate_focus_appearance (window, FALSE);
|
||||
if (window->has_focus)
|
||||
{
|
||||
@ -4911,6 +4915,9 @@ set_workspace_state (MetaWindow *window,
|
||||
}
|
||||
}
|
||||
|
||||
if (!window->constructing)
|
||||
meta_window_update_appears_focused (window);
|
||||
|
||||
/* queue a move_resize since changing workspaces may change
|
||||
* the relevant struts
|
||||
*/
|
||||
@ -5266,9 +5273,26 @@ meta_window_change_workspace_by_index (MetaWindow *window,
|
||||
meta_window_change_workspace (window, workspace);
|
||||
}
|
||||
|
||||
static void
|
||||
meta_window_appears_focused_changed (MetaWindow *window)
|
||||
void
|
||||
meta_window_update_appears_focused (MetaWindow *window)
|
||||
{
|
||||
MetaWorkspaceManager *workspace_manager;
|
||||
MetaWorkspace *workspace;
|
||||
gboolean appears_focused;
|
||||
|
||||
workspace_manager = window->display->workspace_manager;
|
||||
workspace = meta_window_get_workspace (window);
|
||||
|
||||
if (workspace && workspace != workspace_manager->active_workspace)
|
||||
appears_focused = window == meta_workspace_get_default_focus_window (workspace);
|
||||
else
|
||||
appears_focused = window->has_focus || window->attached_focus_window;
|
||||
|
||||
if (window->appears_focused == appears_focused)
|
||||
return;
|
||||
|
||||
window->appears_focused = appears_focused;
|
||||
|
||||
set_net_wm_state (window);
|
||||
meta_window_frame_size_changed (window);
|
||||
|
||||
@ -5348,7 +5372,7 @@ meta_window_propagate_focus_appearance (MetaWindow *window,
|
||||
|
||||
if (child_focus_state_changed && !parent->has_focus)
|
||||
{
|
||||
meta_window_appears_focused_changed (parent);
|
||||
meta_window_update_appears_focused (parent);
|
||||
}
|
||||
|
||||
child = parent;
|
||||
@ -5423,7 +5447,7 @@ meta_window_set_focused_internal (MetaWindow *window,
|
||||
g_signal_emit (window, window_signals[FOCUS], 0);
|
||||
|
||||
if (!window->attached_focus_window)
|
||||
meta_window_appears_focused_changed (window);
|
||||
meta_window_update_appears_focused (window);
|
||||
|
||||
meta_window_propagate_focus_appearance (window, TRUE);
|
||||
}
|
||||
@ -5436,7 +5460,7 @@ meta_window_set_focused_internal (MetaWindow *window,
|
||||
meta_window_propagate_focus_appearance (window, FALSE);
|
||||
|
||||
if (!window->attached_focus_window)
|
||||
meta_window_appears_focused_changed (window);
|
||||
meta_window_update_appears_focused (window);
|
||||
|
||||
/* Re-grab for click to focus and raise-on-click, if necessary */
|
||||
if (meta_prefs_get_focus_mode () == G_DESKTOP_FOCUS_MODE_CLICK ||
|
||||
@ -7361,7 +7385,7 @@ meta_window_get_frame (MetaWindow *window)
|
||||
gboolean
|
||||
meta_window_appears_focused (MetaWindow *window)
|
||||
{
|
||||
return window->has_focus || (window->attached_focus_window != NULL);
|
||||
return window->appears_focused;
|
||||
}
|
||||
|
||||
gboolean
|
||||
@ -8099,7 +8123,7 @@ meta_window_set_transient_for (MetaWindow *window,
|
||||
return;
|
||||
}
|
||||
|
||||
if (meta_window_appears_focused (window) && window->transient_for != NULL)
|
||||
if (window->appears_focused && window->transient_for != NULL)
|
||||
meta_window_propagate_focus_appearance (window, FALSE);
|
||||
|
||||
/* may now be a dialog */
|
||||
@ -8155,7 +8179,7 @@ meta_window_set_transient_for (MetaWindow *window,
|
||||
if (!window->constructing && !window->override_redirect)
|
||||
meta_window_queue (window, META_QUEUE_MOVE_RESIZE | META_QUEUE_CALC_SHOWING);
|
||||
|
||||
if (meta_window_appears_focused (window) && window->transient_for != NULL)
|
||||
if (window->appears_focused && window->transient_for != NULL)
|
||||
meta_window_propagate_focus_appearance (window, TRUE);
|
||||
}
|
||||
|
||||
|
@ -365,15 +365,37 @@ meta_workspace_remove (MetaWorkspace *workspace)
|
||||
*/
|
||||
}
|
||||
|
||||
static void
|
||||
update_workspace_default_focus (MetaWorkspace *workspace,
|
||||
MetaWindow *not_this_one)
|
||||
{
|
||||
g_autoptr (GSList) windows = NULL;
|
||||
GSList *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_update_appears_focused (window);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
meta_workspace_add_window (MetaWorkspace *workspace,
|
||||
MetaWindow *window)
|
||||
{
|
||||
MetaWorkspaceManager *workspace_manager;
|
||||
|
||||
g_return_if_fail (g_list_find (workspace->mru_list, window) == NULL);
|
||||
|
||||
COGL_TRACE_BEGIN_SCOPED (MetaWorkspaceAddWindow,
|
||||
"Workspace (add window)");
|
||||
|
||||
workspace_manager = workspace->display->workspace_manager;
|
||||
|
||||
workspace->mru_list = g_list_prepend (workspace->mru_list, window);
|
||||
|
||||
workspace->windows = g_list_prepend (workspace->windows, window);
|
||||
@ -386,6 +408,9 @@ meta_workspace_add_window (MetaWorkspace *workspace,
|
||||
meta_workspace_invalidate_work_area (workspace);
|
||||
}
|
||||
|
||||
if (workspace != workspace_manager->active_workspace)
|
||||
update_workspace_default_focus (workspace, window);
|
||||
|
||||
g_signal_emit (workspace, signals[WINDOW_ADDED], 0, window);
|
||||
g_object_notify_by_pspec (G_OBJECT (workspace), obj_props[PROP_N_WINDOWS]);
|
||||
}
|
||||
@ -394,6 +419,8 @@ void
|
||||
meta_workspace_remove_window (MetaWorkspace *workspace,
|
||||
MetaWindow *window)
|
||||
{
|
||||
MetaWorkspaceManager *workspace_manager = workspace->display->workspace_manager;
|
||||
|
||||
COGL_TRACE_BEGIN_SCOPED (MetaWorkspaceRemoveWindow,
|
||||
"Workspace (remove window)");
|
||||
|
||||
@ -410,6 +437,9 @@ meta_workspace_remove_window (MetaWorkspace *workspace,
|
||||
meta_workspace_invalidate_work_area (workspace);
|
||||
}
|
||||
|
||||
if (workspace != workspace_manager->active_workspace)
|
||||
update_workspace_default_focus (workspace, window);
|
||||
|
||||
g_signal_emit (workspace, signals[WINDOW_REMOVED], 0, window);
|
||||
g_object_notify (G_OBJECT (workspace), "n-windows");
|
||||
}
|
||||
@ -658,6 +688,7 @@ meta_workspace_activate_with_focus (MetaWorkspace *workspace,
|
||||
if (focus_this)
|
||||
{
|
||||
meta_window_activate (focus_this, timestamp);
|
||||
update_workspace_default_focus (workspace, focus_this);
|
||||
}
|
||||
else if (move_window)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user