[metacity] stack: change how we choose default focus window



commit 186b2b7851208afb52b5239a36a86620d2fcd5c4
Author: Alberts Muktupāvels <alberts muktupavels gmail com>
Date:   Fri Nov 29 16:32:23 2019 +0200

    stack: change how we choose default focus window
    
    Commit f628d8f8901f46fa9e00707ae9d7ccfd1e85f427 changed how we
    choose the default focus window from the MRU to the topmost in the
    stack. Unfortunately most of the time this gives unexpected result
    if there are windows in META_LAYER_TOP and/or META_LAYER_FULLSCREEN
    layers.
    
    Re-sort windows using only stack position with one exception, keep
    windows in META_LAYER_DESKTOP layer last and apply two rules when
    choosing default window:
    - fullscreen window should not get focus if it is not on the same
      monitor as not_this_one window. If fullscreen window is on other
      monitor then windows under it also should not get focus.
    - desktop window should be always last choice.

 src/core/stack.c | 86 +++++++++++++++++++++++++++++++++++++++++++++++++++-----
 1 file changed, 79 insertions(+), 7 deletions(-)
---
diff --git a/src/core/stack.c b/src/core/stack.c
index dc96d818..8ca11cde 100644
--- a/src/core/stack.c
+++ b/src/core/stack.c
@@ -1155,6 +1155,53 @@ window_contains_point (MetaWindow *window,
   return POINT_IN_RECT (root_x, root_y, rect);
 }
 
+static int
+compare_default_focus_window_layer (MetaWindow *a,
+                                    MetaWindow *b)
+{
+  if (a->layer == META_LAYER_DESKTOP ||
+      b->layer == META_LAYER_DESKTOP)
+    {
+      if (a->layer < b->layer)
+        return 1;
+      else if (a->layer > b->layer)
+        return -1;
+    }
+
+  return 0;
+}
+
+static int
+compare_default_focus_window_position (MetaWindow *a,
+                                       MetaWindow *b)
+{
+  if (a->stack_position < b->stack_position)
+    return 1;
+  else if (a->stack_position > b->stack_position)
+    return -1;
+
+  return 0;
+}
+
+static int
+compare_default_focus_window_func (gconstpointer a,
+                                   gconstpointer b)
+{
+  MetaWindow *window_a;
+  MetaWindow *window_b;
+  int result;
+
+  window_a = (MetaWindow *) a;
+  window_b = (MetaWindow *) b;
+
+  result = compare_default_focus_window_layer (window_a, window_b);
+
+  if (result == 0)
+    result = compare_default_focus_window_position (window_a, window_b);
+
+  return result;
+}
+
 static MetaWindow*
 get_default_focus_window (MetaStack     *stack,
                           MetaWorkspace *workspace,
@@ -1163,20 +1210,28 @@ get_default_focus_window (MetaStack     *stack,
                           int            root_x,
                           int            root_y)
 {
+  MetaWindow *default_focus_window;
+  GList *tmp;
+  GList *l;
+
   /* Find the topmost, focusable, mapped, window.
    * not_this_one is being unfocused or going away, so exclude it.
    */
 
-  GList *l;
+  default_focus_window = NULL;
 
   stack_ensure_sorted (stack);
 
-  /* top of this layer is at the front of the list */
-  for (l = stack->sorted; l != NULL; l = l->next)
+  tmp = g_list_copy (stack->sorted);
+  tmp = g_list_sort (tmp, compare_default_focus_window_func);
+
+  for (l = tmp; l != NULL; l = l->next)
     {
-      MetaWindow *window = l->data;
+      MetaWindow *window;
+
+      window = l->data;
 
-      if (!window)
+      if (window == NULL)
         continue;
 
       if (window == not_this_one)
@@ -1200,10 +1255,27 @@ get_default_focus_window (MetaStack     *stack,
       if (window->type == META_WINDOW_DOCK)
         continue;
 
-      return window;
+      if (window->fullscreen &&
+          not_this_one != NULL &&
+          default_focus_window == NULL &&
+          windows_on_different_monitor (window, not_this_one))
+        {
+          default_focus_window = window;
+          continue;
+        }
+
+      if (default_focus_window != NULL &&
+          (!windows_on_different_monitor (window, default_focus_window) ||
+           window->layer == META_LAYER_DESKTOP))
+        continue;
+
+      default_focus_window = window;
+      break;
     }
 
-  return NULL;
+  g_list_free (tmp);
+
+  return default_focus_window;
 }
 
 MetaWindow*


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