[mutter] core: Move remaining default focus window handling to workspace



commit b4b9a7c90ff97a078b33844c2e99bcaedd708745
Author: Sebastian Wick <sebastian wick redhat com>
Date:   Tue Jul 12 00:45:43 2022 +0200

    core: Move remaining default focus window handling to workspace
    
    Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2489>

 src/core/display-private.h      |   3 -
 src/core/display.c              |  24 --------
 src/core/stack.c                | 125 +---------------------------------------
 src/core/stack.h                |  67 +--------------------
 src/core/window.c               |  10 +++-
 src/core/workspace-private.h    |   8 ++-
 src/core/workspace.c            | 117 ++++++++++++++++++++++++++++++++-----
 src/wayland/meta-xwayland-dnd.c |   8 +--
 src/x11/window-x11.c            |   3 +-
 9 files changed, 126 insertions(+), 239 deletions(-)
---
diff --git a/src/core/display-private.h b/src/core/display-private.h
index 37932095b8..145509e913 100644
--- a/src/core/display-private.h
+++ b/src/core/display-private.h
@@ -411,9 +411,6 @@ gboolean meta_display_apply_startup_properties (MetaDisplay *display,
 void meta_display_queue_workarea_recalc  (MetaDisplay *display);
 void meta_display_queue_check_fullscreen (MetaDisplay *display);
 
-MetaWindow *meta_display_get_pointer_window (MetaDisplay *display,
-                                             MetaWindow  *not_this_one);
-
 MetaWindow *meta_display_get_window_from_id (MetaDisplay *display,
                                              uint64_t     window_id);
 uint64_t    meta_display_generate_window_id (MetaDisplay *display);
diff --git a/src/core/display.c b/src/core/display.c
index fb92244164..f10334665c 100644
--- a/src/core/display.c
+++ b/src/core/display.c
@@ -3794,30 +3794,6 @@ meta_display_get_monitor_in_fullscreen (MetaDisplay *display,
   purposes */ return logical_monitor->in_fullscreen == TRUE;
 }
 
-MetaWindow *
-meta_display_get_pointer_window (MetaDisplay *display,
-                                 MetaWindow  *not_this_one)
-{
-  MetaWorkspaceManager *workspace_manager = display->workspace_manager;
-  MetaBackend *backend = meta_get_backend ();
-  MetaCursorTracker *cursor_tracker = meta_backend_get_cursor_tracker (backend);
-  MetaWindow *window;
-  graphene_point_t point;
-
-  if (not_this_one)
-    meta_topic (META_DEBUG_FOCUS,
-                "Focusing mouse window excluding %s", not_this_one->desc);
-
-  meta_cursor_tracker_get_pointer (cursor_tracker, &point, NULL);
-
-  window = meta_stack_get_default_focus_window_at_point (display->stack,
-                                                         workspace_manager->active_workspace,
-                                                         not_this_one,
-                                                         point.x, point.y);
-
-  return window;
-}
-
 void
 meta_display_focus_default_window (MetaDisplay *display,
                                    guint32      timestamp)
diff --git a/src/core/stack.c b/src/core/stack.c
index 481e722327..2481adf780 100644
--- a/src/core/stack.c
+++ b/src/core/stack.c
@@ -50,6 +50,7 @@ static void stack_do_constrain (MetaStack *stack);
 static void stack_do_resort (MetaStack *stack);
 static void stack_ensure_sorted (MetaStack *stack);
 
+
 enum
 {
   PROP_DISPLAY = 1,
@@ -1007,110 +1008,6 @@ meta_stack_get_below (MetaStack  *stack,
     return below;
 }
 
-static gboolean
-window_contains_point (MetaWindow *window,
-                       int         root_x,
-                       int         root_y)
-{
-  MetaRectangle rect;
-
-  meta_window_get_frame_rect (window, &rect);
-
-  return META_POINT_IN_RECT (root_x, root_y, rect);
-}
-
-static gboolean
-window_can_get_default_focus (MetaWindow    *window,
-                              MetaWorkspace *workspace)
-{
-  if (window->unmaps_pending > 0)
-    return FALSE;
-
-  if (window->unmanaging)
-    return FALSE;
-
-  if (!meta_window_is_focusable (window))
-    return FALSE;
-
-  if (!meta_window_showing_on_its_workspace (window))
-    return FALSE;
-
-  if (!meta_window_located_on_workspace (window, workspace))
-    return FALSE;
-
-  if (window->type == META_WINDOW_DOCK)
-    return FALSE;
-
-  return TRUE;
-}
-
-static MetaWindow *
-get_default_focus_window (MetaStack     *stack,
-                          MetaWorkspace *workspace,
-                          MetaWindow    *not_this_one,
-                          gboolean       must_be_at_point,
-                          int            root_x,
-                          int            root_y)
-{
-  /* Find the topmost, focusable, mapped, window.
-   * not_this_one is being unfocused or going away, so exclude it.
-   */
-
-  GList *l;
-
-  stack_ensure_sorted (stack);
-
-  /* top of this layer is at the front of the list */
-  for (l = stack->sorted; l != NULL; l = l->next)
-    {
-      MetaWindow *window = l->data;
-
-      if (!window)
-        continue;
-
-      if (window == not_this_one)
-        continue;
-
-      if (!window_can_get_default_focus (window, workspace))
-        continue;
-
-      if (must_be_at_point && !window_contains_point (window, root_x, root_y))
-        continue;
-
-      return window;
-    }
-
-  return NULL;
-}
-
-MetaWindow *
-meta_stack_get_default_focus_window_at_point (MetaStack     *stack,
-                                              MetaWorkspace *workspace,
-                                              MetaWindow    *not_this_one,
-                                              int            root_x,
-                                              int            root_y)
-{
-  g_return_val_if_fail (META_IS_STACK (stack), NULL);
-  g_return_val_if_fail (META_IS_WORKSPACE (workspace), NULL);
-  g_return_val_if_fail (!not_this_one || META_IS_WINDOW (not_this_one), NULL);
-
-  return get_default_focus_window (stack, workspace, not_this_one,
-                                   TRUE, root_x, root_y);
-}
-
-MetaWindow *
-meta_stack_get_default_focus_window (MetaStack     *stack,
-                                     MetaWorkspace *workspace,
-                                     MetaWindow    *not_this_one)
-{
-  g_return_val_if_fail (META_IS_STACK (stack), NULL);
-  g_return_val_if_fail (META_IS_WORKSPACE (workspace), NULL);
-  g_return_val_if_fail (!not_this_one || META_IS_WINDOW (not_this_one), NULL);
-
-  return get_default_focus_window (stack, workspace, not_this_one,
-                                   FALSE, 0, 0);
-}
-
 GList *
 meta_stack_list_windows (MetaStack     *stack,
                          MetaWorkspace *workspace)
@@ -1139,26 +1036,6 @@ meta_stack_list_windows (MetaStack     *stack,
   return workspace_windows;
 }
 
-GList *
-meta_stack_get_default_focus_candidates (MetaStack     *stack,
-                                         MetaWorkspace *workspace)
-{
-  GList *windows = meta_stack_list_windows (stack, workspace);
-  GList *l;
-
-  for (l = windows; l;)
-    {
-      GList *next = l->next;
-
-      if (!window_can_get_default_focus (l->data, workspace))
-        windows = g_list_delete_link (windows, l);
-
-      l = next;
-    }
-
-  return windows;
-}
-
 int
 meta_stack_windows_cmp (MetaStack  *stack,
                         MetaWindow *window_a,
diff --git a/src/core/stack.h b/src/core/stack.h
index ec5753fe70..a33fac45fe 100644
--- a/src/core/stack.h
+++ b/src/core/stack.h
@@ -257,72 +257,6 @@ MetaWindow * meta_stack_get_below (MetaStack  *stack,
                                    MetaWindow *window,
                                    gboolean    only_within_layer);
 
-/**
- * meta_stack_get_default_focus_window:
- * @stack: The stack to search.
- * @workspace: %NULL to search all workspaces; otherwise only windows
- *             from that workspace will be returned.
- * @not_this_one: Window to ignore because it's being unfocussed or
- *                going away.
- *
- * Find the topmost, focusable, mapped, window in a stack. If you supply
- * a window as @not_this_one, we won't return that one (presumably
- * because it's going to be going away).  But if you do supply @not_this_one
- * and we find its parent, we'll return that; and if @not_this_one is in
- * a group, we'll return the top window of that group.
- *
- * Also, we are prejudiced against dock windows.  Every kind of window, even
- * the desktop, will be returned in preference to a dock window.
- *
- * Returns: The window matching all these constraints or %NULL if none does.
-  */
-MetaWindow * meta_stack_get_default_focus_window (MetaStack     *stack,
-                                                  MetaWorkspace *workspace,
-                                                  MetaWindow    *not_this_one);
-
-/**
- * meta_stack_get_default_focus_window_at_point:
- * @stack: The stack to search.
- * @workspace: %NULL to search all workspaces; otherwise only windows
- *             from that workspace will be returned.
- * @not_this_one: Window to ignore because it's being unfocussed or
- *                going away.
- * @root_x: The returned window must contain this point,
- *          unless it's a dock.
- * @root_y: See root_x.
- *
- * Find the topmost, focusable, mapped, window in a stack.  If you supply
- * a window as @not_this_one, we won't return that one (presumably
- * because it's going to be going away).  But if you do supply @not_this_one
- * and we find its parent, we'll return that; and if @not_this_one is in
- * a group, we'll return the top window of that group.
- *
- * Also, we are prejudiced against dock windows.  Every kind of window, even
- * the desktop, will be returned in preference to a dock window.
- *
- * Returns: The window matching all these constraints or %NULL if none does.
- */
-MetaWindow * meta_stack_get_default_focus_window_at_point (MetaStack     *stack,
-                                                           MetaWorkspace *workspace,
-                                                           MetaWindow    *not_this_one,
-                                                           int            root_x,
-                                                           int            root_y);
-
-/**
- * meta_stack_get_default_focus_candidates:
- * @stack: The stack to examine.
- * @workspace: If not %NULL, only windows on this workspace will be
- *             returned; otherwise all windows in the stack will be
- *             returned.
- *
- * Returns all the focus candidate windows in the stack, in order.
- *
- * Returns: (transfer container) (element-type Meta.Window):
- *     A #GList of #MetaWindow, in stacking order, honouring layers.
- */
-GList * meta_stack_get_default_focus_candidates (MetaStack     *stack,
-                                                 MetaWorkspace *workspace);
-
 /**
  * meta_stack_list_windows:
  * @stack: The stack to examine.
@@ -403,4 +337,5 @@ void meta_stack_set_positions (MetaStack *stack,
 
 void meta_stack_update_window_tile_matches (MetaStack     *stack,
                                             MetaWorkspace *workspace);
+
 #endif
diff --git a/src/core/window.c b/src/core/window.c
index 0e27145e0d..003437c3d2 100644
--- a/src/core/window.c
+++ b/src/core/window.c
@@ -5058,9 +5058,15 @@ meta_window_update_appears_focused (MetaWindow *window)
   workspace = meta_window_get_workspace (window);
 
   if (workspace && workspace != workspace_manager->active_workspace)
-    appears_focused = window == meta_workspace_get_default_focus_window (workspace);
+    {
+      appears_focused =
+        window == meta_workspace_get_default_focus_window (workspace, NULL) &&
+        meta_prefs_get_focus_mode () == G_DESKTOP_FOCUS_MODE_CLICK;
+    }
   else
-    appears_focused = window->has_focus || window->attached_focus_window;
+    {
+      appears_focused = window->has_focus || window->attached_focus_window;
+    }
 
   if (window->appears_focused == appears_focused)
     return;
diff --git a/src/core/workspace-private.h b/src/core/workspace-private.h
index f0d896f6cd..6afd5562a1 100644
--- a/src/core/workspace-private.h
+++ b/src/core/workspace-private.h
@@ -92,10 +92,16 @@ GList* meta_workspace_get_onscreen_region       (MetaWorkspace *workspace);
 GList * meta_workspace_get_onmonitor_region (MetaWorkspace      *workspace,
                                              MetaLogicalMonitor *logical_monitor);
 
-MetaWindow * meta_workspace_get_default_focus_window (MetaWorkspace *workspace);
 void meta_workspace_focus_default_window (MetaWorkspace *workspace,
                                           MetaWindow    *not_this_one,
                                           guint32        timestamp);
+MetaWindow * meta_workspace_get_default_focus_window (MetaWorkspace *workspace,
+                                                      MetaWindow    *not_this_one);
+MetaWindow * meta_workspace_get_default_focus_window_at_point (MetaWorkspace *workspace,
+                                                               MetaWindow    *not_this_one,
+                                                               int            root_x,
+                                                               int            root_y);
+GList * meta_workspace_get_default_focus_candidates (MetaWorkspace *workspace);
 
 const char* meta_workspace_get_name (MetaWorkspace *workspace);
 
diff --git a/src/core/workspace.c b/src/core/workspace.c
index 29cc302aef..03b177e555 100644
--- a/src/core/workspace.c
+++ b/src/core/workspace.c
@@ -39,6 +39,7 @@
 #include <string.h>
 
 #include "backends/meta-backend-private.h"
+#include "backends/meta-cursor-tracker-private.h"
 #include "backends/meta-logical-monitor.h"
 #include "cogl/cogl.h"
 #include "core/boxes-private.h"
@@ -53,6 +54,8 @@ void meta_workspace_queue_calc_showing   (MetaWorkspace *workspace);
 static void focus_ancestor_or_mru_window (MetaWorkspace *workspace,
                                           MetaWindow    *not_this_one,
                                           guint32        timestamp);
+static MetaWindow * get_pointer_window (MetaWorkspace *workspace,
+                                        MetaWindow    *not_this_one);
 
 G_DEFINE_TYPE (MetaWorkspace, meta_workspace, G_TYPE_OBJECT);
 
@@ -1330,7 +1333,8 @@ meta_workspace_focus_default_window (MetaWorkspace *workspace,
   else
     {
       MetaWindow * window;
-      window = meta_display_get_pointer_window (workspace->display, not_this_one);
+
+      window = get_pointer_window (workspace, not_this_one);
       if (window &&
           window->type != META_WINDOW_DOCK &&
           window->type != META_WINDOW_DESKTOP)
@@ -1381,7 +1385,8 @@ is_focusable (MetaWindow    *window,
               MetaWorkspace *workspace)
 {
   return !window->unmanaging &&
-         window->mapped &&
+         window->unmaps_pending == 0 &&
+         window->type != META_WINDOW_DOCK &&
          meta_window_is_focusable (window) &&
          meta_window_located_on_workspace (window, workspace) &&
          meta_window_showing_on_its_workspace (window);
@@ -1402,13 +1407,63 @@ find_focusable_ancestor (MetaWindow *window,
   return TRUE;
 }
 
-static MetaWindow *
-get_default_focus_window (MetaWorkspace *workspace,
-                          MetaWindow    *not_this_one)
+GList *
+meta_workspace_get_default_focus_candidates (MetaWorkspace *workspace)
 {
   GList *l;
+  GList *candidates = NULL;
 
   for (l = workspace->mru_list; l; l = l->next)
+    {
+      MetaWindow *window = l->data;
+
+      g_assert (window);
+
+      if (!is_focusable (window, workspace))
+        continue;
+
+      candidates = g_list_prepend (candidates, window);
+    }
+
+  return candidates;
+}
+
+static gboolean
+window_contains_point (MetaWindow *window,
+                       int         root_x,
+                       int         root_y)
+{
+  MetaRectangle rect;
+
+  meta_window_get_frame_rect (window, &rect);
+
+  return META_POINT_IN_RECT (root_x, root_y, rect);
+}
+
+MetaWindow *
+meta_workspace_get_default_focus_window_at_point (MetaWorkspace *workspace,
+                                                  MetaWindow    *not_this_one,
+                                                  int            root_x,
+                                                  int            root_y)
+{
+  g_autoptr (GList) sorted = NULL;
+  GList *l;
+  MetaStack *stack;
+
+  g_return_val_if_fail (META_IS_WORKSPACE (workspace), NULL);
+  g_return_val_if_fail (!not_this_one || META_IS_WINDOW (not_this_one), NULL);
+
+  stack = workspace->display->stack;
+
+  g_return_val_if_fail (META_IS_STACK (stack), NULL);
+
+  /* Find the topmost, focusable, mapped, window.
+   * not_this_one is being unfocused or going away, so exclude it.
+   */
+  sorted = g_list_reverse (meta_stack_list_windows (stack, workspace));
+
+  /* top of this layer is at the front of the list */
+  for (l = sorted; l != NULL; l = l->next)
     {
       MetaWindow *window = l->data;
 
@@ -1420,6 +1475,9 @@ get_default_focus_window (MetaWorkspace *workspace,
       if (!is_focusable (window, workspace))
         continue;
 
+      if (!window_contains_point (window, root_x, root_y))
+        continue;
+
       return window;
     }
 
@@ -1427,16 +1485,49 @@ get_default_focus_window (MetaWorkspace *workspace,
 }
 
 MetaWindow *
-meta_workspace_get_default_focus_window (MetaWorkspace *workspace)
+meta_workspace_get_default_focus_window (MetaWorkspace *workspace,
+                                         MetaWindow    *not_this_one)
 {
-  if (meta_prefs_get_focus_mode () == G_DESKTOP_FOCUS_MODE_CLICK)
-    {
-      return get_default_focus_window (workspace, NULL);
-    }
-  else
+  GList *l;
+
+  g_return_val_if_fail (META_IS_WORKSPACE (workspace), NULL);
+  g_return_val_if_fail (!not_this_one || META_IS_WINDOW (not_this_one), NULL);
+
+  for (l = workspace->mru_list; l; l = l->next)
     {
-      return NULL;
+      MetaWindow *window = l->data;
+
+      g_assert (window);
+
+      if (window == not_this_one)
+        continue;
+
+      if (!is_focusable (window, workspace))
+        continue;
+
+      return window;
     }
+
+  return NULL;
+}
+
+static MetaWindow *
+get_pointer_window (MetaWorkspace *workspace,
+                    MetaWindow    *not_this_one)
+{
+  MetaBackend *backend = meta_get_backend ();
+  MetaCursorTracker *cursor_tracker = meta_backend_get_cursor_tracker (backend);
+  graphene_point_t point;
+
+  if (not_this_one)
+    meta_topic (META_DEBUG_FOCUS,
+                "Focusing mouse window excluding %s", not_this_one->desc);
+
+  meta_cursor_tracker_get_pointer (cursor_tracker, &point, NULL);
+
+  return meta_workspace_get_default_focus_window_at_point (workspace,
+                                                           not_this_one,
+                                                           point.x, point.y);
 }
 
 static gboolean
@@ -1515,7 +1606,7 @@ focus_ancestor_or_mru_window (MetaWorkspace *workspace,
         }
     }
 
-  window = get_default_focus_window (workspace, not_this_one);
+  window = meta_workspace_get_default_focus_window (workspace, not_this_one);
 
   if (window)
     {
diff --git a/src/wayland/meta-xwayland-dnd.c b/src/wayland/meta-xwayland-dnd.c
index 0aa4c5efba..7c6de409bf 100644
--- a/src/wayland/meta-xwayland-dnd.c
+++ b/src/wayland/meta-xwayland-dnd.c
@@ -35,6 +35,7 @@
 #include <X11/extensions/Xfixes.h>
 
 #include "core/meta-workspace-manager-private.h"
+#include "core/workspace-private.h"
 #include "meta/meta-x11-errors.h"
 #include "wayland/meta-wayland-data-device.h"
 #include "wayland/meta-xwayland-private.h"
@@ -726,10 +727,9 @@ pick_drop_surface (MetaWaylandCompositor *compositor,
   graphene_point_t pos;
 
   clutter_event_get_coords (event, &pos.x, &pos.y);
-  focus_window = meta_stack_get_default_focus_window_at_point (display->stack,
-                                                               workspace,
-                                                               NULL,
-                                                               pos.x, pos.y);
+  focus_window = meta_workspace_get_default_focus_window_at_point (workspace,
+                                                                   NULL,
+                                                                   pos.x, pos.y);
   return focus_window ? focus_window->surface : NULL;
 }
 
diff --git a/src/x11/window-x11.c b/src/x11/window-x11.c
index 4e5ab93406..ac9450669f 100644
--- a/src/x11/window-x11.c
+++ b/src/x11/window-x11.c
@@ -901,7 +901,6 @@ maybe_focus_default_window (MetaDisplay *display,
                             guint32      timestamp)
 {
   MetaWorkspace *workspace;
-  MetaStack *stack = display->stack;
   g_autoptr (GList) focusable_windows = NULL;
   g_autoptr (GQueue) focus_candidates = NULL;
   GList *l;
@@ -917,7 +916,7 @@ maybe_focus_default_window (MetaDisplay *display,
     * focused window, will stop the chained requests.
     */
   focusable_windows =
-    meta_stack_get_default_focus_candidates (stack, workspace);
+    meta_workspace_get_default_focus_candidates (workspace);
   focus_candidates = g_queue_new ();
 
   for (l = g_list_last (focusable_windows); l; l = l->prev)


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