]> git.sur5r.net Git - i3/i3/commitdiff
Switch and Move to next workspace on the same Output. As requested in \#554
authorMax Alexander Busse <ablepharus@gmail.com>
Sun, 25 Dec 2011 02:30:10 +0000 (03:30 +0100)
committerMichael Stapelberg <michael@stapelberg.de>
Sun, 8 Jan 2012 16:24:21 +0000 (16:24 +0000)
include/workspace.h
src/cmdparse.l
src/cmdparse.y
src/workspace.c

index 995499f2c939706877694b3f35ff9d0c777a6d52..21b733a6601c943da221c17b5f5a22c0a553c98e 100644 (file)
@@ -69,6 +69,18 @@ Con* workspace_next();
  */
 Con* workspace_prev();
 
+/**
+ * Returns the next workspace on the same output
+ *
+ */
+Con* workspace_next_on_output();
+
+/**
+ * Returns the previous workspace on the same output
+ *
+ */
+Con* workspace_prev_on_output();
+
 /**
  * Focuses the previously focused workspace.
  *
index 1431ec357cc3616f4bc1c4388b906eafe25625b2..d382c8db85740bc403e9e6851e4f9088d59d307c 100644 (file)
@@ -78,6 +78,8 @@ EOL (\r?\n)
      * handling strings ('workspace' command) */
 next                            { BEGIN(INITIAL); return TOK_NEXT; }
 prev                            { BEGIN(INITIAL); return TOK_PREV; }
+next_on_output                  { BEGIN(INITIAL); return TOK_NEXT_ON_OUTPUT; }
+prev_on_output                  { BEGIN(INITIAL); return TOK_PREV_ON_OUTPUT; }
 back_and_forth                  { BEGIN(INITIAL); return TOK_BACK_AND_FORTH; }
 
 <WANT_STRING>\"[^\"]+\"         {
index 3f13c72be5da3488587a549572e7e6c32bb7e999..28aa564e4b131704501715e7493ecf649b6400c5 100644 (file)
@@ -155,6 +155,8 @@ bool definitelyGreaterThan(float a, float b, float epsilon) {
 %token              TOK_OPEN            "open"
 %token              TOK_NEXT            "next"
 %token              TOK_PREV            "prev"
+%token              TOK_NEXT_ON_OUTPUT  "next_on_output"
+%token              TOK_PREV_ON_OUTPUT  "prev_on_output"
 %token              TOK_SCRATCHPAD      "scratchpad"
 %token              TOK_SHOW            "show"
 %token              TOK_SPLIT           "split"
@@ -680,6 +682,16 @@ workspace:
         workspace_show(workspace_prev());
         tree_render();
     }
+    | TOK_WORKSPACE TOK_NEXT_ON_OUTPUT
+    {
+        workspace_show(workspace_next_on_output());
+        tree_render();
+    }
+    | TOK_WORKSPACE TOK_PREV_ON_OUTPUT
+    {
+        workspace_show(workspace_prev_on_output());
+        tree_render();
+    }
     | TOK_WORKSPACE TOK_BACK_AND_FORTH
     {
         workspace_back_and_forth();
@@ -912,6 +924,38 @@ move:
 
         tree_render();
     }
+    | TOK_MOVE TOK_WORKSPACE TOK_NEXT_ON_OUTPUT
+    {
+        owindow *current;
+
+        /* get the workspace */
+        Con *ws = workspace_next_on_output();
+
+        HANDLE_EMPTY_MATCH;
+
+        TAILQ_FOREACH(current, &owindows, owindows) {
+            printf("matching: %p / %s\n", current->con, current->con->name);
+            con_move_to_workspace(current->con, ws, true, false);
+        }
+
+        tree_render();
+    }
+    | TOK_MOVE TOK_WORKSPACE TOK_PREV_ON_OUTPUT
+    {
+        owindow *current;
+
+        /* get the workspace */
+        Con *ws = workspace_prev_on_output();
+
+        HANDLE_EMPTY_MATCH;
+
+        TAILQ_FOREACH(current, &owindows, owindows) {
+            printf("matching: %p / %s\n", current->con, current->con->name);
+            con_move_to_workspace(current->con, ws, true, false);
+        }
+
+        tree_render();
+    }
     | TOK_MOVE TOK_OUTPUT STR
     {
         owindow *current;
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.
  *