[mutter] window: Move some display level window processing to MetaDisplay



commit 169dd2fb7add99af8da532504bf88d8faf1a4cdf
Author: Jonas Ã…dahl <jadahl gmail com>
Date:   Sat Jan 29 00:49:50 2022 +0100

    window: Move some display level window processing to MetaDisplay
    
    meta_window_(un)queue() was implemented with global arrays in window.c
    that managed MetaLater handle IDs and lists of window queues. In order
    to rely less on scattered static variables and making it clearer that
    we're dealing with per display window management and not something
    specific to a single window, move the window resize/calc-showing queue
    management to MetaDisplay.
    
    Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2264>

 src/core/display-private.h    |   8 +
 src/core/display.c            | 203 ++++++++++++++++++++++++
 src/core/meta-private-enums.h |   6 +
 src/core/stack.c              |   2 +
 src/core/window-private.h     |  17 +--
 src/core/window.c             | 348 +++++-------------------------------------
 src/x11/meta-x11-display.c    |  23 +++
 7 files changed, 284 insertions(+), 323 deletions(-)
---
diff --git a/src/core/display-private.h b/src/core/display-private.h
index 6b7821412a..e91d730352 100644
--- a/src/core/display-private.h
+++ b/src/core/display-private.h
@@ -432,4 +432,12 @@ gboolean meta_display_init_x11_finish (MetaDisplay   *display,
 
 void     meta_display_shutdown_x11 (MetaDisplay  *display);
 
+void meta_display_queue_window (MetaDisplay   *display,
+                                MetaWindow    *window,
+                                MetaQueueType  queue_types);
+
+void meta_display_unqueue_window (MetaDisplay   *display,
+                                  MetaWindow    *window,
+                                  MetaQueueType  queue_types);
+
 #endif
diff --git a/src/core/display.c b/src/core/display.c
index be1d85b206..5f99578a69 100644
--- a/src/core/display.c
+++ b/src/core/display.c
@@ -124,6 +124,9 @@ typedef struct
 typedef struct _MetaDisplayPrivate
 {
   MetaContext *context;
+
+  guint queue_later_ids[META_N_QUEUE_TYPES];
+  GList *queue_windows[META_N_QUEUE_TYPES];
 } MetaDisplayPrivate;
 
 G_DEFINE_TYPE_WITH_PRIVATE (MetaDisplay, meta_display, G_TYPE_OBJECT)
@@ -163,6 +166,7 @@ enum
   WORKAREAS_CHANGED,
   CLOSING,
   INIT_XSERVER,
+  WINDOW_VISIBILITY_UPDATED,
   LAST_SIGNAL
 };
 
@@ -525,6 +529,16 @@ meta_display_class_init (MetaDisplayClass *klass)
                   NULL, NULL,
                   G_TYPE_BOOLEAN, 1, G_TYPE_TASK);
 
+  display_signals[WINDOW_VISIBILITY_UPDATED] =
+    g_signal_new ("window-visibility-updated",
+                  G_TYPE_FROM_CLASS (klass),
+                  G_SIGNAL_RUN_LAST,
+                  0, NULL, NULL, NULL,
+                  G_TYPE_NONE, 3,
+                  G_TYPE_POINTER,
+                  G_TYPE_POINTER,
+                  G_TYPE_POINTER);
+
   g_object_class_install_property (object_class,
                                    PROP_COMPOSITOR_MODIFIERS,
                                    g_param_spec_flags ("compositor-modifiers",
@@ -3933,3 +3947,192 @@ meta_display_get_selection (MetaDisplay *display)
 {
   return display->selection;
 }
+
+#ifdef WITH_VERBOSE_MODE
+static const char* meta_window_queue_names[META_N_QUEUE_TYPES] =
+  {
+    "calc-showing",
+    "move-resize",
+  };
+#endif
+
+static int
+window_stack_cmp (gconstpointer a,
+                  gconstpointer b)
+{
+  MetaWindow *aw = (gpointer) a;
+  MetaWindow *bw = (gpointer) b;
+
+  return meta_stack_windows_cmp (aw->display->stack,
+                                 aw, bw);
+}
+
+static void
+warn_on_incorrectly_unmanaged_window (MetaWindow *window)
+{
+  g_warn_if_fail (!window->unmanaging);
+}
+
+static gboolean
+update_window_visibilities_idle (gpointer user_data)
+{
+  MetaDisplay *display = META_DISPLAY (user_data);
+  MetaDisplayPrivate *priv = meta_display_get_instance_private (display);
+  int queue_idx;
+  g_autoptr (GList) windows = NULL;
+  g_autoptr (GList) unplaced = NULL;
+  g_autoptr (GList) should_show = NULL;
+  g_autoptr (GList) should_hide = NULL;
+  GList *l;
+
+  COGL_TRACE_BEGIN_SCOPED (MetaDisplayUpdateVisibility,
+                           "Display: Update visibility");
+
+  queue_idx = __builtin_ctz (META_QUEUE_CALC_SHOWING);
+
+  windows = g_steal_pointer (&priv->queue_windows[queue_idx]);
+  priv->queue_later_ids[queue_idx] = 0;
+
+  for (l = windows; l; l = l->next)
+    {
+      MetaWindow *window = l->data;
+
+      if (!window->placed)
+        unplaced = g_list_prepend (unplaced, window);
+      else if (meta_window_should_be_showing (window))
+        should_show = g_list_prepend (should_show, window);
+      else
+        should_hide = g_list_prepend (should_hide, window);
+    }
+
+  /* Sort bottom to top */
+  unplaced = g_list_sort (unplaced, window_stack_cmp);
+  should_hide = g_list_sort (should_hide, window_stack_cmp);
+
+  /* Sort top to bottom */
+  should_show = g_list_sort (should_show, window_stack_cmp);
+  should_show = g_list_reverse (should_show);
+
+  COGL_TRACE_BEGIN (MetaDisplayShowUnplacedWindows,
+                    "Display: Show unplaced windows");
+  g_list_foreach (unplaced, (GFunc) meta_window_update_visibility, NULL);
+  COGL_TRACE_END (MetaDisplayShowUnplacedWindows);
+
+  meta_stack_freeze (display->stack);
+
+  COGL_TRACE_BEGIN (MetaDisplayShowWindows, "Display: Show windows");
+  g_list_foreach (should_show, (GFunc) meta_window_update_visibility, NULL);
+  COGL_TRACE_END (MetaDisplayShowWindows);
+
+  COGL_TRACE_BEGIN (MetaDisplayHideWindows, "Display: Show windows");
+  g_list_foreach (should_hide, (GFunc) meta_window_update_visibility, NULL);
+  COGL_TRACE_END (MetaDisplayHideWindows);
+
+  meta_stack_thaw (display->stack);
+
+  g_list_foreach (windows, (GFunc) meta_window_clear_queued, NULL);
+
+  g_signal_emit (display, display_signals[WINDOW_VISIBILITY_UPDATED], 0,
+                 unplaced, should_show, should_hide);
+
+  g_list_foreach (windows, (GFunc) warn_on_incorrectly_unmanaged_window, NULL);
+
+  return G_SOURCE_REMOVE;
+}
+
+static gboolean
+move_resize_idle (gpointer user_data)
+{
+  MetaDisplay *display = META_DISPLAY (user_data);
+  MetaDisplayPrivate *priv = meta_display_get_instance_private (display);
+  int queue_idx;
+  g_autoptr (GList) windows = NULL;
+
+  queue_idx = __builtin_ctz (META_QUEUE_MOVE_RESIZE);
+
+  windows = g_steal_pointer (&priv->queue_windows[queue_idx]);
+  priv->queue_later_ids[queue_idx] = 0;
+
+  g_list_foreach (windows, (GFunc) meta_window_update_layout, NULL);
+  g_list_foreach (windows, (GFunc) warn_on_incorrectly_unmanaged_window, NULL);
+
+  return G_SOURCE_REMOVE;
+}
+
+void
+meta_display_queue_window (MetaDisplay   *display,
+                           MetaWindow    *window,
+                           MetaQueueType  queue_types)
+{
+  MetaDisplayPrivate *priv = meta_display_get_instance_private (display);
+  MetaCompositor *compositor = display->compositor;
+  MetaLaters *laters = meta_compositor_get_laters (compositor);
+  int queue_idx;
+
+  for (queue_idx = 0; queue_idx < META_N_QUEUE_TYPES; queue_idx++)
+    {
+      const MetaLaterType window_queue_later_when[META_N_QUEUE_TYPES] =
+        {
+          META_LATER_CALC_SHOWING,
+          META_LATER_RESIZE,
+        };
+
+      const GSourceFunc window_queue_later_handler[META_N_QUEUE_TYPES] =
+        {
+          update_window_visibilities_idle,
+          move_resize_idle,
+        };
+
+      if (!(queue_types & 1 << queue_idx))
+        continue;
+
+      meta_topic (META_DEBUG_WINDOW_STATE,
+                  "Queueing %s for window '%s'",
+                  meta_window_queue_names[queue_idx],
+                  meta_window_get_description (window));
+
+      priv->queue_windows[queue_idx] =
+        g_list_prepend (priv->queue_windows[queue_idx], window);
+
+      if (!priv->queue_later_ids[queue_idx])
+        {
+          meta_laters_add (laters,
+                           window_queue_later_when[queue_idx],
+                           window_queue_later_handler[queue_idx],
+                           display, NULL);
+
+        }
+    }
+}
+
+void
+meta_display_unqueue_window (MetaDisplay   *display,
+                             MetaWindow    *window,
+                             MetaQueueType  queue_types)
+{
+  MetaDisplayPrivate *priv = meta_display_get_instance_private (display);
+  MetaCompositor *compositor = display->compositor;
+  MetaLaters *laters = meta_compositor_get_laters (compositor);
+  int queue_idx;
+
+  for (queue_idx = 0; queue_idx < META_N_QUEUE_TYPES; queue_idx++)
+    {
+      if (!(queue_types & 1 << queue_idx))
+        continue;
+
+      meta_topic (META_DEBUG_WINDOW_STATE,
+                  "Unqueuing %s for window '%s'",
+                  meta_window_queue_names[queue_idx],
+                  window->desc);
+
+      priv->queue_windows[queue_idx] =
+        g_list_remove (priv->queue_windows[queue_idx], window);
+
+      if (!priv->queue_windows[queue_idx] && priv->queue_later_ids[queue_idx])
+        {
+          meta_laters_remove (laters,
+                              priv->queue_later_ids[queue_idx]);
+          priv->queue_later_ids[queue_idx] = 0;
+        }
+    }
+}
diff --git a/src/core/meta-private-enums.h b/src/core/meta-private-enums.h
index 1a361c7820..ae6a9bbe5f 100644
--- a/src/core/meta-private-enums.h
+++ b/src/core/meta-private-enums.h
@@ -28,4 +28,10 @@ typedef enum _MetaX11DisplayPolicy
   META_X11_DISPLAY_POLICY_DISABLED,
 } MetaX11DisplayPolicy;
 
+typedef enum
+{
+  META_QUEUE_CALC_SHOWING = 1 << 0,
+  META_QUEUE_MOVE_RESIZE = 1 << 1,
+} MetaQueueType;
+
 #endif /* META_PRIVATE_ENUMS_H */
diff --git a/src/core/stack.c b/src/core/stack.c
index 1af59f5be5..481e722327 100644
--- a/src/core/stack.c
+++ b/src/core/stack.c
@@ -416,6 +416,8 @@ meta_stack_thaw (MetaStack *stack)
 {
   g_return_if_fail (stack->freeze_count > 0);
 
+  COGL_TRACE_BEGIN_SCOPED (MetaStackThaw, "Stack: thaw");
+
   stack->freeze_count -= 1;
   meta_stack_changed (stack);
   meta_stack_update_window_tile_matches (stack, NULL);
diff --git a/src/core/window-private.h b/src/core/window-private.h
index 258445d984..ad1dd5a863 100644
--- a/src/core/window-private.h
+++ b/src/core/window-private.h
@@ -56,13 +56,7 @@ typedef enum
   META_CLIENT_TYPE_MAX_RECOGNIZED = 2
 } MetaClientType;
 
-typedef enum
-{
-  META_QUEUE_CALC_SHOWING = 1 << 0,
-  META_QUEUE_MOVE_RESIZE  = 1 << 1,
-} MetaQueueType;
-
-#define NUMBER_OF_QUEUES 2
+#define META_N_QUEUE_TYPES 2
 
 typedef enum
 {
@@ -397,9 +391,6 @@ struct _MetaWindow
   /* Are we in meta_window_new()? */
   guint constructing : 1;
 
-  /* Are we in the various queues? (Bitfield: see META_WINDOW_IS_IN_QUEUE) */
-  guint is_in_queues : NUMBER_OF_QUEUES;
-
   /* Used by keybindings.c */
   guint keys_grabbed : 1;     /* normal keybindings grabbed */
   guint grab_on_frame : 1;    /* grabs are on the frame */
@@ -915,4 +906,10 @@ gboolean meta_window_unit_cgroup_equal (MetaWindow *window1,
 void meta_window_check_alive_on_event (MetaWindow *window,
                                        uint32_t    timestamp);
 
+void meta_window_update_visibility (MetaWindow  *window);
+
+void meta_window_clear_queued (MetaWindow *window);
+
+void meta_window_update_layout (MetaWindow *window);
+
 #endif
diff --git a/src/core/window.c b/src/core/window.c
index eacde2b470..4a0c6242e0 100644
--- a/src/core/window.c
+++ b/src/core/window.c
@@ -109,8 +109,6 @@
 
 #define SNAP_SECURITY_LABEL_PREFIX "snap."
 
-static int destroying_windows_disallowed = 0;
-
 /* Each window has a "stamp" which is a non-recycled 64-bit ID. They
  * start after the end of the XID space so that, for stacking
  * we can keep a guint64 that represents one or the other
@@ -131,8 +129,6 @@ static void     meta_window_save_rect         (MetaWindow    *window);
 static void     ensure_mru_position_after (MetaWindow *window,
                                            MetaWindow *after_this_one);
 
-static void meta_window_move_resize_now (MetaWindow  *window);
-
 static void meta_window_unqueue (MetaWindow    *window,
                                  MetaQueueType  queuebits);
 
@@ -170,17 +166,12 @@ static MetaWindow * meta_window_find_tile_match (MetaWindow   *window,
                                                  MetaTileMode  mode);
 static void update_edge_constraints (MetaWindow *window);
 
-/* Idle handlers for the three queues (run with meta_later_add()). The
- * "data" parameter in each case will be a GINT_TO_POINTER of the
- * index into the queue arrays to use.
- *
- * TODO: Possibly there is still some code duplication among these, which we
- * need to sort out at some point.
- */
-static gboolean idle_calc_showing (gpointer data);
-static gboolean idle_move_resize (gpointer data);
+typedef struct _MetaWindowPrivate
+{
+  MetaQueueType queued_types;
+} MetaWindowPrivate;
 
-G_DEFINE_ABSTRACT_TYPE (MetaWindow, meta_window, G_TYPE_OBJECT);
+G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (MetaWindow, meta_window, G_TYPE_OBJECT)
 
 enum
 {
@@ -1083,7 +1074,6 @@ _meta_window_shared_new (MetaDisplay         *display,
   window->placed = ((window->mapped && !window->hidden) || window->override_redirect);
   window->denied_focus_and_not_transient = FALSE;
   window->unmanaging = FALSE;
-  window->is_in_queues = 0;
   window->keys_grabbed = FALSE;
   window->grab_on_frame = FALSE;
   window->all_keys_grabbed = FALSE;
@@ -1458,10 +1448,6 @@ meta_window_unmanage (MetaWindow  *window,
   meta_compositor_remove_window (window->display->compositor, window);
   window->known_to_compositor = FALSE;
 
-  if (destroying_windows_disallowed > 0)
-    meta_bug ("Tried to destroy window %s while destruction was not allowed",
-              window->desc);
-
   meta_display_unregister_stamp (window->display, window->stamp);
 
   if (meta_prefs_get_attach_modal_dialogs ())
@@ -1774,289 +1760,65 @@ implement_showing (MetaWindow *window,
     sync_client_window_mapped (window);
 }
 
-static void
-meta_window_calc_showing (MetaWindow  *window)
+void
+meta_window_update_visibility (MetaWindow  *window)
 {
   implement_showing (window, meta_window_should_be_showing (window));
 }
 
-static guint queue_later[NUMBER_OF_QUEUES] = {};
-static GSList *queue_pending[NUMBER_OF_QUEUES] = {};
-
-static int
-stackcmp (gconstpointer a, gconstpointer b)
-{
-  MetaWindow *aw = (gpointer) a;
-  MetaWindow *bw = (gpointer) b;
-
-  return meta_stack_windows_cmp (aw->display->stack,
-                                 aw, bw);
-}
-
-static gboolean
-idle_calc_showing (gpointer data)
+void
+meta_window_clear_queued (MetaWindow *window)
 {
-  MetaDisplay *display = meta_get_display ();
-  GSList *tmp;
-  GSList *copy;
-  GSList *should_show;
-  GSList *should_hide;
-  GSList *unplaced;
-  GSList *displays;
-  guint queue_index = GPOINTER_TO_INT (data);
-
-  COGL_TRACE_BEGIN_SCOPED (MetaWindowCalcShowing, "Window: Calc showing");
-
-  g_return_val_if_fail (queue_pending[queue_index] != NULL, FALSE);
-
-  meta_topic (META_DEBUG_WINDOW_STATE,
-              "Clearing the calc_showing queue");
-
-  /* Work with a copy, for reentrancy. The allowed reentrancy isn't
-   * complete; destroying a window while we're in here would result in
-   * badness. But it's OK to queue/unqueue calc_showings.
-   */
-  copy = g_slist_copy (queue_pending[queue_index]);
-  g_slist_free (queue_pending[queue_index]);
-  queue_pending[queue_index] = NULL;
-  queue_later[queue_index] = 0;
-
-  destroying_windows_disallowed += 1;
-
-  /* We map windows from top to bottom and unmap from bottom to
-   * top, to avoid extra expose events. The exception is
-   * for unplaced windows, which have to be mapped from bottom to
-   * top so placement works.
-   */
-  should_show = NULL;
-  should_hide = NULL;
-  unplaced = NULL;
-  displays = NULL;
-
-  COGL_TRACE_BEGIN (MetaWindowCalcShowingCalc, "Window: Calc showing (calc)");
-
-  tmp = copy;
-  while (tmp != NULL)
-    {
-      MetaWindow *window;
-
-      window = tmp->data;
-
-      if (!window->placed)
-        unplaced = g_slist_prepend (unplaced, window);
-      else if (meta_window_should_be_showing (window))
-        should_show = g_slist_prepend (should_show, window);
-      else
-        should_hide = g_slist_prepend (should_hide, window);
-
-      tmp = tmp->next;
-    }
-
-  /* bottom to top */
-  unplaced = g_slist_sort (unplaced, stackcmp);
-  should_hide = g_slist_sort (should_hide, stackcmp);
-  /* top to bottom */
-  should_show = g_slist_sort (should_show, stackcmp);
-  should_show = g_slist_reverse (should_show);
-
-  COGL_TRACE_END (MetaWindowCalcShowingCalc);
-
-  COGL_TRACE_BEGIN (MetaWindowCalcShowingUnplaced,
-                    "Window: Calc showing (calc unplaced)");
-
-  tmp = unplaced;
-  while (tmp != NULL)
-    {
-      MetaWindow *window;
-
-      window = tmp->data;
-
-      meta_window_calc_showing (window);
-
-      tmp = tmp->next;
-    }
-
-  COGL_TRACE_END (MetaWindowCalcShowingUnplaced);
-
-  meta_stack_freeze (display->stack);
-
-  COGL_TRACE_BEGIN (MetaWindowCalcShowingShow, "Window: Calc showing (show)");
-  tmp = should_show;
-  while (tmp != NULL)
-    {
-      MetaWindow *window;
-
-      window = tmp->data;
-
-      implement_showing (window, TRUE);
-
-      tmp = tmp->next;
-    }
-  COGL_TRACE_END (MetaWindowCalcShowingShow);
-
-  COGL_TRACE_BEGIN (MetaWindowCalcShowingHide, "Window: Calc showing (hide)");
-  tmp = should_hide;
-  while (tmp != NULL)
-    {
-      MetaWindow *window;
-
-      window = tmp->data;
-
-      implement_showing (window, FALSE);
-
-      tmp = tmp->next;
-    }
-  COGL_TRACE_END (MetaWindowCalcShowingHide);
-
-  COGL_TRACE_BEGIN (MetaWindowCalcShowingSync,
-                    "Window: Calc showing (sync stack)");
-  meta_stack_thaw (display->stack);
-  COGL_TRACE_END (MetaWindowCalcShowingSync);
-
-  tmp = copy;
-  while (tmp != NULL)
-    {
-      MetaWindow *window;
+  MetaWindowPrivate *priv = meta_window_get_instance_private (window);
 
-      window = tmp->data;
-
-      /* important to set this here for reentrancy -
-       * if we queue a window again while it's in "copy",
-       * then queue_calc_showing will just return since
-       * we are still in the calc_showing queue
-       */
-      window->is_in_queues &= ~META_QUEUE_CALC_SHOWING;
-
-      tmp = tmp->next;
-    }
-
-  if (meta_prefs_get_focus_mode () != G_DESKTOP_FOCUS_MODE_CLICK)
-    {
-      /* When display->mouse_mode is false, we want to ignore
-       * EnterNotify events unless they come from mouse motion.  To do
-       * that, we set a sentinel property on the root window if we're
-       * not in mouse_mode.
-       */
-      tmp = should_show;
-      while (tmp != NULL)
-        {
-          MetaWindow *window = tmp->data;
-          MetaDisplay *display = window->display;
-
-          if (display->x11_display && !display->mouse_mode)
-            meta_x11_display_increment_focus_sentinel (display->x11_display);
-
-          tmp = tmp->next;
-        }
-    }
-
-  g_slist_free (copy);
-
-  g_slist_free (unplaced);
-  g_slist_free (should_show);
-  g_slist_free (should_hide);
-  g_slist_free (displays);
-
-  destroying_windows_disallowed -= 1;
-
-  return FALSE;
+  priv->queued_types &= ~META_QUEUE_CALC_SHOWING;
 }
 
-#ifdef WITH_VERBOSE_MODE
-static const gchar* meta_window_queue_names[NUMBER_OF_QUEUES] =
-  {"calc_showing", "move_resize", };
-#endif
-
 static void
 meta_window_unqueue (MetaWindow    *window,
-                     MetaQueueType  queuebits)
+                     MetaQueueType  queue_types)
 {
-  int queuenum;
-
-  for (queuenum = 0; queuenum < NUMBER_OF_QUEUES; queuenum++)
-    {
-      if ((queuebits & 1 << queuenum) &&
-          (window->is_in_queues & 1 << queuenum))
-        {
+  MetaWindowPrivate *priv = meta_window_get_instance_private (window);
 
-          meta_topic (META_DEBUG_WINDOW_STATE,
-                      "Removing %s from the %s queue",
-                      window->desc,
-                      meta_window_queue_names[queuenum]);
+  queue_types &= priv->queued_types;
 
-          queue_pending[queuenum] = g_slist_remove (queue_pending[queuenum], window);
-          window->is_in_queues &= ~(1 << queuenum);
+  if (!queue_types)
+    return;
 
-          if (queue_pending[queuenum] == NULL && queue_later[queuenum] != 0)
-            {
-              meta_later_remove (queue_later[queuenum]);
-              queue_later[queuenum] = 0;
-            }
-        }
-    }
+  meta_display_unqueue_window (window->display, window, queue_types);
+  priv->queued_types &= ~queue_types;
 }
 
 static void
 meta_window_flush_calc_showing (MetaWindow *window)
 {
-  if (window->is_in_queues & META_QUEUE_CALC_SHOWING)
+  MetaWindowPrivate *priv = meta_window_get_instance_private (window);
+
+  if (priv->queued_types & META_QUEUE_CALC_SHOWING)
     {
       meta_window_unqueue (window, META_QUEUE_CALC_SHOWING);
-      meta_window_calc_showing (window);
+      meta_window_update_visibility (window);
     }
 }
 
 void
 meta_window_queue (MetaWindow   *window,
-                   MetaQueueType queuebits)
+                   MetaQueueType queue_types)
 {
-  unsigned int queuenum;
+  MetaWindowPrivate *priv = meta_window_get_instance_private (window);
 
   g_return_if_fail (!window->override_redirect ||
-                    (queuebits & META_QUEUE_MOVE_RESIZE) == 0);
-
-  for (queuenum = 0; queuenum < NUMBER_OF_QUEUES; queuenum++)
-    {
-      if (queuebits & 1 << queuenum)
-        {
-          const MetaLaterType window_queue_later_when[NUMBER_OF_QUEUES] =
-            {
-              META_LATER_CALC_SHOWING,
-              META_LATER_RESIZE,
-            };
-
-          const GSourceFunc window_queue_later_handler[NUMBER_OF_QUEUES] =
-            {
-              idle_calc_showing,
-              idle_move_resize,
-            };
+                    (queue_types & META_QUEUE_MOVE_RESIZE) == 0);
 
-          if (window->unmanaging)
-            break;
-
-          if (window->is_in_queues & 1 << queuenum)
-            break;
-
-          meta_topic (META_DEBUG_WINDOW_STATE,
-                      "Putting %s in the %s queue",
-                      window->desc,
-                      meta_window_queue_names[queuenum]);
-
-          window->is_in_queues |= 1 << queuenum;
+  if (window->unmanaging)
+    return;
 
-          if (queue_later[queuenum] == 0)
-            {
-              queue_later[queuenum] =
-                meta_later_add (window_queue_later_when[queuenum],
-                                window_queue_later_handler[queuenum],
-                                GUINT_TO_POINTER (queuenum),
-                                NULL);
-            }
+  queue_types &= ~priv->queued_types;
+  if (!queue_types)
+    return;
 
-          queue_pending[queuenum] = g_slist_prepend (queue_pending[queuenum],
-                                                     window);
-      }
-  }
+  priv->queued_types |= queue_types;
+  meta_display_queue_window (window->display, window, queue_types);
 }
 
 static gboolean
@@ -4090,7 +3852,7 @@ meta_window_move_resize_internal (MetaWindow          *window,
     }
 
   /* If we did placement, then we need to save the position that the window
-   * was placed at to make sure that meta_window_move_resize_now places the
+   * was placed at to make sure that meta_window_update_layout() places the
    * window correctly.
    */
   if (did_placement)
@@ -4367,8 +4129,8 @@ meta_window_resize_frame_with_gravity (MetaWindow *window,
   meta_window_move_resize_internal (window, flags, gravity, rect);
 }
 
-static void
-meta_window_move_resize_now (MetaWindow  *window)
+void
+meta_window_update_layout (MetaWindow *window)
 {
   meta_window_move_resize_frame (window, FALSE,
                                  window->unconstrained_rect.x,
@@ -4377,46 +4139,6 @@ meta_window_move_resize_now (MetaWindow  *window)
                                  window->unconstrained_rect.height);
 }
 
-static gboolean
-idle_move_resize (gpointer data)
-{
-  GSList *tmp;
-  GSList *copy;
-  guint queue_index = GPOINTER_TO_INT (data);
-
-  meta_topic (META_DEBUG_GEOMETRY, "Clearing the move_resize queue");
-
-  /* Work with a copy, for reentrancy. The allowed reentrancy isn't
-   * complete; destroying a window while we're in here would result in
-   * badness. But it's OK to queue/unqueue move_resizes.
-   */
-  copy = g_slist_copy (queue_pending[queue_index]);
-  g_slist_free (queue_pending[queue_index]);
-  queue_pending[queue_index] = NULL;
-  queue_later[queue_index] = 0;
-
-  destroying_windows_disallowed += 1;
-
-  tmp = copy;
-  while (tmp != NULL)
-    {
-      MetaWindow *window;
-
-      window = tmp->data;
-
-      /* As a side effect, sets window->move_resize_queued = FALSE */
-      meta_window_move_resize_now (window);
-
-      tmp = tmp->next;
-    }
-
-  g_slist_free (copy);
-
-  destroying_windows_disallowed -= 1;
-
-  return FALSE;
-}
-
 void
 meta_window_get_gravity_position (MetaWindow  *window,
                                   MetaGravity  gravity,
diff --git a/src/x11/meta-x11-display.c b/src/x11/meta-x11-display.c
index 7b89cac248..d4b5ff425e 100644
--- a/src/x11/meta-x11-display.c
+++ b/src/x11/meta-x11-display.c
@@ -1104,6 +1104,25 @@ meta_x11_init_gdk_display (GError **error)
   return TRUE;
 }
 
+static void
+on_window_visibility_updated (MetaDisplay    *display,
+                              GList          *placed_windows,
+                              GList          *shown_windows,
+                              GList          *hidden_windows,
+                              MetaX11Display *x11_display)
+{
+  GList *l;
+
+  if (meta_prefs_get_focus_mode () == G_DESKTOP_FOCUS_MODE_CLICK)
+    return;
+
+  if (display->mouse_mode)
+    return;
+
+  for (l = shown_windows; l; l = l->next)
+    meta_x11_display_increment_focus_sentinel (x11_display);
+}
+
 /**
  * meta_x11_display_new:
  *
@@ -1236,6 +1255,10 @@ meta_x11_display_new (MetaDisplay *display, GError **error)
                            G_CALLBACK (update_cursor_theme),
                            x11_display,
                            G_CONNECT_SWAPPED);
+  g_signal_connect_object (display,
+                           "window-visibility-updated",
+                           G_CALLBACK (on_window_visibility_updated),
+                           x11_display, 0);
 
   update_cursor_theme (x11_display);
 


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