]> git.lizzy.rs Git - bspwm.git/commitdiff
Options for 'cycle_desktop': --skip-{free,occupied}
authorBastien Dejean <nihilhill@gmail.com>
Tue, 23 Oct 2012 11:31:11 +0000 (13:31 +0200)
committerBastien Dejean <nihilhill@gmail.com>
Tue, 23 Oct 2012 11:31:11 +0000 (13:31 +0200)
README.md
messages.c
messages.h
tree.c
tree.h
types.h

index 09d70a131cd379af80604bf50a38db83e60fd8bb..d30d87049cfee45a78c31264a52fff25e016e5fc 100644 (file)
--- 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
index e174f5fe4a7ec0d001cc5b0a6d6ce2ccfa9df6fa..5ce56bab45e73b738cfed523eecef0c8ab2ad482 100644 (file)
@@ -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;
index cf3c7c92279644975ec780557c566f8fa2dd3fd4..a76c3ded7eee54fa21c604721960dabe88997763 100644 (file)
@@ -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 2943f6684982ba2f6722c07248270c548bc5c7c6..fb733d7609c74a91607c1428547f6f52f70872bf 100644 (file)
--- 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 6f3ff84181766001ae1f311da9bcabad20d0a5f5..4970e512cf00f3d7de4e04032f22e1ef6cd7821e 100644 (file)
--- 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 ea48f3b3a96d7f67fcf8f2412cc030769a4b5c03..44dcf69cbfbd59e790ec524f55133542f7aa4409 100644 (file)
--- 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