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.
This commit is contained in:
Peter Bui 2011-08-03 17:41:40 -04:00 committed by Michael Stapelberg
parent 8287a94292
commit 1750192f63
2 changed files with 104 additions and 8 deletions

View File

@ -30,6 +30,10 @@
for (Con *child = (Con*)-1; (child == (Con*)-1) && ((child = 0), true);) \ for (Con *child = (Con*)-1; (child == (Con*)-1) && ((child = 0), true);) \
TAILQ_FOREACH(child, &((head)->nodes_head), nodes) 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 */ /* greps the ->nodes of the given head and returns the first node that matches the given condition */
#define GREP_FIRST(dest, head, condition) \ #define GREP_FIRST(dest, head, condition) \
NODES_FOREACH(head) { \ NODES_FOREACH(head) { \

View File

@ -234,11 +234,57 @@ void workspace_show(const char *num) {
* *
*/ */
void workspace_next() { void workspace_next() {
Con *ws = con_get_workspace(focused); Con *current = con_get_workspace(focused);
Con *next = TAILQ_NEXT(ws, nodes); Con *next = NULL;
if (!next) Con *output;
next = TAILQ_FIRST(&(ws->parent->nodes_head));
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); workspace_show(next->name);
} }
@ -247,11 +293,57 @@ void workspace_next() {
* *
*/ */
void workspace_prev() { void workspace_prev() {
Con *ws = con_get_workspace(focused); Con *current = con_get_workspace(focused);
Con *prev = TAILQ_PREV(ws, nodes_head, nodes); Con *prev = NULL;
if (!prev) Con *output;
prev = TAILQ_LAST(&(ws->parent->nodes_head), nodes_head);
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); workspace_show(prev->name);
} }