From: Bastien Dejean Date: Tue, 23 Oct 2012 11:31:11 +0000 (+0200) Subject: Options for 'cycle_desktop': --skip-{free,occupied} X-Git-Url: https://git.lizzy.rs/?a=commitdiff_plain;h=243f1245e702adacb317968b7e8ea4114ce53e0b;p=bspwm.git Options for 'cycle_desktop': --skip-{free,occupied} --- diff --git a/README.md b/README.md index 09d70a1..d30d870 100644 --- a/README.md +++ b/README.md @@ -167,7 +167,7 @@ The following messages are handled: cycle_monitor CYC Select the next or previous monitor. - cycle_desktop CYC + cycle_desktop CYC [--skip-free|--skip-occupied] Select the next or previous desktop. layout LYT diff --git a/messages.c b/messages.c index e174f5f..5ce56ba 100644 --- a/messages.c +++ b/messages.c @@ -195,23 +195,13 @@ void process_message(char *msg, char *rsp) char *dir = strtok(NULL, TOKEN_SEP); if (dir != NULL) { cycle_dir_t d; - if (parse_cycle_direction(dir, &d)) - cycle_desktop(d); - } - } else if (strcmp(cmd, "nearest") == 0) { - if (mon->desk->focus != NULL && mon->desk->focus->client->fullscreen) - return; - char *arg = strtok(NULL, TOKEN_SEP); - if (arg != NULL) { - nearest_arg_t a; - if (parse_nearest_argument(arg, &a)) { - skip_client_t k; + if (parse_cycle_direction(dir, &d)) { + skip_desktop_t k; char *skip = strtok(NULL, TOKEN_SEP); - if (parse_skip_client(skip, &k)) - nearest_leaf(mon, mon->desk, mon->desk->focus, a, k); + if (parse_skip_desktop(skip, &k)) + cycle_desktop(mon, mon->desk, d, k); } } - return; } else if (strcmp(cmd, "cycle") == 0) { if (mon->desk->focus != NULL && mon->desk->focus->client->fullscreen) return; @@ -226,6 +216,20 @@ void process_message(char *msg, char *rsp) } } return; + } else if (strcmp(cmd, "nearest") == 0) { + if (mon->desk->focus != NULL && mon->desk->focus->client->fullscreen) + return; + char *arg = strtok(NULL, TOKEN_SEP); + if (arg != NULL) { + nearest_arg_t a; + if (parse_nearest_argument(arg, &a)) { + skip_client_t k; + char *skip = strtok(NULL, TOKEN_SEP); + if (parse_skip_client(skip, &k)) + nearest_leaf(mon, mon->desk, mon->desk->focus, a, k); + } + } + return; } else if (strcmp(cmd, "rule") == 0) { char *name = strtok(NULL, TOKEN_SEP); if (name != NULL) { @@ -490,20 +494,35 @@ bool parse_cycle_direction(char *s, cycle_dir_t *d) bool parse_skip_client(char *s, skip_client_t *k) { - if (s == NULL || strcmp(s, "--skip-none") == 0) { - *k = SKIP_NONE; + if (s == NULL) { + *k = CLIENT_SKIP_NONE; return true; } else if (strcmp(s, "--skip-floating") == 0) { - *k = SKIP_FLOATING; + *k = CLIENT_SKIP_FLOATING; return true; } else if (strcmp(s, "--skip-tiled") == 0) { - *k = SKIP_TILED; + *k = CLIENT_SKIP_TILED; return true; } else if (strcmp(s, "--skip-class-equal") == 0) { - *k = SKIP_CLASS_EQUAL; + *k = CLIENT_SKIP_CLASS_EQUAL; return true; } else if (strcmp(s, "--skip-class-differ") == 0) { - *k = SKIP_CLASS_DIFFER; + *k = CLIENT_SKIP_CLASS_DIFFER; + return true; + } + return false; +} + +bool parse_skip_desktop(char *s, skip_desktop_t *k) +{ + if (s == NULL) { + *k = DESKTOP_SKIP_NONE; + return true; + } else if (strcmp(s, "--skip-free") == 0) { + *k = DESKTOP_SKIP_FREE; + return true; + } else if (strcmp(s, "--skip-occupied") == 0) { + *k = DESKTOP_SKIP_OCCUPIED; return true; } return false; diff --git a/messages.h b/messages.h index cf3c7c9..a76c3de 100644 --- a/messages.h +++ b/messages.h @@ -13,6 +13,7 @@ bool parse_nearest_argument(char *, nearest_arg_t *); bool parse_cycle_direction(char *, cycle_dir_t *); bool parse_list_option(char *, list_option_t *); bool parse_skip_client(char *, skip_client_t *); +bool parse_skip_desktop(char *, skip_desktop_t *); bool parse_corner(char *, corner_t *); bool parse_rotate(char *, rotate_t *); bool parse_fence_move(char *, fence_move_t *); diff --git a/tree.c b/tree.c index 2943f66..fb733d7 100644 --- a/tree.c +++ b/tree.c @@ -681,36 +681,23 @@ void cycle_monitor(cycle_dir_t dir) select_monitor((mon->prev == NULL ? mon_tail : mon->prev)); } -void cycle_desktop(cycle_dir_t dir) +void cycle_desktop(monitor_t *m, desktop_t *d, cycle_dir_t dir, skip_desktop_t skip) { - if (dir == CYCLE_NEXT) - select_desktop((mon->desk->next == NULL ? mon->desk_head : mon->desk->next)); - else if (dir == CYCLE_PREV) - select_desktop((mon->desk->prev == NULL ? mon->desk_tail : mon->desk->prev)); -} - -void nearest_leaf(monitor_t *m, desktop_t *d, node_t *n, nearest_arg_t dir, skip_client_t skip) -{ - if (n == NULL) - return; - - PUTS("nearest leaf"); - - node_t *x = NULL; - - for (node_t *f = first_extrema(d->root); f != NULL; f = next_leaf(f)) - if (skip == SKIP_NONE || (skip == SKIP_TILED && !is_tiled(f->client)) || (skip == SKIP_FLOATING && is_tiled(f->client)) - || (skip == SKIP_CLASS_DIFFER && strcmp(f->client->class_name, n->client->class_name) == 0) - || (skip == SKIP_CLASS_EQUAL && strcmp(f->client->class_name, n->client->class_name) != 0)) - if ((dir == NEAREST_OLDER - && (f->client->uid < n->client->uid) - && (x == NULL || f->client->uid > x->client->uid)) - || (dir == NEAREST_NEWER - && (f->client->uid > n->client->uid) - && (x == NULL || f->client->uid < x->client->uid))) - x = f; + desktop_t *f = (dir == CYCLE_PREV ? d->prev : d->next); + if (f == NULL) + f = (dir == CYCLE_PREV ? m->desk_tail : m->desk_head); - focus_node(m, d, x, true); + while (f != d) { + if (skip == DESKTOP_SKIP_NONE + || (skip == DESKTOP_SKIP_FREE && f->root != NULL) + || (skip == DESKTOP_SKIP_OCCUPIED && f->root == NULL)) { + select_desktop(f); + return; + } + f = (dir == CYCLE_PREV ? f->prev : f->next); + if (f == NULL) + f = (dir == CYCLE_PREV ? m->desk_tail : m->desk_head); + } } void cycle_leaf(monitor_t *m, desktop_t *d, node_t *n, cycle_dir_t dir, skip_client_t skip) @@ -726,9 +713,9 @@ void cycle_leaf(monitor_t *m, desktop_t *d, node_t *n, cycle_dir_t dir, skip_cli while (f != n) { bool tiled = is_tiled(f->client); - if (skip == SKIP_NONE || (skip == SKIP_TILED && !tiled) || (skip == SKIP_FLOATING && tiled) - || (skip == SKIP_CLASS_DIFFER && strcmp(f->client->class_name, n->client->class_name) == 0) - || (skip == SKIP_CLASS_EQUAL && strcmp(f->client->class_name, n->client->class_name) != 0)) { + if (skip == CLIENT_SKIP_NONE || (skip == CLIENT_SKIP_TILED && !tiled) || (skip == CLIENT_SKIP_FLOATING && tiled) + || (skip == CLIENT_SKIP_CLASS_DIFFER && strcmp(f->client->class_name, n->client->class_name) == 0) + || (skip == CLIENT_SKIP_CLASS_EQUAL && strcmp(f->client->class_name, n->client->class_name) != 0)) { focus_node(m, d, f, true); return; } @@ -738,6 +725,30 @@ void cycle_leaf(monitor_t *m, desktop_t *d, node_t *n, cycle_dir_t dir, skip_cli } } +void nearest_leaf(monitor_t *m, desktop_t *d, node_t *n, nearest_arg_t dir, skip_client_t skip) +{ + if (n == NULL) + return; + + PUTS("nearest leaf"); + + node_t *x = NULL; + + for (node_t *f = first_extrema(d->root); f != NULL; f = next_leaf(f)) + if (skip == CLIENT_SKIP_NONE || (skip == CLIENT_SKIP_TILED && !is_tiled(f->client)) || (skip == CLIENT_SKIP_FLOATING && is_tiled(f->client)) + || (skip == CLIENT_SKIP_CLASS_DIFFER && strcmp(f->client->class_name, n->client->class_name) == 0) + || (skip == CLIENT_SKIP_CLASS_EQUAL && strcmp(f->client->class_name, n->client->class_name) != 0)) + if ((dir == NEAREST_OLDER + && (f->client->uid < n->client->uid) + && (x == NULL || f->client->uid > x->client->uid)) + || (dir == NEAREST_NEWER + && (f->client->uid > n->client->uid) + && (x == NULL || f->client->uid < x->client->uid))) + x = f; + + focus_node(m, d, x, true); +} + void update_vacant_state(node_t *n) { if (n == NULL) diff --git a/tree.h b/tree.h index 6f3ff84..4970e51 100644 --- a/tree.h +++ b/tree.h @@ -36,12 +36,12 @@ void transfer_node(monitor_t *, desktop_t *, monitor_t *, desktop_t *, node_t *) void select_monitor(monitor_t *); void select_desktop(desktop_t *); void cycle_monitor(cycle_dir_t); -void cycle_desktop(cycle_dir_t); -void nearest_leaf(monitor_t *, desktop_t *, node_t *, nearest_arg_t, skip_client_t); +void cycle_desktop(monitor_t *, desktop_t *, cycle_dir_t, skip_desktop_t); void cycle_leaf(monitor_t *, desktop_t *, node_t *, cycle_dir_t, skip_client_t); +void nearest_leaf(monitor_t *, desktop_t *, node_t *, nearest_arg_t, skip_client_t); void update_vacant_state(node_t *); -monitor_t *find_monitor(char *); void add_desktop(monitor_t *, char *); void add_monitor(xcb_rectangle_t *); +monitor_t *find_monitor(char *); #endif diff --git a/types.h b/types.h index ea48f3b..44dcf69 100644 --- a/types.h +++ b/types.h @@ -42,13 +42,19 @@ typedef enum { } list_option_t; typedef enum { - SKIP_NONE, - SKIP_FLOATING, - SKIP_TILED, - SKIP_CLASS_EQUAL, - SKIP_CLASS_DIFFER + CLIENT_SKIP_NONE, + CLIENT_SKIP_FLOATING, + CLIENT_SKIP_TILED, + CLIENT_SKIP_CLASS_EQUAL, + CLIENT_SKIP_CLASS_DIFFER } skip_client_t; +typedef enum { + DESKTOP_SKIP_NONE, + DESKTOP_SKIP_FREE, + DESKTOP_SKIP_OCCUPIED +} skip_desktop_t; + typedef enum { CYCLE_NEXT, CYCLE_PREV