#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>
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;
ws = win->ws;
wl = &ws->winlist;
cur_focus = ws->focus;
- winlostfocus = cur_focus;
/* pickle, just focus on whatever */
if (cur_focus == NULL) {
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. */
- bar_check_opts();
- 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;
if (all_iconics)
return;
- winlostfocus = cur_focus;
-
switch (args->id) {
case SWM_ARG_ID_FOCUSPREV:
head = TAILQ_PREV(cur_focus, ws_win_list, entry);
default:
return;
}
- if (winfocus == winlostfocus || winfocus == NULL) {
- /* update the bar so that title/class/name will be cleared. */
- bar_check_opts();
- return;
- }
focus_magic(winfocus);
}
{ "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 };
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
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);
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");
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);
}
}
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,
{
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 */
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)
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