Make RaiseLower work for the dock as well
authorMikael Magnusson <mikachu@gmail.com>
Sat, 12 Jul 2014 03:19:41 +0000 (05:19 +0200)
committerMikael Magnusson <mikachu@gmail.com>
Mon, 20 Oct 2014 08:28:00 +0000 (10:28 +0200)
As a side effect, _NET_RESTACK_REQUEST now also allows specifying the dock as the sibling.

openbox/event.c
openbox/stacking.c
openbox/stacking.h

index 9f56030..350c148 100644 (file)
@@ -1198,7 +1198,7 @@ static void event_handle_client(ObClient *client, XEvent *e)
             }
 
         if (e->xconfigurerequest.value_mask & CWStackMode) {
-            ObClient *sibling = NULL;
+            ObWindow *sibling = NULL;
             gulong ignore_start;
             gboolean ok = TRUE;
 
@@ -1209,7 +1209,11 @@ static void event_handle_client(ObClient *client, XEvent *e)
                 if (win && WINDOW_IS_CLIENT(win) &&
                     WINDOW_AS_CLIENT(win) != client)
                 {
-                    sibling = WINDOW_AS_CLIENT(win);
+                    sibling = win;
+                }
+                else if (win && WINDOW_IS_DOCK(win))
+                {
+                    sibling = win;
                 }
                 else
                     /* an invalid sibling was specified so don't restack at
@@ -1560,13 +1564,17 @@ static void event_handle_client(ObClient *client, XEvent *e)
                               "invalid source indication %ld",
                               client->title, e->xclient.data.l[0]);
             } else {
-                ObClient *sibling = NULL;
+                ObWindow *sibling = NULL;
                 if (e->xclient.data.l[1]) {
                     ObWindow *win = window_find(e->xclient.data.l[1]);
                     if (WINDOW_IS_CLIENT(win) &&
                         WINDOW_AS_CLIENT(win) != client)
                     {
-                        sibling = WINDOW_AS_CLIENT(win);
+                        sibling = win;
+                    }
+                    if (WINDOW_IS_DOCK(win))
+                    {
+                        sibling = win;
                     }
                     if (sibling == NULL)
                         ob_debug_type(OB_DEBUG_APP_BUGS,
index 58551b5..0ef900a 100644 (file)
@@ -26,6 +26,8 @@
 #include "window.h"
 #include "event.h"
 #include "debug.h"
+#include "dock.h"
+#include "config.h"
 #include "obt/prop.h"
 
 GList  *stacking_list = NULL;
@@ -567,14 +569,18 @@ void stacking_add_nonintrusive(ObWindow *win)
 /*! Returns TRUE if client is occluded by the sibling. If sibling is NULL it
   tries against all other clients.
 */
-static gboolean stacking_occluded(ObClient *client, ObClient *sibling)
+static gboolean stacking_occluded(ObClient *client, ObWindow *sibling_win)
 {
     GList *it;
     gboolean occluded = FALSE;
+    ObClient *sibling = NULL;
+
+    if (sibling_win && WINDOW_IS_CLIENT(sibling_win))
+        sibling = WINDOW_AS_CLIENT(sibling_win);
 
     /* no need for any looping in this case */
     if (sibling && client->layer != sibling->layer)
-        return occluded;
+        return FALSE;
 
     for (it = g_list_previous(g_list_find(stacking_list, client)); it;
          it = g_list_previous(it))
@@ -601,6 +607,21 @@ static gboolean stacking_occluded(ObClient *client, ObClient *sibling)
                         break; /* we past its layer */
                 }
             }
+        } else if (WINDOW_IS_DOCK(it->data)) {
+            ObDock *dock = it->data;
+            if (RECT_INTERSECTS_RECT(dock->area, client->frame->area))
+            {
+                if (sibling_win != NULL) {
+                    if (DOCK_AS_WINDOW(dock) == sibling_win) {
+                        occluded = TRUE;
+                        break;
+                    }
+                }
+                else if (config_dock_layer == client->layer) {
+                    occluded = TRUE;
+                    break;
+                }
+            }
         }
     return occluded;
 }
@@ -608,14 +629,18 @@ static gboolean stacking_occluded(ObClient *client, ObClient *sibling)
 /*! Returns TRUE if client occludes the sibling. If sibling is NULL it tries
   against all other clients.
 */
-static gboolean stacking_occludes(ObClient *client, ObClient *sibling)
+static gboolean stacking_occludes(ObClient *client, ObWindow *sibling_win)
 {
     GList *it;
     gboolean occludes = FALSE;
+    ObClient *sibling = NULL;
+
+    if (sibling_win && WINDOW_IS_CLIENT(sibling_win))
+        sibling = WINDOW_AS_CLIENT(sibling_win);
 
     /* no need for any looping in this case */
     if (sibling && client->layer != sibling->layer)
-        return occludes;
+        return FALSE;
 
     for (it = g_list_next(g_list_find(stacking_list, client));
          it; it = g_list_next(it))
@@ -643,14 +668,35 @@ static gboolean stacking_occludes(ObClient *client, ObClient *sibling)
                 }
             }
         }
+        else if (WINDOW_IS_DOCK(it->data)) {
+            ObDock *dock = it->data;
+            if (RECT_INTERSECTS_RECT(dock->area, client->frame->area))
+            {
+                if (sibling_win != NULL) {
+                    if (DOCK_AS_WINDOW(dock) == sibling_win) {
+                        occludes = TRUE;
+                        break;
+                    }
+                }
+                else if (config_dock_layer == client->layer) {
+                    occludes = TRUE;
+                    break;
+                }
+            }
+        }
     return occludes;
 }
 
-gboolean stacking_restack_request(ObClient *client, ObClient *sibling,
+gboolean stacking_restack_request(ObClient *client, ObWindow *sibling_win,
                                   gint detail)
 {
     gboolean ret = FALSE;
 
+    ObClient *sibling = NULL;
+
+    if (sibling_win && WINDOW_IS_CLIENT(sibling_win))
+        sibling = WINDOW_AS_CLIENT(sibling_win);
+
     if (sibling && ((client->desktop != sibling->desktop &&
                      client->desktop != DESKTOP_ALL &&
                      sibling->desktop != DESKTOP_ALL) ||
@@ -674,7 +720,7 @@ gboolean stacking_restack_request(ObClient *client, ObClient *sibling,
                  client->title, sibling ? sibling->title : "(all)");
         /* if this client occludes sibling (or anything if NULL), then
            lower it to the bottom */
-        if (stacking_occludes(client, sibling)) {
+        if (stacking_occludes(client, sibling_win)) {
             stacking_lower(CLIENT_AS_WINDOW(client));
             ret = TRUE;
         }
@@ -688,7 +734,7 @@ gboolean stacking_restack_request(ObClient *client, ObClient *sibling,
     case TopIf:
         ob_debug("Restack request TopIf for client %s sibling %s",
                  client->title, sibling ? sibling->title : "(all)");
-        if (stacking_occluded(client, sibling)) {
+        if (stacking_occluded(client, sibling_win)) {
             stacking_raise(CLIENT_AS_WINDOW(client));
             ret = TRUE;
         }
@@ -696,11 +742,11 @@ gboolean stacking_restack_request(ObClient *client, ObClient *sibling,
     case Opposite:
         ob_debug("Restack request Opposite for client %s sibling %s",
                  client->title, sibling ? sibling->title : "(all)");
-        if (stacking_occluded(client, sibling)) {
+        if (stacking_occluded(client, sibling_win)) {
             stacking_raise(CLIENT_AS_WINDOW(client));
             ret = TRUE;
         }
-        else if (stacking_occludes(client, sibling)) {
+        else if (stacking_occludes(client, sibling_win)) {
             stacking_lower(CLIENT_AS_WINDOW(client));
             ret = TRUE;
         }
index c14aa2e..ebfa175 100644 (file)
@@ -71,7 +71,7 @@ void stacking_below(struct _ObWindow *window, struct _ObWindow *below);
 
 /*! Restack a window based upon a sibling (or all windows) in various ways.
   @param client The client to be restacked
-  @param sibling Another client to compare to, or NULL to compare to all
+  @param sibling A window to compare to, or NULL to compare to all
                  windows
   @param detail One of Above, Below, TopIf, BottomIf, Opposite
   @return TRUE if the client was restacked
@@ -79,7 +79,7 @@ void stacking_below(struct _ObWindow *window, struct _ObWindow *below);
   how each detail works with and without a sibling.
 */
 gboolean stacking_restack_request(struct _ObClient *client,
-                                  struct _ObClient *sibling,
+                                  struct _ObWindow *sibling_win,
                                   gint detail);
 
 #endif