]> code.delx.au - spectrwm/blobdiff - spectrwm.c
Add myself to the copyright
[spectrwm] / spectrwm.c
index 93ed998587b6903cf0af7ca1fe560f32dc9f976c..4f2399cdd07724d35d72b95e057f0a78b871641a 100644 (file)
@@ -8,6 +8,7 @@
  * Copyright (c) 2011-2012 Reginald Kennedy <rk@rejii.com>
  * Copyright (c) 2011-2012 Lawrence Teo <lteo@lteo.net>
  * Copyright (c) 2011-2012 Tiago Cunha <tcunha@gmx.com>
+ * Copyright (c) 2012 David Hill <dhill@mindcry.org>
  *
  * Permission to use, copy, modify, and distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
  * DEALINGS IN THE SOFTWARE.
  */
 
-#include <stdio.h>
-#include <stdlib.h>
-#include <err.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <locale.h>
-#include <unistd.h>
-#include <time.h>
-#include <signal.h>
-#include <string.h>
-#include <util.h>
-#include <pwd.h>
-#include <paths.h>
-#include <ctype.h>
-
+/* kernel includes */
 #include <sys/types.h>
 #include <sys/time.h>
 #include <sys/stat.h>
 #include "tree.h"
 #endif
 
+/* /usr/includes */
+#include <ctype.h>
+#include <err.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <locale.h>
+#include <paths.h>
+#include <pwd.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <unistd.h>
+#include <util.h>
 #include <X11/cursorfont.h>
-#include <X11/keysym.h>
-#include <X11/XKBlib.h>
-#include <X11/Xatom.h>
+#include <X11/extensions/Xrandr.h>
+#include <X11/Xft/Xft.h>
 #include <X11/Xlib-xcb.h>
-#include <xcb/randr.h>
 #include <xcb/xcb_atom.h>
 #include <xcb/xcb_aux.h>
 #include <xcb/xcb_event.h>
 #include <xcb/xcb_icccm.h>
 #include <xcb/xcb_keysyms.h>
 #include <xcb/xtest.h>
-#include <X11/Xproto.h>
-#include <X11/Xutil.h>
-#include <X11/extensions/Xrandr.h>
-#include <X11/extensions/XTest.h>
+#include <xcb/randr.h>
 
+/* local includes */
+#include "version.h"
 #ifdef __OSX__
 #include <osx.h>
 #endif
 
-#include "version.h"
-
 #ifdef SPECTRWM_BUILDSTR
 static const char      *buildstr = SPECTRWM_BUILDSTR;
 #else
@@ -181,6 +178,7 @@ static const char   *buildstr = SPECTRWM_VERSION;
 #define SWM_D_EVENTQ           0x1000
 #define SWM_D_CONF             0x2000
 #define SWM_D_BAR              0x4000
+#define SWM_D_INIT             0x8000
 
 u_int32_t              swm_debug = 0
                            | SWM_D_MISC
@@ -198,15 +196,25 @@ u_int32_t         swm_debug = 0
                            | SWM_D_EVENTQ
                            | SWM_D_CONF
                            | SWM_D_BAR
+                           | SWM_D_INIT
                            ;
 #else
 #define DPRINTF(x...)
 #define DNPRINTF(n,x...)
 #endif
 
-#define LENGTH(x)              (sizeof x / sizeof x[0])
+/* convert 8-bit to 16-bit */
+#define RGB_8_TO_16(col)       ((col) << 8) + (col)
+
+#define        PIXEL_TO_XRENDERCOLOR(px, xrc)                                  \
+       xrc.red = RGB_8_TO_16((px) >> 16 & 0xff);                       \
+       xrc.green = RGB_8_TO_16((px) >> 8 & 0xff);                      \
+       xrc.blue = RGB_8_TO_16((px) & 0xff);                            \
+       xrc.alpha = 0xffff;
+
+#define LENGTH(x)              (int)(sizeof (x) / sizeof (x)[0])
 #define MODKEY                 Mod1Mask
-#define CLEANMASK(mask)                (mask & ~(numlockmask | LockMask))
+#define CLEANMASK(mask)                ((mask) & ~(numlockmask | LockMask))
 #define BUTTONMASK             (ButtonPressMask|ButtonReleaseMask)
 #define MOUSEMASK              (BUTTONMASK|PointerMotionMask)
 #define SWM_PROPLEN            (16)
@@ -217,7 +225,7 @@ u_int32_t           swm_debug = 0
 #define Y(r)                   (r)->g.y
 #define WIDTH(r)               (r)->g.w
 #define HEIGHT(r)              (r)->g.h
-#define BORDER(w)              (w->bordered ? border_width : 0)
+#define BORDER(w)              ((w)->bordered ? border_width : 0)
 #define MAX_X(r)               ((r)->g.x + (r)->g.w)
 #define MAX_Y(r)               ((r)->g.y + (r)->g.h)
 #define SH_MIN(w)              (w)->sh.flags & XCB_ICCCM_SIZE_HINT_P_MIN_SIZE
@@ -245,25 +253,26 @@ u_int32_t         swm_debug = 0
 #endif
 
 char                   **start_argv;
-xcb_atom_t             astate;
-xcb_atom_t             aprot;
-xcb_atom_t             adelete;
-xcb_atom_t             takefocus;
+xcb_atom_t             a_state;
+xcb_atom_t             a_prot;
+xcb_atom_t             a_delete;
+xcb_atom_t             a_takefocus;
 xcb_atom_t             a_wmname;
 xcb_atom_t             a_netwmname;
 xcb_atom_t             a_utf8_string;
 xcb_atom_t             a_string;
 xcb_atom_t             a_swm_iconic;
+xcb_atom_t             a_swm_ws;
 volatile sig_atomic_t   running = 1;
 volatile sig_atomic_t   restart_wm = 0;
 int                    outputs = 0;
 /*int                  last_focus_event = FocusOut;*/
-int                    (*xerrorxlib)(Display *, XErrorEvent *);
 int                    other_wm;
 int                    ss_enabled = 0;
 int                    xrandr_support;
 int                    xrandr_eventbase;
 unsigned int           numlockmask = 0;
+
 Display                        *display;
 xcb_connection_t       *conn;
 xcb_key_symbols_t      *syms;
@@ -353,17 +362,11 @@ int                       border_width = 1;
 int                    verbose_layout = 0;
 time_t                 time_started;
 pid_t                  bar_pid;
-XFontSet               bar_fs;
-XFontSetExtents                *bar_fs_extents;
+XftFont                        *bar_font;
 char                   *bar_fonts;
+XftColor               bar_font_color;
 struct passwd          *pwd;
 
-#define SWM_MENU_FN    (2)
-#define SWM_MENU_NB    (4)
-#define SWM_MENU_NF    (6)
-#define SWM_MENU_SB    (8)
-#define SWM_MENU_SF    (10)
-
 /* layout manager data */
 struct swm_geometry {
        int                     x;
@@ -425,7 +428,7 @@ TAILQ_HEAD(ws_win_list, ws_win);
 /* pid goo */
 struct pid_e {
        TAILQ_ENTRY(pid_e)      entry;
-       long                    pid;
+       pid_t                   pid;
        int                     ws;
 };
 TAILQ_HEAD(pid_list, pid_e);
@@ -441,15 +444,6 @@ void       max_stack(struct workspace *, struct swm_geometry *);
 void   plain_stacker(struct workspace *);
 void   fancy_stacker(struct workspace *);
 
-struct ws_win *find_window(xcb_window_t);
-
-void           grabbuttons(struct ws_win *, int);
-void           new_region(struct swm_screen *, int, int, int, int);
-void           unmanage_window(struct ws_win *);
-uint16_t       getstate(xcb_window_t);
-
-int            conf_load(char *, int);
-
 struct layout {
        void            (*l_stack)(struct workspace *, struct swm_geometry *);
        void            (*l_config)(struct workspace *, int);
@@ -523,7 +517,7 @@ struct swm_screen {
 
        /* colors */
        struct {
-               uint32_t        color;
+               uint32_t        pixel;
                char            *name;
        } c[SWM_S_COLOR_MAX];
 
@@ -574,9 +568,6 @@ union arg {
        char                    **argv;
 };
 
-void   focus(struct swm_region *, union arg *);
-void   focus_magic(struct ws_win *);
-
 /* quirks */
 struct quirk {
        TAILQ_ENTRY(quirk)      entry;
@@ -656,18 +647,30 @@ struct ewmh_hint {
     {"_SWM_WM_STATE_MANUAL", XCB_ATOM_NONE},
 };
 
-void            store_float_geom(struct ws_win *, struct swm_region *);
-int             floating_toggle_win(struct ws_win *);
-void            constrain_window(struct ws_win *, struct swm_region *, int);
-void            update_window(struct ws_win *);
-void            spawn_select(struct swm_region *, union arg *, char *, int *);
-char           *get_win_name(xcb_window_t);
-xcb_atom_t      get_atom_from_string(const char *);
-void            map_window_raised(xcb_window_t);
-void            do_sync(void);
+/* function prototypes */
+int     conf_load(char *, int);
+void    constrain_window(struct ws_win *, struct swm_region *, int);
+void    do_sync(void);
+void    event_handle(xcb_generic_event_t *);
+struct ws_win  *find_window(xcb_window_t);
+int     floating_toggle_win(struct ws_win *);
+void    focus(struct swm_region *, union arg *);
+void    focus_magic(struct ws_win *);
+xcb_atom_t get_atom_from_string(const char *);
 xcb_screen_t   *get_screen(int);
-int             parse_rgb(const char *, uint16_t *, uint16_t *, uint16_t *);
-void            event_handle(xcb_generic_event_t *);
+char   *get_win_name(xcb_window_t);
+uint32_t getstate(xcb_window_t);
+void    grabbuttons(struct ws_win *, int);
+void    map_window_raised(xcb_window_t);
+void    new_region(struct swm_screen *, int, int, int, int);
+int     parse_rgb(const char *, uint16_t *, uint16_t *, uint16_t *);
+void    spawn_select(struct swm_region *, union arg *, char *, int *);
+void    store_float_geom(struct ws_win *, struct swm_region *);
+void    unmanage_window(struct ws_win *);
+void    update_window(struct ws_win *);
+#ifdef SWM_DEBUG
+char   *get_atom_name(xcb_atom_t);
+#endif
 
 int
 parse_rgb(const char *rgb, uint16_t *rr, uint16_t *gg, uint16_t *bb)
@@ -677,9 +680,9 @@ parse_rgb(const char *rgb, uint16_t *rr, uint16_t *gg, uint16_t *bb)
        if (sscanf(rgb, "rgb:%x/%x/%x", &tmpr, &tmpg, &tmpb) != 3)
                return (-1);
 
-       *rr = tmpr << 8;
-       *gg = tmpg << 8;
-       *bb = tmpb << 8;
+       *rr = RGB_8_TO_16(tmpr);
+       *gg = RGB_8_TO_16(tmpg);
+       *bb = RGB_8_TO_16(tmpb);
 
        return (0);
 }
@@ -720,7 +723,6 @@ map_window_raised(xcb_window_t win)
            XCB_CONFIG_WINDOW_STACK_MODE, &val);
 
        xcb_map_window(conn, win);
-       xcb_flush(conn);
 }
 
 xcb_atom_t
@@ -730,7 +732,7 @@ get_atom_from_string(const char *str)
        xcb_intern_atom_reply_t         *r;
        xcb_atom_t                      atom;
 
-       c = xcb_intern_atom(conn, False, strlen(str), str);
+       c = xcb_intern_atom(conn, 0, strlen(str), str);
        r = xcb_intern_atom_reply(conn, c, NULL);
        if (r) {
                atom = r->atom;
@@ -746,35 +748,26 @@ void
 update_iconic(struct ws_win *win, int newv)
 {
        int32_t                         v = newv;
-       xcb_atom_t                      iprop;
 
        win->iconic = newv;
 
-       iprop = get_atom_from_string("_SWM_ICONIC");
-       if (iprop == XCB_ATOM_NONE)
-               return;
-
        if (newv)
                xcb_change_property(conn, XCB_PROP_MODE_REPLACE, win->id,
-                   iprop, XCB_ATOM_INTEGER, 32, 1, &v);
+                   a_swm_iconic, XCB_ATOM_INTEGER, 32, 1, &v);
        else
-               xcb_delete_property(conn, win->id, iprop);
+               xcb_delete_property(conn, win->id, a_swm_iconic);
 }
 
 int32_t
 get_iconic(struct ws_win *win)
 {
        int32_t                         v = 0;
-       xcb_atom_t                      iprop;
        xcb_get_property_reply_t        *pr = NULL;
 
-       iprop = get_atom_from_string("_SWM_ICONIC");
-       if (iprop == XCB_ATOM_NONE)
-               goto out;
 
        pr = xcb_get_property_reply(conn,
-           xcb_get_property(conn, False, win->id, iprop, XCB_ATOM_INTEGER,
-           0, 1), NULL);
+           xcb_get_property(conn, 0, win->id, a_swm_iconic,
+           XCB_ATOM_INTEGER, 0, 1), NULL);
        if (!pr)
                goto out;
        if (pr->type != XCB_ATOM_INTEGER || pr->format != 32)
@@ -825,51 +818,51 @@ teardown_ewmh(void)
 
        for (i = 0; i < num_screens; i++) {
                /* Get the support check window and destroy it */
-               pc = xcb_get_property(conn, False, screens[i].root, sup_check,
+               pc = xcb_get_property(conn, 0, screens[i].root, sup_check,
                    XCB_ATOM_WINDOW, 0, 1);
                pr = xcb_get_property_reply(conn, pc, NULL);
-               if (pr) {
+               if (!pr)
+                       continue;
+               if (pr->format == sup_check) {
                        id = *((xcb_window_t *)xcb_get_property_value(pr));
 
                        xcb_destroy_window(conn, id);
                        xcb_delete_property(conn, screens[i].root, sup_check);
                        xcb_delete_property(conn, screens[i].root, sup_list);
-
-                       free(pr);
                }
+               free(pr);
        }
 }
 
 void
 ewmh_autoquirk(struct ws_win *win)
 {
-       int                     i;
-       unsigned long           n;
-       xcb_atom_t              type;
-
+       uint32_t                i, n;
+       xcb_atom_t              *type;
        xcb_get_property_cookie_t       c;
        xcb_get_property_reply_t        *r;
 
-       c = xcb_get_property(conn, False, win->id,
-           ewmh[_NET_WM_WINDOW_TYPE].atom, XCB_ATOM_ATOM, 0, (~0L));
+       c = xcb_get_property(conn, 0, win->id,
+           ewmh[_NET_WM_WINDOW_TYPE].atom, XCB_ATOM_ATOM, 0, UINT32_MAX);
        r = xcb_get_property_reply(conn, c, NULL);
        if (!r)
                return;
+
        n = xcb_get_property_value_length(r);
+       type = xcb_get_property_value(r);
 
        for (i = 0; i < n; i++) {
-               type = *((xcb_atom_t *)xcb_get_property_value(r));
-               if (type == ewmh[_NET_WM_WINDOW_TYPE_NORMAL].atom)
+               if (type[i] == ewmh[_NET_WM_WINDOW_TYPE_NORMAL].atom)
                        break;
-               if (type == ewmh[_NET_WM_WINDOW_TYPE_DOCK].atom ||
-                   type == ewmh[_NET_WM_WINDOW_TYPE_TOOLBAR].atom ||
-                   type == ewmh[_NET_WM_WINDOW_TYPE_UTILITY].atom) {
+               if (type[i] == ewmh[_NET_WM_WINDOW_TYPE_DOCK].atom ||
+                   type[i] == ewmh[_NET_WM_WINDOW_TYPE_TOOLBAR].atom ||
+                   type[i] == ewmh[_NET_WM_WINDOW_TYPE_UTILITY].atom) {
                        win->floating = 1;
                        win->quirks = SWM_Q_FLOAT | SWM_Q_ANYWHERE;
                        break;
                }
-               if (type == ewmh[_NET_WM_WINDOW_TYPE_SPLASH].atom ||
-                   type == ewmh[_NET_WM_WINDOW_TYPE_DIALOG].atom) {
+               if (type[i] == ewmh[_NET_WM_WINDOW_TYPE_SPLASH].atom ||
+                   type[i] == ewmh[_NET_WM_WINDOW_TYPE_DIALOG].atom) {
                        win->floating = 1;
                        win->quirks = SWM_Q_FLOAT;
                        break;
@@ -950,6 +943,9 @@ ewmh_update_win_state(struct ws_win *win, long state, long action)
        if (win == NULL)
                return;
 
+       DNPRINTF(SWM_D_PROP, "ewmh_update_win_state: window: 0x%x, state: %ld, "
+           "action: %ld\n", win->id, state, action);
+
        if (state == ewmh[_NET_WM_STATE_FULLSCREEN].atom)
                mask = EWMH_F_FULLSCREEN;
        if (state == ewmh[_NET_WM_STATE_ABOVE].atom)
@@ -1032,8 +1028,8 @@ ewmh_get_win_state(struct ws_win *win)
        if (win->manual)
                win->ewmh_flags |= SWM_F_MANUAL;
 
-       c = xcb_get_property(conn, False, win->id, ewmh[_NET_WM_STATE].atom,
-           XCB_ATOM_ATOM, 0, (~0L));
+       c = xcb_get_property(conn, 0, win->id, ewmh[_NET_WM_STATE].atom,
+           XCB_ATOM_ATOM, 0, UINT32_MAX);
        r = xcb_get_property_reply(conn, c, NULL);
        if (!r)
                return;
@@ -1053,10 +1049,13 @@ void
 dumpwins(struct swm_region *r, union arg *args)
 {
        struct ws_win                           *win;
-       uint16_t                                state;
+       uint32_t                                state;
        xcb_get_window_attributes_cookie_t      c;
        xcb_get_window_attributes_reply_t       *wa;
 
+       /* suppress unused warning since var is needed */
+       (void)args;
+
        if (r->ws == NULL) {
                warnx("dumpwins: invalid workspace");
                return;
@@ -1114,7 +1113,7 @@ void                      mappingnotify(xcb_mapping_notify_event_t *);
 void                   maprequest(xcb_map_request_event_t *);
 void                   propertynotify(xcb_property_notify_event_t *);
 void                   unmapnotify(xcb_unmap_notify_event_t *);
-void                   visibilitynotify(xcb_visibility_notify_event_t *);
+/*void                 visibilitynotify(xcb_visibility_notify_event_t *);*/
 void                   clientmessage(xcb_client_message_event_t *);
 void                   screenchange(xcb_randr_screen_change_notify_event_t *);
 
@@ -1167,11 +1166,11 @@ sighdlr(int sig)
 }
 
 struct pid_e *
-find_pid(long pid)
+find_pid(pid_t pid)
 {
        struct pid_e            *p = NULL;
 
-       DNPRINTF(SWM_D_MISC, "find_pid: %lu\n", pid);
+       DNPRINTF(SWM_D_MISC, "find_pid: %d\n", pid);
 
        if (pid == 0)
                return (NULL);
@@ -1185,7 +1184,7 @@ find_pid(long pid)
 }
 
 uint32_t
-name_to_color(const char *colorname)
+name_to_pixel(const char *colorname)
 {
        uint32_t                        result = 0;
        char                            cname[32] = "#";
@@ -1239,13 +1238,13 @@ setscreencolor(char *val, int i, int c)
 
        num_screens = xcb_setup_roots_length(xcb_get_setup(conn));
        if (i > 0 && i <= num_screens) {
-               screens[i - 1].c[c].color = name_to_color(val);
+               screens[i - 1].c[c].pixel = name_to_pixel(val);
                free(screens[i - 1].c[c].name);
                if ((screens[i - 1].c[c].name = strdup(val)) == NULL)
                        err(1, "strdup");
        } else if (i == -1) {
                for (i = 0; i < num_screens; i++) {
-                       screens[i].c[c].color = name_to_color(val);
+                       screens[i].c[c].pixel = name_to_pixel(val);
                        free(screens[i].c[c].name);
                        if ((screens[i].c[c].name = strdup(val)) == NULL)
                                err(1, "strdup");
@@ -1284,12 +1283,12 @@ plain_stacker(struct workspace *ws)
 void
 custom_region(char *val)
 {
-       unsigned int                    sidx, x, y, w, h;
-       int                             num_screens;
+       unsigned int                    x, y, w, h;
+       int                             sidx, num_screens;
        xcb_screen_t                    *screen;
 
        num_screens = xcb_setup_roots_length(xcb_get_setup(conn));
-       if (sscanf(val, "screen[%u]:%ux%u+%u+%u", &sidx, &w, &h, &x, &y) != 5)
+       if (sscanf(val, "screen[%d]:%ux%u+%u+%u", &sidx, &w, &h, &x, &y) != 5)
                errx(1, "invalid custom region, "
                    "should be 'screen[<n>]:<n>x<n>+<n>+<n>");
        if (sidx < 1 || sidx > num_screens)
@@ -1329,24 +1328,26 @@ socket_setnonblock(int fd)
 void
 bar_print(struct swm_region *r, const char *s)
 {
-       int                     x = 0;
-       size_t                  len;
-       xcb_rectangle_t         rect;
-       uint32_t                gcv[1];
-       XRectangle              ibox, lbox;
+       size_t                          len;
+       xcb_rectangle_t                 rect;
+       uint32_t                        gcv[1];
+       int32_t                         x = 0;
+       XGlyphInfo                      info;
+       XftDraw                         *draw;
 
        len = strlen(s);
-       XmbTextExtents(bar_fs, s, len, &ibox, &lbox);
+
+       XftTextExtentsUtf8(display, bar_font, (FcChar8 *)s, len, &info);
 
        switch (bar_justify) {
        case SWM_BAR_JUSTIFY_LEFT:
                x = SWM_BAR_OFFSET;
                break;
        case SWM_BAR_JUSTIFY_CENTER:
-               x = (WIDTH(r) - lbox.width) / 2;
+               x = (WIDTH(r) - info.width) / 2;
                break;
        case SWM_BAR_JUSTIFY_RIGHT:
-               x = WIDTH(r) - lbox.width - SWM_BAR_OFFSET;
+               x = WIDTH(r) - info.width - SWM_BAR_OFFSET;
                break;
        }
 
@@ -1359,19 +1360,26 @@ bar_print(struct swm_region *r, const char *s)
        rect.height = HEIGHT(r->bar);
 
        /* clear back buffer */
-       gcv[0] = r->s->c[SWM_S_COLOR_BAR].color;
+       gcv[0] = r->s->c[SWM_S_COLOR_BAR].pixel;
        xcb_change_gc(conn, r->s->bar_gc, XCB_GC_FOREGROUND, gcv);
        xcb_poly_fill_rectangle(conn, r->bar->buffer, r->s->bar_gc,
            sizeof(rect), &rect);
 
        /* draw back buffer */
-       gcv[0] = r->s->c[SWM_S_COLOR_BAR].color;
+       gcv[0] = r->s->c[SWM_S_COLOR_BAR].pixel;
        xcb_change_gc(conn, r->s->bar_gc, XCB_GC_BACKGROUND, gcv);
-       gcv[0] = r->s->c[SWM_S_COLOR_BAR_FONT].color;
+       gcv[0] = r->s->c[SWM_S_COLOR_BAR_FONT].pixel;
        xcb_change_gc(conn, r->s->bar_gc, XCB_GC_FOREGROUND, gcv);
-       xcb_image_text_8(conn, len, r->bar->buffer, r->s->bar_gc, x,
-           (bar_fs_extents->max_logical_extent.height - lbox.height) / 2 -
-           lbox.y, s);
+
+       draw = XftDrawCreate(display, r->bar->buffer,
+           DefaultVisual(display, r->s->idx),
+           DefaultColormap(display, r->s->idx));
+
+       XftDrawStringUtf8(draw, &bar_font_color, bar_font, x,
+           (HEIGHT(r->bar) + bar_font->height) / 2 - bar_font->descent,
+           (FcChar8 *)s, len);
+
+       XftDrawDestroy(draw);
 
        /* blt */
        xcb_copy_area(conn, r->bar->buffer, r->bar->id, r->s->bar_gc, 0, 0,
@@ -1548,7 +1556,7 @@ void
 bar_replace_pad(char *tmp, int *limit, size_t sz)
 {
        /* special case; no limit given, pad one space, instead */
-       if (*limit == sz - 1)
+       if (*limit == (int)sz - 1)
                *limit = 1;
        snprintf(tmp, sz, "%*s", *limit, " ");
 }
@@ -1571,7 +1579,7 @@ bar_replace_seq(char *fmt, char *fmtrep, struct swm_region *r, size_t *offrep,
        size = 0;
        if (sscanf(fmt, "%d%n", &limit, &size) != 1)
                limit = sizeof tmp - 1;
-       if (limit <= 0 || limit >= sizeof tmp)
+       if (limit <= 0 || limit >= (int)sizeof tmp)
                limit = sizeof tmp - 1;
 
        /* there is nothing to replace (ie EOL) */
@@ -1627,7 +1635,7 @@ bar_replace_seq(char *fmt, char *fmtrep, struct swm_region *r, size_t *offrep,
 
        len = strlen(tmp);
        ptr = tmp;
-       if (len < limit)
+       if ((int)len < limit)
                limit = len;
        while (limit-- > 0) {
                if (*offrep >= sz - 1)
@@ -1748,6 +1756,9 @@ bar_update(void)
 void
 bar_signal(int sig)
 {
+       /* suppress unused warning since var is needed */
+       (void)sig;
+
        bar_alarm = 1;
 }
 
@@ -1757,6 +1768,10 @@ bar_toggle(struct swm_region *r, union arg *args)
        struct swm_region       *tmpr;
        int                     i, num_screens;
 
+       /* suppress unused warnings since vars are needed */
+       (void)r;
+       (void)args;
+
        DNPRINTF(SWM_D_BAR, "bar_toggle\n");
 
        num_screens = xcb_setup_roots_length(xcb_get_setup(conn));
@@ -1777,6 +1792,8 @@ bar_toggle(struct swm_region *r, union arg *args)
        stack();
        /* must be after stack */
        bar_update();
+
+       xcb_flush(conn);
 }
 
 void
@@ -1820,8 +1837,8 @@ bar_refresh(void)
                TAILQ_FOREACH(r, &screens[i].rl, entry) {
                        if (r->bar == NULL)
                                continue;
-                       wa[0] = screens[i].c[SWM_S_COLOR_BAR].color;
-                       wa[1] = screens[i].c[SWM_S_COLOR_BAR_BORDER].color;
+                       wa[0] = screens[i].c[SWM_S_COLOR_BAR].pixel;
+                       wa[1] = screens[i].c[SWM_S_COLOR_BAR_BORDER].pixel;
                        xcb_change_window_attributes(conn, r->bar->id,
                            XCB_CW_BACK_PIXEL | XCB_CW_BORDER_PIXEL, wa);
                }
@@ -1831,61 +1848,73 @@ bar_refresh(void)
 void
 bar_setup(struct swm_region *r)
 {
-       char                    *default_string;
-       char                    **missing_charsets;
-       int                     num_missing_charsets = 0;
-       int                     i;
+       char                    *font, *fontpos;
+       int                     count;
        xcb_screen_t            *screen = get_screen(r->s->idx);
        uint32_t                wa[3];
+       XRenderColor            color;
 
-       if (bar_fs) {
-               XFreeFontSet(display, bar_fs);
-               bar_fs = NULL;
-       }
+       if (r->bar != NULL)
+               return;
 
        if ((r->bar = calloc(1, sizeof(struct swm_bar))) == NULL)
                err(1, "bar_setup: calloc: failed to allocate memory.");
 
-       DNPRINTF(SWM_D_BAR, "bar_setup: loading bar_fonts: %s\n", bar_fonts);
-
-       bar_fs = XCreateFontSet(display, bar_fonts, &missing_charsets,
-           &num_missing_charsets, &default_string);
-
-       if (num_missing_charsets > 0) {
-               warnx("Unable to load charset(s):");
+       if (bar_font == NULL) {
+               while ((font = strsep(&bar_fonts, ",")) != NULL) {
+                       if (*font == '\0')
+                               continue;
 
-               for (i = 0; i < num_missing_charsets; ++i)
-                       warnx("%s", missing_charsets[i]);
+                       DNPRINTF(SWM_D_INIT, "bar_setup: try font %s\n", font);
 
-               XFreeStringList(missing_charsets);
+                       count = 0;
+                       fontpos = font;
+                       while ((fontpos = index(fontpos, '-'))) {
+                               count++;
+                               fontpos++;
+                       }
 
-               if (strcmp(default_string, ""))
-                       warnx("Glyphs from those sets will be replaced "
-                           "by '%s'.", default_string);
-               else
-                       warnx("Glyphs from those sets won't be drawn.");
+                       if (count == 14)
+                               bar_font = XftFontOpenXlfd(display, r->s->idx,
+                                               font);
+                       else
+                               bar_font = XftFontOpenName(display, r->s->idx,
+                                               font);
+                       if (!bar_font) {
+                               warnx("unable to load font %s", font);
+                               continue;
+                       } else {
+                               DNPRINTF(SWM_D_INIT, "successfully opened "
+                                   "font %s\n", font);
+                               break;
+                       }
+               }
        }
 
-       if (bar_fs == NULL)
-               errx(1, "Error creating font set structure.");
-
-       bar_fs_extents = XExtentsOfFontSet(bar_fs);
+       if (bar_font == NULL)
+               errx(1, "unable to open a font");
 
-       bar_height = bar_fs_extents->max_logical_extent.height +
-           2 * bar_border_width;
+       bar_height = bar_font->height + 2 * bar_border_width;
 
        if (bar_height < 1)
                bar_height = 1;
 
+       PIXEL_TO_XRENDERCOLOR(r->s->c[SWM_S_COLOR_BAR_FONT].pixel, color);
+
+       if (!XftColorAllocValue(display, DefaultVisual(display, r->s->idx),
+           DefaultColormap(display, r->s->idx), &color, &bar_font_color))
+               warn("unable to allocate Xft color");
+
        X(r->bar) = X(r);
        Y(r->bar) = bar_at_bottom ? (Y(r) + HEIGHT(r) - bar_height) : Y(r);
        WIDTH(r->bar) = WIDTH(r) - 2 * bar_border_width;
        HEIGHT(r->bar) = bar_height - 2 * bar_border_width;
 
        r->bar->id = xcb_generate_id(conn);
-       wa[0] = r->s->c[SWM_S_COLOR_BAR].color;
-       wa[1] = r->s->c[SWM_S_COLOR_BAR_BORDER].color;
+       wa[0] = r->s->c[SWM_S_COLOR_BAR].pixel;
+       wa[1] = r->s->c[SWM_S_COLOR_BAR_BORDER].pixel;
        wa[2] = XCB_EVENT_MASK_EXPOSURE;
+
        xcb_create_window(conn, XCB_COPY_FROM_PARENT, r->bar->id, r->s->root,
            X(r->bar), Y(r->bar), WIDTH(r->bar), HEIGHT(r->bar),
            bar_border_width, XCB_WINDOW_CLASS_INPUT_OUTPUT,
@@ -1932,22 +1961,23 @@ set_win_state(struct ws_win *win, uint16_t state)
        if (win == NULL)
                return;
 
-       xcb_change_property(conn, XCB_PROP_MODE_REPLACE, win->id, astate,
-           astate, 32, 2, data);
+       xcb_change_property(conn, XCB_PROP_MODE_REPLACE, win->id, a_state,
+           a_state, 32, 2, data);
 }
 
-uint16_t
+uint32_t
 getstate(xcb_window_t w)
 {
-       uint16_t                        result = 0;
+       uint32_t                        result = 0;
        xcb_get_property_cookie_t       c;
        xcb_get_property_reply_t        *r;
 
-       c = xcb_get_property(conn, False, w, astate, astate, 0L, 2L);
+       c = xcb_get_property(conn, 0, w, a_state, a_state, 0L, 2L);
        r = xcb_get_property_reply(conn, c, NULL);
 
        if (r) {
-               result = *((uint16_t *)xcb_get_property_value(r));
+               if (r->type == a_state && r->format == 32 && r->length == 2)
+                       result = *((uint32_t *)xcb_get_property_value(r));
                free(r);
        }
 
@@ -1959,6 +1989,10 @@ getstate(xcb_window_t w)
 void
 version(struct swm_region *r, union arg *args)
 {
+       /* suppress unused warnings since vars are needed */
+       (void)r;
+       (void)args;
+
        bar_version = !bar_version;
        if (bar_version)
                snprintf(bar_vertext, sizeof bar_vertext,
@@ -1966,6 +2000,8 @@ version(struct swm_region *r, union arg *args)
        else
                strlcpy(bar_vertext, "", sizeof bar_vertext);
        bar_update();
+
+       xcb_flush(conn);
 }
 
 void
@@ -1979,12 +2015,12 @@ client_msg(struct ws_win *win, xcb_atom_t a)
        bzero(&ev, sizeof ev);
        ev.response_type = XCB_CLIENT_MESSAGE;
        ev.window = win->id;
-       ev.type = aprot;
+       ev.type = a_prot;
        ev.format = 32;
        ev.data.data32[0] = a;
        ev.data.data32[1] = XCB_CURRENT_TIME;
 
-       xcb_send_event(conn, False, win->id,
+       xcb_send_event(conn, 0, win->id,
            XCB_EVENT_MASK_NO_EVENT, (const char *)&ev);
 }
 
@@ -2004,7 +2040,7 @@ config_win(struct ws_win *win, xcb_configure_request_event_t *ev)
        ce.y = Y(win);
        ce.width = WIDTH(win);
        ce.height = HEIGHT(win);
-       ce.override_redirect = False;
+       ce.override_redirect = 0;
 
        if (ev == NULL) {
                /* EWMH */
@@ -2064,8 +2100,8 @@ config_win(struct ws_win *win, xcb_configure_request_event_t *ev)
            "(%d,%d) %d x %d, border: %d\n", YESNO(ev == NULL), win->id, ce.x,
            ce.y, ce.width, ce.height, ce.border_width);
 
-       xcb_send_event(conn, False, win->id, XCB_EVENT_MASK_STRUCTURE_NOTIFY,
-               (char *)&ce);
+       xcb_send_event(conn, 0, win->id, XCB_EVENT_MASK_STRUCTURE_NOTIFY,
+           (char *)&ce);
 }
 
 int
@@ -2091,6 +2127,10 @@ count_win(struct workspace *ws, int count_transient)
 void
 quit(struct swm_region *r, union arg *args)
 {
+       /* suppress unused warnings since vars are needed */
+       (void)r;
+       (void)args;
+
        DNPRINTF(SWM_D_MISC, "quit\n");
        running = 0;
 }
@@ -2098,6 +2138,8 @@ quit(struct swm_region *r, union arg *args)
 void
 unmap_window(struct ws_win *win)
 {
+       DNPRINTF(SWM_D_EVENT, "unmap_window: window: 0x%x\n", win->id);
+
        if (win == NULL)
                return;
 
@@ -2109,7 +2151,7 @@ unmap_window(struct ws_win *win)
 
        xcb_unmap_window(conn, win->id);
        xcb_change_window_attributes(conn, win->id,
-           XCB_CW_BORDER_PIXEL, &win->s->c[SWM_S_COLOR_UNFOCUS].color);
+           XCB_CW_BORDER_PIXEL, &win->s->c[SWM_S_COLOR_UNFOCUS].pixel);
 }
 
 void
@@ -2148,22 +2190,27 @@ fake_keypress(struct ws_win *win, xcb_keysym_t keysym, uint16_t modifiers)
        event.event_y = Y(win);
        event.root_x = 1;
        event.root_y = 1;
-       event.same_screen = True;
+       event.same_screen = 1;
        event.detail = *keycode;
        event.state = modifiers;
 
        event.response_type = XCB_KEY_PRESS;
-       xcb_send_event(conn, True, win->id,
-           XCB_EVENT_MASK_KEY_PRESS, (char *)&event);
+       xcb_send_event(conn, 1, win->id,
+           XCB_EVENT_MASK_KEY_PRESS, (const char *)&event);
 
        event.response_type = XCB_KEY_RELEASE;
-       xcb_send_event(conn, True, win->id,
-           XCB_EVENT_MASK_KEY_RELEASE, (char *)&event);
+       xcb_send_event(conn, 1, win->id,
+           XCB_EVENT_MASK_KEY_RELEASE, (const char *)&event);
+
+       free(keycode);
 }
 
 void
 restart(struct swm_region *r, union arg *args)
 {
+       /* suppress unused warning since var is needed */
+       (void)args;
+
        DNPRINTF(SWM_D_MISC, "restart: %s\n", start_argv[0]);
 
        /* disable alarm because the following code may not be interrupted */
@@ -2175,6 +2222,9 @@ restart(struct swm_region *r, union arg *args)
        bar_extra = 1;
        unmap_all();
 
+       XftFontClose(display, bar_font);
+       XftColorFree(display, DefaultVisual(display, r->s->idx),
+           DefaultColormap(display, r->s->idx), &bar_font_color);
        xcb_key_symbols_free(syms);
        xcb_flush(conn);
        xcb_disconnect(conn);
@@ -2187,8 +2237,8 @@ restart(struct swm_region *r, union arg *args)
 struct swm_region *
 root_to_region(xcb_window_t root)
 {
-       struct swm_region       *r = NULL;
-       int                     i, num_screens;
+       struct swm_region               *r = NULL;
+       int                             i, num_screens;
        xcb_query_pointer_reply_t       *qpr;
 
        DNPRINTF(SWM_D_MISC, "root_to_region: window: 0x%x\n", root);
@@ -2239,7 +2289,6 @@ find_window(xcb_window_t id)
 {
        struct ws_win           *win;
        int                     i, j, num_screens;
-       xcb_query_tree_cookie_t c;
        xcb_query_tree_reply_t  *r;
 
        num_screens = xcb_setup_roots_length(xcb_get_setup(conn));
@@ -2249,14 +2298,15 @@ find_window(xcb_window_t id)
                                if (id == win->id)
                                        return (win);
 
-       c = xcb_query_tree(conn, id);
-       r = xcb_query_tree_reply(conn, c, NULL);
+       r = xcb_query_tree_reply(conn, xcb_query_tree(conn, id), NULL);
        if (!r)
                return (NULL);
 
        /* if we were looking for the parent return that window instead */
-       if (r->parent == 0 || r->root == r->parent)
+       if (r->parent == 0 || r->root == r->parent) {
+               free(r);
                return (NULL);
+       }
 
        /* look for parent */
        for (i = 0; i < num_screens; i++)
@@ -2279,8 +2329,7 @@ spawn(int ws_idx, union arg *args, int close_fd)
 
        DNPRINTF(SWM_D_MISC, "spawn: %s\n", args->argv[0]);
 
-       if (display)
-               close(xcb_get_file_descriptor(conn));
+       close(xcb_get_file_descriptor(conn));
 
        setenv("LD_PRELOAD", SWM_LIB, 1);
 
@@ -2430,7 +2479,7 @@ unfocus_win(struct ws_win *win)
 
        grabbuttons(win, 0);
        xcb_change_window_attributes(conn, win->id, XCB_CW_BORDER_PIXEL,
-           &win->ws->r->s->c[SWM_S_COLOR_UNFOCUS].color);
+           &win->ws->r->s->c[SWM_S_COLOR_UNFOCUS].pixel);
        xcb_change_property(conn, XCB_PROP_MODE_REPLACE, win->s->root,
            ewmh[_NET_ACTIVE_WINDOW].atom, XCB_ATOM_WINDOW, 32, 1, &none);
 }
@@ -2454,7 +2503,6 @@ void
 focus_win(struct ws_win *win)
 {
        struct ws_win           *cfw = NULL;
-       xcb_get_input_focus_cookie_t    c;
        xcb_get_input_focus_reply_t     *r;
        xcb_window_t                    cur_focus = XCB_WINDOW_NONE;
 
@@ -2478,8 +2526,7 @@ focus_win(struct ws_win *win)
                return;
        }
 
-       c = xcb_get_input_focus(conn);
-       r = xcb_get_input_focus_reply(conn, c, NULL);
+       r = xcb_get_input_focus_reply(conn, xcb_get_input_focus(conn), NULL);
        if (r) {
                cur_focus = r->focus;
                free(r);
@@ -2487,12 +2534,14 @@ focus_win(struct ws_win *win)
        if ((cfw = find_window(cur_focus)) != NULL)
                unfocus_win(cfw);
        else {
+#if 0
                /* use larger hammer since the window was killed somehow */
-               /* TAILQ_FOREACH(cfw, &win->ws->winlist, entry)
+               TAILQ_FOREACH(cfw, &win->ws->winlist, entry)
                        if (cfw->ws && cfw->ws->r && cfw->ws->r->s)
                                xcb_change_window_attributes(conn, cfw->id,
                                    XCB_CW_BORDER_PIXEL,
-                                   &cfw->ws->r->s->c[SWM_S_COLOR_UNFOCUS].color);*/
+                                   &cfw->ws->r->s->c[SWM_S_COLOR_UNFOCUS].pixel);
+#endif
        }
 
        win->ws->focus = win;
@@ -2503,8 +2552,8 @@ focus_win(struct ws_win *win)
                            win->id, XCB_CURRENT_TIME);
                grabbuttons(win, 1);
                xcb_change_window_attributes(conn, win->id,
-                       XCB_CW_BORDER_PIXEL,
-                       &win->ws->r->s->c[SWM_S_COLOR_FOCUS].color);
+                   XCB_CW_BORDER_PIXEL,
+                   &win->ws->r->s->c[SWM_S_COLOR_FOCUS].pixel);
                if (win->ws->cur_layout->flags & SWM_L_MAPONFOCUS ||
                    win->ws->always_raise)
                        map_window_raised(win->id);
@@ -2517,6 +2566,20 @@ focus_win(struct ws_win *win)
        bar_update();
 }
 
+void
+event_drain(uint8_t rt)
+{
+       xcb_generic_event_t     *evt;
+
+       xcb_flush(conn);
+       while ((evt = xcb_poll_for_event(conn))) {
+               if (XCB_EVENT_RESPONSE_TYPE(evt) != rt)
+                       event_handle(evt);
+
+               free(evt);
+       }
+}
+
 void
 switchws(struct swm_region *r, union arg *args)
 {
@@ -2570,6 +2633,13 @@ switchws(struct swm_region *r, union arg *args)
        if (unmap_old)
                TAILQ_FOREACH(win, &old_ws->winlist, entry)
                        unmap_window(win);
+
+       if (focus_mode == SWM_FOCUS_DEFAULT)
+               event_drain(XCB_ENTER_NOTIFY);
+       else
+               xcb_flush(conn);
+
+       DNPRINTF(SWM_D_WS, "switchws: done\n");
 }
 
 void
@@ -2774,6 +2844,8 @@ swapwin(struct swm_region *r, union arg *args)
        sort_windows(wl);
 
        stack();
+
+       xcb_flush(conn);
 }
 
 void
@@ -2962,6 +3034,8 @@ focus(struct swm_region *r, union arg *args)
        }
 
        focus_magic(winfocus);
+
+       xcb_flush(conn);
 }
 
 void
@@ -2970,6 +3044,9 @@ cycle_layout(struct swm_region *r, union arg *args)
        struct workspace        *ws = r->ws;
        union arg               a;
 
+       /* suppress unused warning since var is needed */
+       (void)args;
+
        DNPRINTF(SWM_D_EVENT, "cycle_layout: workspace: %d\n", ws->idx);
 
        ws->cur_layout++;
@@ -2977,9 +3054,12 @@ cycle_layout(struct swm_region *r, union arg *args)
                ws->cur_layout = &layouts[0];
 
        stack();
+       bar_update();
 
-       a.id = SWM_ARG_ID_FOCUSCUR;
+       if (focus_mode == SWM_FOCUS_DEFAULT)
+               event_drain(XCB_ENTER_NOTIFY);
 
+       a.id = SWM_ARG_ID_FOCUSCUR;
        focus(r, &a);
 }
 
@@ -3037,6 +3117,9 @@ stack(void) {
        if (font_adjusted)
                font_adjusted--;
 
+       if (focus_mode == SWM_FOCUS_DEFAULT)
+               event_drain(XCB_ENTER_NOTIFY);
+
        DNPRINTF(SWM_D_STACK, "stack: end\n");
 }
 
@@ -3538,7 +3621,6 @@ send_to_ws(struct swm_region *r, union arg *args)
        int                     wsid = args->id;
        struct ws_win           *win = NULL, *parent;
        struct workspace        *ws, *nws;
-       xcb_atom_t              ws_idx_atom = XCB_ATOM_NONE;
        char                    ws_idx_str[SWM_PROPLEN];
        union arg               a;
 
@@ -3578,24 +3660,26 @@ send_to_ws(struct swm_region *r, union arg *args)
        win->ws = nws;
 
        /* Try to update the window's workspace property */
-       ws_idx_atom = get_atom_from_string("_SWM_WS");
-       if (ws_idx_atom &&
-           snprintf(ws_idx_str, SWM_PROPLEN, "%d", nws->idx) <
-               SWM_PROPLEN) {
+       if (snprintf(ws_idx_str, SWM_PROPLEN, "%d", nws->idx) < SWM_PROPLEN) {
                DNPRINTF(SWM_D_PROP, "send_to_ws: set property: _SWM_WS: %s\n",
                    ws_idx_str);
                xcb_change_property(conn, XCB_PROP_MODE_REPLACE, win->id,
-                   ws_idx_atom, XCB_ATOM_STRING, 8, strlen(ws_idx_str),
+                   a_swm_ws, XCB_ATOM_STRING, 8, strlen(ws_idx_str),
                    ws_idx_str);
        }
 
        stack();
        bar_update();
+
+       xcb_flush(conn);
 }
 
 void
 pressbutton(struct swm_region *r, union arg *args)
 {
+       /* suppress unused warning since var is needed */
+       (void)r;
+
        xcb_test_fake_input(conn, XCB_BUTTON_PRESS, args->id,
            XCB_CURRENT_TIME, XCB_WINDOW_NONE, 0, 0, 0);
        xcb_test_fake_input(conn, XCB_BUTTON_RELEASE, args->id,
@@ -3605,6 +3689,9 @@ pressbutton(struct swm_region *r, union arg *args)
 void
 raise_toggle(struct swm_region *r, union arg *args)
 {
+       /* suppress unused warning since var is needed */
+       (void)args;
+
        if (r == NULL || r->ws == NULL)
                return;
 
@@ -3613,6 +3700,8 @@ raise_toggle(struct swm_region *r, union arg *args)
        /* bring floaters back to top */
        if (r->ws->always_raise == 0)
                stack();
+
+       xcb_flush(conn);
 }
 
 void
@@ -3620,6 +3709,9 @@ iconify(struct swm_region *r, union arg *args)
 {
        union arg a;
 
+       /* suppress unused warning since var is needed */
+       (void)args;
+
        if (r->ws->focus == NULL)
                return;
        unmap_window(r->ws->focus);
@@ -3629,6 +3721,8 @@ iconify(struct swm_region *r, union arg *args)
        r->ws->focus = NULL;
        a.id = SWM_ARG_ID_FOCUSCUR;
        focus(r, &a);
+
+       xcb_flush(conn);
 }
 
 char *
@@ -3642,12 +3736,10 @@ get_win_name(xcb_window_t win)
        if (xcb_icccm_get_wm_name_reply(conn, c, &r, NULL)) {
                if (r.name_len > 0) {
                        name = malloc(r.name_len + 1);
-                       if (!name) {
-                               xcb_icccm_get_text_property_reply_wipe(&r);
-                               return (NULL);
+                       if (name) {
+                               memcpy(name, r.name, r.name_len);
+                               name[r.name_len] = '\0';
                        }
-                       memcpy(name, r.name, r.name_len);
-                       name[r.name_len] = '\0';
                }
                xcb_icccm_get_text_property_reply_wipe(&r);
        }
@@ -3701,6 +3793,8 @@ uniconify(struct swm_region *r, union arg *args)
        }
 
        fclose(lfile);
+
+       xcb_flush(conn);
 }
 
 void
@@ -3780,7 +3874,9 @@ search_win(struct swm_region *r, union arg *args)
        char                    s[8];
        FILE                    *lfile;
        size_t                  len;
-       XRectangle              ibox, lbox;
+       XftDraw                 *draw;
+       XGlyphInfo              info;
+
        DNPRINTF(SWM_D_MISC, "search_win\n");
 
        search_r = r;
@@ -3811,13 +3907,13 @@ search_win(struct swm_region *r, union arg *args)
                snprintf(s, sizeof s, "%d", i);
                len = strlen(s);
 
-               XmbTextExtents(bar_fs, s, len, &ibox, &lbox);
+               XftTextExtentsUtf8(display, bar_font, (FcChar8 *)s, len, &info);
 
                w = xcb_generate_id(conn);
-               wa[0] = r->s->c[SWM_S_COLOR_FOCUS].color;
-               wa[1] = r->s->c[SWM_S_COLOR_UNFOCUS].color;
+               wa[0] = r->s->c[SWM_S_COLOR_FOCUS].pixel;
+               wa[1] = r->s->c[SWM_S_COLOR_UNFOCUS].pixel;
                xcb_create_window(conn, XCB_COPY_FROM_PARENT, w, win->id, 0, 0,
-                   lbox.width + 4, bar_fs_extents->max_logical_extent.height,
+                   info.width + 4, bar_font->height + 4,
                    1, XCB_WINDOW_CLASS_INPUT_OUTPUT, XCB_COPY_FROM_PARENT,
                    XCB_CW_BACK_PIXEL | XCB_CW_BORDER_PIXEL, wa);
 
@@ -3825,16 +3921,22 @@ search_win(struct swm_region *r, union arg *args)
                TAILQ_INSERT_TAIL(&search_wl, sw, entry);
 
                sw->gc = xcb_generate_id(conn);
-               gcv[0] = r->s->c[SWM_S_COLOR_BAR].color;
-               gcv[1] = r->s->c[SWM_S_COLOR_FOCUS].color;
+               gcv[0] = r->s->c[SWM_S_COLOR_BAR].pixel;
+               gcv[1] = r->s->c[SWM_S_COLOR_FOCUS].pixel;
                gcv[2] = 0;
                xcb_create_gc(conn, sw->gc, w, XCB_GC_FOREGROUND |
                    XCB_GC_BACKGROUND | XCB_GC_GRAPHICS_EXPOSURES, gcv);
                map_window_raised(w);
 
-               xcb_image_text_8(conn, len, w, sw->gc, 2,
-                   (bar_fs_extents->max_logical_extent.height -
-                   lbox.height) / 2 - lbox.y, s);
+               draw = XftDrawCreate(display, w,
+                   DefaultVisual(display, r->s->idx),
+                   DefaultColormap(display, r->s->idx));
+
+               XftDrawStringUtf8(draw, &bar_font_color, bar_font, 2,
+                   (HEIGHT(r->bar) + bar_font->height) / 2 - bar_font->descent,
+                   (FcChar8 *)s, len);
+
+               XftDrawDestroy(draw);
 
                DNPRINTF(SWM_D_MISC, "search_win: mapped window: 0x%x\n", w);
 
@@ -3843,6 +3945,8 @@ search_win(struct swm_region *r, union arg *args)
        }
 
        fclose(lfile);
+
+       xcb_flush(conn);
 }
 
 void
@@ -3902,7 +4006,7 @@ search_resp_name_workspace(char *resp, unsigned long len)
 }
 
 void
-search_resp_search_workspace(char *resp, unsigned long len)
+search_resp_search_workspace(char *resp)
 {
        char                    *p, *q;
        int                     ws_idx;
@@ -3920,7 +4024,7 @@ search_resp_search_workspace(char *resp, unsigned long len)
        p = strchr(q, ':');
        if (p != NULL)
                *p = '\0';
-       ws_idx = strtonum(q, 1, workspace_limit, &errstr);
+       ws_idx = (int)strtonum(q, 1, workspace_limit, &errstr);
        if (errstr) {
                DNPRINTF(SWM_D_MISC, "workspace idx is %s: %s",
                    errstr, q);
@@ -3933,7 +4037,7 @@ search_resp_search_workspace(char *resp, unsigned long len)
 }
 
 void
-search_resp_search_window(char *resp, unsigned long len)
+search_resp_search_window(char *resp)
 {
        char                    *s;
        int                     idx;
@@ -3949,7 +4053,7 @@ search_resp_search_window(char *resp, unsigned long len)
                return;
        }
 
-       idx = strtonum(s, 1, INT_MAX, &errstr);
+       idx = (int)strtonum(s, 1, INT_MAX, &errstr);
        if (errstr) {
                DNPRINTF(SWM_D_MISC, "window idx is %s: %s",
                    errstr, s);
@@ -4006,10 +4110,10 @@ search_do_resp(void)
                search_resp_name_workspace(resp, len);
                break;
        case SWM_SEARCH_SEARCH_WORKSPACE:
-               search_resp_search_workspace(resp, len);
+               search_resp_search_workspace(resp);
                break;
        case SWM_SEARCH_SEARCH_WINDOW:
-               search_resp_search_window(resp, len);
+               search_resp_search_window(resp);
                break;
        }
 
@@ -4034,7 +4138,9 @@ wkill(struct swm_region *r, union arg *args)
                xcb_kill_client(conn, r->ws->focus->id);
        else
                if (r->ws->focus->can_delete)
-                       client_msg(r->ws->focus, adelete);
+                       client_msg(r->ws->focus, a_delete);
+
+       xcb_flush(conn);
 }
 
 
@@ -4083,6 +4189,9 @@ floating_toggle(struct swm_region *r, union arg *args)
        struct ws_win           *win = r->ws->focus;
        union arg               a;
 
+       /* suppress unused warning since var is needed */
+       (void)args;
+
        if (win == NULL)
                return;
 
@@ -4095,6 +4204,9 @@ floating_toggle(struct swm_region *r, union arg *args)
                a.id = SWM_ARG_ID_FOCUSCUR;
                focus(win->ws->r, &a);
        }
+
+       xcb_flush(conn);
+       event_drain(XCB_ENTER_NOTIFY);
 }
 
 void
@@ -4143,8 +4255,8 @@ update_window(struct ws_win *win)
        uint32_t        wc[5];
 
        mask = XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y |
-               XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT |
-               XCB_CONFIG_WINDOW_BORDER_WIDTH;
+           XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT |
+           XCB_CONFIG_WINDOW_BORDER_WIDTH;
        wc[0] = X(win);
        wc[1] = Y(win);
        wc[2] = WIDTH(win);
@@ -4167,13 +4279,12 @@ resize(struct ws_win *win, union arg *args)
        struct swm_region       *r = NULL;
        int                     resize_step = 0;
        struct swm_geometry     g;
-       int                     top = 0, left = 0, buttonrelease;
+       int                     top = 0, left = 0, resizing;
        int                     dx, dy;
        unsigned int            shape; /* cursor style */
        xcb_cursor_t            cursor;
        xcb_font_t              cursor_font;
        xcb_grab_pointer_cookie_t       gpc;
-       xcb_grab_pointer_reply_t        *gpr;
        xcb_query_pointer_reply_t       *xpr;
        xcb_generic_event_t             *evt;
        xcb_motion_notify_event_t       *mne;
@@ -4185,7 +4296,7 @@ resize(struct ws_win *win, union arg *args)
        if (win->ewmh_flags & EWMH_F_FULLSCREEN)
                return;
 
-       DNPRINTF(SWM_D_MOUSE, "resize: window: 0x%x, floating: %s, "
+       DNPRINTF(SWM_D_EVENT, "resize: window: 0x%x, floating: %s, "
            "transient: 0x%x\n", win->id, YESNO(win->floating),
            win->transient);
 
@@ -4257,27 +4368,17 @@ resize(struct ws_win *win, union arg *args)
        xcb_create_glyph_cursor(conn, cursor, cursor_font, cursor_font,
            shape, shape + 1, 0, 0, 0, 0xffff, 0xffff, 0xffff);
 
-       gpc = xcb_grab_pointer(conn, False, win->id, MOUSEMASK,
+       gpc = xcb_grab_pointer(conn, 0, win->id, MOUSEMASK,
            XCB_GRAB_MODE_ASYNC, XCB_GRAB_MODE_ASYNC, XCB_WINDOW_NONE, cursor,
            XCB_CURRENT_TIME),
-       gpr = xcb_grab_pointer_reply(conn, gpc, NULL);
-       if (!gpr) {
-               xcb_free_cursor(conn, cursor);
-               xcb_close_font(conn, cursor_font);
-               free(xpr);
-               return;
-       }
 
        xcb_flush(conn);
-       buttonrelease = 0;
-       while ((evt = xcb_poll_for_event(conn)) && buttonrelease != 1) {
-               /*
-               XMaskEvent(display, MOUSEMASK | ExposureMask |
-                   SubstructureRedirectMask, &ev);
-               */
+       resizing = 1;
+       while ((evt = xcb_wait_for_event(conn)) && resizing) {
                switch (XCB_EVENT_RESPONSE_TYPE(evt)) {
                case XCB_BUTTON_RELEASE:
-                       buttonrelease = 1;
+                       DNPRINTF(SWM_D_EVENT, "resize: BUTTON_RELEASE\n");
+                       resizing = 0;
                        break;
                case XCB_MOTION_NOTIFY:
                        mne = (xcb_motion_notify_event_t *)evt;
@@ -4349,8 +4450,8 @@ resize(struct ws_win *win, union arg *args)
        xcb_ungrab_pointer(conn, XCB_CURRENT_TIME);
        xcb_free_cursor(conn, cursor);
        xcb_close_font(conn, cursor_font);
-       free(gpr);
        free(xpr);
+       DNPRINTF(SWM_D_EVENT, "resize: done\n");
 }
 
 void
@@ -4372,12 +4473,11 @@ void
 move(struct ws_win *win, union arg *args)
 {
        xcb_timestamp_t         timestamp = 0;
-       int                     move_step = 0, buttonrelease;
+       int                     move_step = 0, moving;
        struct swm_region       *r = NULL;
        xcb_font_t                      cursor_font;
        xcb_cursor_t                    cursor;
        xcb_grab_pointer_cookie_t       gpc;
-       xcb_grab_pointer_reply_t        *gpr;
        xcb_query_pointer_reply_t       *qpr;
        xcb_generic_event_t             *evt;
        xcb_motion_notify_event_t       *mne;
@@ -4389,7 +4489,7 @@ move(struct ws_win *win, union arg *args)
        if (win->ewmh_flags & EWMH_F_FULLSCREEN)
                return;
 
-       DNPRINTF(SWM_D_MOUSE, "move: window: 0x%x, floating: %s, transient: "
+       DNPRINTF(SWM_D_EVENT, "move: window: 0x%x, floating: %s, transient: "
            "0x%x\n", win->id, YESNO(win->floating), win->transient);
 
        /* in max_stack mode should only move transients */
@@ -4442,15 +4542,9 @@ move(struct ws_win *win, union arg *args)
        xcb_create_glyph_cursor(conn, cursor, cursor_font, cursor_font,
                XC_fleur, XC_fleur + 1, 0, 0, 0, 0xffff, 0xffff, 0xffff);
 
-       gpc = xcb_grab_pointer(conn, False, win->id, MOUSEMASK,
+       gpc = xcb_grab_pointer(conn, 0, win->id, MOUSEMASK,
            XCB_GRAB_MODE_ASYNC, XCB_GRAB_MODE_ASYNC,
            XCB_WINDOW_NONE, cursor, XCB_CURRENT_TIME);
-       gpr = xcb_grab_pointer_reply(conn, gpc, NULL);
-       if (!gpr) {
-               xcb_free_cursor(conn, cursor);
-               xcb_close_font(conn, cursor_font);
-               return;
-       }
 
        /* get cursor offset from window root */
        qpr = xcb_query_pointer_reply(conn, xcb_query_pointer(conn, win->id),
@@ -4463,15 +4557,12 @@ move(struct ws_win *win, union arg *args)
        }
 
        xcb_flush(conn);
-       buttonrelease = 0;
-       while ((evt = xcb_poll_for_event(conn)) && buttonrelease != 1) {
-               /*
-               XMaskEvent(display, MOUSEMASK | ExposureMask |
-                   SubstructureRedirectMask, &ev);
-               */
+       moving = 1;
+       while ((evt = xcb_wait_for_event(conn)) && moving) {
                switch (XCB_EVENT_RESPONSE_TYPE(evt)) {
                case XCB_BUTTON_RELEASE:
-                       buttonrelease = 1;
+                       DNPRINTF(SWM_D_EVENT, "move: BUTTON_RELEASE\n");
+                       moving = 0;
                        break;
                case XCB_MOTION_NOTIFY:
                        mne = (xcb_motion_notify_event_t *)evt;
@@ -4502,6 +4593,7 @@ move(struct ws_win *win, union arg *args)
        xcb_free_cursor(conn, cursor);
        xcb_close_font(conn, cursor_font);
        xcb_ungrab_pointer(conn, XCB_CURRENT_TIME);
+       DNPRINTF(SWM_D_EVENT, "move: done\n");
 }
 
 void
@@ -4523,128 +4615,168 @@ move_step(struct swm_region *r, union arg *args)
 
 /* user/key callable function IDs */
 enum keyfuncid {
-       kf_cycle_layout,
-       kf_flip_layout,
-       kf_stack_reset,
-       kf_master_shrink,
-       kf_master_grow,
-       kf_master_add,
-       kf_master_del,
-       kf_stack_inc,
-       kf_stack_dec,
-       kf_swap_main,
-       kf_focus_next,
-       kf_focus_prev,
-       kf_swap_next,
-       kf_swap_prev,
-       kf_quit,
-       kf_restart,
-       kf_focus_main,
-       kf_ws_1,
-       kf_ws_2,
-       kf_ws_3,
-       kf_ws_4,
-       kf_ws_5,
-       kf_ws_6,
-       kf_ws_7,
-       kf_ws_8,
-       kf_ws_9,
-       kf_ws_10,
-       kf_ws_11,
-       kf_ws_12,
-       kf_ws_13,
-       kf_ws_14,
-       kf_ws_15,
-       kf_ws_16,
-       kf_ws_17,
-       kf_ws_18,
-       kf_ws_19,
-       kf_ws_20,
-       kf_ws_21,
-       kf_ws_22,
-       kf_ws_next,
-       kf_ws_prev,
-       kf_ws_next_all,
-       kf_ws_prev_all,
-       kf_ws_prior,
-       kf_screen_next,
-       kf_screen_prev,
-       kf_mvws_1,
-       kf_mvws_2,
-       kf_mvws_3,
-       kf_mvws_4,
-       kf_mvws_5,
-       kf_mvws_6,
-       kf_mvws_7,
-       kf_mvws_8,
-       kf_mvws_9,
-       kf_mvws_10,
-       kf_mvws_11,
-       kf_mvws_12,
-       kf_mvws_13,
-       kf_mvws_14,
-       kf_mvws_15,
-       kf_mvws_16,
-       kf_mvws_17,
-       kf_mvws_18,
-       kf_mvws_19,
-       kf_mvws_20,
-       kf_mvws_21,
-       kf_mvws_22,
-       kf_bar_toggle,
-       kf_wind_kill,
-       kf_wind_del,
-       kf_float_toggle,
-       kf_version,
-       kf_spawn_custom,
-       kf_iconify,
-       kf_uniconify,
-       kf_raise_toggle,
-       kf_button2,
-       kf_width_shrink,
-       kf_width_grow,
-       kf_height_shrink,
-       kf_height_grow,
-       kf_move_left,
-       kf_move_right,
-       kf_move_up,
-       kf_move_down,
-       kf_name_workspace,
-       kf_search_workspace,
-       kf_search_win,
-       kf_dumpwins, /* MUST BE LAST */
-       kf_invalid
+       KF_BAR_TOGGLE,
+       KF_BUTTON2,
+       KF_CYCLE_LAYOUT,
+       KF_FLIP_LAYOUT,
+       KF_FLOAT_TOGGLE,
+       KF_FOCUS_MAIN,
+       KF_FOCUS_NEXT,
+       KF_FOCUS_PREV,
+       KF_HEIGHT_GROW,
+       KF_HEIGHT_SHRINK,
+       KF_ICONIFY,
+       KF_MASTER_SHRINK,
+       KF_MASTER_GROW,
+       KF_MASTER_ADD,
+       KF_MASTER_DEL,
+       KF_MOVE_DOWN,
+       KF_MOVE_LEFT,
+       KF_MOVE_RIGHT,
+       KF_MOVE_UP,
+       KF_MVWS_1,
+       KF_MVWS_2,
+       KF_MVWS_3,
+       KF_MVWS_4,
+       KF_MVWS_5,
+       KF_MVWS_6,
+       KF_MVWS_7,
+       KF_MVWS_8,
+       KF_MVWS_9,
+       KF_MVWS_10,
+       KF_MVWS_11,
+       KF_MVWS_12,
+       KF_MVWS_13,
+       KF_MVWS_14,
+       KF_MVWS_15,
+       KF_MVWS_16,
+       KF_MVWS_17,
+       KF_MVWS_18,
+       KF_MVWS_19,
+       KF_MVWS_20,
+       KF_MVWS_21,
+       KF_MVWS_22,
+       KF_NAME_WORKSPACE,
+       KF_QUIT,
+       KF_RAISE_TOGGLE,
+       KF_RESTART,
+       KF_SCREEN_NEXT,
+       KF_SCREEN_PREV,
+       KF_SEARCH_WIN,
+       KF_SEARCH_WORKSPACE,
+       KF_SPAWN_CUSTOM,
+       KF_STACK_INC,
+       KF_STACK_DEC,
+       KF_STACK_RESET,
+       KF_SWAP_MAIN,
+       KF_SWAP_NEXT,
+       KF_SWAP_PREV,
+       KF_UNICONIFY,
+       KF_VERSION,
+       KF_WIDTH_GROW,
+       KF_WIDTH_SHRINK,
+       KF_WIND_DEL,
+       KF_WIND_KILL,
+       KF_WS_1,
+       KF_WS_2,
+       KF_WS_3,
+       KF_WS_4,
+       KF_WS_5,
+       KF_WS_6,
+       KF_WS_7,
+       KF_WS_8,
+       KF_WS_9,
+       KF_WS_10,
+       KF_WS_11,
+       KF_WS_12,
+       KF_WS_13,
+       KF_WS_14,
+       KF_WS_15,
+       KF_WS_16,
+       KF_WS_17,
+       KF_WS_18,
+       KF_WS_19,
+       KF_WS_20,
+       KF_WS_21,
+       KF_WS_22,
+       KF_WS_NEXT,
+       KF_WS_NEXT_ALL,
+       KF_WS_PREV,
+       KF_WS_PREV_ALL,
+       KF_WS_PRIOR,
+       KF_DUMPWINS, /* MUST BE LAST */
+       KF_INVALID
 };
 
 /* key definitions */
-void
-dummykeyfunc(struct swm_region *r, union arg *args)
-{
-};
-
 struct keyfunc {
        char                    name[SWM_FUNCNAME_LEN];
        void                    (*func)(struct swm_region *r, union arg *);
        union arg               args;
-} keyfuncs[kf_invalid + 1] = {
+} keyfuncs[KF_INVALID + 1] = {
        /* name                 function        argument */
+       { "bar_toggle",         bar_toggle,     {0} },
+       { "button2",            pressbutton,    {2} },
        { "cycle_layout",       cycle_layout,   {0} },
        { "flip_layout",        stack_config,   {.id = SWM_ARG_ID_FLIPLAYOUT} },
-       { "stack_reset",        stack_config,   {.id = SWM_ARG_ID_STACKRESET} },
+       { "float_toggle",       floating_toggle,{0} },
+       { "focus_main",         focus,          {.id = SWM_ARG_ID_FOCUSMAIN} },
+       { "focus_next",         focus,          {.id = SWM_ARG_ID_FOCUSNEXT} },
+       { "focus_prev",         focus,          {.id = SWM_ARG_ID_FOCUSPREV} },
+       { "height_grow",        resize_step,    {.id = SWM_ARG_ID_HEIGHTGROW} },
+       { "height_shrink",      resize_step,    {.id = SWM_ARG_ID_HEIGHTSHRINK} },
+       { "iconify",            iconify,        {0} },
        { "master_shrink",      stack_config,   {.id = SWM_ARG_ID_MASTERSHRINK} },
        { "master_grow",        stack_config,   {.id = SWM_ARG_ID_MASTERGROW} },
        { "master_add",         stack_config,   {.id = SWM_ARG_ID_MASTERADD} },
        { "master_del",         stack_config,   {.id = SWM_ARG_ID_MASTERDEL} },
+       { "move_down",          move_step,      {.id = SWM_ARG_ID_MOVEDOWN} },
+       { "move_left",          move_step,      {.id = SWM_ARG_ID_MOVELEFT} },
+       { "move_right",         move_step,      {.id = SWM_ARG_ID_MOVERIGHT} },
+       { "move_up",            move_step,      {.id = SWM_ARG_ID_MOVEUP} },
+       { "mvws_1",             send_to_ws,     {.id = 0} },
+       { "mvws_2",             send_to_ws,     {.id = 1} },
+       { "mvws_3",             send_to_ws,     {.id = 2} },
+       { "mvws_4",             send_to_ws,     {.id = 3} },
+       { "mvws_5",             send_to_ws,     {.id = 4} },
+       { "mvws_6",             send_to_ws,     {.id = 5} },
+       { "mvws_7",             send_to_ws,     {.id = 6} },
+       { "mvws_8",             send_to_ws,     {.id = 7} },
+       { "mvws_9",             send_to_ws,     {.id = 8} },
+       { "mvws_10",            send_to_ws,     {.id = 9} },
+       { "mvws_11",            send_to_ws,     {.id = 10} },
+       { "mvws_12",            send_to_ws,     {.id = 11} },
+       { "mvws_13",            send_to_ws,     {.id = 12} },
+       { "mvws_14",            send_to_ws,     {.id = 13} },
+       { "mvws_15",            send_to_ws,     {.id = 14} },
+       { "mvws_16",            send_to_ws,     {.id = 15} },
+       { "mvws_17",            send_to_ws,     {.id = 16} },
+       { "mvws_18",            send_to_ws,     {.id = 17} },
+       { "mvws_19",            send_to_ws,     {.id = 18} },
+       { "mvws_20",            send_to_ws,     {.id = 19} },
+       { "mvws_21",            send_to_ws,     {.id = 20} },
+       { "mvws_22",            send_to_ws,     {.id = 21} },
+       { "name_workspace",     name_workspace, {0} },
+       { "quit",               quit,           {0} },
+       { "raise_toggle",       raise_toggle,   {0} },
+       { "restart",            restart,        {0} },
+       { "screen_next",        cyclescr,       {.id = SWM_ARG_ID_CYCLESC_UP} },
+       { "screen_prev",        cyclescr,       {.id = SWM_ARG_ID_CYCLESC_DOWN} },
+       { "search_win",         search_win,     {0} },
+       { "search_workspace",   search_workspace,       {0} },
+       { "spawn_custom",       NULL,           {0} },
        { "stack_inc",          stack_config,   {.id = SWM_ARG_ID_STACKINC} },
        { "stack_dec",          stack_config,   {.id = SWM_ARG_ID_STACKDEC} },
+       { "stack_reset",        stack_config,   {.id = SWM_ARG_ID_STACKRESET} },
        { "swap_main",          swapwin,        {.id = SWM_ARG_ID_SWAPMAIN} },
-       { "focus_next",         focus,          {.id = SWM_ARG_ID_FOCUSNEXT} },
-       { "focus_prev",         focus,          {.id = SWM_ARG_ID_FOCUSPREV} },
        { "swap_next",          swapwin,        {.id = SWM_ARG_ID_SWAPNEXT} },
        { "swap_prev",          swapwin,        {.id = SWM_ARG_ID_SWAPPREV} },
-       { "quit",               quit,           {0} },
-       { "restart",            restart,        {0} },
-       { "focus_main",         focus,          {.id = SWM_ARG_ID_FOCUSMAIN} },
+       { "uniconify",          uniconify,      {0} },
+       { "version",            version,        {0} },
+       { "width_grow",         resize_step,    {.id = SWM_ARG_ID_WIDTHGROW} },
+       { "width_shrink",       resize_step,    {.id = SWM_ARG_ID_WIDTHSHRINK} },
+       { "wind_del",           wkill,          {.id = SWM_ARG_ID_DELETEWINDOW} },
+       { "wind_kill",          wkill,          {.id = SWM_ARG_ID_KILLWINDOW} },
        { "ws_1",               switchws,       {.id = 0} },
        { "ws_2",               switchws,       {.id = 1} },
        { "ws_3",               switchws,       {.id = 2} },
@@ -4668,55 +4800,10 @@ struct keyfunc {
        { "ws_21",              switchws,       {.id = 20} },
        { "ws_22",              switchws,       {.id = 21} },
        { "ws_next",            cyclews,        {.id = SWM_ARG_ID_CYCLEWS_UP} },
-       { "ws_prev",            cyclews,        {.id = SWM_ARG_ID_CYCLEWS_DOWN} },
        { "ws_next_all",        cyclews,        {.id = SWM_ARG_ID_CYCLEWS_UP_ALL} },
+       { "ws_prev",            cyclews,        {.id = SWM_ARG_ID_CYCLEWS_DOWN} },
        { "ws_prev_all",        cyclews,        {.id = SWM_ARG_ID_CYCLEWS_DOWN_ALL} },
        { "ws_prior",           priorws,        {0} },
-       { "screen_next",        cyclescr,       {.id = SWM_ARG_ID_CYCLESC_UP} },
-       { "screen_prev",        cyclescr,       {.id = SWM_ARG_ID_CYCLESC_DOWN} },
-       { "mvws_1",             send_to_ws,     {.id = 0} },
-       { "mvws_2",             send_to_ws,     {.id = 1} },
-       { "mvws_3",             send_to_ws,     {.id = 2} },
-       { "mvws_4",             send_to_ws,     {.id = 3} },
-       { "mvws_5",             send_to_ws,     {.id = 4} },
-       { "mvws_6",             send_to_ws,     {.id = 5} },
-       { "mvws_7",             send_to_ws,     {.id = 6} },
-       { "mvws_8",             send_to_ws,     {.id = 7} },
-       { "mvws_9",             send_to_ws,     {.id = 8} },
-       { "mvws_10",            send_to_ws,     {.id = 9} },
-       { "mvws_11",            send_to_ws,     {.id = 10} },
-       { "mvws_12",            send_to_ws,     {.id = 11} },
-       { "mvws_13",            send_to_ws,     {.id = 12} },
-       { "mvws_14",            send_to_ws,     {.id = 13} },
-       { "mvws_15",            send_to_ws,     {.id = 14} },
-       { "mvws_16",            send_to_ws,     {.id = 15} },
-       { "mvws_17",            send_to_ws,     {.id = 16} },
-       { "mvws_18",            send_to_ws,     {.id = 17} },
-       { "mvws_19",            send_to_ws,     {.id = 18} },
-       { "mvws_20",            send_to_ws,     {.id = 19} },
-       { "mvws_21",            send_to_ws,     {.id = 20} },
-       { "mvws_22",            send_to_ws,     {.id = 21} },
-       { "bar_toggle",         bar_toggle,     {0} },
-       { "wind_kill",          wkill,          {.id = SWM_ARG_ID_KILLWINDOW} },
-       { "wind_del",           wkill,          {.id = SWM_ARG_ID_DELETEWINDOW} },
-       { "float_toggle",       floating_toggle,{0} },
-       { "version",            version,        {0} },
-       { "spawn_custom",       dummykeyfunc,   {0} },
-       { "iconify",            iconify,        {0} },
-       { "uniconify",          uniconify,      {0} },
-       { "raise_toggle",       raise_toggle,   {0} },
-       { "button2",            pressbutton,    {2} },
-       { "width_shrink",       resize_step,    {.id = SWM_ARG_ID_WIDTHSHRINK} },
-       { "width_grow",         resize_step,    {.id = SWM_ARG_ID_WIDTHGROW} },
-       { "height_shrink",      resize_step,    {.id = SWM_ARG_ID_HEIGHTSHRINK} },
-       { "height_grow",        resize_step,    {.id = SWM_ARG_ID_HEIGHTGROW} },
-       { "move_left",          move_step,      {.id = SWM_ARG_ID_MOVELEFT} },
-       { "move_right",         move_step,      {.id = SWM_ARG_ID_MOVERIGHT} },
-       { "move_up",            move_step,      {.id = SWM_ARG_ID_MOVEUP} },
-       { "move_down",          move_step,      {.id = SWM_ARG_ID_MOVEDOWN} },
-       { "name_workspace",     name_workspace, {0} },
-       { "search_workspace",   search_workspace,       {0} },
-       { "search_win",         search_win,     {0} },
        { "dumpwins",           dumpwins,       {0} }, /* MUST BE LAST */
        { "invalid key func",   NULL,           {0} },
 };
@@ -4801,6 +4888,9 @@ spawn_expand(struct swm_region *r, union arg *args, char *spawn_name,
        int                     i;
        char                    *ap, **real_args;
 
+       /* suppress unused warning since var is needed */
+       (void)args;
+
        DNPRINTF(SWM_D_SPAWN, "spawn_expand: %s\n", spawn_name);
 
        /* find program */
@@ -4938,7 +5028,7 @@ spawn_insert(char *name, char *args)
        DNPRINTF(SWM_D_SPAWN, "spawn_insert: %s\n", name);
 
        if ((sp = calloc(1, sizeof *sp)) == NULL)
-               err(1, "spawn_insert: malloc");
+               err(1, "spawn_insert: calloc");
        if ((sp->name = strdup(name)) == NULL)
                err(1, "spawn_insert: strdup");
 
@@ -5023,6 +5113,9 @@ setspawn(char *name, char *args)
 int
 setconfspawn(char *selector, char *value, int flags)
 {
+       /* suppress unused warning since var is needed */
+       (void)flags;
+
        DNPRINTF(SWM_D_SPAWN, "setconfspawn: [%s] [%s]\n", selector, value);
 
        setspawn(selector, value);
@@ -5080,7 +5173,7 @@ parsekeys(char *keystr, unsigned int currmod, unsigned int *mod, KeySym *ks)
                return (1);
        }
        cp = keystr;
-       *ks = NoSymbol;
+       *ks = XCB_NO_SYMBOL;
        *mod = 0;
        while ((name = strsep(&cp, SWM_KEY_WS)) != NULL) {
                DNPRINTF(SWM_D_KEY, "parsekeys: key [%s]\n", name);
@@ -5103,7 +5196,7 @@ parsekeys(char *keystr, unsigned int currmod, unsigned int *mod, KeySym *ks)
                else {
                        *ks = XStringToKeysym(name);
                        XConvertCase(*ks, ks, &uks);
-                       if (ks == NoSymbol) {
+                       if (ks == XCB_NO_SYMBOL) {
                                DNPRINTF(SWM_D_KEY,
                                    "parsekeys: invalid key %s\n",
                                    name);
@@ -5190,14 +5283,14 @@ setkeybinding(unsigned int mod, KeySym ks, enum keyfuncid kfid,
            keyfuncs[kfid].name, spawn_name);
 
        if ((kp = key_lookup(mod, ks)) != NULL) {
-               if (kfid == kf_invalid)
+               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) {
+       if (kfid == KF_INVALID) {
                warnx("error: setkeybinding: cannot find mod/key combination");
                DNPRINTF(SWM_D_KEY, "setkeybinding: leave\n");
                return;
@@ -5214,18 +5307,22 @@ setconfbinding(char *selector, char *value, int flags)
        unsigned int            mod;
        KeySym                  ks;
        struct spawn_prog       *sp;
+
+       /* suppress unused warning since var is needed */
+       (void)flags;
+
        DNPRINTF(SWM_D_KEY, "setconfbinding: enter\n");
        if (selector == NULL) {
                DNPRINTF(SWM_D_KEY, "setconfbinding: unbind %s\n", value);
                if (parsekeys(value, mod_key, &mod, &ks) == 0) {
-                       kfid = kf_invalid;
+                       kfid = KF_INVALID;
                        setkeybinding(mod, ks, kfid, NULL);
                        return (0);
                } else
                        return (1);
        }
        /* search by key function name */
-       for (kfid = 0; kfid < kf_invalid; (kfid)++) {
+       for (kfid = 0; kfid < KF_INVALID; (kfid)++) {
                if (strncasecmp(selector, keyfuncs[kfid].name,
                    SWM_FUNCNAME_LEN) == 0) {
                        DNPRINTF(SWM_D_KEY, "setconfbinding: %s: match\n",
@@ -5243,7 +5340,7 @@ setconfbinding(char *selector, char *value, int flags)
                        DNPRINTF(SWM_D_KEY, "setconfbinding: %s: match\n",
                            selector);
                        if (parsekeys(value, mod_key, &mod, &ks) == 0) {
-                               setkeybinding(mod, ks, kf_spawn_custom,
+                               setkeybinding(mod, ks, KF_SPAWN_CUSTOM,
                                    sp->name);
                                return (0);
                        } else
@@ -5257,104 +5354,104 @@ setconfbinding(char *selector, char *value, int flags)
 void
 setup_keys(void)
 {
-       setkeybinding(MODKEY,           XK_space,       kf_cycle_layout,NULL);
-       setkeybinding(MODKEY|ShiftMask, XK_backslash,   kf_flip_layout, NULL);
-       setkeybinding(MODKEY|ShiftMask, XK_space,       kf_stack_reset, NULL);
-       setkeybinding(MODKEY,           XK_h,           kf_master_shrink,NULL);
-       setkeybinding(MODKEY,           XK_l,           kf_master_grow, NULL);
-       setkeybinding(MODKEY,           XK_comma,       kf_master_add,  NULL);
-       setkeybinding(MODKEY,           XK_period,      kf_master_del,  NULL);
-       setkeybinding(MODKEY|ShiftMask, XK_comma,       kf_stack_inc,   NULL);
-       setkeybinding(MODKEY|ShiftMask, XK_period,      kf_stack_dec,   NULL);
-       setkeybinding(MODKEY,           XK_Return,      kf_swap_main,   NULL);
-       setkeybinding(MODKEY,           XK_j,           kf_focus_next,  NULL);
-       setkeybinding(MODKEY,           XK_k,           kf_focus_prev,  NULL);
-       setkeybinding(MODKEY|ShiftMask, XK_j,           kf_swap_next,   NULL);
-       setkeybinding(MODKEY|ShiftMask, XK_k,           kf_swap_prev,   NULL);
-       setkeybinding(MODKEY|ShiftMask, XK_Return,      kf_spawn_custom,"term");
-       setkeybinding(MODKEY,           XK_p,           kf_spawn_custom,"menu");
-       setkeybinding(MODKEY|ShiftMask, XK_q,           kf_quit,        NULL);
-       setkeybinding(MODKEY,           XK_q,           kf_restart,     NULL);
-       setkeybinding(MODKEY,           XK_m,           kf_focus_main,  NULL);
-       setkeybinding(MODKEY,           XK_1,           kf_ws_1,        NULL);
-       setkeybinding(MODKEY,           XK_2,           kf_ws_2,        NULL);
-       setkeybinding(MODKEY,           XK_3,           kf_ws_3,        NULL);
-       setkeybinding(MODKEY,           XK_4,           kf_ws_4,        NULL);
-       setkeybinding(MODKEY,           XK_5,           kf_ws_5,        NULL);
-       setkeybinding(MODKEY,           XK_6,           kf_ws_6,        NULL);
-       setkeybinding(MODKEY,           XK_7,           kf_ws_7,        NULL);
-       setkeybinding(MODKEY,           XK_8,           kf_ws_8,        NULL);
-       setkeybinding(MODKEY,           XK_9,           kf_ws_9,        NULL);
-       setkeybinding(MODKEY,           XK_0,           kf_ws_10,       NULL);
-       setkeybinding(MODKEY,           XK_F1,          kf_ws_11,       NULL);
-       setkeybinding(MODKEY,           XK_F2,          kf_ws_12,       NULL);
-       setkeybinding(MODKEY,           XK_F3,          kf_ws_13,       NULL);
-       setkeybinding(MODKEY,           XK_F4,          kf_ws_14,       NULL);
-       setkeybinding(MODKEY,           XK_F5,          kf_ws_15,       NULL);
-       setkeybinding(MODKEY,           XK_F6,          kf_ws_16,       NULL);
-       setkeybinding(MODKEY,           XK_F7,          kf_ws_17,       NULL);
-       setkeybinding(MODKEY,           XK_F8,          kf_ws_18,       NULL);
-       setkeybinding(MODKEY,           XK_F9,          kf_ws_19,       NULL);
-       setkeybinding(MODKEY,           XK_F10,         kf_ws_20,       NULL);
-       setkeybinding(MODKEY,           XK_F11,         kf_ws_21,       NULL);
-       setkeybinding(MODKEY,           XK_F12,         kf_ws_22,       NULL);
-       setkeybinding(MODKEY,           XK_Right,       kf_ws_next,     NULL);
-       setkeybinding(MODKEY,           XK_Left,        kf_ws_prev,     NULL);
-       setkeybinding(MODKEY,           XK_Up,          kf_ws_next_all, NULL);
-       setkeybinding(MODKEY,           XK_Down,        kf_ws_prev_all, NULL);
-       setkeybinding(MODKEY,           XK_a,           kf_ws_prior,    NULL);
-       setkeybinding(MODKEY|ShiftMask, XK_Right,       kf_screen_next, NULL);
-       setkeybinding(MODKEY|ShiftMask, XK_Left,        kf_screen_prev, NULL);
-       setkeybinding(MODKEY|ShiftMask, XK_1,           kf_mvws_1,      NULL);
-       setkeybinding(MODKEY|ShiftMask, XK_2,           kf_mvws_2,      NULL);
-       setkeybinding(MODKEY|ShiftMask, XK_3,           kf_mvws_3,      NULL);
-       setkeybinding(MODKEY|ShiftMask, XK_4,           kf_mvws_4,      NULL);
-       setkeybinding(MODKEY|ShiftMask, XK_5,           kf_mvws_5,      NULL);
-       setkeybinding(MODKEY|ShiftMask, XK_6,           kf_mvws_6,      NULL);
-       setkeybinding(MODKEY|ShiftMask, XK_7,           kf_mvws_7,      NULL);
-       setkeybinding(MODKEY|ShiftMask, XK_8,           kf_mvws_8,      NULL);
-       setkeybinding(MODKEY|ShiftMask, XK_9,           kf_mvws_9,      NULL);
-       setkeybinding(MODKEY|ShiftMask, XK_0,           kf_mvws_10,     NULL);
-       setkeybinding(MODKEY|ShiftMask, XK_F1,          kf_mvws_11,     NULL);
-       setkeybinding(MODKEY|ShiftMask, XK_F2,          kf_mvws_12,     NULL);
-       setkeybinding(MODKEY|ShiftMask, XK_F3,          kf_mvws_13,     NULL);
-       setkeybinding(MODKEY|ShiftMask, XK_F4,          kf_mvws_14,     NULL);
-       setkeybinding(MODKEY|ShiftMask, XK_F5,          kf_mvws_15,     NULL);
-       setkeybinding(MODKEY|ShiftMask, XK_F6,          kf_mvws_16,     NULL);
-       setkeybinding(MODKEY|ShiftMask, XK_F7,          kf_mvws_17,     NULL);
-       setkeybinding(MODKEY|ShiftMask, XK_F8,          kf_mvws_18,     NULL);
-       setkeybinding(MODKEY|ShiftMask, XK_F9,          kf_mvws_19,     NULL);
-       setkeybinding(MODKEY|ShiftMask, XK_F10,         kf_mvws_20,     NULL);
-       setkeybinding(MODKEY|ShiftMask, XK_F11,         kf_mvws_21,     NULL);
-       setkeybinding(MODKEY|ShiftMask, XK_F12,         kf_mvws_22,     NULL);
-       setkeybinding(MODKEY,           XK_b,           kf_bar_toggle,  NULL);
-       setkeybinding(MODKEY,           XK_Tab,         kf_focus_next,  NULL);
-       setkeybinding(MODKEY|ShiftMask, XK_Tab,         kf_focus_prev,  NULL);
-       setkeybinding(MODKEY|ShiftMask, XK_x,           kf_wind_kill,   NULL);
-       setkeybinding(MODKEY,           XK_x,           kf_wind_del,    NULL);
-       setkeybinding(MODKEY,           XK_s,           kf_spawn_custom,"screenshot_all");
-       setkeybinding(MODKEY|ShiftMask, XK_s,           kf_spawn_custom,"screenshot_wind");
-       setkeybinding(MODKEY,           XK_t,           kf_float_toggle,NULL);
-       setkeybinding(MODKEY|ShiftMask, XK_v,           kf_version,     NULL);
-       setkeybinding(MODKEY|ShiftMask, XK_Delete,      kf_spawn_custom,"lock");
-       setkeybinding(MODKEY|ShiftMask, XK_i,           kf_spawn_custom,"initscr");
-       setkeybinding(MODKEY,           XK_w,           kf_iconify,     NULL);
-       setkeybinding(MODKEY|ShiftMask, XK_w,           kf_uniconify,   NULL);
-       setkeybinding(MODKEY|ShiftMask, XK_r,           kf_raise_toggle,NULL);
-       setkeybinding(MODKEY,           XK_v,           kf_button2,     NULL);
-       setkeybinding(MODKEY,           XK_equal,       kf_width_grow,  NULL);
-       setkeybinding(MODKEY,           XK_minus,       kf_width_shrink,NULL);
-       setkeybinding(MODKEY|ShiftMask, XK_equal,       kf_height_grow, NULL);
-       setkeybinding(MODKEY|ShiftMask, XK_minus,       kf_height_shrink,NULL);
-       setkeybinding(MODKEY,           XK_bracketleft, kf_move_left,   NULL);
-       setkeybinding(MODKEY,           XK_bracketright,kf_move_right,  NULL);
-       setkeybinding(MODKEY|ShiftMask, XK_bracketleft, kf_move_up,     NULL);
-       setkeybinding(MODKEY|ShiftMask, XK_bracketright,kf_move_down,   NULL);
-       setkeybinding(MODKEY|ShiftMask, XK_slash,       kf_name_workspace,NULL);
-       setkeybinding(MODKEY,           XK_slash,       kf_search_workspace,NULL);
-       setkeybinding(MODKEY,           XK_f,           kf_search_win,  NULL);
+       setkeybinding(MODKEY,           XK_space,       KF_CYCLE_LAYOUT,NULL);
+       setkeybinding(MODKEY|ShiftMask, XK_backslash,   KF_FLIP_LAYOUT, NULL);
+       setkeybinding(MODKEY|ShiftMask, XK_space,       KF_STACK_RESET, NULL);
+       setkeybinding(MODKEY,           XK_h,           KF_MASTER_SHRINK, NULL);
+       setkeybinding(MODKEY,           XK_l,           KF_MASTER_GROW, NULL);
+       setkeybinding(MODKEY,           XK_comma,       KF_MASTER_ADD,  NULL);
+       setkeybinding(MODKEY,           XK_period,      KF_MASTER_DEL,  NULL);
+       setkeybinding(MODKEY|ShiftMask, XK_comma,       KF_STACK_INC,   NULL);
+       setkeybinding(MODKEY|ShiftMask, XK_period,      KF_STACK_DEC,   NULL);
+       setkeybinding(MODKEY,           XK_Return,      KF_SWAP_MAIN,   NULL);
+       setkeybinding(MODKEY,           XK_j,           KF_FOCUS_NEXT,  NULL);
+       setkeybinding(MODKEY,           XK_k,           KF_FOCUS_PREV,  NULL);
+       setkeybinding(MODKEY|ShiftMask, XK_j,           KF_SWAP_NEXT,   NULL);
+       setkeybinding(MODKEY|ShiftMask, XK_k,           KF_SWAP_PREV,   NULL);
+       setkeybinding(MODKEY|ShiftMask, XK_Return,      KF_SPAWN_CUSTOM,"term");
+       setkeybinding(MODKEY,           XK_p,           KF_SPAWN_CUSTOM,"menu");
+       setkeybinding(MODKEY|ShiftMask, XK_q,           KF_QUIT,        NULL);
+       setkeybinding(MODKEY,           XK_q,           KF_RESTART,     NULL);
+       setkeybinding(MODKEY,           XK_m,           KF_FOCUS_MAIN,  NULL);
+       setkeybinding(MODKEY,           XK_1,           KF_WS_1,        NULL);
+       setkeybinding(MODKEY,           XK_2,           KF_WS_2,        NULL);
+       setkeybinding(MODKEY,           XK_3,           KF_WS_3,        NULL);
+       setkeybinding(MODKEY,           XK_4,           KF_WS_4,        NULL);
+       setkeybinding(MODKEY,           XK_5,           KF_WS_5,        NULL);
+       setkeybinding(MODKEY,           XK_6,           KF_WS_6,        NULL);
+       setkeybinding(MODKEY,           XK_7,           KF_WS_7,        NULL);
+       setkeybinding(MODKEY,           XK_8,           KF_WS_8,        NULL);
+       setkeybinding(MODKEY,           XK_9,           KF_WS_9,        NULL);
+       setkeybinding(MODKEY,           XK_0,           KF_WS_10,       NULL);
+       setkeybinding(MODKEY,           XK_F1,          KF_WS_11,       NULL);
+       setkeybinding(MODKEY,           XK_F2,          KF_WS_12,       NULL);
+       setkeybinding(MODKEY,           XK_F3,          KF_WS_13,       NULL);
+       setkeybinding(MODKEY,           XK_F4,          KF_WS_14,       NULL);
+       setkeybinding(MODKEY,           XK_F5,          KF_WS_15,       NULL);
+       setkeybinding(MODKEY,           XK_F6,          KF_WS_16,       NULL);
+       setkeybinding(MODKEY,           XK_F7,          KF_WS_17,       NULL);
+       setkeybinding(MODKEY,           XK_F8,          KF_WS_18,       NULL);
+       setkeybinding(MODKEY,           XK_F9,          KF_WS_19,       NULL);
+       setkeybinding(MODKEY,           XK_F10,         KF_WS_20,       NULL);
+       setkeybinding(MODKEY,           XK_F11,         KF_WS_21,       NULL);
+       setkeybinding(MODKEY,           XK_F12,         KF_WS_22,       NULL);
+       setkeybinding(MODKEY,           XK_Right,       KF_WS_NEXT,     NULL);
+       setkeybinding(MODKEY,           XK_Left,        KF_WS_PREV,     NULL);
+       setkeybinding(MODKEY,           XK_Up,          KF_WS_NEXT_ALL, NULL);
+       setkeybinding(MODKEY,           XK_Down,        KF_WS_PREV_ALL, NULL);
+       setkeybinding(MODKEY,           XK_a,           KF_WS_PRIOR,    NULL);
+       setkeybinding(MODKEY|ShiftMask, XK_Right,       KF_SCREEN_NEXT, NULL);
+       setkeybinding(MODKEY|ShiftMask, XK_Left,        KF_SCREEN_PREV, NULL);
+       setkeybinding(MODKEY|ShiftMask, XK_1,           KF_MVWS_1,      NULL);
+       setkeybinding(MODKEY|ShiftMask, XK_2,           KF_MVWS_2,      NULL);
+       setkeybinding(MODKEY|ShiftMask, XK_3,           KF_MVWS_3,      NULL);
+       setkeybinding(MODKEY|ShiftMask, XK_4,           KF_MVWS_4,      NULL);
+       setkeybinding(MODKEY|ShiftMask, XK_5,           KF_MVWS_5,      NULL);
+       setkeybinding(MODKEY|ShiftMask, XK_6,           KF_MVWS_6,      NULL);
+       setkeybinding(MODKEY|ShiftMask, XK_7,           KF_MVWS_7,      NULL);
+       setkeybinding(MODKEY|ShiftMask, XK_8,           KF_MVWS_8,      NULL);
+       setkeybinding(MODKEY|ShiftMask, XK_9,           KF_MVWS_9,      NULL);
+       setkeybinding(MODKEY|ShiftMask, XK_0,           KF_MVWS_10,     NULL);
+       setkeybinding(MODKEY|ShiftMask, XK_F1,          KF_MVWS_11,     NULL);
+       setkeybinding(MODKEY|ShiftMask, XK_F2,          KF_MVWS_12,     NULL);
+       setkeybinding(MODKEY|ShiftMask, XK_F3,          KF_MVWS_13,     NULL);
+       setkeybinding(MODKEY|ShiftMask, XK_F4,          KF_MVWS_14,     NULL);
+       setkeybinding(MODKEY|ShiftMask, XK_F5,          KF_MVWS_15,     NULL);
+       setkeybinding(MODKEY|ShiftMask, XK_F6,          KF_MVWS_16,     NULL);
+       setkeybinding(MODKEY|ShiftMask, XK_F7,          KF_MVWS_17,     NULL);
+       setkeybinding(MODKEY|ShiftMask, XK_F8,          KF_MVWS_18,     NULL);
+       setkeybinding(MODKEY|ShiftMask, XK_F9,          KF_MVWS_19,     NULL);
+       setkeybinding(MODKEY|ShiftMask, XK_F10,         KF_MVWS_20,     NULL);
+       setkeybinding(MODKEY|ShiftMask, XK_F11,         KF_MVWS_21,     NULL);
+       setkeybinding(MODKEY|ShiftMask, XK_F12,         KF_MVWS_22,     NULL);
+       setkeybinding(MODKEY,           XK_b,           KF_BAR_TOGGLE,  NULL);
+       setkeybinding(MODKEY,           XK_Tab,         KF_FOCUS_NEXT,  NULL);
+       setkeybinding(MODKEY|ShiftMask, XK_Tab,         KF_FOCUS_PREV,  NULL);
+       setkeybinding(MODKEY|ShiftMask, XK_x,           KF_WIND_KILL,   NULL);
+       setkeybinding(MODKEY,           XK_x,           KF_WIND_DEL,    NULL);
+       setkeybinding(MODKEY,           XK_s,           KF_SPAWN_CUSTOM,"screenshot_all");
+       setkeybinding(MODKEY|ShiftMask, XK_s,           KF_SPAWN_CUSTOM,"screenshot_wind");
+       setkeybinding(MODKEY,           XK_t,           KF_FLOAT_TOGGLE,NULL);
+       setkeybinding(MODKEY|ShiftMask, XK_v,           KF_VERSION,     NULL);
+       setkeybinding(MODKEY|ShiftMask, XK_Delete,      KF_SPAWN_CUSTOM,"lock");
+       setkeybinding(MODKEY|ShiftMask, XK_i,           KF_SPAWN_CUSTOM,"initscr");
+       setkeybinding(MODKEY,           XK_w,           KF_ICONIFY,     NULL);
+       setkeybinding(MODKEY|ShiftMask, XK_w,           KF_UNICONIFY,   NULL);
+       setkeybinding(MODKEY|ShiftMask, XK_r,           KF_RAISE_TOGGLE,NULL);
+       setkeybinding(MODKEY,           XK_v,           KF_BUTTON2,     NULL);
+       setkeybinding(MODKEY,           XK_equal,       KF_WIDTH_GROW,  NULL);
+       setkeybinding(MODKEY,           XK_minus,       KF_WIDTH_SHRINK,NULL);
+       setkeybinding(MODKEY|ShiftMask, XK_equal,       KF_HEIGHT_GROW,NULL);
+       setkeybinding(MODKEY|ShiftMask, XK_minus,       KF_HEIGHT_SHRINK,NULL);
+       setkeybinding(MODKEY,           XK_bracketleft, KF_MOVE_LEFT,NULL);
+       setkeybinding(MODKEY,           XK_bracketright,KF_MOVE_RIGHT,NULL);
+       setkeybinding(MODKEY|ShiftMask, XK_bracketleft, KF_MOVE_UP,     NULL);
+       setkeybinding(MODKEY|ShiftMask, XK_bracketright,KF_MOVE_DOWN,NULL);
+       setkeybinding(MODKEY|ShiftMask, XK_slash,       KF_NAME_WORKSPACE,NULL);
+       setkeybinding(MODKEY,           XK_slash,       KF_SEARCH_WORKSPACE,NULL);
+       setkeybinding(MODKEY,           XK_f,           KF_SEARCH_WIN,  NULL);
 #ifdef SWM_DEBUG
-       setkeybinding(MODKEY|ShiftMask, XK_d,           kf_dumpwins,    NULL);
+       setkeybinding(MODKEY|ShiftMask, XK_d,           KF_DUMPWINS,    NULL);
 #endif
 }
 
@@ -5373,6 +5470,11 @@ int
 setkeymapping(char *selector, char *value, int flags)
 {
        char                    keymapping_file[PATH_MAX];
+
+       /* suppress unused warnings since vars are needed */
+       (void)selector;
+       (void)flags;
+
        DNPRINTF(SWM_D_KEY, "setkeymapping: enter\n");
        if (value[0] == '~')
                snprintf(keymapping_file, sizeof keymapping_file, "%s/%s",
@@ -5394,7 +5496,7 @@ updatenumlockmask(void)
 {
        unsigned int                            i, j;
        xcb_get_modifier_mapping_reply_t        *modmap_r;
-       xcb_keycode_t                           *modmap, kc;
+       xcb_keycode_t                           *modmap, kc, *keycode;
 
        DNPRINTF(SWM_D_MISC, "updatenumlockmask\n");
        numlockmask = 0;
@@ -5408,10 +5510,11 @@ updatenumlockmask(void)
                        for (j = 0; j < modmap_r->keycodes_per_modifier; j++) {
                                kc = modmap[i * modmap_r->keycodes_per_modifier
                                    + j];
-
-                               if (kc == *((xcb_keycode_t *)xcb_key_symbols_get_keycode(syms,
-                                   XK_Num_Lock)))
+                               keycode = xcb_key_symbols_get_keycode(syms,
+                                               XK_Num_Lock);
+                               if (kc == *keycode)  
                                        numlockmask = (1 << i);
+                               free(keycode);
                        }
                }
                free(modmap_r);
@@ -5421,8 +5524,8 @@ updatenumlockmask(void)
 void
 grabkeys(void)
 {
-       int                     num_screens;
-       unsigned int            j, k;
+       int                     num_screens, k;
+       unsigned int            j;
        xcb_keycode_t           *code;
        unsigned int            modifiers[] =
            { 0, LockMask, numlockmask, numlockmask | LockMask };
@@ -5441,11 +5544,12 @@ grabkeys(void)
                        if ((code = xcb_key_symbols_get_keycode(syms,
                                        kp->keysym)))
                                for (j = 0; j < LENGTH(modifiers); j++)
-                                       xcb_grab_key(conn, True,
+                                       xcb_grab_key(conn, 1,
                                            screens[k].root,
                                            kp->mod | modifiers[j],
                                            *code, XCB_GRAB_MODE_ASYNC,
                                            XCB_GRAB_MODE_ASYNC);
+                               free(code);
                }
        }
 }
@@ -5464,7 +5568,7 @@ grabbuttons(struct ws_win *win, int focused)
                for (i = 0; i < LENGTH(buttons); i++)
                        if (buttons[i].action == client_click)
                                for (j = 0; j < LENGTH(modifiers); j++)
-                                       xcb_grab_button(conn, False, win->id,
+                                       xcb_grab_button(conn, 0, win->id,
                                            BUTTONMASK,
                                            XCB_GRAB_MODE_ASYNC,
                                            XCB_GRAB_MODE_SYNC,
@@ -5473,7 +5577,7 @@ grabbuttons(struct ws_win *win, int focused)
                                            buttons[i].button,
                                            buttons[i].mask);
        } else
-               xcb_grab_button(conn, False, win->id, BUTTONMASK,
+               xcb_grab_button(conn, 0, win->id, BUTTONMASK,
                    XCB_GRAB_MODE_ASYNC, XCB_GRAB_MODE_SYNC, XCB_WINDOW_NONE,
                    XCB_CURSOR_NONE, XCB_BUTTON_INDEX_ANY, XCB_BUTTON_MASK_ANY);
 }
@@ -5606,6 +5710,10 @@ setconfquirk(char *selector, char *value, int flags)
        char                    *cp, *class, *name;
        int                     retval;
        unsigned long           quirks;
+
+       /* suppress unused warning since var is needed */
+       (void)flags;
+
        if (selector == NULL)
                return (0);
        if ((cp = strchr(selector, ':')) == NULL)
@@ -5680,6 +5788,9 @@ setconfvalue(char *selector, char *value, int flags)
        int     i;
        char    *b;
 
+       /* suppress unused warning since var is needed */
+       (void)selector;
+
        switch (flags) {
        case SWM_S_BAR_ACTION:
                free(bar_argv[0]);
@@ -5705,7 +5816,6 @@ setconfvalue(char *selector, char *value, int flags)
                if (asprintf(&bar_fonts, "%s,%s", value, bar_fonts) == -1)
                        err(1, "setconfvalue: asprintf: failed to allocate "
                                "memory for bar_fonts.");
-
                free(b);
                break;
        case SWM_S_BAR_FORMAT:
@@ -5851,6 +5961,10 @@ setconfvalue(char *selector, char *value, int flags)
 int
 setconfmodkey(char *selector, char *value, int flags)
 {
+       /* suppress unused warnings since vars are needed */
+       (void)selector;
+       (void)flags;
+
        if (!strncasecmp(value, "Mod1", strlen("Mod1")))
                update_modkey(Mod1Mask);
        else if (!strncasecmp(value, "Mod2", strlen("Mod2")))
@@ -5874,6 +5988,10 @@ setconfcolor(char *selector, char *value, int flags)
 int
 setconfregion(char *selector, char *value, int flags)
 {
+       /* suppress unused warnings since vars are needed */
+       (void)selector;
+       (void)flags;
+
        custom_region(value);
        return (0);
 }
@@ -5886,9 +6004,13 @@ setautorun(char *selector, char *value, int flags)
        char                    *ap, *sp = s;
        union arg               a;
        int                     argc = 0;
-       long                    pid;
+       pid_t                   pid;
        struct pid_e            *p;
 
+       /* suppress unused warnings since vars are needed */
+       (void)selector;
+       (void)flags;
+
        if (getenv("SWM_STARTED"))
                return (0);
 
@@ -5951,6 +6073,10 @@ setlayout(char *selector, char *value, int flags)
        char                    s[1024];
        struct workspace        *ws;
 
+       /* suppress unused warnings since vars are needed */
+       (void)selector;
+       (void)flags;
+
        if (getenv("SWM_STARTED"))
                return (0);
 
@@ -6122,7 +6248,7 @@ conf_load(char *filename, int keymapping)
                for (i = 0; i < LENGTH(configopt); i++) {
                        opt = &configopt[i];
                        if (!strncasecmp(cp, opt->optname, wordlen) &&
-                           strlen(opt->optname) == wordlen) {
+                           (int)strlen(opt->optname) == wordlen) {
                                optind = i;
                                break;
                        }
@@ -6227,10 +6353,10 @@ set_child_transient(struct ws_win *win, xcb_window_t *trans)
        }
 }
 
-long
+pid_t
 window_get_pid(xcb_window_t win)
 {
-       long                            ret = 0;
+       pid_t                           ret = 0;
        const char                      *errstr;
        xcb_atom_t                      apid;
        xcb_get_property_cookie_t       pc;
@@ -6240,52 +6366,95 @@ window_get_pid(xcb_window_t win)
        if (apid == XCB_ATOM_NONE)
                goto tryharder;
 
-       pc = xcb_get_property(conn, False, win, apid, XCB_ATOM_CARDINAL, 0, 1);
+       pc = xcb_get_property(conn, 0, win, apid, XCB_ATOM_CARDINAL, 0, 1);
        pr = xcb_get_property_reply(conn, pc, NULL);
        if (!pr)
                goto tryharder;
-       if (pr->type != XCB_ATOM_CARDINAL)
+       if (pr->type != XCB_ATOM_CARDINAL) {
+               free(pr);
                goto tryharder;
+       }
 
-       ret = *(long *)xcb_get_property_value(pr);
+       if (pr->type == apid && pr->format == 32)
+               ret = *((pid_t *)xcb_get_property_value(pr));
        free(pr);
 
        return (ret);
 
 tryharder:
        apid = get_atom_from_string("_SWM_PID");
-       pc = xcb_get_property(conn, False, win, apid, XCB_ATOM_STRING,
+       pc = xcb_get_property(conn, 0, win, apid, XCB_ATOM_STRING,
            0, SWM_PROPLEN);
        pr = xcb_get_property_reply(conn, pc, NULL);
        if (!pr)
                return (0);
-       if (pr->type != XCB_ATOM_STRING)
+       if (pr->type != apid) {
                free(pr);
                return (0);
-       ret = strtonum(xcb_get_property_value(pr), 0, UINT_MAX, &errstr);
+       }
+
+       ret = (pid_t)strtonum(xcb_get_property_value(pr), 0, INT_MAX, &errstr);
        free(pr);
 
        return (ret);
 }
 
+int
+get_ws_idx(xcb_window_t id)
+{
+       int                     ws_idx = -1;
+       char                    *prop = NULL;
+       size_t                  proplen;
+       const char              *errstr;
+       xcb_get_property_reply_t        *gpr;
+
+       gpr = xcb_get_property_reply(conn,
+               xcb_get_property(conn, 0, id, a_swm_ws,
+                   XCB_ATOM_STRING, 0, SWM_PROPLEN),
+               NULL);
+       if (!gpr)
+               return (-1);
+       if (gpr->type) {
+               proplen = xcb_get_property_value_length(gpr);
+               if (proplen > 0) {
+                       prop = malloc(proplen + 1);
+                       if (prop) {
+                               memcpy(prop,
+                                   xcb_get_property_value(gpr),
+                                   proplen);
+                               prop[proplen] = '\0';
+                       }
+               }
+       }
+       free(gpr);
+
+       if (prop) {
+               DNPRINTF(SWM_D_PROP, "get_ws_idx: _SWM_WS: %s\n", prop);
+               ws_idx = (int)strtonum(prop, 0, workspace_limit - 1, &errstr);
+               if (errstr) {
+                       DNPRINTF(SWM_D_PROP, "get_ws_idx: window: #%s: %s",
+                           errstr, prop);
+               }
+               free(prop);
+       }
+
+       return ws_idx;
+}
+
 struct ws_win *
 manage_window(xcb_window_t id)
 {
        xcb_window_t            trans = XCB_WINDOW_NONE;
        struct workspace        *ws;
        struct ws_win           *win, *ww;
-       int                     i, ws_idx, border_me = 0;
-       xcb_atom_t              ws_idx_atom = XCB_ATOM_NONE;
+       int                     ws_idx, border_me = 0;
        char                    ws_idx_str[SWM_PROPLEN], *prop = NULL;
-       size_t                  proplen;
        struct swm_region       *r;
-       const char              *errstr;
        struct pid_e            *p;
        struct quirk            *qp;
-       uint32_t                event_mask;
-       xcb_atom_t              prot;
-       xcb_get_property_reply_t        *gpr;
+       uint32_t                event_mask, i;
        xcb_icccm_get_wm_protocols_reply_t      wpr;
+       xcb_icccm_get_wm_class_reply_t          tmpch;
 
        if ((win = find_window(id)) != NULL)
                return (win);   /* already being managed */
@@ -6332,26 +6501,8 @@ manage_window(xcb_window_t id)
        p = find_pid(window_get_pid(id));
 
        /* Get all the window data in one shot */
-       ws_idx_atom = get_atom_from_string("_SWM_WS");
-       if (ws_idx_atom) {
-               gpr = xcb_get_property_reply(conn,
-                       xcb_get_property(conn, False, id, ws_idx_atom,
-                           XCB_ATOM_STRING, 0, SWM_PROPLEN),
-                       NULL);
-               if (gpr) {
-                       proplen = xcb_get_property_value_length(gpr);
-                       if (proplen > 0) {
-                               prop = malloc(proplen + 1);
-                               if (prop) {
-                                       memcpy(prop,
-                                           xcb_get_property_value(gpr),
-                                           proplen);
-                                       prop[proplen] = '\0';
-                               }
-                       }
-                       free(gpr);
-               }
-       }
+       ws_idx = get_ws_idx(id);
+
        win->wa = xcb_get_geometry_reply(conn,
            xcb_get_geometry(conn, id),
            NULL);
@@ -6371,16 +6522,14 @@ manage_window(xcb_window_t id)
                    "transient: 0x%x\n", win->id, win->transient);
        }
 
-       prot = get_atom_from_string("WM_PROTOCOLS");
-
        /* get supported protocols */
        if (xcb_icccm_get_wm_protocols_reply(conn,
-           xcb_icccm_get_wm_protocols(conn, id, prot),
+           xcb_icccm_get_wm_protocols(conn, id, a_prot),
            &wpr, NULL)) {
                for (i = 0; i < wpr.atoms_len; i++) {
-                       if (wpr.atoms[i] == takefocus)
+                       if (wpr.atoms[i] == a_takefocus)
                                win->take_focus = 1;
-                       if (wpr.atoms[i] == adelete)
+                       if (wpr.atoms[i] == a_delete)
                                win->can_delete = 1;
                }
                xcb_icccm_get_wm_protocols_reply_wipe(&wpr);
@@ -6399,14 +6548,7 @@ manage_window(xcb_window_t id)
                TAILQ_REMOVE(&pidlist, p, entry);
                free(p);
                p = NULL;
-       } else if (prop && win->transient == 0) {
-               DNPRINTF(SWM_D_PROP, "manage_window: get _SWM_WS: %s\n", prop);
-               ws_idx = strtonum(prop, 0, workspace_limit - 1,
-                   &errstr);
-               if (errstr) {
-                       DNPRINTF(SWM_D_EVENT, "manage_window: window: #%s: %s",
-                           errstr, prop);
-               }
+       } else if (ws_idx != -1 && win->transient == 0) {
                ws = &r->s->ws[ws_idx];
        } else {
                ws = r->ws;
@@ -6463,13 +6605,12 @@ manage_window(xcb_window_t id)
        constrain_window(win, r, 0);
 
        /* Set window properties so we can remember this after reincarnation */
-       if (ws_idx_atom && prop == NULL &&
-           snprintf(ws_idx_str, SWM_PROPLEN, "%d", ws->idx) <
-               SWM_PROPLEN) {
+       if (prop == NULL && snprintf(ws_idx_str, SWM_PROPLEN, "%d", ws->idx) <
+           SWM_PROPLEN) {
                DNPRINTF(SWM_D_PROP, "manage_window: set _SWM_WS: %s\n",
                    ws_idx_str);
                xcb_change_property(conn, XCB_PROP_MODE_REPLACE, win->id,
-                   ws_idx_atom, XCB_ATOM_STRING, 8, strlen(ws_idx_str),
+                   a_swm_ws, XCB_ATOM_STRING, 8, strlen(ws_idx_str),
                    ws_idx_str);
        }
        if (prop)
@@ -6479,7 +6620,12 @@ manage_window(xcb_window_t id)
 
        if (xcb_icccm_get_wm_class_reply(conn,
            xcb_icccm_get_wm_class(conn, win->id),
-           &win->ch, NULL)) {
+           &tmpch, NULL)) {
+               win->ch.class_name = tmpch.class_name;
+               win->ch.instance_name = tmpch.instance_name;
+
+               xcb_get_wm_class_reply_wipe(&tmpch);
+
                DNPRINTF(SWM_D_CLASS, "manage_window: class: %s, name: %s\n",
                    win->ch.class_name, win->ch.instance_name);
 
@@ -6558,9 +6704,7 @@ free_window(struct ws_win *win)
 
        if (win->wa)
                free(win->wa);
-
-       xcb_icccm_get_wm_class_reply_wipe(&win->ch);
-
+       
        kill_refs(win);
 
        /* paint memory */
@@ -6614,25 +6758,26 @@ focus_magic(struct ws_win *win)
                if (win->java) {
                        focus_win(win->child_trans);
                        if (win->child_trans->take_focus)
-                               client_msg(win, takefocus);
+                               client_msg(win, a_takefocus);
                } else {
                        /* make sure transient hasn't disappeared */
                        if (validate_win(win->child_trans) == 0) {
                                focus_win(win->child_trans);
                                if (win->child_trans->take_focus)
-                                       client_msg(win->child_trans, takefocus);
+                                       client_msg(win->child_trans,
+                                           a_takefocus);
                        } else {
                                win->child_trans = NULL;
                                focus_win(win);
                                if (win->take_focus)
-                                       client_msg(win, takefocus);
+                                       client_msg(win, a_takefocus);
                        }
                }
        } else {
                /* regular focus */
                focus_win(win);
                if (win->take_focus)
-                       client_msg(win, takefocus);
+                       client_msg(win, a_takefocus);
        }
 }
 
@@ -6656,33 +6801,33 @@ expose(xcb_expose_event_t *e)
 void
 keypress(xcb_key_press_event_t *e)
 {
-       KeySym                  keysym;
+       xcb_keysym_t            keysym;
        struct key              *kp;
-       struct swm_region       *r;
 
-       keysym = XkbKeycodeToKeysym(display, (KeyCode)e->detail, 0, 0);
+       keysym = xcb_key_press_lookup_keysym(syms, e, 0);
 
-       DNPRINTF(SWM_D_EVENT, "keypress: %u\n", e->detail);
+       DNPRINTF(SWM_D_EVENT, "keypress: %u %u\n", e->detail, keysym);
 
        if ((kp = key_lookup(CLEANMASK(e->state), keysym)) == NULL)
                return;
-       if (keyfuncs[kp->funcid].func == NULL)
-               return;
 
-       r = root_to_region(e->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));
+       if (kp->funcid == KF_SPAWN_CUSTOM)
+               spawn_custom(root_to_region(e->root),
+                   &(keyfuncs[kp->funcid].args), kp->spawn_name);
+       else if (keyfuncs[kp->funcid].func)
+               keyfuncs[kp->funcid].func(root_to_region(e->root),
+                   &(keyfuncs[kp->funcid].args));
 }
 
 void
 buttonpress(xcb_button_press_event_t *e)
 {
        struct ws_win           *win;
-       int                     i, action;
+       int                     i;
+       unsigned int            action;
 
-       DNPRINTF(SWM_D_EVENT, "buttonpress: window 0x%x\n", e->event);
+       DNPRINTF(SWM_D_EVENT, "buttonpress: window 0x%x, detail: %u\n",
+           e->event, e->detail);
 
        if ((win = find_window(e->event)) == NULL)
                return;
@@ -6695,7 +6840,32 @@ buttonpress(xcb_button_press_event_t *e)
                    buttons[i].button == e->detail &&
                    CLEANMASK(buttons[i].mask) == CLEANMASK(e->state))
                        buttons[i].func(win, &buttons[i].args);
+
+       xcb_flush(conn);
+}
+
+#ifdef SWM_DEBUG
+void
+print_win_geom(xcb_window_t w)
+{
+       xcb_get_geometry_reply_t        *wa;
+
+       wa = xcb_get_geometry_reply(conn, xcb_get_geometry(conn, w), NULL);
+
+       if (!wa) {
+               DNPRINTF(SWM_D_MISC, "print_win_geom: window not found: 0x%x\n",
+                   w);
+               return;
+       }
+
+       DNPRINTF(SWM_D_MISC, "print_win_geom: window: 0x%x, root: 0x%x, "
+           "depth: %u, (x,y) w x h: (%d,%d) %d x %d, border: %d\n",
+           w, wa->root, wa->depth, wa->x,  wa->y, wa->width, wa->height,
+           wa->border_width);
+
+       free(wa);
 }
+#endif
 
 void
 configurerequest(xcb_configure_request_event_t *e)
@@ -6708,42 +6878,52 @@ configurerequest(xcb_configure_request_event_t *e)
        if ((win = find_window(e->window)) == NULL)
                if ((win = find_unmanaged_window(e->window)) == NULL)
                        new = 1;
-
+#ifdef SWM_DEBUG
+       print_win_geom(e->window);
+#endif
        if (new) {
+               DNPRINTF(SWM_D_EVENT, "configurerequest: new window: 0x%x, "
+                   "value_mask: 0x%x", e->window, e->value_mask);
                if (e->value_mask & XCB_CONFIG_WINDOW_X) {
                        mask |= XCB_CONFIG_WINDOW_X;
                        wc[i++] = e->x;
+                       DPRINTF(", X: %d", e->x);
                }
                if (e->value_mask & XCB_CONFIG_WINDOW_Y) {
                        mask |= XCB_CONFIG_WINDOW_Y;
                        wc[i++] = e->y;
+                       DPRINTF(", Y: %d", e->y);
                }
                if (e->value_mask & XCB_CONFIG_WINDOW_WIDTH) {
                        mask |= XCB_CONFIG_WINDOW_WIDTH;
                        wc[i++] = e->width;
+                       DPRINTF(", W: %u", e->width);
                }
                if (e->value_mask & XCB_CONFIG_WINDOW_HEIGHT) {
                        mask |= XCB_CONFIG_WINDOW_HEIGHT;
                        wc[i++] = e->height;
+                       DPRINTF(", H: %u", e->height);
                }
                if (e->value_mask & XCB_CONFIG_WINDOW_BORDER_WIDTH) {
                        mask |= XCB_CONFIG_WINDOW_BORDER_WIDTH;
                        wc[i++] = e->border_width;
+                       DPRINTF(", Border: %u", e->border_width);
                }
                if (e->value_mask & XCB_CONFIG_WINDOW_SIBLING) {
                        mask |= XCB_CONFIG_WINDOW_SIBLING;
                        wc[i++] = e->sibling;
+                       DPRINTF(", Sibling: 0x%x", e->sibling);
                }
                if (e->value_mask & XCB_CONFIG_WINDOW_STACK_MODE) {
                        mask |= XCB_CONFIG_WINDOW_STACK_MODE;
                        wc[i++] = e->stack_mode;
+                       DPRINTF(", StackMode: %u", e->stack_mode);
                }
 
-               DNPRINTF(SWM_D_EVENT, "configurerequest: new window: 0x%x, "
-                   "new: %s, (x,y) w x h: (%d,%d) %d x %d\n", e->window,
-                   YESNO(new), wc[0], wc[1], wc[2], wc[3]);
+               if (mask != 0)
+                       xcb_configure_window(conn, e->window, mask, wc);
 
-               xcb_configure_window(conn, e->window, mask, wc);
+               DPRINTF(", Sent: %s\n", YESNO((mask != 0)));
        } else if ((!win->manual || win->quirks & SWM_Q_ANYWHERE) &&
            !(win->ewmh_flags & EWMH_F_FULLSCREEN)) {
                win->g_float.x = e->x - X(win->ws->r);
@@ -6763,6 +6943,8 @@ configurerequest(xcb_configure_request_event_t *e)
        } else {
                config_win(win, e);
        }
+
+       xcb_flush(conn);
 }
 
 void
@@ -6810,11 +6992,6 @@ void
 enternotify(xcb_enter_notify_event_t *e)
 {
        struct ws_win           *win;
-#if 0
-       struct ws_win           *w;
-       Window                  focus_return;
-       int                     revert_to_return;
-#endif
        DNPRINTF(SWM_D_FOCUS, "enternotify: window: 0x%x, mode: %d, detail: "
            "%d, root: 0x%x, subwindow: 0x%x, same_screen_focus: %s, "
            "state: %d\n", e->event, e->mode, e->detail, e->root,
@@ -6832,74 +7009,6 @@ enternotify(xcb_enter_notify_event_t *e)
        case SWM_FOCUS_FOLLOW:
                break;
        case SWM_FOCUS_SYNERGY:
-#if 0
-       /*
-        * all these checks need to be in this order because the
-        * XCheckTypedWindowEvent relies on weeding out the previous events
-        *
-        * making this code an option would enable a follow mouse for focus
-        * feature
-        */
-
-       /*
-        * state is set when we are switching workspaces and focus is set when
-        * the window or a subwindow already has focus (occurs during restart).
-        *
-        * Only honor the focus flag if last_focus_event is not FocusOut,
-        * this allows spectrwm to continue to control focus when another
-        * program is also playing with it.
-        */
-       if (ev->state || (ev->focus && last_focus_event != FocusOut)) {
-               DNPRINTF(SWM_D_EVENT, "ignoring enternotify: focus\n");
-               return;
-       }
-
-       /*
-        * happens when a window is created or destroyed and the border
-        * crosses the mouse pointer and when switching ws
-        *
-        * we need the subwindow test to see if we came from root in order
-        * to give focus to floaters
-        */
-       if (ev->mode == NotifyNormal && ev->detail == NotifyVirtual &&
-           ev->subwindow == 0) {
-               DNPRINTF(SWM_D_EVENT, "ignoring enternotify: NotifyVirtual\n");
-               return;
-       }
-
-       /* this window already has focus */
-       if (ev->mode == NotifyNormal && ev->detail == NotifyInferior) {
-               DNPRINTF(SWM_D_EVENT, "ignoring enternotify: win has focus\n");
-               return;
-       }
-
-       /* this window is being deleted or moved to another ws */
-       if (XCheckTypedWindowEvent(display, ev->window, ConfigureNotify,
-           &cne) == True) {
-               DNPRINTF(SWM_D_EVENT, "ignoring enternotify: configurenotify\n");
-               XPutBackEvent(display, &cne);
-               return;
-       }
-
-       if ((win = find_window(ev->window)) == NULL) {
-               DNPRINTF(SWM_D_EVENT, "ignoring enternotify: win == NULL\n");
-               return;
-       }
-
-       /*
-        * In fullstack kill all enters unless they come from a different ws
-        * (i.e. another region) or focus has been grabbed externally.
-        */
-       if (win->ws->cur_layout->flags & SWM_L_FOCUSPREV &&
-           last_focus_event != FocusOut) {
-               XGetInputFocus(display, &focus_return, &revert_to_return);
-               if ((w = find_window(focus_return)) == NULL ||
-                   w->ws == win->ws) {
-                       DNPRINTF(SWM_D_EVENT, "ignoring event: fullstack\n");
-                       return;
-               }
-       }
-#endif
                break;
        }
 
@@ -6909,6 +7018,8 @@ enternotify(xcb_enter_notify_event_t *e)
        }
 
        focus_magic(win);
+
+       xcb_flush(conn);
 }
 
 /* lets us use one switch statement for arbitrary mode/detail combinations */
@@ -6976,17 +7087,16 @@ maprequest(xcb_map_request_event_t *e)
                focus_magic(win);
 }
 
-void
-propertynotify(xcb_property_notify_event_t *e)
-{
-       struct ws_win           *win;
 #ifdef SWM_DEBUG
-       char                            *name;
+char *
+get_atom_name(xcb_atom_t atom)
+{
+       char                            *name = NULL;
        size_t                          len;
        xcb_get_atom_name_reply_t       *r;
 
        r = xcb_get_atom_name_reply(conn,
-           xcb_get_atom_name(conn, e->atom),
+           xcb_get_atom_name(conn, atom),
            NULL);
        if (r) {
                len = xcb_get_atom_name_name_length(r);
@@ -6995,15 +7105,26 @@ propertynotify(xcb_property_notify_event_t *e)
                        if (name) {
                                memcpy(name, xcb_get_atom_name_name(r), len);
                                name[len] = '\0';
-
-                               DNPRINTF(SWM_D_EVENT,
-                                   "propertynotify: window: 0x%x, atom: %s\n",
-                                   e->window, name);
-                               free(name);
                        }
                }
                free(r);
        }
+
+       return (name);
+}
+#endif
+
+void
+propertynotify(xcb_property_notify_event_t *e)
+{
+       struct ws_win           *win;
+#ifdef SWM_DEBUG
+       char                    *name;
+
+       name = get_atom_name(e->atom);
+       DNPRINTF(SWM_D_EVENT, "propertynotify: window: 0x%x, atom: %s(%u)\n",
+           e->window, name, e->atom);
+       free(name);
 #endif
 
        win = find_window(e->window);
@@ -7019,20 +7140,6 @@ propertynotify(xcb_property_notify_event_t *e)
        }
 
        switch (e->atom) {
-#if 0
-       case XCB_ATOM_WM_NORMAL_HINTS:
-               xcb_icccm_get_wm_normal_hints(conn,
-                       xcb_iccom_get_wm_normal_hints(conn, win->id),
-                       &win->sh, NULL);
-               warnx("normal hints: flag 0x%x", win->sh.flags);
-               if (win->sh.flags & XCB_SIZE_HINT_P_MIN_SIZE) {
-                       WIDTH(win) = win->sh.min_width;
-                       HEIGHT(win) = win->sh.min_height;
-                       warnx("min %d %d", WIDTH(win), HEIGHT(win));
-               }
-               XMoveResizeWindow(display, win->id,
-                   X(win), Y(win), WIDTH(win), HEIGHT(win));
-#endif
        case XCB_ATOM_WM_CLASS:
        case XCB_ATOM_WM_NAME:
                bar_update();
@@ -7060,52 +7167,56 @@ unmapnotify(xcb_unmap_notify_event_t *e)
 
                /* resend unmap because we ated it */
                xcb_unmap_window(conn, e->window);
+               xcb_flush(conn);
        }
 }
 
+#if 0
 void
 visibilitynotify(xcb_visibility_notify_event_t *e)
 {
-       int                     i, num_screens;
-       struct swm_region       *r;
-
        DNPRINTF(SWM_D_EVENT, "visibilitynotify: window: 0x%x\n",
            e->window);
-
-       if (e->state == XCB_VISIBILITY_UNOBSCURED) {
-               num_screens = xcb_setup_roots_length(xcb_get_setup(conn));
-               for (i = 0; i < num_screens; i++)
-                       TAILQ_FOREACH(r, &screens[i].rl, entry)
-                               if (e->window == WINID(r->bar))
-                                       bar_update();
-       }
 }
+#endif
 
 void
 clientmessage(xcb_client_message_event_t *e)
 {
        struct ws_win *win;
+       xcb_map_request_event_t mre;
+#ifdef SWM_DEBUG
+       char                    *name;
 
+       name = get_atom_name(e->type);
+       DNPRINTF(SWM_D_EVENT, "clientmessage: window: 0x%x, atom: %s(%u)\n",
+           e->window, name, e->type);
+       free(name);
+#endif
        win = find_window(e->window);
-       if (win == NULL)
+
+       if (win == NULL) {
+               if (e->type == ewmh[_NET_ACTIVE_WINDOW].atom) {
+                       DNPRINTF(SWM_D_EVENT, "clientmessage: request focus on "
+                           "unmanaged window.\n");
+                       mre.window = e->window;
+                       maprequest(&mre);
+               }
                return;
        }
 
-       DNPRINTF(SWM_D_EVENT, "clientmessage: window: 0x%x, type: %u\n",
-           e->window, e->response_type);
-
-       if (e->response_type == ewmh[_NET_ACTIVE_WINDOW].atom) {
+       if (e->type == ewmh[_NET_ACTIVE_WINDOW].atom) {
                DNPRINTF(SWM_D_EVENT, "clientmessage: _NET_ACTIVE_WINDOW\n");
                focus_win(win);
        }
-       if (e->response_type == ewmh[_NET_CLOSE_WINDOW].atom) {
+       if (e->type == ewmh[_NET_CLOSE_WINDOW].atom) {
                DNPRINTF(SWM_D_EVENT, "clientmessage: _NET_CLOSE_WINDOW\n");
                if (win->can_delete)
-                       client_msg(win, adelete);
+                       client_msg(win, a_delete);
                else
                        xcb_kill_client(conn, win->id);
        }
-       if (e->response_type == ewmh[_NET_MOVERESIZE_WINDOW].atom) {
+       if (e->type == ewmh[_NET_MOVERESIZE_WINDOW].atom) {
                DNPRINTF(SWM_D_EVENT,
                    "clientmessage: _NET_MOVERESIZE_WINDOW\n");
                if (win->floating) {
@@ -7126,7 +7237,7 @@ clientmessage(xcb_client_message_event_t *e)
                        config_win(win, NULL);
                }
        }
-       if (e->response_type == ewmh[_NET_WM_STATE].atom) {
+       if (e->type == ewmh[_NET_WM_STATE].atom) {
                DNPRINTF(SWM_D_EVENT, "clientmessage: _NET_WM_STATE\n");
                ewmh_update_win_state(win, e->data.data32[1], e->data.data32[0]);
                if (e->data.data32[2])
@@ -7135,38 +7246,36 @@ clientmessage(xcb_client_message_event_t *e)
 
                stack();
        }
-}
-
-int
-xerror_start(Display *d, XErrorEvent *ee)
-{
-       other_wm = 1;
-       return (-1);
-}
 
-int
-xerror(Display *d, XErrorEvent *ee)
-{
-       /* warnx("error: %p %p", display, ee); */
-       return (-1);
+       xcb_flush(conn);
 }
 
 int
-active_wm(void)
+enable_wm(void)
 {
-       other_wm = 0;
-       xerrorxlib = XSetErrorHandler(xerror_start);
+       int                     num_screens, i;
+       const uint32_t          val = XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT;
+       xcb_screen_t            *sc;
+       xcb_void_cookie_t       wac;
+       xcb_generic_error_t     *error;
 
        /* this causes an error if some other window manager is running */
-       XSelectInput(display, DefaultRootWindow(display),
-           SubstructureRedirectMask);
-       do_sync();
-       if (other_wm)
-               return (1);
+       num_screens = xcb_setup_roots_length(xcb_get_setup(conn));
+       for (i = 0; i < num_screens; i++) {
+               sc = get_screen(i);
+               DNPRINTF(SWM_D_INIT, "enable_wm: screen %d, root: 0x%x\n",
+                   i, sc->root);
+               wac = xcb_change_window_attributes_checked(conn, sc->root,
+                   XCB_CW_EVENT_MASK, &val);
+               if ((error = xcb_request_check(conn, wac))) {
+                       DNPRINTF(SWM_D_INIT, "enable_wm: error_code: %u\n",
+                           error->error_code);
+                       free(error);
+                       return 1;
+               }
+       }
 
-       XSetErrorHandler(xerror);
-       do_sync();
-       return (0);
+       return 0;
 }
 
 void
@@ -7287,8 +7396,9 @@ scan_xrandr(int i)
                        return;
                } else
                        ncrtc = srr->num_crtcs;
+
+               crtc = xcb_randr_get_screen_resources_current_crtcs(srr);
                for (c = 0; c < ncrtc; c++) {
-                       crtc = xcb_randr_get_screen_resources_current_crtcs(srr);
                        cic = xcb_randr_get_crtc_info(conn, crtc[c],
                            XCB_CURRENT_TIME);
                        cir = xcb_randr_get_crtc_info_reply(conn, cic, NULL);
@@ -7325,14 +7435,6 @@ screenchange(xcb_randr_screen_change_notify_event_t *e)
 
        DNPRINTF(SWM_D_EVENT, "screenchange: root: 0x%x\n", e->root);
 
-       if (e->rotation & (XCB_RANDR_ROTATION_ROTATE_90
-           | XCB_RANDR_ROTATION_ROTATE_270))
-               xcb_randr_set_screen_size(conn, e->root, e->height,
-                   e->width, e->mheight, e->mwidth);
-       else
-               xcb_randr_set_screen_size(conn, e->root, e->width,
-                   e->height, e->mwidth, e->mheight);
-
        num_screens = xcb_setup_roots_length(xcb_get_setup(conn));
        /* silly event doesn't include the screen index */
        for (i = 0; i < num_screens; i++)
@@ -7344,6 +7446,9 @@ screenchange(xcb_randr_screen_change_notify_event_t *e)
        /* brute force for now, just re-enumerate the regions */
        scan_xrandr(i);
 
+#ifdef SWM_DEBUG
+       print_win_geom(e->root);
+#endif
        /* add bars to all regions */
        for (i = 0; i < num_screens; i++)
                TAILQ_FOREACH(r, &screens[i].rl, entry)
@@ -7365,6 +7470,7 @@ grab_windows(void)
        xcb_get_window_attributes_reply_t       *r;
        xcb_get_property_cookie_t               pc;
 
+       DNPRINTF(SWM_D_INIT, "grab_windows: begin\n");
        num_screens = xcb_setup_roots_length(xcb_get_setup(conn));
        for (i = 0; i < num_screens; i++) {
                qtc = xcb_query_tree(conn, screens[i].root);
@@ -7419,6 +7525,7 @@ grab_windows(void)
                }
                free(qtr);
        }
+       DNPRINTF(SWM_D_INIT, "grab_windows: done\n");
 }
 
 void
@@ -7440,12 +7547,12 @@ setup_screens(void)
                    "screens");
 
        /* initial Xrandr setup */
-       xrandr_support = False;
-       c = xcb_randr_query_version(conn, True, True);
+       xrandr_support = 0;
+       c = xcb_randr_query_version(conn, 1, 1);
        r = xcb_randr_query_version_reply(conn, c, NULL);
        if (r) {
                if (r->major_version >= 1)
-                       xrandr_support = True;
+                       xrandr_support = 1;
                free(r);
        }
        qep = xcb_get_extension_data(conn, &xcb_randr_id);
@@ -7456,7 +7563,7 @@ setup_screens(void)
 
        cursor = xcb_generate_id(conn);
        xcb_create_glyph_cursor(conn, cursor, cursor_font, cursor_font,
-               XC_left_ptr, XC_left_ptr + 1, 0, 0, 0, 0xffff, 0xffff, 0xffff);
+           XC_left_ptr, XC_left_ptr + 1, 0, 0, 0, 0xffff, 0xffff, 0xffff);
        wa[0] = cursor;
 
        /* map physical screens */
@@ -7465,7 +7572,7 @@ setup_screens(void)
                screens[i].idx = i;
                TAILQ_INIT(&screens[i].rl);
                TAILQ_INIT(&screens[i].orl);
-               screens[i].root = RootWindow(display, i);
+               screens[i].root = get_screen(i)->root;
 
                /* set default colors */
                setscreencolor("red", i + 1, SWM_S_COLOR_FOCUS);
@@ -7522,28 +7629,40 @@ setup_globals(void)
 
        if ((clock_format = strdup("%a %b %d %R %Z %Y")) == NULL)
                err(1, "setup_globals: strdup: failed to allocate memory.");
+
+       if ((syms = xcb_key_symbols_alloc(conn)) == NULL)
+               errx(1, "unable to allocate key symbols");
+
+       a_state = get_atom_from_string("WM_STATE");
+       a_prot = get_atom_from_string("WM_PROTOCOLS");
+       a_delete = get_atom_from_string("WM_DELETE_WINDOW");
+       a_takefocus = get_atom_from_string("WM_TAKE_FOCUS");
+       a_wmname = get_atom_from_string("WM_NAME");
+       a_netwmname = get_atom_from_string("_NET_WM_NAME");
+       a_utf8_string = get_atom_from_string("UTF8_STRING");
+       a_string = get_atom_from_string("STRING");
+       a_swm_iconic = get_atom_from_string("_SWM_ICONIC");
+       a_swm_ws = get_atom_from_string("_SWM_WS");
 }
 
 void
 workaround(void)
 {
        int                     i, num_screens;
-       xcb_atom_t              netwmcheck, netwmname, utf8_string;
+       xcb_atom_t              netwmcheck;
        xcb_window_t            root, win;
        uint32_t                wa[2];
 
        /* work around sun jdk bugs, code from wmname */
        netwmcheck = get_atom_from_string("_NET_SUPPORTING_WM_CHECK");
-       netwmname = get_atom_from_string("_NET_WM_NAME");
-       utf8_string = get_atom_from_string("UTF8_STRING");
 
        num_screens = xcb_setup_roots_length(xcb_get_setup(conn));
        for (i = 0; i < num_screens; i++) {
                root = screens[i].root;
 
                win = xcb_generate_id(conn);
-               wa[0] = screens[i].c[SWM_S_COLOR_UNFOCUS].color;
-               wa[1] = screens[i].c[SWM_S_COLOR_UNFOCUS].color;
+               wa[0] = screens[i].c[SWM_S_COLOR_UNFOCUS].pixel;
+               wa[1] = screens[i].c[SWM_S_COLOR_UNFOCUS].pixel;
                xcb_create_window(conn, XCB_COPY_FROM_PARENT, win, 0, 0, 0, 1,
                    1, 0, XCB_WINDOW_CLASS_INPUT_OUTPUT, XCB_COPY_FROM_PARENT,
                    XCB_CW_BACK_PIXEL | XCB_CW_BORDER_PIXEL, wa);
@@ -7553,7 +7672,7 @@ workaround(void)
                xcb_change_property(conn, XCB_PROP_MODE_REPLACE, win,
                    netwmcheck, XCB_ATOM_WINDOW, 32, 1, &win);
                xcb_change_property(conn, XCB_PROP_MODE_REPLACE, win,
-                   netwmname, utf8_string, 8, strlen("LG3D"), "LG3D");
+                   a_netwmname, a_utf8_string, 8, strlen("LG3D"), "LG3D");
        }
 }
 
@@ -7571,6 +7690,11 @@ void
 event_handle(xcb_generic_event_t *evt)
 {
        uint8_t type = XCB_EVENT_RESPONSE_TYPE(evt);
+
+       DNPRINTF(SWM_D_EVENT, "XCB Event: %s(%d)\n",
+           xcb_event_get_label(XCB_EVENT_RESPONSE_TYPE(evt)),
+           XCB_EVENT_RESPONSE_TYPE(evt));
+
        switch (type) {
 #define EVENT(type, callback) case type: callback((void *)evt); return
        EVENT(0, event_error);
@@ -7606,7 +7730,7 @@ event_handle(xcb_generic_event_t *evt)
        /*EVENT(XCB_SELECTION_NOTIFY, );*/
        /*EVENT(XCB_SELECTION_REQUEST, );*/
        EVENT(XCB_UNMAP_NOTIFY, unmapnotify);
-       EVENT(XCB_VISIBILITY_NOTIFY, visibilitynotify);
+       /*EVENT(XCB_VISIBILITY_NOTIFY, visibilitynotify);*/
 #undef EVENT
        }
        if (type - xrandr_eventbase == XCB_RANDR_SCREEN_CHANGE_NOTIFY)
@@ -7624,25 +7748,19 @@ main(int argc, char *argv[])
        int                     xfd, i, num_screens;
        struct sigaction        sact;
        xcb_generic_event_t     *evt;
-#if 0
        struct timeval          tv;
        fd_set                  rd;
-#endif
+
+       /* suppress unused warning since var is needed */
+       (void)argc;
 
        time_started = time(NULL);
 
        start_argv = argv;
        warnx("Welcome to spectrwm V%s Build: %s", SPECTRWM_VERSION, buildstr);
-       if (!setlocale(LC_CTYPE, "") || !setlocale(LC_TIME, "") ||
-           !XSupportsLocale())
+       if (!setlocale(LC_CTYPE, "") || !setlocale(LC_TIME, ""))
                warnx("no locale support");
 
-       if (!X_HAVE_UTF8_STRING)
-               warnx("no UTF-8 support");
-
-       if (!(display = XOpenDisplay(0)))
-               errx(1, "can not open display");
-
        /* handle some signals */
        bzero(&sact, sizeof(sact));
        sigemptyset(&sact.sa_mask);
@@ -7657,24 +7775,17 @@ main(int argc, char *argv[])
        sact.sa_flags = SA_NOCLDSTOP;
        sigaction(SIGCHLD, &sact, NULL);
 
+       if (!(display = XOpenDisplay(0)))
+               errx(1, "can not open display");
+
        conn = XGetXCBConnection(display);
        if (xcb_connection_has_error(conn))
                errx(1, "can not get XCB connection");
 
-       xfd = xcb_get_file_descriptor(conn);
-       syms = xcb_key_symbols_alloc(conn);
-       if (!syms)
-               errx(1, "unable to allocate key symbols");
+       XSetEventQueueOwner(display, XCBOwnsEventQueue);
 
-       astate = get_atom_from_string("WM_STATE");
-       aprot = get_atom_from_string("WM_PROTOCOLS");
-       adelete = get_atom_from_string("WM_DELETE_WINDOW");
-       takefocus = get_atom_from_string("WM_TAKE_FOCUS");
-       a_wmname = get_atom_from_string("WM_NAME");
-       a_netwmname = get_atom_from_string("_NET_WM_NAME");
-       a_utf8_string = get_atom_from_string("UTF8_STRING");
-       a_string = get_atom_from_string("STRING");
-       a_swm_iconic = get_atom_from_string("_SWM_ICONIC");
+       xcb_prefetch_extension_data(conn, &xcb_randr_id);
+       xfd = xcb_get_file_descriptor(conn);
 
        /* look for local and global conf file */
        pwd = getpwuid(getuid());
@@ -7686,14 +7797,13 @@ main(int argc, char *argv[])
 
        /* flush all events */
        while ((evt = xcb_poll_for_event(conn))) {
-               uint8_t type = XCB_EVENT_RESPONSE_TYPE(evt);
-               if (type == 0)
+               if (XCB_EVENT_RESPONSE_TYPE(evt) == 0)
                        event_handle(evt);
                free(evt);
        }
 
-       if (active_wm())
-               errx(1, "other wm running");
+       if (enable_wm() != 0)
+               errx(1, "another window manager is currently running");
 
        xcb_aux_sync(conn);
 
@@ -7771,9 +7881,6 @@ noconfig:
 
        while (running) {
                while ((evt = xcb_poll_for_event(conn))) {
-                       DNPRINTF(SWM_D_EVENT, "XCB Event: %s(%d)\n",
-                           xcb_event_get_label(XCB_EVENT_RESPONSE_TYPE(evt)),
-                           XCB_EVENT_RESPONSE_TYPE(evt));
                        if (running == 0)
                                goto done;
                        event_handle(evt);
@@ -7800,7 +7907,6 @@ noconfig:
                        continue;
                }
 
-#if 0
                FD_ZERO(&rd);
                FD_SET(xfd, &rd);
                tv.tv_sec = 1;
@@ -7808,7 +7914,6 @@ noconfig:
                if (select(xfd + 1, &rd, NULL, NULL, &tv) == -1)
                        if (errno != EINTR)
                                DNPRINTF(SWM_D_MISC, "select failed");
-#endif
                if (restart_wm == 1)
                        restart(NULL, NULL);
                if (search_resp == 1)
@@ -7827,9 +7932,12 @@ done:
        for (i = 0; i < num_screens; ++i)
                if (screens[i].bar_gc != 0)
                        xcb_free_gc(conn, screens[i].bar_gc);
-       XFreeFontSet(display, bar_fs);
 
+       XftFontClose(display, bar_font);
+       XftColorFree(display, DefaultVisual(display, 0),
+           DefaultColormap(display, 0), &bar_font_color);
        xcb_key_symbols_free(syms);
+       xcb_flush(conn);
        xcb_disconnect(conn);
 
        return (0);