[mutter] Use MetaStackTracker to avoid a round-trip XQueryTree()



commit 43511c316e5b95f6dfc7dd850e981880039e4d14
Author: Owen W. Taylor <otaylor fishsoup net>
Date:   Tue Jun 16 08:44:17 2009 -0400

    Use MetaStackTracker to avoid a round-trip XQueryTree()
    
    With MetaStackTracker, it's no longer necessary to XQueryTree to
    get a reasonably-up-to-date view of the server stacking order.
    
    Add some comments explaining unclear aspects of
    raise_window_relative_to_managed_windows() and with future possible
    improvements.
    
    http://bugzilla.gnome.org/show_bug.cgi?id=585984

 src/core/stack.c |   51 ++++++++++++++++++++++-----------------------------
 1 files changed, 22 insertions(+), 29 deletions(-)
---
diff --git a/src/core/stack.c b/src/core/stack.c
index 40a9365..561d766 100644
--- a/src/core/stack.c
+++ b/src/core/stack.c
@@ -960,41 +960,33 @@ stack_ensure_sorted (MetaStack *stack)
  * This function is used to avoid raising a window above popup
  * menus and other such things.
  *
- * FIXME This is sort of an expensive function, should probably
- * do something to avoid it. One approach would be to reverse
- * the stacking algorithm to work by placing each window above
- * the others, and start by lowering a window to the bottom
- * (instead of the current way, which works by placing each
- * window below another and starting with a raise)
+ * The key to the operation of this function is that we are expecting
+ * at most one window to be added at a time. If xwindow is newly added,
+ * then its own stack position will be too high (the frame window
+ * is created at the top of the stack), but if we ignore xwindow,
+ * then the *next* managed window in the stack will be a window that
+ * we've already stacked.
+ *
+ * We could generalize this and remove the assumption that windows
+ * are added one at a time by keeping an explicit ->stacked flag in
+ * MetaWindow.
+ *
+ * An alternate approach would be to reverse the stacking algorithm to
+ * work by placing each window above the others, and start by lowering
+ * a window to the bottom (instead of the current way, which works by
+ * placing each window below another and starting with a raise)
  */
 static void
 raise_window_relative_to_managed_windows (MetaScreen *screen,
                                           Window      xwindow)
 {
 
-  Window ignored1, ignored2;
   Window *children;
-  unsigned int n_children;
+  int n_children;
   int i;
 
-  /* Normally XQueryTree() means "must grab server" but here
-   * we don't, since we know we won't manage any new windows
-   * or restack any windows before using the XQueryTree results.
-   */
-  
-  meta_error_trap_push_with_return (screen->display);
-  
-  XQueryTree (screen->display->xdisplay,
-              screen->xroot,
-              &ignored1, &ignored2, &children, &n_children);
-
-  if (meta_error_trap_pop_with_return (screen->display, TRUE) != Success)
-    {
-      meta_topic (META_DEBUG_STACK,
-                  "Error querying root children to raise window 0x%lx\n",
-                  xwindow);
-      return;
-    }
+  meta_stack_tracker_get_stack (screen->stack_tracker,
+                                &children, &n_children);
 
   /* Children are in order from bottom to top. We want to
    * find the topmost managed child, then configure
@@ -1062,9 +1054,6 @@ raise_window_relative_to_managed_windows (MetaScreen *screen,
                     xwindow);
       meta_error_trap_pop (screen->display, FALSE);
     }
-  
-  if (children)
-    XFree (children);
 }
 
 /**
@@ -1073,6 +1062,10 @@ raise_window_relative_to_managed_windows (MetaScreen *screen,
  * or XConfigureWindow on a few particular windows if we do and can figure
  * out the minimum set of changes.  After that, we set __NET_CLIENT_LIST
  * and __NET_CLIENT_LIST_STACKING.
+ *
+ * FIXME: Now that we have a good view of the stacking order on the server
+ * with MetaStackTracker it should be possible to do a simpler and better
+ * job of computing the minimal set of stacking requests needed.
  */
 static void
 stack_sync_to_server (MetaStack *stack)



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