]> code.delx.au - spectrwm/blobdiff - scrotwm.c
add rb stuff to linux
[spectrwm] / scrotwm.c
index 658696b1a93cae32099d889c8dfb4cd6ba57311f..bf4a3bdc4d3abecaa2753b3e2af7accbc10eead4 100644 (file)
--- a/scrotwm.c
+++ b/scrotwm.c
 #include <sys/queue.h>
 #include <sys/param.h>
 #include <sys/select.h>
+#if defined(__linux__)
+#include "linux/tree.h"
+#elif defined(__OpenBSD__)
+#include <sys/tree.h>
+# endif
 
 #include <X11/cursorfont.h>
 #include <X11/keysym.h>
@@ -1484,6 +1489,13 @@ bar_update(void)
        alarm(bar_delay);
 }
 
+void
+bar_check_opts(void)
+{
+       if (title_class_enabled || title_name_enabled || window_name_enabled)
+               bar_update();
+}
+
 void
 bar_signal(int sig)
 {
@@ -2215,8 +2227,7 @@ focus_win(struct ws_win *win)
                    PropModeReplace, (unsigned char *)&win->id,1);
        }
 
-       if (window_name_enabled || title_class_enabled || title_name_enabled)
-               bar_update();
+       bar_check_opts();
 }
 
 void
@@ -2481,7 +2492,7 @@ swapwin(struct swm_region *r, union arg *args)
 void
 focus_prev(struct ws_win *win)
 {
-       struct ws_win           *winfocus = NULL, *winlostfocus = NULL;
+       struct ws_win           *winfocus = NULL;
        struct ws_win           *cur_focus = NULL;
        struct ws_win_list      *wl = NULL;
        struct workspace        *ws = NULL;
@@ -2494,7 +2505,6 @@ focus_prev(struct ws_win *win)
        ws = win->ws;
        wl = &ws->winlist;
        cur_focus = ws->focus;
-       winlostfocus = cur_focus;
 
        /* pickle, just focus on whatever */
        if (cur_focus == NULL) {
@@ -2532,22 +2542,15 @@ focus_prev(struct ws_win *win)
                winfocus = TAILQ_LAST(wl, ws_win_list);
        if (winfocus == NULL || winfocus == win)
                winfocus = TAILQ_NEXT(cur_focus, entry);
-done:
-       if (winfocus == winlostfocus || winfocus == NULL) {
-               /* update the bar so that title/class/name will be cleared. */
-               if (window_name_enabled || title_name_enabled ||
-                   title_class_enabled)
-                       bar_update();
-               return;
-       }
 
+done:
        focus_magic(winfocus);
 }
 
 void
 focus(struct swm_region *r, union arg *args)
 {
-       struct ws_win           *winfocus = NULL, *winlostfocus = NULL, *head;
+       struct ws_win           *winfocus = NULL, *head;
        struct ws_win           *cur_focus = NULL;
        struct ws_win_list      *wl = NULL;
        struct workspace        *ws = NULL;
@@ -2589,8 +2592,6 @@ focus(struct swm_region *r, union arg *args)
        if (all_iconics)
                return;
 
-       winlostfocus = cur_focus;
-
        switch (args->id) {
        case SWM_ARG_ID_FOCUSPREV:
                head = TAILQ_PREV(cur_focus, ws_win_list, entry);
@@ -2644,14 +2645,6 @@ focus(struct swm_region *r, union arg *args)
        default:
                return;
        }
-       if (winfocus == winlostfocus || winfocus == NULL) {
-               /* update the bar so that title/class/name will be cleared. */
-               if (window_name_enabled || title_name_enabled ||
-                   title_class_enabled)
-                       bar_update();
-
-               return;
-       }
 
        focus_magic(winfocus);
 }
@@ -4326,14 +4319,32 @@ struct keyfunc {
        { "invalid key func",   NULL,           {0} },
 };
 struct key {
-       TAILQ_ENTRY(key)        entry;
+       RB_ENTRY(key)           entry;
        unsigned int            mod;
        KeySym                  keysym;
        enum keyfuncid          funcid;
        char                    *spawn_name;
 };
-TAILQ_HEAD(key_list, key);
-struct key_list                        keys = TAILQ_HEAD_INITIALIZER(keys);
+RB_HEAD(key_list, key);
+
+int
+key_cmp(struct key *kp1, struct key *kp2)
+{
+       if (kp1->keysym < kp2->keysym)
+               return (-1);
+       if (kp1->keysym > kp2->keysym)
+               return (1);
+
+       if (kp1->mod < kp2->mod)
+               return (-1);
+       if (kp1->mod > kp2->mod)
+               return (1);
+
+       return (0);
+}
+
+RB_GENERATE_STATIC(key_list, key, entry, key_cmp);
+struct key_list                        keys;
 
 /* mouse */
 enum { client_click, root_click };
@@ -4357,7 +4368,7 @@ update_modkey(unsigned int mod)
        struct key              *kp;
 
        mod_key = mod;
-       TAILQ_FOREACH(kp, &keys, entry)
+       RB_FOREACH(kp, key_list, &keys)
                if (kp->mod & ShiftMask)
                        kp->mod = mod | ShiftMask;
                else
@@ -4725,17 +4736,28 @@ key_insert(unsigned int mod, KeySym ks, enum keyfuncid kfid, char *spawn_name)
        kp->keysym = ks;
        kp->funcid = kfid;
        kp->spawn_name = strdupsafe(spawn_name);
-       TAILQ_INSERT_TAIL(&keys, kp, entry);
+       RB_INSERT(key_list, &keys, kp);
 
        DNPRINTF(SWM_D_KEY, "key_insert: leave\n");
 }
 
+struct key *
+key_lookup(unsigned int mod, KeySym ks)
+{
+       struct key              kp;
+
+       kp.keysym = ks;
+       kp.mod = mod;
+
+       return (RB_FIND(key_list, &keys, &kp));
+}
+
 void
 key_remove(struct key *kp)
 {
        DNPRINTF(SWM_D_KEY, "key_remove: %s\n", keyfuncs[kp->funcid].name);
 
-       TAILQ_REMOVE(&keys, kp, entry);
+       RB_REMOVE(key_list, &keys, kp);
        free(kp->spawn_name);
        free(kp);
 
@@ -4764,15 +4786,13 @@ setkeybinding(unsigned int mod, KeySym ks, enum keyfuncid kfid,
        DNPRINTF(SWM_D_KEY, "setkeybinding: enter %s [%s]\n",
            keyfuncs[kfid].name, spawn_name);
 
-       TAILQ_FOREACH(kp, &keys, entry) {
-               if (kp->mod == mod && kp->keysym == ks) {
-                       if (kfid == kf_invalid)
-                               key_remove(kp);
-                       else
-                               key_replace(kp, mod, ks, kfid, spawn_name);
-                       DNPRINTF(SWM_D_KEY, "setkeybinding: leave\n");
-                       return;
-               }
+       if ((kp = key_lookup(mod, ks)) != NULL) {
+               if (kfid == kf_invalid)
+                       key_remove(kp);
+               else
+                       key_replace(kp, mod, ks, kfid, spawn_name);
+               DNPRINTF(SWM_D_KEY, "setkeybinding: leave\n");
+               return;
        }
        if (kfid == kf_invalid) {
                warnx("error: setkeybinding: cannot find mod/key combination");
@@ -4914,13 +4934,11 @@ setup_keys(void)
 void
 clear_keys(void)
 {
-       struct key              *kp_loop, *kp_next;
+       struct key              *kp;
 
-       kp_loop = TAILQ_FIRST(&keys);
-       while (kp_loop != NULL) {
-               kp_next = TAILQ_NEXT(kp_loop, entry);
-               key_remove(kp_loop);
-               kp_loop = kp_next;
+       while (RB_EMPTY(&keys) == 0) {
+               kp = RB_ROOT(&keys);
+               key_remove(kp);
        }
 }
 
@@ -4978,7 +4996,7 @@ grabkeys(void)
                if (TAILQ_EMPTY(&screens[k].rl))
                        continue;
                XUngrabKey(display, AnyKey, AnyModifier, screens[k].root);
-               TAILQ_FOREACH(kp, &keys, entry) {
+               RB_FOREACH(kp, key_list, &keys) {
                        if ((code = XKeysymToKeycode(display, kp->keysym)))
                                for (j = 0; j < LENGTH(modifiers); j++)
                                        XGrabKey(display, code,
@@ -5997,8 +6015,11 @@ focus_magic(struct ws_win *win)
 {
        DNPRINTF(SWM_D_FOCUS, "focus_magic: window: 0x%lx\n", WINID(win));
 
-       if (win == NULL)
+       if (win == NULL) {
+               /* if there are no windows clear the status-bar */
+               bar_check_opts();
                return;
+       }
 
        if (win->child_trans) {
                /* win = parent & has a transient so focus on that */
@@ -6007,7 +6028,7 @@ focus_magic(struct ws_win *win)
                        if (win->child_trans->take_focus)
                                client_msg(win, takefocus);
                } else {
-                       /* make sure transient hasn't dissapeared */
+                       /* make sure transient hasn't disappeared */
                        if (validate_win(win->child_trans) == 0) {
                                focus_win(win->child_trans);
                                if (win->child_trans->take_focus)
@@ -6039,24 +6060,19 @@ keypress(XEvent *e)
        KeySym                  keysym;
        XKeyEvent               *ev = &e->xkey;
        struct key              *kp;
+       struct swm_region       *r;
 
        keysym = XKeycodeToKeysym(display, (KeyCode)ev->keycode, 0);
-       TAILQ_FOREACH(kp, &keys, entry)
-               if (keysym == kp->keysym
-                   && CLEANMASK(kp->mod) == CLEANMASK(ev->state)
-                   && keyfuncs[kp->funcid].func) {
-                       if (kp->funcid == kf_spawn_custom)
-                               spawn_custom(
-                                   root_to_region(ev->root),
-                                   &(keyfuncs[kp->funcid].args),
-                                   kp->spawn_name
-                                   );
-                       else
-                               keyfuncs[kp->funcid].func(
-                                   root_to_region(ev->root),
-                                   &(keyfuncs[kp->funcid].args)
-                                   );
-               }
+       if ((kp = key_lookup(CLEANMASK(ev->state), keysym)) == NULL)
+               return;
+       if (keyfuncs[kp->funcid].func == NULL)
+               return;
+
+       r = root_to_region(ev->root);
+       if (kp->funcid == kf_spawn_custom)
+               spawn_custom(r, &(keyfuncs[kp->funcid].args), kp->spawn_name);
+       else
+               keyfuncs[kp->funcid].func(r, &(keyfuncs[kp->funcid].args));
 }
 
 void