]> git.lizzy.rs Git - bspwm.git/commitdiff
New arguments for `swap`: `biggest` and `smallest`
authorBastien Dejean <nihilhill@gmail.com>
Tue, 2 Apr 2013 13:02:45 +0000 (15:02 +0200)
committerBastien Dejean <nihilhill@gmail.com>
Tue, 2 Apr 2013 13:02:45 +0000 (15:02 +0200)
README.md
bspwm.1
messages.c
messages.h
tree.c
tree.h
types.h

index 53fe4b7486f283857871db07eafa52ce74b8eef6..63e60e344b0849750c521b9e80cb0f8e921d244a 100644 (file)
--- a/README.md
+++ b/README.md
@@ -99,7 +99,7 @@ The following messages are handled:
 
 - `shift left|right|up|down` — Exchange the current window with the given neighbor.
 
-- `swap` — Swap the focused window with the last focused window.
+- `swap [biggest|smallest]` — Swap the focused window with the biggest/smallest window or with the last focused window if no arguments are given.
 
 - `push left|right|up|down` — Push the fence located in the given direction.
 
diff --git a/bspwm.1 b/bspwm.1
index f97776df213f293a44d4f39f9ce59f0c260556da..d96669f25150044d52174252273f6e4f05a7f8bc 100644 (file)
--- a/bspwm.1
+++ b/bspwm.1
@@ -130,8 +130,8 @@ Focus the neighbor window situated in the given direction.
 .BI shift " left|right|up|down"
 Exchange the current window with the given neighbor.
 .TP
-.BI swap
-Swap the focused window with the last focused window.
+.BI swap " [biggest|smallest]"
+Swap the focused window with the biggest/smallest window or with the last focused window if no arguments are given.
 .TP
 .BI push " left|right|up|down"
 Push the fence located in the given direction.
index cbfdfa1985a42bf5e232bb38eebc2c08acd70fe6..758e04b87cd1a4bfdbc36d9d2b81f8892024d7a0 100644 (file)
@@ -389,7 +389,16 @@ void process_message(char *msg, char *rsp)
                 remove_rule_by_uid(uid);
         return;
     } else if (strcmp(cmd, "swap") == 0) {
-        swap_nodes(mon->desk, mon->desk->focus, mon->desk, mon->desk->last_focus);
+        char *arg;
+        swap_arg_t a;
+        if ((arg = strtok(NULL, TOK_SEP)) != NULL) {
+            if (parse_swap_argument(arg, &a)) {
+                node_t *n = find_by_area(mon->desk, a);
+                swap_nodes(mon->desk, mon->desk->focus, mon->desk, n);
+            }
+        } else {
+            swap_nodes(mon->desk, mon->desk->focus, mon->desk, mon->desk->last_focus);
+        }
     } else if (strcmp(cmd, "alternate") == 0) {
         focus_node(mon, mon->desk, mon->desk->last_focus, true);
         return;
@@ -634,6 +643,18 @@ bool parse_nearest_argument(char *s, nearest_arg_t *a)
     return false;
 }
 
+bool parse_swap_argument(char *s, swap_arg_t *a)
+{
+    if (strcmp(s, "biggest") == 0) {
+        *a = SWAP_BIGGEST;
+        return true;
+    } else if (strcmp(s, "smallest") == 0) {
+        *a = SWAP_SMALLEST;
+        return true;
+    }
+    return false;
+}
+
 bool parse_cycle_direction(char *s, cycle_dir_t *d)
 {
     if (strcmp(s, "prev") == 0) {
index 8f7d5d6d7296c32e161526e7a0656c6c4156f9c0..7e5c3f6f37635c015eb6f311efd12d65b6fbf7ed 100644 (file)
@@ -12,6 +12,7 @@ bool parse_bool(char *, bool *);
 bool parse_layout(char *, layout_t *);
 bool parse_direction(char *, direction_t *);
 bool parse_nearest_argument(char *, nearest_arg_t *);
+bool parse_swap_argument(char *, swap_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 *);
diff --git a/tree.c b/tree.c
index 00fd26862f1bee163283bd29449013e354e10bc5..9c8390b28c084d424e8234da5b58d963735738bd 100644 (file)
--- a/tree.c
+++ b/tree.c
@@ -126,6 +126,37 @@ node_t *find_neighbor(node_t *n, direction_t dir)
     return NULL;
 }
 
+int tiled_area(node_t *n)
+{
+    if (n == NULL)
+        return -1;
+    xcb_rectangle_t rect = n->client->tiled_rectangle;
+    return rect.width * rect.height;
+}
+
+node_t *find_by_area(desktop_t *d, swap_arg_t a)
+{
+    if (d == NULL)
+        return NULL;
+
+    node_t *r = NULL;
+    int r_area = tiled_area(r);
+
+    for (node_t *f = first_extrema(d->root); f != NULL; f = next_leaf(f)) {
+        int f_area = tiled_area(f);
+        if (r == NULL) {
+            r = f;
+            r_area = f_area;
+        } else if ((a == SWAP_BIGGEST && f_area > r_area)
+                || (a == SWAP_SMALLEST && f_area < r_area)) {
+            r = f;
+            r_area = f_area;
+        }
+    }
+
+    return r;
+}
+
 void move_fence(node_t *n, direction_t dir, fence_move_t mov)
 {
     node_t *fence = find_fence(n, dir);
diff --git a/tree.h b/tree.h
index a3ecb20916fc91feb4b3c7749947e019b87195a7..089a842d46bab72b1f62f99ee773e0c71f73f937 100644 (file)
--- a/tree.h
+++ b/tree.h
@@ -16,6 +16,8 @@ node_t *next_leaf(node_t *);
 node_t *prev_leaf(node_t *);
 node_t *find_fence(node_t *, direction_t);
 node_t *find_neighbor(node_t *, direction_t);
+int tiled_area(node_t *);
+node_t *find_by_area(desktop_t *, swap_arg_t);
 void move_fence(node_t *, direction_t, fence_move_t);
 void rotate_tree(node_t *, rotate_t);
 void flip_tree(node_t *, flip_t);
diff --git a/types.h b/types.h
index 7b59f1c3108c4258229ec9a02721ade3b3d81d6a..94e7aca9e144d9ffdd79e667c488b0c81bad7ffd 100644 (file)
--- a/types.h
+++ b/types.h
@@ -70,6 +70,11 @@ typedef enum {
     NEAREST_NEWER
 } nearest_arg_t;
 
+typedef enum {
+    SWAP_BIGGEST,
+    SWAP_SMALLEST
+} swap_arg_t;
+
 typedef enum {
     CIRCULATE_FORWARD,
     CIRCULATE_BACKWARD