]> git.sur5r.net Git - i3/i3/commitdiff
rewrite con_descend_orientation
authorMichael Stapelberg <michael@stapelberg.de>
Sun, 7 Aug 2011 13:57:36 +0000 (15:57 +0200)
committerMichael Stapelberg <michael@stapelberg.de>
Sun, 7 Aug 2011 13:57:36 +0000 (15:57 +0200)
It now uses the container orientation (if it is appropriate, the last focused
one otherwise) to recurse. This works better if the target workspace is in
vertical orientation when you use right/left or if it is in horizontal
orientation but you use up/down.

src/con.c

index e42e8c77501536b31b91e883d2cb1cc71f2dea72..5b5acc1b1b4598007a32f67cded10669e638f5e0 100644 (file)
--- a/src/con.c
+++ b/src/con.c
@@ -773,34 +773,6 @@ Con *con_descend_tiling_focused(Con *con) {
     return next;
 }
 
-/*
- * Recursively walk tree of nodes and check all nodes for condition.  Returns
- * container that matches condition (i.e. leftmost, rightmost, etc.).
- *
- */
-Con *_con_descend_direction(Con *con, Con *next, direction_t direction) {
-    #define DESCEND_DIRECTION(condition) \
-        if (TAILQ_EMPTY(&(con->nodes_head))) \
-            if (!next || condition) \
-                next = con; \
-        NODES_FOREACH(con) \
-            next = _con_descend_direction(child, next, direction); \
-        break;
-
-    switch (direction) {
-        case D_LEFT:
-            DESCEND_DIRECTION(next->rect.x < con->rect.x)
-        case D_RIGHT:
-            DESCEND_DIRECTION(next->rect.x > con->rect.x)
-        case D_UP:
-            DESCEND_DIRECTION(next->rect.y > con->rect.y)
-        case D_DOWN:
-            DESCEND_DIRECTION(next->rect.y < con->rect.y)
-    }
-
-    return next;
-}
-
 /*
  * Returns the leftmost, rightmost, etc. container in sub-tree. For example, if
  * direction is D_LEFT, then we return the rightmost container and if direction
@@ -809,7 +781,49 @@ Con *_con_descend_direction(Con *con, Con *next, direction_t direction) {
  *
  */
 Con *con_descend_direction(Con *con, direction_t direction) {
-    return _con_descend_direction(con, NULL, direction);
+    Con *most;
+    DLOG("con_descend_direction(%p, %d)\n", con, direction);
+    if (direction == D_LEFT || direction == D_RIGHT) {
+        if (con->orientation == HORIZ) {
+            /* If the direction is horizontal, we can use either the first
+             * (D_RIGHT) or the last con (D_LEFT) */
+            if (direction == D_RIGHT)
+                most = TAILQ_FIRST(&(con->nodes_head));
+            else most = TAILQ_LAST(&(con->nodes_head), nodes_head);
+        } else if (con->orientation == VERT) {
+            /* Wrong orientation. We use the last focused con. Within that con,
+             * we recurse to chose the left/right con or at least the last
+             * focused one. */
+            most = TAILQ_FIRST(&(con->focus_head));
+        } else {
+            /* If the con has no orientation set, it’s not a split container
+             * but a container with a client window, so stop recursing */
+            return con;
+        }
+    }
+
+    if (direction == D_UP || direction == D_DOWN) {
+        if (con->orientation == VERT) {
+            /* If the direction is vertical, we can use either the first
+             * (D_DOWN) or the last con (D_UP) */
+            if (direction == D_UP)
+                most = TAILQ_LAST(&(con->nodes_head), nodes_head);
+            else most = TAILQ_FIRST(&(con->nodes_head));
+        } else if (con->orientation == HORIZ) {
+            /* Wrong orientation. We use the last focused con. Within that con,
+             * we recurse to chose the top/bottom con or at least the last
+             * focused one. */
+            most = TAILQ_FIRST(&(con->focus_head));
+        } else {
+            /* If the con has no orientation set, it’s not a split container
+             * but a container with a client window, so stop recursing */
+            return con;
+        }
+    }
+
+    if (!most)
+        return con;
+    return con_descend_direction(most, direction);
 }
 
 /*