]> git.sur5r.net Git - i3/i3/commitdiff
Modify workspace next/prev to account for workspaces on all outputs.
authorPeter Bui <pnutzh4x0r@gmail.com>
Wed, 3 Aug 2011 21:41:40 +0000 (17:41 -0400)
committerMichael Stapelberg <michael@stapelberg.de>
Wed, 3 Aug 2011 22:12:09 +0000 (00:12 +0200)
Generally, the traversal goes: numbered workspaces in order, and then
named workspaces in the order in which they appear in the tree.

Example:
    Output 1:       Output 2:
1 3 D C         2 4 B A

Traversal: 1, 2, 3, 4, D, C, B, A, 1, ...

Note, after the numbered workspaces, we traverse the named workspaces
from output 1, and then output 2, etc.

include/util.h
src/workspace.c

index 0e48843cfb36b3d9f8f280749dddc464f0b51917..edc51d812de74580d6387aca300a70a5e4c597df 100644 (file)
     for (Con *child = (Con*)-1; (child == (Con*)-1) && ((child = 0), true);) \
         TAILQ_FOREACH(child, &((head)->nodes_head), nodes)
 
+#define NODES_FOREACH_REVERSE(head) \
+    for (Con *child = (Con*)-1; (child == (Con*)-1) && ((child = 0), true);) \
+        TAILQ_FOREACH_REVERSE(child, &((head)->nodes_head), nodes_head, nodes)
+
 /* greps the ->nodes of the given head and returns the first node that matches the given condition */
 #define GREP_FIRST(dest, head, condition) \
     NODES_FOREACH(head) { \
index 8354906a4aea72ab7fcd90d16bd84fc09577d33c..2fe9630483029de25500239f1e6342f97b27efa0 100644 (file)
@@ -234,11 +234,57 @@ void workspace_show(const char *num) {
  *
  */
 void workspace_next() {
-    Con *ws = con_get_workspace(focused);
-    Con *next = TAILQ_NEXT(ws, nodes);
-    if (!next)
-        next = TAILQ_FIRST(&(ws->parent->nodes_head));
+    Con *current = con_get_workspace(focused);
+    Con *next = NULL;
+    Con *output;
 
+    if (current->num == -1) {
+        /* If currently a named workspace, find next named workspace. */
+        next = TAILQ_NEXT(current, nodes);
+    } else {
+        /* If currently a numbered workspace, find next numbered workspace. */
+        TAILQ_FOREACH(output, &(croot->nodes_head), nodes)
+            NODES_FOREACH(output_get_content(output)) {
+                if (child->type != CT_WORKSPACE)
+                    continue;
+                if (child->num == -1)
+                    break;
+                /* Need to check child against current and next because we are
+                 * traversing multiple lists and thus are not guaranteed the
+                 * relative order between the list of workspaces. */
+                if (current->num < child->num && (!next || child->num < next->num))
+                    next = child;
+            }
+    }
+
+    /* Find next named workspace. */
+    if (!next) {
+        bool found_current = false;
+        TAILQ_FOREACH(output, &(croot->nodes_head), nodes)
+            NODES_FOREACH(output_get_content(output)) {
+                if (child->type != CT_WORKSPACE)
+                    continue;
+                if (child == current) {
+                    found_current = 1;
+                } else if (child->num == -1 && (current->num != -1 || found_current)) {
+                    next = child;
+                    goto workspace_next_show;
+                }
+            }
+    }
+
+    /* Find first workspace. */
+    if (!next) {
+        TAILQ_FOREACH(output, &(croot->nodes_head), nodes)
+            NODES_FOREACH(output_get_content(output)) {
+                if (child->type != CT_WORKSPACE)
+                    continue;
+                if (!next || (child->num != -1 && child->num < next->num))
+                    next = child;
+            }
+    }
+
+workspace_next_show:
     workspace_show(next->name);
 }
 
@@ -247,11 +293,57 @@ void workspace_next() {
  *
  */
 void workspace_prev() {
-    Con *ws = con_get_workspace(focused);
-    Con *prev = TAILQ_PREV(ws, nodes_head, nodes);
-    if (!prev)
-        prev = TAILQ_LAST(&(ws->parent->nodes_head), nodes_head);
+    Con *current = con_get_workspace(focused);
+    Con *prev = NULL;
+    Con *output;
+
+    if (current->num == -1) {
+        /* If named workspace, find previous named workspace. */
+        prev = TAILQ_PREV(current, nodes_head, nodes);
+        if (prev && prev->num != -1)
+            prev = NULL;
+    } else {
+        /* If numbered workspace, find previous numbered workspace. */
+        TAILQ_FOREACH_REVERSE(output, &(croot->nodes_head), nodes_head, nodes)
+            NODES_FOREACH_REVERSE(output_get_content(output)) {
+                if (child->type != CT_WORKSPACE || child->num == -1)
+                    continue;
+                /* Need to check child against current and previous because we
+                 * are traversing multiple lists and thus are not guaranteed
+                 * the relative order between the list of workspaces. */
+                if (current->num > child->num && (!prev || child->num > prev->num))
+                    prev = child;
+            }
+    }
+
+    /* Find previous named workspace. */
+    if (!prev) {
+        bool found_current = false;
+        TAILQ_FOREACH_REVERSE(output, &(croot->nodes_head), nodes_head, nodes)
+            NODES_FOREACH_REVERSE(output_get_content(output)) {
+                if (child->type != CT_WORKSPACE)
+                    continue;
+                if (child == current) {
+                    found_current = 1;
+                } else if (child->num == -1 && (current->num != -1 || found_current)) {
+                    prev = child;
+                    goto workspace_prev_show;
+                }
+            }
+    }
+
+    /* Find last workspace. */
+    if (!prev) {
+        TAILQ_FOREACH_REVERSE(output, &(croot->nodes_head), nodes_head, nodes)
+            NODES_FOREACH_REVERSE(output_get_content(output)) {
+                if (child->type != CT_WORKSPACE)
+                    continue;
+                if (!prev || child->num > prev->num)
+                    prev = child;
+            }
+    }
 
+workspace_prev_show:
     workspace_show(prev->name);
 }