From c28eceb152c48b5207be4097cb1fd2dca43d2d90 Mon Sep 17 00:00:00 2001 From: Bastien Dejean Date: Thu, 1 Nov 2012 22:47:03 +0100 Subject: [PATCH] New message: 'circulate' --- README.md | 3 +++ bspwm.1 | 3 +++ messages.c | 21 +++++++++++++++++++++ messages.h | 1 + tree.c | 19 +++++++++++++++++++ tree.h | 1 + types.h | 5 +++++ 7 files changed, 53 insertions(+) diff --git a/README.md b/README.md index 122de2c..0f15bee 100644 --- a/README.md +++ b/README.md @@ -116,6 +116,9 @@ The following messages are handled: nearest older|newer [--skip-floating|--skip-tiled|--skip-class-equal|--skip-class-differ] Focus the nearest window matching the given constraints. + circulate forward|backward + Circulate the leaves in the given direction. + toggle_fullscreen Toggle the fullscreen state of the current window. diff --git a/bspwm.1 b/bspwm.1 index 672c253..f2823ea 100644 --- a/bspwm.1 +++ b/bspwm.1 @@ -143,6 +143,9 @@ Focus the next or previous window matching the given constraints. .BI nearest " older|newer [--skip-floating|--skip-tiled|--skip-class-equal|--skip-class-differ]" Focus the nearest window matching the given constraints. .TP +.BI circulate " forward|backward" +Circulate the leaves in the given direction. +.TP .BI toggle_fullscreen Toggle the fullscreen state of the current window. .TP diff --git a/messages.c b/messages.c index 747fff2..8539102 100644 --- a/messages.c +++ b/messages.c @@ -232,6 +232,15 @@ void process_message(char *msg, char *rsp) } if (mon->desk->layout == LAYOUT_TILED) return; + } else if (strcmp(cmd, "circulate") == 0) { + if (mon->desk->layout == LAYOUT_MONOCLE || (mon->desk->focus != NULL && mon->desk->focus->client->fullscreen)) + return; + char *dir = strtok(NULL, TOKEN_SEP); + if (dir != NULL) { + circulate_dir_t d; + if (parse_circulate_direction(dir, &d)) + circulate_leaves(mon, mon->desk, d); + } } else if (strcmp(cmd, "rule") == 0) { char *name = strtok(NULL, TOKEN_SEP); if (name != NULL) { @@ -502,6 +511,18 @@ bool parse_cycle_direction(char *s, cycle_dir_t *d) return false; } +bool parse_circulate_direction(char *s, circulate_dir_t *d) +{ + if (strcmp(s, "forward") == 0) { + *d = CIRCULATE_FORWARD; + return true; + } else if (strcmp(s, "backward") == 0) { + *d = CIRCULATE_BACKWARD; + return true; + } + return false; +} + bool parse_skip_client(char *s, skip_client_t *k) { if (s == NULL) { diff --git a/messages.h b/messages.h index 7941e97..aef82f2 100644 --- a/messages.h +++ b/messages.h @@ -11,6 +11,7 @@ bool parse_layout(char *, layout_t *); bool parse_direction(char *, direction_t *); bool parse_nearest_argument(char *, nearest_arg_t *); bool parse_cycle_direction(char *, cycle_dir_t *); +bool parse_circulate_direction(char *, circulate_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 *); diff --git a/tree.c b/tree.c index 0ab917d..e0e1e30 100644 --- a/tree.c +++ b/tree.c @@ -751,6 +751,25 @@ void nearest_leaf(monitor_t *m, desktop_t *d, node_t *n, nearest_arg_t dir, skip focus_node(m, d, x, true); } +void circulate_leaves(monitor_t *m, desktop_t *d, circulate_dir_t dir) { + if (d == NULL || d->root == NULL || is_leaf(d->root)) + return; + node_t *par = d->focus->parent; + bool first = is_first_child(d->focus); + if (dir == CIRCULATE_FORWARD) + for (node_t *s = second_extrema(d->root), *f = prev_leaf(s); f != NULL && s != NULL; s = prev_leaf(f), f = prev_leaf(s)) + swap_nodes(f, s); + else + for (node_t *f = first_extrema(d->root), *s = next_leaf(f); f != NULL && s != NULL; f = next_leaf(s), s = next_leaf(f)) + swap_nodes(f, s); + if (is_floating(d->focus->client)) + return; + if (first) + focus_node(m, d, par->first_child, true); + else + focus_node(m, d, par->second_child, true); +} + void update_vacant_state(node_t *n) { if (n == NULL) diff --git a/tree.h b/tree.h index 84a12c4..5d1ca3d 100644 --- a/tree.h +++ b/tree.h @@ -39,6 +39,7 @@ void cycle_monitor(cycle_dir_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 circulate_leaves(monitor_t *, desktop_t *, circulate_dir_t); void update_vacant_state(node_t *); void add_desktop(monitor_t *, char *); void add_monitor(xcb_rectangle_t *); diff --git a/types.h b/types.h index 44dcf69..5f02f35 100644 --- a/types.h +++ b/types.h @@ -65,6 +65,11 @@ typedef enum { NEAREST_NEWER } nearest_arg_t; +typedef enum { + CIRCULATE_FORWARD, + CIRCULATE_BACKWARD +} circulate_dir_t; + typedef enum { ROTATE_CLOCKWISE, ROTATE_COUNTER_CLOCKWISE, -- 2.44.0