From: Peter Bui Date: Wed, 3 Aug 2011 21:41:40 +0000 (-0400) Subject: Modify workspace next/prev to account for workspaces on all outputs. X-Git-Tag: 4.0.2~59^2 X-Git-Url: https://git.sur5r.net/?a=commitdiff_plain;h=1750192f633a191e138aac4bec493339b22942be;p=i3%2Fi3 Modify workspace next/prev to account for workspaces on all outputs. 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. --- diff --git a/include/util.h b/include/util.h index 0e48843c..edc51d81 100644 --- a/include/util.h +++ b/include/util.h @@ -30,6 +30,10 @@ 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) { \ diff --git a/src/workspace.c b/src/workspace.c index 8354906a..2fe96304 100644 --- a/src/workspace.c +++ b/src/workspace.c @@ -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); }