]> git.sur5r.net Git - i3/i3/blobdiff - src/workspace.c
Switch and Move to next workspace on the same Output. As requested in \#554
[i3/i3] / src / workspace.c
index b8fb73a6d35107450218e4f689dd20927910b746..55d4af61685f484e091e15c1200585cefa3c392d 100644 (file)
@@ -409,6 +409,118 @@ workspace_prev_end:
     return prev;
 }
 
+
+/*
+ * Focuses the next workspace on the same output.
+ *
+ */
+Con* workspace_next_on_output() {
+    Con *current = con_get_workspace(focused);
+    Con *next = NULL;
+    Con *output  = con_get_output(focused);
+
+    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. */
+        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;
+        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_on_output_end;
+            }
+        }
+    }
+
+    /* Find first workspace. */
+    if (!next) {
+        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_on_output_end:
+    return next;
+}
+
+/*
+ * Focuses the previous workspace on same output.
+ *
+ */
+Con* workspace_prev_on_output() {
+    Con *current = con_get_workspace(focused);
+    Con *prev = NULL;
+    Con *output  = con_get_output(focused);
+
+    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. */
+        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;
+        NODES_FOREACH_REVERSE(output_get_content(output)) {
+            if (child->type != CT_WORKSPACE)
+                continue;
+            if (child == current) {
+                found_current = true;
+            } else if (child->num == -1 && (current->num != -1 || found_current)) {
+                prev = child;
+                goto workspace_prev_on_output_end;
+            }
+        }
+    }
+
+    /* Find last workspace. */
+    if (!prev) {
+        NODES_FOREACH_REVERSE(output_get_content(output)) {
+            if (child->type != CT_WORKSPACE)
+                continue;
+            if (!prev || child->num > prev->num)
+                prev = child;
+        }
+    }
+
+workspace_prev_on_output_end:
+    return prev;
+}
+
 /*
  * Focuses the previously focused workspace.
  *