X-Git-Url: https://jasonwoof.com/gitweb/?a=blobdiff_plain;f=spectrwm.c;h=ab82ff1bb75ebb8bc20827827d3fdba9062cadb7;hb=f6733e1aa641ae84bb9b76267a7adde30a7f71bc;hp=7420e87bd1f2ad8b597f839a3aaf0258e5f90615;hpb=3f7a3f07f64906e8b2752070fc07a94c9459be05;p=spectrwm.git diff --git a/spectrwm.c b/spectrwm.c index 7420e87..ab82ff1 100644 --- a/spectrwm.c +++ b/spectrwm.c @@ -54,21 +54,7 @@ * DEALINGS IN THE SOFTWARE. */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - +/* kernel includes */ #include #include #include @@ -86,25 +72,41 @@ #include "tree.h" #endif +/* /usr/includes */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include #include -#include -#include -#include -#include -#include -#include -#include -#include +#include #include #include +#include +#include +#include +#include +#include +#include +#include +#include +/* local includes */ +#include "version.h" #ifdef __OSX__ #include #endif -#include "version.h" - #ifdef SPECTRWM_BUILDSTR static const char *buildstr = SPECTRWM_BUILDSTR; #else @@ -122,23 +124,46 @@ static const char *buildstr = SPECTRWM_VERSION; #endif #if defined(__OpenBSD__) -#define xcb_icccm_wm_hints_t xcb_wm_hints_t -#define xcb_icccm_get_wm_hints xcb_get_wm_hints -#define xcb_icccm_get_wm_hints_reply xcb_get_wm_hints_reply +#define XCB_ICCCM_SIZE_HINT_P_MIN_SIZE XCB_SIZE_HINT_P_MIN_SIZE +#define XCB_ICCCM_SIZE_HINT_P_MAX_SIZE XCB_SIZE_HINT_P_MAX_SIZE +#define XCB_ICCCM_SIZE_HINT_P_RESIZE_INC XCB_SIZE_HINT_P_RESIZE_INC #define XCB_ICCCM_WM_HINT_X_URGENCY XCB_WM_HINT_X_URGENCY #define XCB_ICCCM_WM_STATE_ICONIC XCB_WM_STATE_ICONIC #define XCB_ICCCM_WM_STATE_WITHDRAWN XCB_WM_STATE_WITHDRAWN #define XCB_ICCCM_WM_STATE_NORMAL XCB_WM_STATE_NORMAL +#define xcb_icccm_get_text_property_reply_t xcb_get_text_property_reply_t +#define xcb_icccm_get_text_property_reply_wipe xcb_get_text_property_reply_wipe +#define xcb_icccm_get_wm_class xcb_get_wm_class +#define xcb_icccm_get_wm_class_reply xcb_get_wm_class_reply +#define xcb_icccm_get_wm_class_reply_t xcb_get_wm_class_reply_t +#define xcb_icccm_get_wm_class_reply_wipe xcb_get_wm_class_reply_wipe +#define xcb_icccm_get_wm_hints xcb_get_wm_hints +#define xcb_icccm_get_wm_hints_reply xcb_get_wm_hints_reply #define xcb_icccm_get_wm_name xcb_get_wm_name #define xcb_icccm_get_wm_name_reply xcb_get_wm_name_reply +#define xcb_icccm_get_wm_normal_hints xcb_get_wm_normal_hints +#define xcb_icccm_get_wm_normal_hints_reply xcb_get_wm_normal_hints_reply +#define xcb_icccm_get_wm_protocols xcb_get_wm_protocols +#define xcb_icccm_get_wm_protocols_reply xcb_get_wm_protocols_reply +#define xcb_icccm_get_wm_protocols_reply_t xcb_get_wm_protocols_reply_t +#define xcb_icccm_get_wm_protocols_reply_wipe xcb_get_wm_protocols_reply_wipe #define xcb_icccm_get_wm_transient_for xcb_get_wm_transient_for #define xcb_icccm_get_wm_transient_for_reply xcb_get_wm_transient_for_reply +#define xcb_icccm_wm_hints_t xcb_wm_hints_t #endif -/*#define SWM_DEBUG*/ +#define SWM_DEBUG #ifdef SWM_DEBUG -#define DPRINTF(x...) do { if (swm_debug) fprintf(stderr, x); } while (0) -#define DNPRINTF(n,x...) do { if (swm_debug & n) fprintf(stderr, x); } while (0) +#define DPRINTF(x...) do { \ + if (swm_debug) \ + fprintf(stderr, x); \ +} while (0) +#define DNPRINTF(n,x...) do { \ + if (swm_debug & n) { \ + fprintf(stderr, "%ld ", (long)(time(NULL) - time_started)); \ + fprintf(stderr, x); \ + } \ +} while (0) #define SWM_D_MISC 0x0001 #define SWM_D_EVENT 0x0002 #define SWM_D_WS 0x0004 @@ -177,7 +202,7 @@ u_int32_t swm_debug = 0 #define DNPRINTF(n,x...) #endif -#define LENGTH(x) (sizeof x / sizeof x[0]) +#define LENGTH(x) (int)(sizeof x / sizeof x[0]) #define MODKEY Mod1Mask #define CLEANMASK(mask) (mask & ~(numlockmask | LockMask)) #define BUTTONMASK (ButtonPressMask|ButtonReleaseMask) @@ -193,13 +218,13 @@ u_int32_t swm_debug = 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_mask & PMinSize +#define SH_MIN(w) (w)->sh.flags & XCB_ICCCM_SIZE_HINT_P_MIN_SIZE #define SH_MIN_W(w) (w)->sh.min_width #define SH_MIN_H(w) (w)->sh.min_height -#define SH_MAX(w) (w)->sh_mask & PMaxSize +#define SH_MAX(w) (w)->sh.flags & XCB_ICCCM_SIZE_HINT_P_MAX_SIZE #define SH_MAX_W(w) (w)->sh.max_width #define SH_MAX_H(w) (w)->sh.max_height -#define SH_INC(w) (w)->sh_mask & PResizeInc +#define SH_INC(w) (w)->sh.flags & XCB_ICCCM_SIZE_HINT_P_RESIZE_INC #define SH_INC_W(w) (w)->sh.width_inc #define SH_INC_H(w) (w)->sh.height_inc #define SWM_MAX_FONT_STEPS (3) @@ -218,10 +243,10 @@ 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; @@ -230,15 +255,14 @@ xcb_atom_t a_swm_iconic; 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 last_focus_event = FocusOut;*/ 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; int cycle_empty = 0; int cycle_visible = 0; @@ -323,18 +347,15 @@ int spawn_position = SWM_STACK_TOP; int disable_border = 0; int border_width = 1; int verbose_layout = 0; +time_t time_started; pid_t bar_pid; +#if 0 XFontSet bar_fs; XFontSetExtents *bar_fs_extents; +#endif char *bar_fonts; 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; @@ -374,7 +395,7 @@ struct ws_win { int floatmaxed; /* whether maxed by max_stack */ int floating; int manual; - int iconic; + int32_t iconic; int bordered; unsigned int ewmh_flags; int font_size_boundary[SWM_MAX_FONT_STEPS]; @@ -386,18 +407,17 @@ struct ws_win { unsigned long quirks; struct workspace *ws; /* always valid */ struct swm_screen *s; /* always valid, never changes */ - XWindowAttributes wa; - XSizeHints sh; - long sh_mask; - XClassHint ch; - xcb_wm_hints_t hints; + xcb_get_geometry_reply_t *wa; + xcb_size_hints_t sh; + xcb_icccm_get_wm_class_reply_t ch; + xcb_icccm_wm_hints_t hints; }; 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); @@ -413,15 +433,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); @@ -546,9 +557,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; @@ -628,16 +636,43 @@ 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); +char *get_win_name(xcb_window_t); +uint16_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 *); + +/* function definitions */ +int +parse_rgb(const char *rgb, uint16_t *rr, uint16_t *gg, uint16_t *bb) +{ + unsigned int tmpr, tmpg, tmpb; + + if (sscanf(rgb, "rgb:%x/%x/%x", &tmpr, &tmpg, &tmpb) != 3) + return (-1); + + *rr = tmpr << 8; + *gg = tmpg << 8; + *bb = tmpb << 8; + + return (0); +} xcb_screen_t * get_screen(int screen) @@ -672,10 +707,9 @@ map_window_raised(xcb_window_t win) uint32_t val = XCB_STACK_MODE_ABOVE; xcb_configure_window(conn, win, - XCB_CONFIG_WINDOW_STACK_MODE, &val); + XCB_CONFIG_WINDOW_STACK_MODE, &val); xcb_map_window(conn, win); - xcb_flush(conn); } xcb_atom_t @@ -711,34 +745,32 @@ update_iconic(struct ws_win *win, int newv) if (newv) xcb_change_property(conn, XCB_PROP_MODE_REPLACE, win->id, - iprop, XCB_ATOM_INTEGER, 32, 1, &v); + iprop, XCB_ATOM_INTEGER, 32, 1, &v); else xcb_delete_property(conn, win->id, iprop); } -int +int32_t get_iconic(struct ws_win *win) { - int32_t v = 0, *vtmp; + int32_t v = 0; xcb_atom_t iprop; - xcb_get_property_cookie_t pc; xcb_get_property_reply_t *pr = NULL; iprop = get_atom_from_string("_SWM_ICONIC"); if (iprop == XCB_ATOM_NONE) goto out; - pc = xcb_get_property(conn, False, win->id, iprop, XCB_ATOM_INTEGER, - 0, 1); - pr = xcb_get_property_reply(conn, pc, NULL); + pr = xcb_get_property_reply(conn, + xcb_get_property(conn, False, win->id, iprop, XCB_ATOM_INTEGER, + 0, 1), NULL); if (!pr) goto out; if (pr->type != XCB_ATOM_INTEGER || pr->format != 32) goto out; - vtmp = xcb_get_property_value(pr); - v = *vtmp; + v = *((int32_t *)xcb_get_property_value(pr)); out: - if (pr != NULL) + if (pr) free(pr); return (v); } @@ -762,8 +794,8 @@ setup_ewmh(void) xcb_delete_property(conn, screens[i].root, sup_list); for (j = 0; j < LENGTH(ewmh); j++) xcb_change_property(conn, XCB_PROP_MODE_APPEND, - screens[i].root, sup_list, XCB_ATOM_ATOM, 32, 1, - &ewmh[j].atom); + screens[i].root, sup_list, XCB_ATOM_ATOM, 32, 1, + &ewmh[j].atom); } } @@ -783,7 +815,7 @@ 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, - XCB_ATOM_WINDOW, 0, 1); + XCB_ATOM_WINDOW, 0, 1); pr = xcb_get_property_reply(conn, pc, NULL); if (pr) { id = *((xcb_window_t *)xcb_get_property_value(pr)); @@ -800,33 +832,32 @@ teardown_ewmh(void) 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)); + 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; @@ -890,8 +921,7 @@ ewmh_update_actions(struct ws_win *win) } xcb_change_property(conn, XCB_PROP_MODE_REPLACE, win->id, - ewmh[_NET_WM_ALLOWED_ACTIONS].atom, XCB_ATOM_ATOM, 32, 1, - actions); + ewmh[_NET_WM_ALLOWED_ACTIONS].atom, XCB_ATOM_ATOM, 32, 1, actions); } #define _NET_WM_STATE_REMOVE 0 /* remove/unset property */ @@ -953,24 +983,24 @@ ewmh_update_win_state(struct ws_win *win, long state, long action) if (win->ewmh_flags & EWMH_F_FULLSCREEN) xcb_change_property(conn, XCB_PROP_MODE_APPEND, win->id, - ewmh[_NET_WM_STATE].atom, XCB_ATOM_ATOM, 32, 1, - &ewmh[_NET_WM_STATE_FULLSCREEN].atom); + ewmh[_NET_WM_STATE].atom, XCB_ATOM_ATOM, 32, 1, + &ewmh[_NET_WM_STATE_FULLSCREEN].atom); if (win->ewmh_flags & EWMH_F_SKIP_PAGER) xcb_change_property(conn, XCB_PROP_MODE_APPEND, win->id, - ewmh[_NET_WM_STATE].atom, XCB_ATOM_ATOM, 32, 1, - &ewmh[_NET_WM_STATE_SKIP_PAGER].atom); + ewmh[_NET_WM_STATE].atom, XCB_ATOM_ATOM, 32, 1, + &ewmh[_NET_WM_STATE_SKIP_PAGER].atom); if (win->ewmh_flags & EWMH_F_SKIP_TASKBAR) xcb_change_property(conn, XCB_PROP_MODE_APPEND, win->id, - ewmh[_NET_WM_STATE].atom, XCB_ATOM_ATOM, 32, 1, - &ewmh[_NET_WM_STATE_SKIP_TASKBAR].atom); + ewmh[_NET_WM_STATE].atom, XCB_ATOM_ATOM, 32, 1, + &ewmh[_NET_WM_STATE_SKIP_TASKBAR].atom); if (win->ewmh_flags & EWMH_F_ABOVE) xcb_change_property(conn, XCB_PROP_MODE_APPEND, win->id, - ewmh[_NET_WM_STATE].atom, XCB_ATOM_ATOM, 32, 1, - &ewmh[_NET_WM_STATE_ABOVE].atom); + ewmh[_NET_WM_STATE].atom, XCB_ATOM_ATOM, 32, 1, + &ewmh[_NET_WM_STATE_ABOVE].atom); if (win->ewmh_flags & SWM_F_MANUAL) xcb_change_property(conn, XCB_PROP_MODE_APPEND, win->id, - ewmh[_NET_WM_STATE].atom, XCB_ATOM_ATOM, 32, 1, - &ewmh[_SWM_WM_STATE_MANUAL].atom); + ewmh[_NET_WM_STATE].atom, XCB_ATOM_ATOM, 32, 1, + &ewmh[_SWM_WM_STATE_MANUAL].atom); } void @@ -991,7 +1021,7 @@ ewmh_get_win_state(struct ws_win *win) win->ewmh_flags |= SWM_F_MANUAL; c = xcb_get_property(conn, False, win->id, ewmh[_NET_WM_STATE].atom, - XCB_ATOM_ATOM, 0, (~0L)); + XCB_ATOM_ATOM, 0, UINT32_MAX); r = xcb_get_property_reply(conn, c, NULL); if (!r) return; @@ -999,142 +1029,14 @@ ewmh_get_win_state(struct ws_win *win) states = xcb_get_property_value(r); n = xcb_get_property_value_length(r); - free(r); - for (i = 0; i < n; i++) ewmh_update_win_state(win, states[i], _NET_WM_STATE_ADD); + + free(r); } /* events */ #ifdef SWM_DEBUG -char * -geteventname(XEvent *e) -{ - char *name = NULL; - - switch (e->type) { - case KeyPress: - name = "KeyPress"; - break; - case KeyRelease: - name = "KeyRelease"; - break; - case ButtonPress: - name = "ButtonPress"; - break; - case ButtonRelease: - name = "ButtonRelease"; - break; - case MotionNotify: - name = "MotionNotify"; - break; - case EnterNotify: - name = "EnterNotify"; - break; - case LeaveNotify: - name = "LeaveNotify"; - break; - case FocusIn: - name = "FocusIn"; - break; - case FocusOut: - name = "FocusOut"; - break; - case KeymapNotify: - name = "KeymapNotify"; - break; - case Expose: - name = "Expose"; - break; - case GraphicsExpose: - name = "GraphicsExpose"; - break; - case NoExpose: - name = "NoExpose"; - break; - case VisibilityNotify: - name = "VisibilityNotify"; - break; - case CreateNotify: - name = "CreateNotify"; - break; - case DestroyNotify: - name = "DestroyNotify"; - break; - case UnmapNotify: - name = "UnmapNotify"; - break; - case MapNotify: - name = "MapNotify"; - break; - case MapRequest: - name = "MapRequest"; - break; - case ReparentNotify: - name = "ReparentNotify"; - break; - case ConfigureNotify: - name = "ConfigureNotify"; - break; - case ConfigureRequest: - name = "ConfigureRequest"; - break; - case GravityNotify: - name = "GravityNotify"; - break; - case ResizeRequest: - name = "ResizeRequest"; - break; - case CirculateNotify: - name = "CirculateNotify"; - break; - case CirculateRequest: - name = "CirculateRequest"; - break; - case PropertyNotify: - name = "PropertyNotify"; - break; - case SelectionClear: - name = "SelectionClear"; - break; - case SelectionRequest: - name = "SelectionRequest"; - break; - case SelectionNotify: - name = "SelectionNotify"; - break; - case ColormapNotify: - name = "ColormapNotify"; - break; - case ClientMessage: - name = "ClientMessage"; - break; - case MappingNotify: - name = "MappingNotify"; - break; - default: - name = "Unknown"; - } - - return (name); -} - -char * -xrandr_geteventname(XEvent *e) -{ - char *name = NULL; - - switch(e->type - xrandr_eventbase) { - case RRScreenChangeNotify: - name = "RRScreenChangeNotify"; - break; - default: - name = "Unknown"; - } - - return (name); -} - void dumpwins(struct swm_region *r, union arg *args) { @@ -1155,8 +1057,8 @@ dumpwins(struct swm_region *r, union arg *args) wa = xcb_get_window_attributes_reply(conn, c, NULL); if (wa) { warnx("window: 0x%x, map_state: %d, state: %u, " - "transient: 0x%x", win->id, wa->map_state, - state, win->transient); + "transient: 0x%x", win->id, wa->map_state, + state, win->transient); free(wa); } else warnx("window: 0x%x, failed xcb_get_window_attributes", @@ -1170,8 +1072,8 @@ dumpwins(struct swm_region *r, union arg *args) wa = xcb_get_window_attributes_reply(conn, c, NULL); if (wa) { warnx("window: 0x%x, map_state: %d, state: %u, " - "transient: 0x%x", win->id, wa->map_state, - state, win->transient); + "transient: 0x%x", win->id, wa->map_state, + state, win->transient); free(wa); } else warnx("window: 0x%x, failed xcb_get_window_attributes", @@ -1187,40 +1089,22 @@ dumpwins(struct swm_region *r, union arg *args) } #endif /* SWM_DEBUG */ -void expose(XEvent *); -void keypress(XEvent *); -void buttonpress(XEvent *); -void configurerequest(XEvent *); -void configurenotify(XEvent *); -void destroynotify(XEvent *); -void enternotify(XEvent *); -void focusevent(XEvent *); -void mapnotify(XEvent *); -void mappingnotify(XEvent *); -void maprequest(XEvent *); -void propertynotify(XEvent *); -void unmapnotify(XEvent *); -void visibilitynotify(XEvent *); -void clientmessage(XEvent *); - -void (*handler[LASTEvent])(XEvent *) = { - [Expose] = expose, - [KeyPress] = keypress, - [ButtonPress] = buttonpress, - [ConfigureRequest] = configurerequest, - [ConfigureNotify] = configurenotify, - [DestroyNotify] = destroynotify, - [EnterNotify] = enternotify, - [FocusIn] = focusevent, - [FocusOut] = focusevent, - [MapNotify] = mapnotify, - [MappingNotify] = mappingnotify, - [MapRequest] = maprequest, - [PropertyNotify] = propertynotify, - [UnmapNotify] = unmapnotify, - [VisibilityNotify] = visibilitynotify, - [ClientMessage] = clientmessage, -}; +void event_error(xcb_generic_error_t *); +void expose(xcb_expose_event_t *); +void keypress(xcb_key_press_event_t *); +void buttonpress(xcb_button_press_event_t *); +void configurerequest(xcb_configure_request_event_t *); +void configurenotify(xcb_configure_notify_event_t *); +void destroynotify(xcb_destroy_notify_event_t *); +void enternotify(xcb_enter_notify_event_t *); +void mapnotify(xcb_map_notify_event_t *); +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 clientmessage(xcb_client_message_event_t *); +void screenchange(xcb_randr_screen_change_notify_event_t *); void sighdlr(int sig) @@ -1271,11 +1155,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); @@ -1295,28 +1179,43 @@ name_to_color(const char *colorname) char cname[32] = "#"; xcb_screen_t *screen; xcb_colormap_t cmap; - xcb_alloc_named_color_cookie_t c; - xcb_alloc_named_color_reply_t *r; + xcb_alloc_color_reply_t *cr; + xcb_alloc_named_color_reply_t *nr; + uint16_t rr, gg, bb; - /* XXX - does not support rgb:/RR/GG/BB - * will need to use xcb_alloc_color - */ screen = xcb_setup_roots_iterator(xcb_get_setup(conn)).data; cmap = screen->default_colormap; - c = xcb_alloc_named_color(conn, cmap, strlen(colorname), colorname); - r = xcb_alloc_named_color_reply(conn, c, NULL); - if (!r) { - strlcat(cname, colorname + 2, sizeof cname - 1); - c = xcb_alloc_named_color(conn, cmap, strlen(cname), - cname); - r = xcb_alloc_named_color_reply(conn, c, NULL); + /* color is in format rgb://rr/gg/bb */ + if (strncmp(colorname, "rgb:", 4) == 0) { + if (parse_rgb(colorname, &rr, &gg, &bb) == -1) + warnx("could not parse rgb %s", colorname); + else { + cr = xcb_alloc_color_reply(conn, + xcb_alloc_color(conn, cmap, rr, gg, bb), + NULL); + if (cr) { + result = cr->pixel; + free(cr); + } else + warnx("color '%s' not found", colorname); + } + } else { + nr = xcb_alloc_named_color_reply(conn, + xcb_alloc_named_color(conn, cmap, strlen(colorname), + colorname), NULL); + if (!nr) { + strlcat(cname, colorname + 2, sizeof cname - 1); + nr = xcb_alloc_named_color_reply(conn, + xcb_alloc_named_color(conn, cmap, strlen(cname), + cname), NULL); + } + if (nr) { + result = nr->pixel; + free(nr); + } else + warnx("color '%s' not found", colorname); } - if (r) { - result = r->pixel; - free(r); - } else - warnx("color '%s' not found", colorname); return (result); } @@ -1373,12 +1272,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[]:x++"); if (sidx < 1 || sidx > num_screens) @@ -1425,6 +1324,8 @@ bar_print(struct swm_region *r, const char *s) XRectangle ibox, lbox; len = strlen(s); + /* FIXME fix bar font position calculations */ +#if 0 XmbTextExtents(bar_fs, s, len, &ibox, &lbox); switch (bar_justify) { @@ -1441,6 +1342,7 @@ bar_print(struct swm_region *r, const char *s) if (x < SWM_BAR_OFFSET) x = SWM_BAR_OFFSET; +#endif rect.x = 0; rect.y = 0; @@ -1451,18 +1353,25 @@ bar_print(struct swm_region *r, const char *s) gcv[0] = r->s->c[SWM_S_COLOR_BAR].color; 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); + sizeof(rect), &rect); /* draw back buffer */ + gcv[0] = r->s->c[SWM_S_COLOR_BAR].color; + xcb_change_gc(conn, r->s->bar_gc, XCB_GC_BACKGROUND, gcv); gcv[0] = r->s->c[SWM_S_COLOR_BAR_FONT].color; xcb_change_gc(conn, r->s->bar_gc, XCB_GC_FOREGROUND, gcv); +#if 0 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); + (bar_fs_extents->max_logical_extent.height - lbox.height) / 2 - + lbox.y, s); +#else + /* workaround */ + xcb_image_text_8(conn, len, r->bar->buffer, r->s->bar_gc, 4, 14, s); +#endif /* blt */ xcb_copy_area(conn, r->bar->buffer, r->bar->id, r->s->bar_gc, 0, 0, - 0, 0, WIDTH(r->bar), HEIGHT(r->bar)); + 0, 0, WIDTH(r->bar), HEIGHT(r->bar)); } void @@ -1485,8 +1394,8 @@ bar_class_name(char *s, size_t sz, struct swm_region *r) { if (r == NULL || r->ws == NULL || r->ws->focus == NULL) return; - if (r->ws->focus->ch.res_class != NULL) - strlcat(s, r->ws->focus->ch.res_class, sz); + if (r->ws->focus->ch.class_name != NULL) + strlcat(s, r->ws->focus->ch.class_name, sz); } void @@ -1494,8 +1403,8 @@ bar_title_name(char *s, size_t sz, struct swm_region *r) { if (r == NULL || r->ws == NULL || r->ws->focus == NULL) return; - if (r->ws->focus->ch.res_name != NULL) - strlcat(s, r->ws->focus->ch.res_name, sz); + if (r->ws->focus->ch.instance_name != NULL) + strlcat(s, r->ws->focus->ch.instance_name, sz); } void @@ -1551,7 +1460,7 @@ bar_urgent(char *s, size_t sz) TAILQ_FOREACH(win, &screens[i].ws[j].winlist, entry) { c = xcb_icccm_get_wm_hints(conn, win->id); if (xcb_icccm_get_wm_hints_reply(conn, c, - &hints, NULL) == 0) + &hints, NULL) == 0) continue; if (hints.flags & XCB_ICCCM_WM_HINT_X_URGENCY) urgent[j] = 1; @@ -1864,6 +1773,8 @@ bar_toggle(struct swm_region *r, union arg *args) stack(); /* must be after stack */ bar_update(); + + xcb_flush(conn); } void @@ -1910,7 +1821,7 @@ bar_refresh(void) wa[0] = screens[i].c[SWM_S_COLOR_BAR].color; wa[1] = screens[i].c[SWM_S_COLOR_BAR_BORDER].color; xcb_change_window_attributes(conn, r->bar->id, - XCB_CW_BACK_PIXEL | XCB_CW_BORDER_PIXEL, wa); + XCB_CW_BACK_PIXEL | XCB_CW_BORDER_PIXEL, wa); } bar_update(); } @@ -1923,20 +1834,22 @@ bar_setup(struct swm_region *r) int num_missing_charsets = 0; int i; xcb_screen_t *screen = get_screen(r->s->idx); - uint32_t wa[2]; - + uint32_t wa[3]; + +#if 0 if (bar_fs) { XFreeFontSet(display, bar_fs); bar_fs = NULL; } +#endif if ((r->bar = calloc(1, sizeof(struct swm_bar))) == NULL) err(1, "bar_setup: calloc: failed to allocate memory."); - +#if 0 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); + &num_missing_charsets, &default_string);*/ if (num_missing_charsets > 0) { warnx("Unable to load charset(s):"); @@ -1963,7 +1876,10 @@ bar_setup(struct swm_region *r) if (bar_height < 1) bar_height = 1; - +#else + /* workaround */ + bar_height = 24; +#endif 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; @@ -1972,18 +1888,21 @@ bar_setup(struct swm_region *r) 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; - xcb_create_window(conn, screen->root_depth, 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, - screen->root_visual, XCB_CW_BACK_PIXEL | XCB_CW_BORDER_PIXEL, - wa); + wa[2] = XCB_EVENT_MASK_EXPOSURE; + DNPRINTF(SWM_D_BAR, "bar_setup: create_window: (x,y) w x h: (%d,%d) " + "%d x %d\n", X(r->bar), Y(r->bar), WIDTH(r->bar), HEIGHT(r->bar)); + 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, + XCB_COPY_FROM_PARENT, XCB_CW_BACK_PIXEL | XCB_CW_BORDER_PIXEL + | XCB_CW_EVENT_MASK, wa); r->bar->buffer = xcb_generate_id(conn); xcb_create_pixmap(conn, screen->root_depth, r->bar->buffer, r->bar->id, - WIDTH(r->bar), HEIGHT(r->bar)); + WIDTH(r->bar), HEIGHT(r->bar)); xcb_randr_select_input(conn, r->bar->id, - XCB_RANDR_NOTIFY_MASK_OUTPUT_CHANGE); + XCB_RANDR_NOTIFY_MASK_OUTPUT_CHANGE); if (bar_enabled) map_window_raised(r->bar->id); @@ -2009,17 +1928,6 @@ bar_cleanup(struct swm_region *r) } void -drain_enter_notify(void) -{ - int i = 0; - - while (xcb_poll_for_event(conn)) - i++; - - DNPRINTF(SWM_D_EVENT, "drain_enter_notify: drained: %d\n", i); -} - -void set_win_state(struct ws_win *win, uint16_t state) { uint16_t data[2] = { state, XCB_ATOM_NONE }; @@ -2029,8 +1937,8 @@ 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 @@ -2040,7 +1948,7 @@ getstate(xcb_window_t w) 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, False, w, a_state, a_state, 0L, 2L); r = xcb_get_property_reply(conn, c, NULL); if (r) { @@ -2048,6 +1956,8 @@ getstate(xcb_window_t w) free(r); } + DNPRINTF(SWM_D_MISC, "getstate property: win 0x%x state %u\n", w, + result); return (result); } @@ -2061,6 +1971,8 @@ version(struct swm_region *r, union arg *args) else strlcpy(bar_vertext, "", sizeof bar_vertext); bar_update(); + + xcb_flush(conn); } void @@ -2074,19 +1986,18 @@ 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_EVENT_MASK_NO_EVENT, (const char *)&ev); - xcb_flush(conn); + XCB_EVENT_MASK_NO_EVENT, (const char *)&ev); } /* synthetic response to a ConfigureRequest when not making a change */ void -config_win(struct ws_win *win, XConfigureRequestEvent *ev) +config_win(struct ws_win *win, xcb_configure_request_event_t *ev) { xcb_configure_notify_event_t ce; @@ -2114,10 +2025,10 @@ config_win(struct ws_win *win, XConfigureRequestEvent *ev) ce.window = ev->window; /* make response appear more WM_SIZE_HINTS-compliant */ - if (win->sh_mask) + if (win->sh.flags) DNPRINTF(SWM_D_MISC, "config_win: hints: window: 0x%x," - " sh_mask: %ld, min: %d x %d, max: %d x %d, inc: " - "%d x %d\n", win->id, win->sh_mask, SH_MIN_W(win), + " sh.flags: %u, min: %d x %d, max: %d x %d, inc: " + "%d x %d\n", win->id, win->sh.flags, SH_MIN_W(win), SH_MIN_H(win), SH_MAX_W(win), SH_MAX_H(win), SH_INC_W(win), SH_INC_H(win)); @@ -2153,7 +2064,7 @@ config_win(struct ws_win *win, XConfigureRequestEvent *ev) ce.x += BORDER(win) - ev->border_width; ce.y += BORDER(win) - ev->border_width; ce.border_width = ev->border_width; - ce.above_sibling = ev->above; + ce.above_sibling = ev->sibling; } DNPRINTF(SWM_D_MISC, "config_win: ewmh: %s, window: 0x%x, (x,y) w x h: " @@ -2162,7 +2073,6 @@ config_win(struct ws_win *win, XConfigureRequestEvent *ev) xcb_send_event(conn, False, win->id, XCB_EVENT_MASK_STRUCTURE_NOTIFY, (char *)&ce); - xcb_flush(conn); } int @@ -2206,7 +2116,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].color); } void @@ -2226,15 +2136,17 @@ void fake_keypress(struct ws_win *win, xcb_keysym_t keysym, uint16_t modifiers) { xcb_key_press_event_t event; - xcb_key_symbols_t *syms; xcb_keycode_t *keycode; if (win == NULL) return; - syms = xcb_key_symbols_alloc(conn); keycode = xcb_key_symbols_get_keycode(syms, keysym); + DNPRINTF(SWM_D_MISC, "fake_keypress: win 0x%x keycode %u\n", + win->id, *keycode); + + bzero(&event, sizeof(event)); event.event = win->id; event.root = win->s->root; event.child = XCB_WINDOW_NONE; @@ -2249,14 +2161,11 @@ fake_keypress(struct ws_win *win, xcb_keysym_t keysym, uint16_t modifiers) event.response_type = XCB_KEY_PRESS; xcb_send_event(conn, True, win->id, - XCB_EVENT_MASK_KEY_PRESS, (char *)&event); + 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_flush(conn); - - xcb_key_symbols_free(syms); + XCB_EVENT_MASK_KEY_RELEASE, (const char *)&event); } void @@ -2272,7 +2181,11 @@ restart(struct swm_region *r, union arg *args) bar_extra_stop(); bar_extra = 1; unmap_all(); - XCloseDisplay(display); + + xcb_key_symbols_free(syms); + xcb_flush(conn); + xcb_disconnect(conn); + execvp(start_argv[0], start_argv); warn("execvp failed"); quit(NULL, NULL); @@ -2281,8 +2194,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); @@ -2293,7 +2206,7 @@ root_to_region(xcb_window_t root) break; qpr = xcb_query_pointer_reply(conn, xcb_query_pointer(conn, - screens[i].root), NULL); + screens[i].root), NULL); if (qpr) { DNPRINTF(SWM_D_MISC, "root_to_region: pointer: (%d,%d)\n", @@ -2333,7 +2246,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)); @@ -2343,8 +2255,7 @@ 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); @@ -2373,8 +2284,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); @@ -2488,7 +2398,6 @@ validate_ws(struct workspace *testws) void unfocus_win(struct ws_win *win) { - XEvent cne; xcb_window_t none = XCB_WINDOW_NONE; DNPRINTF(SWM_D_FOCUS, "unfocus_win: window: 0x%x\n", WINID(win)); @@ -2523,16 +2432,11 @@ unfocus_win(struct ws_win *win) win->ws->focus_prev = NULL; } - /* drain all previous unfocus events */ - while (XCheckTypedEvent(display, FocusOut, &cne) == True) - ; - 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].color); xcb_change_property(conn, XCB_PROP_MODE_REPLACE, win->s->root, - ewmh[_NET_ACTIVE_WINDOW].atom, XCB_ATOM_WINDOW, 32, 1, - &none); + ewmh[_NET_ACTIVE_WINDOW].atom, XCB_ATOM_WINDOW, 32, 1, &none); } void @@ -2553,9 +2457,7 @@ unfocus_all(void) void focus_win(struct ws_win *win) { - XEvent cne; 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; @@ -2579,8 +2481,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); @@ -2589,23 +2490,19 @@ focus_win(struct ws_win *win) unfocus_win(cfw); else { /* 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); + XCB_CW_BORDER_PIXEL, + &cfw->ws->r->s->c[SWM_S_COLOR_UNFOCUS].color);*/ } win->ws->focus = win; if (win->ws->r != NULL) { - /* drain all previous focus events */ - while (XCheckTypedEvent(display, FocusIn, &cne) == True) - ; - if (win->java == 0) xcb_set_input_focus(conn, XCB_INPUT_FOCUS_PARENT, - win->id, XCB_CURRENT_TIME); + win->id, XCB_CURRENT_TIME); grabbuttons(win, 1); xcb_change_window_attributes(conn, win->id, XCB_CW_BORDER_PIXEL, @@ -2615,14 +2512,28 @@ focus_win(struct ws_win *win) map_window_raised(win->id); xcb_change_property(conn, XCB_PROP_MODE_REPLACE, win->s->root, - ewmh[_NET_ACTIVE_WINDOW].atom, XCB_ATOM_WINDOW, 32, 1, - &win->id); + ewmh[_NET_ACTIVE_WINDOW].atom, XCB_ATOM_WINDOW, 32, 1, + &win->id); } 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) { int wsid = args->id, unmap_old = 0; @@ -2677,7 +2588,9 @@ switchws(struct swm_region *r, union arg *args) unmap_window(win); if (focus_mode == SWM_FOCUS_DEFAULT) - drain_enter_notify(); + event_drain(XCB_ENTER_NOTIFY); + else + xcb_flush(conn); } void @@ -2774,7 +2687,7 @@ cyclescr(struct swm_region *r, union arg *args) x = X(rr) + 1; y = Y(rr) + 1 + (bar_enabled ? bar_height : 0); xcb_warp_pointer(conn, XCB_WINDOW_NONE, rr->s[i].root, 0, 0, 0, 0, - x, y); + x, y); a.id = SWM_ARG_ID_FOCUSCUR; focus(rr, &a); @@ -2784,7 +2697,7 @@ cyclescr(struct swm_region *r, union arg *args) x = X(rr->ws->focus) + 1; y = Y(rr->ws->focus) + 1; xcb_warp_pointer(conn, XCB_WINDOW_NONE, rr->s[i].root, 0, 0, 0, - 0, x, y); + 0, x, y); } } @@ -2882,6 +2795,8 @@ swapwin(struct swm_region *r, union arg *args) sort_windows(wl); stack(); + + xcb_flush(conn); } void @@ -3070,6 +2985,8 @@ focus(struct swm_region *r, union arg *args) } focus_magic(winfocus); + + xcb_flush(conn); } void @@ -3085,8 +3002,11 @@ cycle_layout(struct swm_region *r, union arg *args) ws->cur_layout = &layouts[0]; stack(); + bar_update(); + if (focus_mode == SWM_FOCUS_DEFAULT) - drain_enter_notify(); + event_drain(XCB_ENTER_NOTIFY); + a.id = SWM_ARG_ID_FOCUSCUR; focus(r, &a); } @@ -3146,7 +3066,7 @@ stack(void) { font_adjusted--; if (focus_mode == SWM_FOCUS_DEFAULT) - drain_enter_notify(); + event_drain(XCB_ENTER_NOTIFY); DNPRINTF(SWM_D_STACK, "stack: end\n"); } @@ -3272,7 +3192,6 @@ adjust_font(struct ws_win *win) void stack_master(struct workspace *ws, struct swm_geometry *g, int rot, int flip) { - XWindowAttributes wa; struct swm_geometry win_g, r_g = *g; struct ws_win *win, *fs_win = NULL; int i, j, s, stacks; @@ -3281,6 +3200,7 @@ stack_master(struct workspace *ws, struct swm_geometry *g, int rot, int flip) int split, colno, winno, mwin, msize, mscale; int remain, missing, v_slice, reconfigure; int bordered = 1; + xcb_get_window_attributes_reply_t *war; DNPRINTF(SWM_D_STACK, "stack_master: workspace: %d, rot: %s, " "flip: %s\n", ws->idx, YESNO(rot), YESNO(flip)); @@ -3443,9 +3363,14 @@ stack_master(struct workspace *ws, struct swm_geometry *g, int rot, int flip) update_window(win); } - if (XGetWindowAttributes(display, win->id, &wa)) - if (wa.map_state == IsUnmapped) + war = xcb_get_window_attributes_reply(conn, + xcb_get_window_attributes(conn, win->id), + NULL); + if (war) { + if (war->map_state == XCB_MAP_STATE_UNMAPPED) map_window_raised(win->id); + free(war); + } last_h = win_g.h; i++; @@ -3691,19 +3616,23 @@ send_to_ws(struct swm_region *r, union arg *args) 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), - ws_idx_str); + ws_idx_atom, 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) { - XTestFakeButtonEvent(display, args->id, True, CurrentTime); - XTestFakeButtonEvent(display, args->id, False, CurrentTime); + 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, + XCB_CURRENT_TIME, XCB_WINDOW_NONE, 0, 0, 0); } void @@ -3717,6 +3646,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 @@ -3729,11 +3660,12 @@ iconify(struct swm_region *r, union arg *args) unmap_window(r->ws->focus); update_iconic(r->ws->focus, 1); stack(); - if (focus_mode == SWM_FOCUS_DEFAULT) - drain_enter_notify(); + r->ws->focus = NULL; a.id = SWM_ARG_ID_FOCUSCUR; focus(r, &a); + + xcb_flush(conn); } char * @@ -3741,21 +3673,22 @@ get_win_name(xcb_window_t win) { char *name = NULL; xcb_get_property_cookie_t c; - xcb_get_text_property_reply_t r; + xcb_icccm_get_text_property_reply_t r; c = xcb_icccm_get_wm_name(conn, win); if (xcb_icccm_get_wm_name_reply(conn, c, &r, NULL)) { - name = malloc(r.name_len + 1); - if (!name) { - xcb_get_text_property_reply_wipe(&r); - return (NULL); + if (r.name_len > 0) { + name = malloc(r.name_len + 1); + if (!name) { + xcb_icccm_get_text_property_reply_wipe(&r); + return (NULL); + } + 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); } - xcb_get_text_property_reply_wipe(&r); - return (name); } @@ -3805,6 +3738,8 @@ uniconify(struct swm_region *r, union arg *args) } fclose(lfile); + + xcb_flush(conn); } void @@ -3879,13 +3814,13 @@ search_win(struct swm_region *r, union arg *args) struct ws_win *win = NULL; struct search_window *sw = NULL; xcb_window_t w; - uint32_t gcv[1], wa[2]; + uint32_t gcv[3], wa[2]; int i; char s[8]; FILE *lfile; size_t len; XRectangle ibox, lbox; - xcb_screen_t *screen; + DNPRINTF(SWM_D_MISC, "search_win\n"); search_r = r; @@ -3912,39 +3847,60 @@ search_win(struct swm_region *r, union arg *args) } sw->idx = i; sw->win = win; - screen = get_screen(sw->idx); snprintf(s, sizeof s, "%d", i); len = strlen(s); + /* FIXME fix calculations */ +#if 0 XmbTextExtents(bar_fs, s, len, &ibox, &lbox); +#endif 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; - xcb_create_window(conn, screen->root_depth, w, win->id, - 0, 0, lbox.width + 4, - bar_fs_extents->max_logical_extent.height, 1, - XCB_WINDOW_CLASS_INPUT_OUTPUT, screen->root_visual, - XCB_CW_BACK_PIXEL | XCB_CW_BORDER_PIXEL, wa); - +#if 0 + xcb_create_window(conn, XCB_COPY_FROM_PARENT, w, win->id, 0, 0, + lbox.width + 4, bar_fs_extents->max_logical_extent.height, + 1, XCB_WINDOW_CLASS_INPUT_OUTPUT, XCB_COPY_FROM_PARENT, + XCB_CW_BACK_PIXEL | XCB_CW_BORDER_PIXEL, wa); +#else + /* workaround */ + xcb_create_window(conn, XCB_COPY_FROM_PARENT, w, win->id, 0, 0, + 22, 20, 1, XCB_WINDOW_CLASS_INPUT_OUTPUT, + XCB_COPY_FROM_PARENT, XCB_CW_BACK_PIXEL | + XCB_CW_BORDER_PIXEL, wa); +#endif + sw->indicator = w; TAILQ_INSERT_TAIL(&search_wl, sw, entry); sw->gc = xcb_generate_id(conn); - gcv[0] = r->s->c[SWM_S_COLOR_BAR].color; - xcb_create_gc(conn, sw->gc, w, XCB_GC_FOREGROUND, gcv); + gcv[0] = r->s->c[SWM_S_COLOR_BAR].color; + gcv[1] = r->s->c[SWM_S_COLOR_FOCUS].color; + 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); +#if 0 xcb_image_text_8(conn, len, w, sw->gc, 2, (bar_fs_extents->max_logical_extent.height - lbox.height) / 2 - lbox.y, s); +#else + /* workaround */ + xcb_image_text_8(conn, len, w, sw->gc, 6, 14, s); +#endif + + DNPRINTF(SWM_D_MISC, "search_win: mapped window: 0x%x\n", w); fprintf(lfile, "%d\n", i); i++; } fclose(lfile); + + xcb_flush(conn); } void @@ -4136,7 +4092,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); } @@ -4192,13 +4150,14 @@ floating_toggle(struct swm_region *r, union arg *args) _NET_WM_STATE_TOGGLE); stack(); - if (focus_mode == SWM_FOCUS_DEFAULT) - drain_enter_notify(); if (win == win->ws->focus) { a.id = SWM_ARG_ID_FOCUSCUR; focus(win->ws->r, &a); } + + xcb_flush(conn); + event_drain(XCB_ENTER_NOTIFY); } void @@ -4267,18 +4226,20 @@ update_window(struct ws_win *win) void resize(struct ws_win *win, union arg *args) { - XEvent ev; - Time time = 0; + xcb_timestamp_t timestamp = 0; struct swm_region *r = NULL; int resize_step = 0; struct swm_geometry g; - int top = 0, left = 0; + 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; if (win == NULL) return; @@ -4287,7 +4248,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); @@ -4331,15 +4292,12 @@ resize(struct ws_win *win, union arg *args) return; } - if (focus_mode == SWM_FOCUS_DEFAULT) - drain_enter_notify(); - /* get cursor offset from window root */ xpr = xcb_query_pointer_reply(conn, xcb_query_pointer(conn, win->id), - NULL); + NULL); if (!xpr) return; - + g = win->g; if (xpr->win_x < WIDTH(win) / 2) @@ -4360,13 +4318,12 @@ resize(struct ws_win *win, union arg *args) cursor = xcb_generate_id(conn); xcb_create_glyph_cursor(conn, cursor, cursor_font, cursor_font, - shape, shape + 1, 0, 0, 0, 0xffff, 0xffff, 0xffff); + shape, shape + 1, 0, 0, 0, 0xffff, 0xffff, 0xffff); - gpr = xcb_grab_pointer_reply(conn, - xcb_grab_pointer(conn, False, win->id, MOUSEMASK, - XCB_GRAB_MODE_ASYNC, XCB_GRAB_MODE_ASYNC, XCB_WINDOW_NONE, - cursor, XCB_CURRENT_TIME), - NULL); + gpc = xcb_grab_pointer(conn, False, 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); @@ -4374,19 +4331,19 @@ resize(struct ws_win *win, union arg *args) return; } - do { - XMaskEvent(display, MOUSEMASK | ExposureMask | - SubstructureRedirectMask, &ev); - switch (ev.type) { - case ConfigureRequest: - case Expose: - case MapRequest: - handler[ev.type](&ev); + xcb_flush(conn); + resizing = 1; + while ((evt = xcb_wait_for_event(conn)) && resizing) { + switch (XCB_EVENT_RESPONSE_TYPE(evt)) { + case XCB_BUTTON_RELEASE: + DNPRINTF(SWM_D_EVENT, "resize: BUTTON_RELEASE\n"); + resizing = 0; break; - case MotionNotify: + case XCB_MOTION_NOTIFY: + mne = (xcb_motion_notify_event_t *)evt; /* cursor offset/delta from start of the operation */ - dx = ev.xmotion.x_root - xpr->root_x; - dy = ev.xmotion.y_root - xpr->root_y; + dx = mne->root_x - xpr->root_x; + dy = mne->root_y - xpr->root_y; /* vertical */ if (top) @@ -4431,15 +4388,19 @@ resize(struct ws_win *win, union arg *args) constrain_window(win, r, 1); /* not free, don't sync more than 120 times / second */ - if ((ev.xmotion.time - time) > (1000 / 120) ) { - time = ev.xmotion.time; + if ((mne->time - timestamp) > (1000 / 120) ) { + timestamp = mne->time; do_sync(); update_window(win); } break; + default: + event_handle(evt); + break; } - } while (ev.type != ButtonRelease); - if (time) { + free(evt); + } + if (timestamp) { do_sync(); update_window(win); } @@ -4450,9 +4411,7 @@ resize(struct ws_win *win, union arg *args) xcb_close_font(conn, cursor_font); free(gpr); free(xpr); - - /* drain events */ - drain_enter_notify(); + DNPRINTF(SWM_D_EVENT, "resize: done\n"); } void @@ -4473,14 +4432,16 @@ resize_step(struct swm_region *r, union arg *args) void move(struct ws_win *win, union arg *args) { - XEvent ev; - Time time = 0; - int move_step = 0; + xcb_timestamp_t timestamp = 0; + 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; if (win == NULL) return; @@ -4489,7 +4450,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 */ @@ -4537,16 +4498,15 @@ move(struct ws_win *win, union arg *args) cursor_font = xcb_generate_id(conn); xcb_open_font(conn, cursor_font, strlen("cursor"), "cursor"); - + cursor = xcb_generate_id(conn); xcb_create_glyph_cursor(conn, cursor, cursor_font, cursor_font, XC_fleur, XC_fleur + 1, 0, 0, 0, 0xffff, 0xffff, 0xffff); - gpr = xcb_grab_pointer_reply(conn, - xcb_grab_pointer(conn, False, win->id, MOUSEMASK, - XCB_GRAB_MODE_ASYNC, XCB_GRAB_MODE_ASYNC, - XCB_WINDOW_NONE, cursor, XCB_CURRENT_TIME), - NULL); + gpc = xcb_grab_pointer(conn, False, 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); @@ -4562,31 +4522,36 @@ move(struct ws_win *win, union arg *args) xcb_close_font(conn, cursor_font); return; } - do { - XMaskEvent(display, MOUSEMASK | ExposureMask | - SubstructureRedirectMask, &ev); - switch (ev.type) { - case ConfigureRequest: - case Expose: - case MapRequest: - handler[ev.type](&ev); + + xcb_flush(conn); + moving = 1; + while ((evt = xcb_wait_for_event(conn)) && moving) { + switch (XCB_EVENT_RESPONSE_TYPE(evt)) { + case XCB_BUTTON_RELEASE: + DNPRINTF(SWM_D_EVENT, "move: BUTTON_RELEASE\n"); + moving = 0; break; - case MotionNotify: - X(win) = ev.xmotion.x_root - qpr->win_x - border_width; - Y(win) = ev.xmotion.y_root - qpr->win_y - border_width; + case XCB_MOTION_NOTIFY: + mne = (xcb_motion_notify_event_t *)evt; + X(win) = mne->root_x - qpr->win_x - border_width; + Y(win) = mne->root_y - qpr->win_y - border_width; constrain_window(win, r, 0); /* not free, don't sync more than 120 times / second */ - if ((ev.xmotion.time - time) > (1000 / 120) ) { - time = ev.xmotion.time; + if ((mne->time - timestamp) > (1000 / 120) ) { + timestamp = mne->time; do_sync(); update_window(win); } break; + default: + event_handle(evt); + break; } - } while (ev.type != ButtonRelease); - if (time) { + free(evt); + } + if (timestamp) { do_sync(); update_window(win); } @@ -4595,9 +4560,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); - - /* drain events */ - drain_enter_notify(); + DNPRINTF(SWM_D_EVENT, "move: done\n"); } void @@ -4619,128 +4582,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 */ - { "cycle_layout", cycle_layout, {0} }, + { "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} }, @@ -4764,55 +4767,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} }, }; @@ -5176,7 +5134,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); @@ -5199,7 +5157,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); @@ -5286,14 +5244,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; @@ -5314,14 +5272,14 @@ setconfbinding(char *selector, char *value, int flags) 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", @@ -5339,7 +5297,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 @@ -5353,104 +5311,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 } @@ -5488,27 +5446,38 @@ setkeymapping(char *selector, char *value, int flags) void updatenumlockmask(void) { - unsigned int i, j; - XModifierKeymap *modmap; + unsigned int i, j; + xcb_get_modifier_mapping_reply_t *modmap_r; + xcb_keycode_t *modmap, kc; DNPRINTF(SWM_D_MISC, "updatenumlockmask\n"); numlockmask = 0; - modmap = XGetModifierMapping(display); - for (i = 0; i < 8; i++) - for (j = 0; j < modmap->max_keypermod; j++) - if (modmap->modifiermap[i * modmap->max_keypermod + j] - == XKeysymToKeycode(display, XK_Num_Lock)) - numlockmask = (1 << i); - XFreeModifiermap(modmap); + modmap_r = xcb_get_modifier_mapping_reply(conn, + xcb_get_modifier_mapping(conn), + NULL); + if (modmap_r) { + modmap = xcb_get_modifier_mapping_keycodes(modmap_r); + for (i = 0; i < 8; i++) { + 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))) + numlockmask = (1 << i); + } + } + free(modmap_r); + } } void grabkeys(void) { - int num_screens; - unsigned int j, k; - KeyCode code; + int num_screens, k; + unsigned int j; + xcb_keycode_t *code; unsigned int modifiers[] = { 0, LockMask, numlockmask, numlockmask | LockMask }; struct key *kp; @@ -5523,12 +5492,14 @@ grabkeys(void) xcb_ungrab_key(conn, XCB_GRAB_ANY, screens[k].root, XCB_MOD_MASK_ANY); RB_FOREACH(kp, key_tree, &keys) { - if ((code = XKeysymToKeycode(display, kp->keysym))) + if ((code = xcb_key_symbols_get_keycode(syms, + kp->keysym))) for (j = 0; j < LENGTH(modifiers); j++) - XGrabKey(display, code, + xcb_grab_key(conn, True, + screens[k].root, kp->mod | modifiers[j], - screens[k].root, True, - GrabModeAsync, GrabModeAsync); + *code, XCB_GRAB_MODE_ASYNC, + XCB_GRAB_MODE_ASYNC); } } } @@ -5542,24 +5513,23 @@ grabbuttons(struct ws_win *win, int focused) updatenumlockmask(); xcb_ungrab_button(conn, XCB_BUTTON_INDEX_ANY, win->id, - XCB_BUTTON_MASK_ANY); + XCB_BUTTON_MASK_ANY); if (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, - BUTTONMASK, - XCB_GRAB_MODE_ASYNC, - XCB_GRAB_MODE_SYNC, - XCB_WINDOW_NONE, - XCB_CURSOR_NONE, - buttons[i].button, - buttons[i].mask); + BUTTONMASK, + XCB_GRAB_MODE_ASYNC, + XCB_GRAB_MODE_SYNC, + XCB_WINDOW_NONE, + XCB_CURSOR_NONE, + buttons[i].button, + buttons[i].mask); } else xcb_grab_button(conn, False, 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); + XCB_GRAB_MODE_ASYNC, XCB_GRAB_MODE_SYNC, XCB_WINDOW_NONE, + XCB_CURSOR_NONE, XCB_BUTTON_INDEX_ANY, XCB_BUTTON_MASK_ANY); } const char *quirkname[] = { @@ -5970,7 +5940,7 @@ 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; if (getenv("SWM_STARTED")) @@ -6273,12 +6243,12 @@ out: } void -set_child_transient(struct ws_win *win, Window *trans) +set_child_transient(struct ws_win *win, xcb_window_t *trans) { struct ws_win *parent, *w; struct swm_region *r; struct workspace *ws; - xcb_wm_hints_t wmh; + xcb_icccm_wm_hints_t wmh; parent = find_window(win->transient); if (parent) @@ -6287,13 +6257,13 @@ set_child_transient(struct ws_win *win, Window *trans) DNPRINTF(SWM_D_MISC, "set_child_transient: parent doesn't exist" " for 0x%x trans 0x%x\n", win->id, win->transient); - r = root_to_region(win->wa.root); + r = root_to_region(win->wa->root); ws = r->ws; /* parent doen't exist in our window list */ TAILQ_FOREACH(w, &ws->winlist, entry) { if (xcb_icccm_get_wm_hints_reply(conn, - xcb_icccm_get_wm_hints(conn, w->id), - &wmh, NULL) != 1) { + xcb_icccm_get_wm_hints(conn, w->id), + &wmh, NULL) != 1) { warnx("can't get hints for 0x%x", w->id); continue; } @@ -6304,17 +6274,17 @@ set_child_transient(struct ws_win *win, Window *trans) w->child_trans = win; win->transient = w->id; *trans = w->id; - DNPRINTF(SWM_D_MISC, "set_child_transient: asjusting " + DNPRINTF(SWM_D_MISC, "set_child_transient: adjusting " "transient to 0x%x\n", win->transient); break; } } } -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; @@ -6328,10 +6298,12 @@ window_get_pid(xcb_window_t win) 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); + ret = *((pid_t *)xcb_get_property_value(pr)); free(pr); return (ret); @@ -6339,14 +6311,16 @@ window_get_pid(xcb_window_t win) tryharder: apid = get_atom_from_string("_SWM_PID"); pc = xcb_get_property(conn, False, win, apid, XCB_ATOM_STRING, - 0, SWM_PROPLEN); + 0, SWM_PROPLEN); pr = xcb_get_property_reply(conn, pc, NULL); if (!pr) return (0); - if (pr->type != XCB_ATOM_STRING) + if (pr->type != XCB_ATOM_STRING) { free(pr); return (0); - ret = strtonum(xcb_get_property_value(pr), 0, UINT_MAX, &errstr); + } + + ret = strtonum(xcb_get_property_value(pr), 0, INT_MAX, &errstr); free(pr); return (ret); @@ -6355,19 +6329,21 @@ tryharder: struct ws_win * manage_window(xcb_window_t id) { - Window trans = 0; + xcb_window_t trans = XCB_WINDOW_NONE; struct workspace *ws; struct ws_win *win, *ww; - int format, i, ws_idx, n, border_me = 0; - unsigned long nitems, bytes; - Atom ws_idx_atom = 0, type; - Atom *prot = NULL, *pp; - unsigned char ws_idx_str[SWM_PROPLEN], *prop = NULL; + int ws_idx, border_me = 0; + xcb_atom_t ws_idx_atom = XCB_ATOM_NONE; + 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; + uint32_t event_mask, i; + xcb_atom_t prot; + xcb_get_property_reply_t *gpr; + xcb_icccm_get_wm_protocols_reply_t wpr; if ((win = find_window(id)) != NULL) return (win); /* already being managed */ @@ -6414,17 +6390,38 @@ manage_window(xcb_window_t id) p = find_pid(window_get_pid(id)); /* Get all the window data in one shot */ - ws_idx_atom = XInternAtom(display, "_SWM_WS", False); + ws_idx_atom = get_atom_from_string("_SWM_WS"); if (ws_idx_atom) { - XGetWindowProperty(display, id, ws_idx_atom, 0, SWM_PROPLEN, - False, XA_STRING, &type, &format, &nitems, &bytes, &prop); + 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); + } } - XGetWindowAttributes(display, id, &win->wa); - XGetWMNormalHints(display, id, &win->sh, &win->sh_mask); + win->wa = xcb_get_geometry_reply(conn, + xcb_get_geometry(conn, id), + NULL); + xcb_icccm_get_wm_normal_hints_reply(conn, + xcb_icccm_get_wm_normal_hints(conn, id), + &win->sh, NULL); xcb_icccm_get_wm_hints_reply(conn, - xcb_icccm_get_wm_hints(conn, id), - &win->hints, NULL); - XGetTransientForHint(display, id, &trans); + xcb_icccm_get_wm_hints(conn, id), + &win->hints, NULL); + xcb_icccm_get_wm_transient_for_reply(conn, + xcb_icccm_get_wm_transient_for(conn, id), + &trans, NULL); if (trans) { win->transient = trans; set_child_transient(win, &trans); @@ -6432,16 +6429,19 @@ 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 (XGetWMProtocols(display, id, &prot, &n)) { - for (i = 0, pp = prot; i < n; i++, pp++) { - if (*pp == takefocus) + if (xcb_icccm_get_wm_protocols_reply(conn, + xcb_icccm_get_wm_protocols(conn, id, prot), + &wpr, NULL)) { + for (i = 0; i < wpr.atoms_len; i++) { + if (wpr.atoms[i] == a_takefocus) win->take_focus = 1; - if (*pp == adelete) + if (wpr.atoms[i] == a_delete) win->can_delete = 1; } - if (prot) - XFree(prot); + xcb_icccm_get_wm_protocols_reply_wipe(&wpr); } win->iconic = get_iconic(win); @@ -6451,7 +6451,7 @@ manage_window(xcb_window_t id) * a workspace (either by spawn() or manually moving), and isn't * transient, * put it in the same workspace */ - r = root_to_region(win->wa.root); + r = root_to_region(win->wa->root); if (p) { ws = &r->s->ws[p->ws]; TAILQ_REMOVE(&pidlist, p, entry); @@ -6459,7 +6459,7 @@ manage_window(xcb_window_t id) p = NULL; } else if (prop && win->transient == 0) { DNPRINTF(SWM_D_PROP, "manage_window: get _SWM_WS: %s\n", prop); - ws_idx = strtonum((const char *)prop, 0, workspace_limit - 1, + ws_idx = strtonum(prop, 0, workspace_limit - 1, &errstr); if (errstr) { DNPRINTF(SWM_D_EVENT, "manage_window: window: #%s: %s", @@ -6505,10 +6505,10 @@ manage_window(xcb_window_t id) } /* ignore window border if there is one. */ - WIDTH(win) = win->wa.width; - HEIGHT(win) = win->wa.height; - X(win) = win->wa.x + win->wa.border_width; - Y(win) = win->wa.y + win->wa.border_width; + WIDTH(win) = win->wa->width; + HEIGHT(win) = win->wa->height; + X(win) = win->wa->x + win->wa->border_width; + Y(win) = win->wa->y + win->wa->border_width; win->bordered = 0; win->g_floatvalid = 0; win->floatmaxed = 0; @@ -6522,34 +6522,37 @@ manage_window(xcb_window_t id) /* Set window properties so we can remember this after reincarnation */ if (ws_idx_atom && prop == NULL && - snprintf((char *)ws_idx_str, SWM_PROPLEN, "%d", ws->idx) < + 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); - XChangeProperty(display, win->id, ws_idx_atom, XA_STRING, 8, - PropModeReplace, ws_idx_str, strlen((char *)ws_idx_str)); + xcb_change_property(conn, XCB_PROP_MODE_REPLACE, win->id, + ws_idx_atom, XCB_ATOM_STRING, 8, strlen(ws_idx_str), + ws_idx_str); } if (prop) - XFree(prop); + free(prop); ewmh_autoquirk(win); - if (XGetClassHint(display, win->id, &win->ch)) { + if (xcb_icccm_get_wm_class_reply(conn, + xcb_icccm_get_wm_class(conn, win->id), + &win->ch, NULL)) { DNPRINTF(SWM_D_CLASS, "manage_window: class: %s, name: %s\n", - win->ch.res_class, win->ch.res_name); + win->ch.class_name, win->ch.instance_name); /* java is retarded so treat it special */ - if (strstr(win->ch.res_name, "sun-awt")) { + if (strstr(win->ch.instance_name, "sun-awt")) { win->java = 1; border_me = 1; } TAILQ_FOREACH(qp, &quirks, entry) { - if (!strcmp(win->ch.res_class, qp->class) && - !strcmp(win->ch.res_name, qp->name)) { + if (!strcmp(win->ch.class_name, qp->class) && + !strcmp(win->ch.instance_name, qp->name)) { DNPRINTF(SWM_D_CLASS, "manage_window: found: " - "class: %s, name: %s\n", win->ch.res_class, - win->ch.res_name); + "class: %s, name: %s\n", win->ch.class_name, + win->ch.instance_name); if (qp->quirk & SWM_Q_FLOAT) { win->floating = 1; border_me = 1; @@ -6590,8 +6593,7 @@ manage_window(xcb_window_t id) } event_mask = XCB_EVENT_MASK_ENTER_WINDOW | XCB_EVENT_MASK_FOCUS_CHANGE | - XCB_EVENT_MASK_PROPERTY_CHANGE | - XCB_EVENT_MASK_STRUCTURE_NOTIFY; + XCB_EVENT_MASK_PROPERTY_CHANGE | XCB_EVENT_MASK_STRUCTURE_NOTIFY; xcb_change_window_attributes(conn, id, XCB_CW_EVENT_MASK, &event_mask); @@ -6610,15 +6612,12 @@ free_window(struct ws_win *win) if (win == NULL) return; - /* needed for restart wm */ - set_win_state(win, XCB_ICCCM_WM_STATE_WITHDRAWN); - TAILQ_REMOVE(&win->ws->unmanagedlist, win, entry); - if (win->ch.res_class) - XFree(win->ch.res_class); - if (win->ch.res_name) - XFree(win->ch.res_name); + if (win->wa) + free(win->wa); + + xcb_icccm_get_wm_class_reply_wipe(&win->ch); kill_refs(win); @@ -6626,6 +6625,7 @@ free_window(struct ws_win *win) memset(win, 0xff, sizeof *win); /* XXX kill later */ free(win); + DNPRINTF(SWM_D_MISC, "free_window: done\n"); } void @@ -6648,7 +6648,7 @@ unmanage_window(struct ws_win *win) /* focus on root just in case */ screen = xcb_setup_roots_iterator(xcb_get_setup(conn)).data; xcb_set_input_focus(conn, XCB_INPUT_FOCUS_POINTER_ROOT, - screen->root, XCB_CURRENT_TIME); + screen->root, XCB_CURRENT_TIME); focus_prev(win); @@ -6672,63 +6672,78 @@ 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); } } void -expose(XEvent *e) +expose(xcb_expose_event_t *e) { - DNPRINTF(SWM_D_EVENT, "expose: window: 0x%lx\n", e->xexpose.window); + int i, num_screens; + struct swm_region *r; + + DNPRINTF(SWM_D_EVENT, "expose: window: 0x%x\n", e->window); + + 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(); + + xcb_flush(conn); } void -keypress(XEvent *e) +keypress(xcb_key_press_event_t *e) { - KeySym keysym; - XKeyEvent *ev = &e->xkey; + xcb_keysym_t keysym; struct key *kp; - struct swm_region *r; - keysym = XkbKeycodeToKeysym(display, (KeyCode)ev->keycode, 0, 0); - if ((kp = key_lookup(CLEANMASK(ev->state), keysym)) == NULL) - return; - if (keyfuncs[kp->funcid].func == NULL) + keysym = xcb_key_press_lookup_keysym(syms, e, 0); + + DNPRINTF(SWM_D_EVENT, "keypress: %u %u\n", e->detail, keysym); + + if ((kp = key_lookup(CLEANMASK(e->state), keysym)) == NULL) return; - r = root_to_region(ev->root); - if (kp->funcid == kf_spawn_custom) - spawn_custom(r, &(keyfuncs[kp->funcid].args), kp->spawn_name); - else - keyfuncs[kp->funcid].func(r, &(keyfuncs[kp->funcid].args)); + 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(XEvent *e) +buttonpress(xcb_button_press_event_t *e) { struct ws_win *win; - int i, action; - XButtonPressedEvent *ev = &e->xbutton; + int i; + unsigned int action; + + DNPRINTF(SWM_D_EVENT, "buttonpress: window 0x%x, detail: %u\n", + e->event, e->detail); - if ((win = find_window(ev->window)) == NULL) + if ((win = find_window(e->event)) == NULL) return; focus_magic(win); @@ -6736,44 +6751,66 @@ buttonpress(XEvent *e) for (i = 0; i < LENGTH(buttons); i++) if (action == buttons[i].action && buttons[i].func && - buttons[i].button == ev->button && - CLEANMASK(buttons[i].mask) == CLEANMASK(ev->state)) + buttons[i].button == e->detail && + CLEANMASK(buttons[i].mask) == CLEANMASK(e->state)) buttons[i].func(win, &buttons[i].args); + + xcb_flush(conn); } void -configurerequest(XEvent *e) +configurerequest(xcb_configure_request_event_t *e) { - XConfigureRequestEvent *ev = &e->xconfigurerequest; struct ws_win *win; - int new = 0; - XWindowChanges wc; + int new = 0, i = 0; + uint16_t mask = 0; + uint32_t wc[7] = {0}; - if ((win = find_window(ev->window)) == NULL) - if ((win = find_unmanaged_window(ev->window)) == NULL) + if ((win = find_window(e->window)) == NULL) + if ((win = find_unmanaged_window(e->window)) == NULL) new = 1; if (new) { - bzero(&wc, sizeof wc); - wc.x = ev->x; - wc.y = ev->y; - wc.width = ev->width; - wc.height = ev->height; - wc.border_width = ev->border_width; - wc.sibling = ev->above; - wc.stack_mode = ev->detail; - - DNPRINTF(SWM_D_EVENT, "configurerequest: new window: 0x%lx, " - "new: %s, (x,y) w x h: (%d,%d) %d x %d\n", ev->window, - YESNO(new), wc.x, wc.y, wc.width, wc.height); - - XConfigureWindow(display, ev->window, ev->value_mask, &wc); + if (e->value_mask & XCB_CONFIG_WINDOW_X) { + mask |= XCB_CONFIG_WINDOW_X; + wc[i++] = e->x; + } + if (e->value_mask & XCB_CONFIG_WINDOW_Y) { + mask |= XCB_CONFIG_WINDOW_Y; + wc[i++] = e->y; + } + if (e->value_mask & XCB_CONFIG_WINDOW_WIDTH) { + mask |= XCB_CONFIG_WINDOW_WIDTH; + wc[i++] = e->width; + } + if (e->value_mask & XCB_CONFIG_WINDOW_HEIGHT) { + mask |= XCB_CONFIG_WINDOW_HEIGHT; + wc[i++] = e->height; + } + if (e->value_mask & XCB_CONFIG_WINDOW_BORDER_WIDTH) { + mask |= XCB_CONFIG_WINDOW_BORDER_WIDTH; + wc[i++] = e->border_width; + } + if (e->value_mask & XCB_CONFIG_WINDOW_SIBLING) { + mask |= XCB_CONFIG_WINDOW_SIBLING; + wc[i++] = e->sibling; + } + if (e->value_mask & XCB_CONFIG_WINDOW_STACK_MODE) { + mask |= XCB_CONFIG_WINDOW_STACK_MODE; + wc[i++] = 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]); + + xcb_configure_window(conn, e->window, mask, wc); } else if ((!win->manual || win->quirks & SWM_Q_ANYWHERE) && - !(win->sh_mask & EWMH_F_FULLSCREEN)) { - win->g_float.x = ev->x - X(win->ws->r); - win->g_float.y = ev->y - Y(win->ws->r); - win->g_float.w = ev->width; - win->g_float.h = ev->height; + !(win->ewmh_flags & EWMH_F_FULLSCREEN)) { + win->g_float.x = e->x - X(win->ws->r); + win->g_float.y = e->y - Y(win->ws->r); + win->g_float.w = e->width; + win->g_float.h = e->height; win->g_floatvalid = 1; if (win->floating) { @@ -6782,42 +6819,43 @@ configurerequest(XEvent *e) win->g.y += Y(win->ws->r); update_window(win); } else { - config_win(win, ev); + config_win(win, e); } } else { - config_win(win, ev); + config_win(win, e); } + + xcb_flush(conn); } void -configurenotify(XEvent *e) +configurenotify(xcb_configure_notify_event_t *e) { struct ws_win *win; - DNPRINTF(SWM_D_EVENT, "configurenotify: window: 0x%lx\n", - e->xconfigure.window); + DNPRINTF(SWM_D_EVENT, "configurenotify: window: 0x%x\n", + e->window); - win = find_window(e->xconfigure.window); + win = find_window(e->window); if (win) { - XGetWMNormalHints(display, win->id, &win->sh, &win->sh_mask); + xcb_icccm_get_wm_normal_hints_reply(conn, + xcb_icccm_get_wm_normal_hints(conn, win->id), + &win->sh, NULL); adjust_font(win); if (font_adjusted) stack(); - if (focus_mode == SWM_FOCUS_DEFAULT) - drain_enter_notify(); } } void -destroynotify(XEvent *e) +destroynotify(xcb_destroy_notify_event_t *e) { struct ws_win *win; - XDestroyWindowEvent *ev = &e->xdestroywindow; - DNPRINTF(SWM_D_EVENT, "destroynotify: window: 0x%lx\n", ev->window); + DNPRINTF(SWM_D_EVENT, "destroynotify: window: 0x%x\n", e->window); - if ((win = find_window(ev->window)) == NULL) { - if ((win = find_unmanaged_window(ev->window)) == NULL) + if ((win = find_window(e->window)) == NULL) { + if ((win = find_unmanaged_window(e->window)) == NULL) return; free_window(win); return; @@ -6828,28 +6866,19 @@ destroynotify(XEvent *e) unmanage_window(win); stack(); - if (focus_mode == SWM_FOCUS_DEFAULT) - drain_enter_notify(); free_window(win); } void -enternotify(XEvent *e) +enternotify(xcb_enter_notify_event_t *e) { - XCrossingEvent *ev = &e->xcrossing; - XEvent cne; 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%lx, mode: %d, detail: " - "%d, root: 0x%lx, subwindow: 0x%lx, same_screen: %s, focus: %s, " - "state: %d\n", ev->window, ev->mode, ev->detail, ev->root, - ev->subwindow, YESNO(ev->same_screen), YESNO(ev->focus), ev->state); + 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, + e->child, YESNO(e->same_screen_focus), e->state); - if (ev->mode != NotifyNormal) { + if (e->mode != XCB_NOTIFY_MODE_NORMAL) { DNPRINTF(SWM_D_EVENT, "skip enternotify: generated by " "cursor grab.\n"); return; @@ -6861,151 +6890,30 @@ enternotify(XEvent *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; } - if ((win = find_window(ev->window)) == NULL) { + if ((win = find_window(e->event)) == NULL) { DNPRINTF(SWM_D_EVENT, "skip enternotify: window is NULL\n"); return; } - /* - * if we have more enternotifies let them handle it in due time - */ - if (XCheckTypedEvent(display, EnterNotify, &cne) == True) { - DNPRINTF(SWM_D_EVENT, - "ignoring enternotify: got more enternotify\n"); - XPutBackEvent(display, &cne); - return; - } - focus_magic(win); + + xcb_flush(conn); } /* lets us use one switch statement for arbitrary mode/detail combinations */ #define MERGE_MEMBERS(a,b) (((a & 0xffff) << 16) | (b & 0xffff)) void -focusevent(XEvent *e) +mapnotify(xcb_map_notify_event_t *e) { -#if 0 struct ws_win *win; - u_int32_t mode_detail; - XFocusChangeEvent *ev = &e->xfocus; - - DNPRINTF(SWM_D_EVENT, "focusevent: %s window: 0x%lx mode: %d " - "detail: %d\n", ev->type == FocusIn ? "entering" : "leaving", - ev->window, ev->mode, ev->detail); - - if (last_focus_event == ev->type) { - DNPRINTF(SWM_D_FOCUS, "ignoring focusevent: bad ordering\n"); - return; - } - - last_focus_event = ev->type; - mode_detail = MERGE_MEMBERS(ev->mode, ev->detail); - - switch (mode_detail) { - /* synergy client focus operations */ - case MERGE_MEMBERS(NotifyNormal, NotifyNonlinear): - case MERGE_MEMBERS(NotifyNormal, NotifyNonlinearVirtual): - /* synergy server focus operations */ - case MERGE_MEMBERS(NotifyWhileGrabbed, NotifyNonlinear): + DNPRINTF(SWM_D_EVENT, "mapnotify: window: 0x%x\n", e->window); - /* Entering applications like rdesktop that mangle the pointer */ - case MERGE_MEMBERS(NotifyNormal, NotifyPointer): - - if ((win = find_window(e->xfocus.window)) != NULL && win->ws->r) - XSetWindowBorder(display, win->id, - win->ws->r->s->c[ev->type == FocusIn ? - SWM_S_COLOR_FOCUS : SWM_S_COLOR_UNFOCUS].color); - break; - default: - warnx("ignoring focusevent"); - DNPRINTF(SWM_D_FOCUS, "ignoring focusevent\n"); - break; - } -#endif -} - -void -mapnotify(XEvent *e) -{ - struct ws_win *win; - XMapEvent *ev = &e->xmap; - - DNPRINTF(SWM_D_EVENT, "mapnotify: window: 0x%lx\n", ev->window); - - win = manage_window(ev->window); + win = manage_window(e->window); if (win) set_win_state(win, XCB_ICCCM_WM_STATE_NORMAL); @@ -7018,61 +6926,83 @@ mapnotify(XEvent *e) } void -mappingnotify(XEvent *e) +mappingnotify(xcb_mapping_notify_event_t *e) { - XMappingEvent *ev = &e->xmapping; + xcb_refresh_keyboard_mapping(syms, e); - XRefreshKeyboardMapping(ev); - if (ev->request == MappingKeyboard) + if (e->request == XCB_MAPPING_KEYBOARD) grabkeys(); } void -maprequest(XEvent *e) +maprequest(xcb_map_request_event_t *e) { struct ws_win *win; struct swm_region *r; - XWindowAttributes wa; - XMapRequestEvent *ev = &e->xmaprequest; + xcb_get_window_attributes_reply_t *war; - DNPRINTF(SWM_D_EVENT, "maprequest: window: 0x%lx\n", - e->xmaprequest.window); + DNPRINTF(SWM_D_EVENT, "maprequest: window: 0x%x\n", + e->window); - if (!XGetWindowAttributes(display, ev->window, &wa)) + war = xcb_get_window_attributes_reply(conn, + xcb_get_window_attributes(conn, e->window), + NULL); + if (!war) return; - if (wa.override_redirect) + if (war->override_redirect) { + free(war); return; + } + free(war); - win = manage_window(e->xmaprequest.window); - if (win == NULL) + win = manage_window(e->window); + if (win == NULL) { return; /* can't happen */ + } stack(); /* make new win focused */ - r = root_to_region(win->wa.root); + r = root_to_region(win->wa->root); if (win->ws == r->ws) focus_magic(win); } void -propertynotify(XEvent *e) +propertynotify(xcb_property_notify_event_t *e) { struct ws_win *win; - XPropertyEvent *ev = &e->xproperty; #ifdef SWM_DEBUG - char *name; - name = XGetAtomName(display, ev->atom); - DNPRINTF(SWM_D_EVENT, "propertynotify: window: 0x%lx, atom: %s\n", - ev->window, name); - XFree(name); + char *name; + size_t len; + xcb_get_atom_name_reply_t *r; + + r = xcb_get_atom_name_reply(conn, + xcb_get_atom_name(conn, e->atom), + NULL); + if (r) { + len = xcb_get_atom_name_name_length(r); + if (len > 0) { + name = malloc(len + 1); + 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); + } #endif - win = find_window(ev->window); + win = find_window(e->window); if (win == NULL) return; - if (ev->state == PropertyDelete && ev->atom == a_swm_iconic) { + if (e->state == XCB_PROPERTY_DELETE && e->atom == a_swm_iconic) { update_iconic(win, 0); map_window_raised(win->id); stack(); @@ -7080,22 +7010,9 @@ propertynotify(XEvent *e) return; } - switch (ev->atom) { -#if 0 - case XA_WM_NORMAL_HINTS: - long mask; - XGetWMNormalHints(display, win->id, &win->sh, &mask); - warnx("normal hints: flag 0x%x", win->sh.flags); - if (win->sh.flags & PMinSize) { - 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 XA_WM_CLASS: - case XA_WM_NAME: + switch (e->atom) { + case XCB_ATOM_WM_CLASS: + case XCB_ATOM_WM_NAME: bar_update(); break; default: @@ -7104,104 +7021,70 @@ propertynotify(XEvent *e) } void -unmapnotify(XEvent *e) +unmapnotify(xcb_unmap_notify_event_t *e) { struct ws_win *win; - DNPRINTF(SWM_D_EVENT, "unmapnotify: window: 0x%lx\n", e->xunmap.window); + DNPRINTF(SWM_D_EVENT, "unmapnotify: window: 0x%x\n", e->window); /* determine if we need to help unmanage this window */ - win = find_window(e->xunmap.window); + win = find_window(e->window); if (win == NULL) return; - if (getstate(e->xunmap.window) == XCB_ICCCM_WM_STATE_NORMAL) { + if (getstate(e->window) == XCB_ICCCM_WM_STATE_NORMAL) { unmanage_window(win); stack(); - /* giant hack for apps that don't destroy transient windows */ - /* eat a bunch of events to prevent remanaging the window */ - XEvent cne; - while (XCheckWindowEvent(display, e->xunmap.window, - EnterWindowMask, &cne)) - ; - while (XCheckWindowEvent(display, e->xunmap.window, - StructureNotifyMask, &cne)) - ; - while (XCheckWindowEvent(display, e->xunmap.window, - SubstructureNotifyMask, &cne)) - ; /* resend unmap because we ated it */ - XUnmapWindow(display, e->xunmap.window); + xcb_unmap_window(conn, e->window); + xcb_flush(conn); } - - if (focus_mode == SWM_FOCUS_DEFAULT) - drain_enter_notify(); } -void -visibilitynotify(XEvent *e) +/*void +visibilitynotify(xcb_visibility_notify_event_t *e) { - int i, num_screens; - struct swm_region *r; - - DNPRINTF(SWM_D_EVENT, "visibilitynotify: window: 0x%lx\n", - e->xvisibility.window); - - if (e->xvisibility.state == VisibilityUnobscured) { - 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->xvisibility.window == WINID(r->bar)) - bar_update(); - } -} + DNPRINTF(SWM_D_EVENT, "visibilitynotify: window: 0x%x\n", + e->window); +}*/ void -clientmessage(XEvent *e) +clientmessage(xcb_client_message_event_t *e) { - XClientMessageEvent *ev; - struct ws_win *win; - - ev = &e->xclient; + struct ws_win *win; - win = find_window(ev->window); - if (win == NULL) { - if (ev->message_type == ewmh[_NET_ACTIVE_WINDOW].atom) { - DNPRINTF(SWM_D_EVENT, "clientmessage: request focus on " - "unmanaged window.\n"); - e->xmaprequest.window = ev->window; - maprequest(e); - } + win = find_window(e->window); + if (win == NULL) return; } - DNPRINTF(SWM_D_EVENT, "clientmessage: window: 0x%lx, type: %ld\n", - ev->window, ev->message_type); + DNPRINTF(SWM_D_EVENT, "clientmessage: window: 0x%x, type: %u\n", + e->window, e->type); - if (ev->message_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 (ev->message_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 (ev->message_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) { - if (ev->data.l[0] & (1<<8)) /* x */ - X(win) = ev->data.l[1]; - if (ev->data.l[0] & (1<<9)) /* y */ - Y(win) = ev->data.l[2]; - if (ev->data.l[0] & (1<<10)) /* width */ - WIDTH(win) = ev->data.l[3]; - if (ev->data.l[0] & (1<<11)) /* height */ - HEIGHT(win) = ev->data.l[4]; + if (e->data.data32[0] & (1<<8)) /* x */ + X(win) = e->data.data32[1]; + if (e->data.data32[0] & (1<<9)) /* y */ + Y(win) = e->data.data32[2]; + if (e->data.data32[0] & (1<<10)) /* width */ + WIDTH(win) = e->data.data32[3]; + if (e->data.data32[0] & (1<<11)) /* height */ + HEIGHT(win) = e->data.data32[4]; update_window(win); } @@ -7211,47 +7094,33 @@ clientmessage(XEvent *e) config_win(win, NULL); } } - if (ev->message_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, ev->data.l[1], ev->data.l[0]); - if (ev->data.l[2]) - ewmh_update_win_state(win, ev->data.l[2], - ev->data.l[0]); + ewmh_update_win_state(win, e->data.data32[1], e->data.data32[0]); + if (e->data.data32[2]) + ewmh_update_win_state(win, e->data.data32[2], + e->data.data32[0]); 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 +void active_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; /* this causes an error if some other window manager is running */ - XSelectInput(display, DefaultRootWindow(display), - SubstructureRedirectMask); - do_sync(); - if (other_wm) - return (1); - - XSetErrorHandler(xerror); - do_sync(); - return (0); + num_screens = xcb_setup_roots_length(xcb_get_setup(conn)); + for (i = 0; i < num_screens; i++) { + sc = get_screen(i); + xcb_change_window_attributes(conn, sc->root, + XCB_CW_EVENT_MASK, &val); + } } void @@ -7362,9 +7231,9 @@ scan_xrandr(int i) #ifdef SWM_XRR_HAS_CRTC if (xrandr_support) { src = xcb_randr_get_screen_resources_current(conn, - screens[i].root); + screens[i].root); srr = xcb_randr_get_screen_resources_current_reply(conn, src, - NULL); + NULL); if (srr == NULL) { new_region(&screens[i], 0, 0, screen->width_in_pixels, @@ -7375,7 +7244,7 @@ scan_xrandr(int i) 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); + XCB_CURRENT_TIME); cir = xcb_randr_get_crtc_info_reply(conn, cic, NULL); if (cir == NULL) continue; @@ -7403,21 +7272,25 @@ scan_xrandr(int i) } void -screenchange(XEvent *e) +screenchange(xcb_randr_screen_change_notify_event_t *e) { - XRRScreenChangeNotifyEvent *xe = (XRRScreenChangeNotifyEvent *)e; struct swm_region *r; int i, num_screens; - DNPRINTF(SWM_D_EVENT, "screenchange: root: 0x%lx\n", xe->root); + DNPRINTF(SWM_D_EVENT, "screenchange: root: 0x%x\n", e->root); - if (!XRRUpdateConfiguration(e)) - return; + 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++) - if (screens[i].root == xe->root) + if (screens[i].root == e->root) break; if (i >= num_screens) errx(1, "screenchange: screen not found"); @@ -7430,8 +7303,6 @@ screenchange(XEvent *e) TAILQ_FOREACH(r, &screens[i].rl, entry) bar_setup(r); stack(); - if (focus_mode == SWM_FOCUS_DEFAULT) - drain_enter_notify(); } void @@ -7469,8 +7340,8 @@ grab_windows(void) } pc = xcb_icccm_get_wm_transient_for(conn, wins[j]); - if (xcb_icccm_get_wm_transient_for_reply(conn, pc, &wins[j], - NULL)) { + if (xcb_icccm_get_wm_transient_for_reply(conn, pc, + &wins[j], NULL)) { free(r); continue; } @@ -7496,8 +7367,8 @@ grab_windows(void) state = getstate(wins[j]); manage = state == XCB_ICCCM_WM_STATE_ICONIC; pc = xcb_icccm_get_wm_transient_for(conn, wins[j]); - if (xcb_icccm_get_wm_transient_for_reply(conn, pc, &wins[j], - NULL) && manage) + if (xcb_icccm_get_wm_transient_for_reply(conn, pc, + &wins[j], NULL) && manage) manage_window(wins[j]); } free(qtr); @@ -7548,7 +7419,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); @@ -7561,11 +7432,11 @@ setup_screens(void) screens[i].bar_gc = xcb_generate_id(conn); gcv[0] = 0; xcb_create_gc(conn, screens[i].bar_gc, screens[i].root, - XCB_GC_GRAPHICS_EXPOSURES, gcv); + XCB_GC_GRAPHICS_EXPOSURES, gcv); /* set default cursor */ xcb_change_window_attributes(conn, screens[i].root, - XCB_CW_CURSOR, wa); + XCB_CW_CURSOR, wa); /* init all workspaces */ /* XXX these should be dynamically allocated too */ @@ -7591,7 +7462,7 @@ setup_screens(void) if (xrandr_support) xcb_randr_select_input(conn, screens[i].root, - XCB_RANDR_NOTIFY_MASK_SCREEN_CHANGE); + XCB_RANDR_NOTIFY_MASK_SCREEN_CHANGE); } xcb_free_cursor(conn, cursor); xcb_close_font(conn, cursor_font); @@ -7605,6 +7476,19 @@ 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"); } void @@ -7613,7 +7497,6 @@ workaround(void) int i, num_screens; xcb_atom_t netwmcheck, netwmname, utf8_string; xcb_window_t root, win; - xcb_screen_t *screen; uint32_t wa[2]; /* work around sun jdk bugs, code from wmname */ @@ -7624,23 +7507,82 @@ workaround(void) num_screens = xcb_setup_roots_length(xcb_get_setup(conn)); for (i = 0; i < num_screens; i++) { root = screens[i].root; - screen = get_screen(i); 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; - xcb_create_window(conn, screen->root_depth, win, 0, - 0, 0, 1, 1, 0, XCB_WINDOW_CLASS_INPUT_OUTPUT, - screen->root_visual, - XCB_CW_BACK_PIXEL | XCB_CW_BORDER_PIXEL, wa); + 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); xcb_change_property(conn, XCB_PROP_MODE_REPLACE, root, - netwmcheck, XCB_ATOM_WINDOW, 32, 1, &win); + netwmcheck, XCB_ATOM_WINDOW, 32, 1, &win); xcb_change_property(conn, XCB_PROP_MODE_REPLACE, win, - netwmcheck, XCB_ATOM_WINDOW, 32, 1, &win); + netwmcheck, XCB_ATOM_WINDOW, 32, 1, &win); xcb_change_property(conn, XCB_PROP_MODE_REPLACE, win, - netwmname, utf8_string, 8, strlen("LG3D"), "LG3D"); - } + netwmname, utf8_string, 8, strlen("LG3D"), "LG3D"); + } +} + +void +event_error(xcb_generic_error_t *e) +{ + DNPRINTF(SWM_D_EVENT, "event_error: %s(%u) from %s(%u), sequence: %u, " + "resource_id: %u, minor_code: %u\n", + xcb_event_get_error_label(e->error_code), e->error_code, + xcb_event_get_request_label(e->major_code), e->major_code, + e->sequence, e->resource_id, e->minor_code); +} + +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); + EVENT(XCB_BUTTON_PRESS, buttonpress); + /*EVENT(XCB_BUTTON_RELEASE, buttonpress);*/ + /*EVENT(XCB_CIRCULATE_NOTIFY, );*/ + /*EVENT(XCB_CIRCULATE_REQUEST, );*/ + EVENT(XCB_CLIENT_MESSAGE, clientmessage); + /*EVENT(XCB_COLORMAP_NOTIFY, );*/ + EVENT(XCB_CONFIGURE_NOTIFY, configurenotify); + EVENT(XCB_CONFIGURE_REQUEST, configurerequest); + /*EVENT(XCB_CREATE_NOTIFY, );*/ + EVENT(XCB_DESTROY_NOTIFY, destroynotify); + EVENT(XCB_ENTER_NOTIFY, enternotify); + EVENT(XCB_EXPOSE, expose); + /*EVENT(XCB_FOCUS_IN, );*/ + /*EVENT(XCB_FOCUS_OUT, );*/ + /*EVENT(XCB_GRAPHICS_EXPOSURE, );*/ + /*EVENT(XCB_GRAVITY_NOTIFY, );*/ + EVENT(XCB_KEY_PRESS, keypress); + /*EVENT(XCB_KEY_RELEASE, keypress);*/ + /*EVENT(XCB_KEYMAP_NOTIFY, );*/ + /*EVENT(XCB_LEAVE_NOTIFY, );*/ + EVENT(XCB_MAP_NOTIFY, mapnotify); + EVENT(XCB_MAP_REQUEST, maprequest); + EVENT(XCB_MAPPING_NOTIFY, mappingnotify); + /*EVENT(XCB_MOTION_NOTIFY, );*/ + /*EVENT(XCB_NO_EXPOSURE, );*/ + EVENT(XCB_PROPERTY_NOTIFY, propertynotify); + /*EVENT(XCB_REPARENT_NOTIFY, );*/ + /*EVENT(XCB_RESIZE_REQUEST, );*/ + /*EVENT(XCB_SELECTION_CLEAR, );*/ + /*EVENT(XCB_SELECTION_NOTIFY, );*/ + /*EVENT(XCB_SELECTION_REQUEST, );*/ + EVENT(XCB_UNMAP_NOTIFY, unmapnotify); + /*EVENT(XCB_VISIBILITY_NOTIFY, visibilitynotify);*/ +#undef EVENT + } + if (type - xrandr_eventbase == XCB_RANDR_SCREEN_CHANGE_NOTIFY) + screenchange((void *)evt); } int @@ -7648,33 +7590,22 @@ main(int argc, char *argv[]) { struct swm_region *r, *rr; struct ws_win *winfocus = NULL; - struct timeval tv; union arg a; char conf[PATH_MAX], *cfile = NULL; struct stat sb; - XEvent e; int xfd, i, num_screens; - fd_set rd; struct sigaction sact; + xcb_generic_event_t *evt; + struct timeval tv; + fd_set rd; + + 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"); - - if (!(conn = XGetXCBConnection(display))) - errx(1, "can not get XCB connection"); - - if (active_wm()) - errx(1, "other wm running"); - /* handle some signals */ bzero(&sact, sizeof(sact)); sigemptyset(&sact.sa_mask); @@ -7689,21 +7620,34 @@ main(int argc, char *argv[]) sact.sa_flags = SA_NOCLDSTOP; sigaction(SIGCHLD, &sact, NULL); - 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"); + conn = xcb_connect(NULL, NULL); + if (xcb_connection_has_error(conn)) + errx(1, "can not get XCB connection"); + + xcb_prefetch_extension_data(conn, &xcb_randr_id); + xfd = xcb_get_file_descriptor(conn); /* look for local and global conf file */ pwd = getpwuid(getuid()); if (pwd == NULL) errx(1, "invalid user: %d", getuid()); + xcb_grab_server(conn); + xcb_aux_sync(conn); + + /* flush all events */ + while ((evt = xcb_poll_for_event(conn))) { + if (XCB_EVENT_RESPONSE_TYPE(evt) == 0) + event_handle(evt); + free(evt); + } + + active_wm(); + xcb_aux_sync(conn); + + if (xcb_poll_for_event(conn) != NULL) + errx(1, "another window manager is currently running"); + setup_globals(); setup_screens(); setup_keys(); @@ -7768,41 +7712,20 @@ noconfig: bar_setup(r); } - unfocus_all(); + //unfocus_all(); grabkeys(); stack(); - if (focus_mode == SWM_FOCUS_DEFAULT) - drain_enter_notify(); - xfd = xcb_get_file_descriptor(conn); + xcb_ungrab_server(conn); + xcb_flush(conn); + while (running) { - while (XPending(display)) { - XNextEvent(display, &e); + while ((evt = xcb_poll_for_event(conn))) { if (running == 0) goto done; - if (e.type < LASTEvent) { - DNPRINTF(SWM_D_EVENTQ ,"XEvent: handled: %s, " - "window: 0x%lx, type: %s (%d), %d remaining" - "\n", YESNO(handler[e.type]), - e.xany.window, geteventname(&e), - e.type, QLength(display)); - - if (handler[e.type]) - handler[e.type](&e); - } else { - DNPRINTF(SWM_D_EVENTQ, "XRandr Event: window: " - "0x%lx, type: %s (%d)\n", e.xany.window, - xrandr_geteventname(&e), e.type); - - switch (e.type - xrandr_eventbase) { - case XCB_RANDR_SCREEN_CHANGE_NOTIFY: - screenchange(&e); - break; - default: - break; - } - } + event_handle(evt); + free(evt); } /* if we are being restarted go focus on first window */ @@ -7816,8 +7739,8 @@ noconfig: /* move pointer to first screen if multi screen */ if (num_screens > 1 || outputs > 1) xcb_warp_pointer(conn, XCB_WINDOW_NONE, - rr->s[0].root, 0, 0, 0, 0, X(rr), - Y(rr) + (bar_enabled ? bar_height : 0)); + rr->s[0].root, 0, 0, 0, 0, X(rr), + Y(rr) + (bar_enabled ? bar_height : 0)); a.id = SWM_ARG_ID_FOCUSCUR; focus(rr, &a); @@ -7850,9 +7773,11 @@ done: for (i = 0; i < num_screens; ++i) if (screens[i].bar_gc != 0) xcb_free_gc(conn, screens[i].bar_gc); +#if 0 XFreeFontSet(display, bar_fs); +#endif + xcb_key_symbols_free(syms); xcb_disconnect(conn); - XCloseDisplay(display); return (0); }