[mutter/wip/exalm/focused-appearance: 3/3] window: Make default focus window on each workspace appear focused




commit ed391eb06b7b35f11314dd3c421d61f6c4b69467
Author: Alexander Mikhaylenko <exalm7659 gmail com>
Date:   Sat Oct 12 23:55:26 2019 +0500

    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>

 src/core/window-private.h |  5 +++++
 src/core/window.c         | 44 ++++++++++++++++++++++++++++++++++----------
 src/core/workspace.c      | 31 +++++++++++++++++++++++++++++++
 3 files changed, 70 insertions(+), 10 deletions(-)
---
diff --git a/src/core/window-private.h b/src/core/window-private.h
index d1730c9880..18f62d1f45 100644
--- a/src/core/window-private.h
+++ b/src/core/window-private.h
@@ -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);
 
diff --git a/src/core/window.c b/src/core/window.c
index 3d6241e387..b23f66e814 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_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);
 }
 
diff --git a/src/core/workspace.c b/src/core/workspace.c
index 564c5589de..76ba87b5ac 100644
--- a/src/core/workspace.c
+++ b/src/core/workspace.c
@@ -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)
     {


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]