[metacity] Honour _NET_RESTACK_WINDOW and sibling-relative stacking



commit 0b5a50c85095a426f7070c5c8fe0af285ac02f62
Author: Christian Hammond <chipx86 chipx86 com>
Date:   Wed Jan 19 09:06:02 2011 -0500

    Honour _NET_RESTACK_WINDOW and sibling-relative stacking
    
    A test case for this patch is available at
    https://view.svn.sourceforge.net/svnroot/view/trunk/wm-test-suite/

 src/core/atomnames.h      |    6 +--
 src/core/display.c        |   43 -----------------
 src/core/window-private.h |    2 +
 src/core/window.c         |  116 +++++++++++++++++++++++++++++++++++---------
 4 files changed, 95 insertions(+), 72 deletions(-)
---
diff --git a/src/core/atomnames.h b/src/core/atomnames.h
index 43710f3..338d055 100644
--- a/src/core/atomnames.h
+++ b/src/core/atomnames.h
@@ -156,11 +156,7 @@ item(_NET_WM_ACTION_ABOVE)
 item(_NET_WM_ACTION_BELOW)
 item(_NET_WM_STATE_STICKY)
 item(_NET_WM_FULLSCREEN_MONITORS)
-
-#if 0
-/* We apparently never use: */
-/* item(_NET_RESTACK_WINDOW) */
-#endif
+item(_NET_RESTACK_WINDOW)
 
 /* eof atomnames.h */
 
diff --git a/src/core/display.c b/src/core/display.c
index b59571d..e816823 100644
--- a/src/core/display.c
+++ b/src/core/display.c
@@ -1358,44 +1358,6 @@ meta_display_queue_autoraise_callback (MetaDisplay *display,
   display->autoraise_window = window;
 }
 
-#if 0
-static void
-handle_net_restack_window (MetaDisplay* display,
-                           XEvent *event)
-{
-  MetaWindow *window;
-
-  window = meta_display_lookup_x_window (display,
-                                         event->xclient.window);
-
-  if (window)
-    {
-      /* FIXME: The EWMH includes a sibling for the restack request, but we
-       * (stupidly) don't currently support these types of raises.
-       *
-       * Also, unconditionally following these is REALLY stupid--we should
-       * combine this code with the stuff in
-       * meta_window_configure_request() which is smart about whether to
-       * follow the request or do something else (though not smart enough
-       * and is also too stupid to handle the sibling stuff).
-       */
-      switch (event->xclient.data.l[2])
-        {
-        case Above:
-          meta_window_raise (window);
-          break;
-        case Below:
-          meta_window_lower (window);
-          break;
-        case TopIf:
-        case BottomIf:
-        case Opposite:
-          break;          
-        }
-    }
-}
-#endif
-
 /**
  * This is the most important function in the whole program. It is the heart,
  * it is the nexus, it is the Grand Central Station of Metacity's world.
@@ -2171,11 +2133,6 @@ event_callback (XEvent   *event,
             else if (event->xproperty.atom ==
                      display->atom__NET_DESKTOP_NAMES)
               meta_screen_update_workspace_names (screen);
-#if 0
-            else if (event->xproperty.atom ==
-                     display->atom__NET_RESTACK_WINDOW)
-              handle_net_restack_window (display, event);
-#endif
 
             /* we just use this property as a sentinel to avoid
              * certain race conditions.  See the comment for the
diff --git a/src/core/window-private.h b/src/core/window-private.h
index da3fc52..7cf5b04 100644
--- a/src/core/window-private.h
+++ b/src/core/window-private.h
@@ -622,6 +622,8 @@ const char* meta_window_get_startup_id (MetaWindow *window);
 void meta_window_recalc_features    (MetaWindow *window);
 void meta_window_recalc_window_type (MetaWindow *window);
 
+void meta_window_stack_just_above (MetaWindow *window,
+                                   MetaWindow *above_this_one);
 void meta_window_stack_just_below (MetaWindow *window,
                                    MetaWindow *below_this_one);
 
diff --git a/src/core/window.c b/src/core/window.c
index 9af5283..11994d5 100644
--- a/src/core/window.c
+++ b/src/core/window.c
@@ -58,6 +58,9 @@ static int destroying_windows_disallowed = 0;
 
 static void     update_sm_hints           (MetaWindow     *window);
 static void     update_net_frame_extents  (MetaWindow     *window);
+static void     restack_window            (MetaWindow     *window,
+                                           MetaWindow     *sibling,
+                                           int             direction);
 static void     recalc_window_type        (MetaWindow     *window);
 static void     recalc_window_features    (MetaWindow     *window);
 static void     invalidate_work_areas     (MetaWindow     *window);
@@ -4713,19 +4716,13 @@ meta_window_configure_request (MetaWindow *window,
                                   event->xconfigurerequest.width,
                                   event->xconfigurerequest.height);
       
-  /* Handle stacking. We only handle raises/lowers, mostly because
-   * stack.c really can't deal with anything else.  I guess we'll fix
-   * that if a client turns up that really requires it. Only a very
-   * few clients even require the raise/lower (and in fact all client
-   * attempts to deal with stacking order are essentially broken,
-   * since they have no idea what other clients are involved or how
-   * the stack looks).
-   *
-   * I'm pretty sure no interesting client uses TopIf, BottomIf, or
-   * Opposite anyway, so the only possible missing thing is
-   * Above/Below with a sibling set. For now we just pretend there's
-   * never a sibling set and always do the full raise/lower instead of
-   * the raise-just-above/below-sibling.
+
+  /* Handle stacking. We only handle raises/lowers (both absolute and
+   * relative to siblings), mostly because stack.c really can't deal with
+   * anything else.  I guess we'll fix that if a client turns up that really
+   * requires it. Only a very few clients even require the raise/lower.  I'm
+   * pretty sure no interesting client uses TopIf, BottomIf, or Opposite
+   * anyway.
    */
   if (event->xconfigurerequest.value_mask & CWStackMode)
     {
@@ -4757,19 +4754,15 @@ meta_window_configure_request (MetaWindow *window,
         }
       else
         {
-          switch (event->xconfigurerequest.detail)
+          MetaWindow *sibling = NULL;
+
+          if (event->xconfigurerequest.above != None)
             {
-            case Above:
-              meta_window_raise (window);
-              break;
-            case Below:
-              meta_window_lower (window);
-              break;
-            case TopIf:
-            case BottomIf:
-            case Opposite:
-              break;
+              sibling = meta_display_lookup_x_window (window->display,
+                event->xconfigurerequest.above);
             }
+
+          restack_window(window, sibling, event->xconfigurerequest.detail);
         }
     }      
   
@@ -4796,6 +4789,51 @@ meta_window_property_notify (MetaWindow *window,
 #define _NET_WM_MOVERESIZE_MOVE_KEYBOARD    10
 #define _NET_WM_MOVERESIZE_CANCEL           11
 
+static void
+restack_window (MetaWindow *window,
+                MetaWindow *sibling,
+                int direction)
+{
+ switch (direction)
+   {
+   case Above:
+     if (sibling)
+       meta_window_stack_just_above (window, sibling);
+     else
+       meta_window_raise (window);
+     break;
+   case Below:
+     if (sibling)
+       meta_window_stack_just_below (window, sibling);
+     else
+       meta_window_lower (window);
+     break;
+   case TopIf:
+   case BottomIf:
+   case Opposite:
+     break;
+   }
+}
+
+static void
+handle_net_restack_window (MetaDisplay* display,
+                           XEvent *event)
+{
+  MetaWindow *window, *sibling = NULL;
+
+  window = meta_display_lookup_x_window (display,
+                                         event->xclient.window);
+
+  if (window)
+    {
+      if (event->xclient.data.l[1])
+        sibling = meta_display_lookup_x_window (display,
+                                                event->xclient.data.l[1]);
+
+      restack_window (window, sibling, event->xclient.data.l[2]);
+    }
+}
+
 gboolean
 meta_window_client_message (MetaWindow *window,
                             XEvent     *event)
@@ -4824,6 +4862,11 @@ meta_window_client_message (MetaWindow *window,
 
       return TRUE;
     }
+  else if (event->xproperty.atom ==
+           display->atom__NET_RESTACK_WINDOW)
+    {
+      handle_net_restack_window (display, event);
+    }
   else if (event->xclient.message_type ==
            display->atom__NET_WM_DESKTOP)
     {
@@ -7997,6 +8040,31 @@ ensure_mru_position_after (MetaWindow *window,
 }
 
 void
+meta_window_stack_just_above (MetaWindow *window,
+                              MetaWindow *above_this_one)
+{
+  g_return_if_fail (window         != NULL);
+  g_return_if_fail (above_this_one != NULL);
+
+  if (window->stack_position < above_this_one->stack_position)
+    {
+      meta_topic (META_DEBUG_STACK,
+                  "Setting stack position of window %s (%d) to %d (making it above window %s).\n",
+                  window->desc,
+                  window->stack_position,
+                  above_this_one->stack_position,
+                  above_this_one->desc);
+      meta_window_set_stack_position (window, above_this_one->stack_position);
+    }
+  else
+    {
+      meta_topic (META_DEBUG_STACK,
+                  "Window %s  was already above window %s.\n",
+                  window->desc, above_this_one->desc);
+    }
+}
+
+void
 meta_window_stack_just_below (MetaWindow *window,
                               MetaWindow *below_this_one)
 {



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