[mutter] reload_transient_for: avoid xtransient_for loops



commit 6dc79ce60ad83c89e5dc1fa9e33b97d51fd3b9c4
Author: Dan Winship <danw gnome org>
Date:   Fri May 6 05:09:04 2011 -0400

    reload_transient_for: avoid xtransient_for loops
    
    Don't set a window's xtransient_for if it would create a loop. Since
    this is the only place we ever set xtransient_for, we can therefore
    assume everywhere else that it does not loop.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=647712

 src/core/constraints.c  |    2 +-
 src/core/display.c      |    2 +-
 src/core/window-props.c |   37 +++++++++++++++++++++++++++++--------
 src/core/window.c       |   35 +++--------------------------------
 4 files changed, 34 insertions(+), 42 deletions(-)
---
diff --git a/src/core/constraints.c b/src/core/constraints.c
index 0d4a94f..67078a0 100644
--- a/src/core/constraints.c
+++ b/src/core/constraints.c
@@ -754,7 +754,7 @@ constrain_modal_dialog (MetaWindow         *window,
 
   if (!meta_prefs_get_attach_modal_dialogs ())
     return TRUE;
-  if (window->type != META_WINDOW_MODAL_DIALOG || !parent || parent == window)
+  if (window->type != META_WINDOW_MODAL_DIALOG || !parent)
     return TRUE;
 
   x = parent->rect.x + (parent->rect.width / 2  - info->current.width / 2);
diff --git a/src/core/display.c b/src/core/display.c
index 8b1b5f2..b93f15a 100644
--- a/src/core/display.c
+++ b/src/core/display.c
@@ -5194,7 +5194,7 @@ prefs_changed_callback (MetaPreference pref,
           MetaWindow *parent = meta_window_get_transient_for (w);
           meta_window_recalc_features (w);
 
-          if (w->type == META_WINDOW_MODAL_DIALOG && parent && parent != w)
+          if (w->type == META_WINDOW_MODAL_DIALOG && parent)
             {
               int x, y;
               /* Forcing a call to move_resize() does two things: first, it handles
diff --git a/src/core/window-props.c b/src/core/window-props.c
index 94b5a94..e970ffe 100644
--- a/src/core/window-props.c
+++ b/src/core/window-props.c
@@ -1468,6 +1468,8 @@ reload_transient_for (MetaWindow    *window,
                       MetaPropValue *value,
                       gboolean       initial)
 {
+  MetaWindow *parent = NULL;
+
   if (window->has_focus && window->xtransient_for != None)
     meta_window_propagate_focus_appearance (window, FALSE);
 
@@ -1477,14 +1479,33 @@ reload_transient_for (MetaWindow    *window,
     window->xtransient_for = value->v.xwindow;
 
   /* Make sure transient_for is valid */
-  if (window->xtransient_for != None &&
-      meta_display_lookup_x_window (window->display, 
-                                    window->xtransient_for) == NULL)
+  if (window->xtransient_for != None)
     {
-      meta_warning (_("Invalid WM_TRANSIENT_FOR window 0x%lx specified "
-                      "for %s.\n"),
-                    window->xtransient_for, window->desc);
-      window->xtransient_for = None;
+      parent = meta_display_lookup_x_window (window->display,
+                                             window->xtransient_for);
+      if (!parent)
+        {
+          meta_warning (_("Invalid WM_TRANSIENT_FOR window 0x%lx specified "
+                          "for %s.\n"),
+                        window->xtransient_for, window->desc);
+          window->xtransient_for = None;
+        }
+    }
+
+  /* Make sure there is not a loop */
+  while (parent)
+    {
+      if (parent == window)
+        {
+          meta_warning (_("WM_TRANSIENT_FOR window 0x%lx for %s "
+                          "would create loop.\n"),
+                        window->xtransient_for, window->desc);
+          window->xtransient_for = None;
+          break;
+        }
+
+      parent = meta_display_lookup_x_window (parent->display,
+                                             parent->xtransient_for);
     }
 
   window->transient_parent_is_root_window =
diff --git a/src/core/window.c b/src/core/window.c
index d2deb53..a069060 100644
--- a/src/core/window.c
+++ b/src/core/window.c
@@ -4214,7 +4214,7 @@ move_attached_dialog (MetaWindow *window,
 {
   MetaWindow *parent = meta_window_get_transient_for (window);
 
-  if (window->type == META_WINDOW_MODAL_DIALOG && parent && parent != window)
+  if (window->type == META_WINDOW_MODAL_DIALOG && parent)
     /* It ignores x,y for such a dialog  */
     meta_window_move (window, FALSE, 0, 0);
 
@@ -9258,46 +9258,17 @@ meta_window_foreach_ancestor (MetaWindow            *window,
                               void                  *user_data)
 {
   MetaWindow *w;
-  MetaWindow *tortoise;
 
   w = window;
-  tortoise = window;
-  while (TRUE)
+  do
     {
       if (w->xtransient_for == None ||
           w->transient_parent_is_root_window)
         break;
 
       w = meta_display_lookup_x_window (w->display, w->xtransient_for);
-
-      if (w == NULL || w == tortoise)
-        break;
-
-      if (!(* func) (w, user_data))
-        break;
-
-      if (w->xtransient_for == None ||
-          w->transient_parent_is_root_window)
-        break;
-
-      w = meta_display_lookup_x_window (w->display, w->xtransient_for);
-
-      if (w == NULL || w == tortoise)
-        break;
-
-      if (!(* func) (w, user_data))
-        break;
-
-      tortoise = meta_display_lookup_x_window (tortoise->display,
-                                               tortoise->xtransient_for);
-
-      /* "w" should have already covered all ground covered by the
-       * tortoise, so the following must hold.
-       */
-      g_assert (tortoise != NULL);
-      g_assert (tortoise->xtransient_for != None);
-      g_assert (!tortoise->transient_parent_is_root_window);
     }
+  while (w && (* func) (w, user_data));
 }
 
 typedef struct



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