X-Git-Url: https://jasonwoof.com/gitweb/?a=blobdiff_plain;f=spectrwm.c;h=665d02074784c2a5491d53898e2bd5192f33f1d7;hb=b4ff36a69396ed4afb8712ddc0d5e2cf557b4edc;hp=f9974421deac6447e9dfa905342f3068eaab12f5;hpb=365159febd102675f6a5bd3ae9ed2c6668aaa0bc;p=spectrwm.git diff --git a/spectrwm.c b/spectrwm.c index f997442..665d020 100644 --- a/spectrwm.c +++ b/spectrwm.c @@ -348,7 +348,7 @@ double dialog_ratio = 0.6; char *bar_argv[] = { NULL, NULL }; int bar_pipe[2]; -unsigned char bar_ext[SWM_BAR_MAX]; +char bar_ext[SWM_BAR_MAX]; char bar_vertext[SWM_BAR_MAX]; int bar_version = 0; sig_atomic_t bar_alarm = 0; @@ -709,6 +709,110 @@ struct spawn_prog { TAILQ_HEAD(spawn_list, spawn_prog); struct spawn_list spawns = TAILQ_HEAD_INITIALIZER(spawns); +/* user/key callable function IDs */ +enum keyfuncid { + 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 +}; + +struct key { + RB_ENTRY(key) entry; + unsigned int mod; + KeySym keysym; + enum keyfuncid funcid; + char *spawn_name; +}; +RB_HEAD(key_tree, key); + /* function prototypes */ void adjust_font(struct ws_win *); void bar_class_name(char *, size_t, struct swm_region *); @@ -767,7 +871,7 @@ char *expand_tilde(const char *); void expose(xcb_expose_event_t *); void fake_keypress(struct ws_win *, xcb_keysym_t, uint16_t); struct pid_e *find_pid(pid_t); -struct ws_win *find_unmanaged_window(xcb_window_t); +struct ws_win *find_unmanaged_window(xcb_window_t); struct ws_win *find_window(xcb_window_t); void floating_toggle(struct swm_region *, union arg *); int floating_toggle_win(struct ws_win *); @@ -806,6 +910,12 @@ void grab_windows(void); void iconify(struct swm_region *, union arg *); int isxlfd(char *); void keypress(xcb_key_press_event_t *); +int key_cmp(struct key *, struct key *); +void key_insert(unsigned int, KeySym, enum keyfuncid, const char *); +struct key *key_lookup(unsigned int, KeySym); +void key_remove(struct key *); +void key_replace(struct key *, unsigned int, KeySym, enum keyfuncid, + const char *); void kill_refs(struct ws_win *); #ifdef SWM_DEBUG void leavenotify(xcb_leave_notify_event_t *); @@ -859,6 +969,7 @@ int setconfquirk(char *, char *, int); int setconfregion(char *, char *, int); int setconfspawn(char *, char *, int); int setconfvalue(char *, char *, int); +void setkeybinding(unsigned int, KeySym, enum keyfuncid, const char *); int setkeymapping(char *, char *, int); int setlayout(char *, char *, int); void setquirk(const char *, const char *, unsigned long); @@ -910,6 +1021,10 @@ void wkill(struct swm_region *, union arg *); void workaround(void); void xft_init(struct swm_region *); +RB_PROTOTYPE(key_tree, key, entry, key_cmp); +RB_GENERATE(key_tree, key, entry, key_cmp); +struct key_tree keys; + void cursors_load(void) { @@ -953,7 +1068,8 @@ char * expand_tilde(const char *s) { struct passwd *ppwd; - int i, max; + int i; + long max; char *user; const char *sc = s; char *result; @@ -1736,7 +1852,7 @@ bar_extra_stop(void) kill(bar_pid, SIGTERM); bar_pid = 0; } - strlcpy((char *)bar_ext, "", sizeof bar_ext); + strlcpy(bar_ext, "", sizeof bar_ext); bar_extra = 0; } @@ -2082,14 +2198,14 @@ bar_update(void) while ((b = fgetln(stdin, &len)) != NULL) if (b && b[len - 1] == '\n') { b[len - 1] = '\0'; - strlcpy((char *)bar_ext, b, sizeof bar_ext); + strlcpy(bar_ext, b, sizeof bar_ext); } if (b == NULL && errno != EAGAIN) { warn("bar_update: bar_extra failed"); bar_extra_stop(); } } else - strlcpy((char *)bar_ext, "", sizeof bar_ext); + strlcpy(bar_ext, "", sizeof bar_ext); bar_fmt_print(); alarm(bar_delay); @@ -2289,7 +2405,7 @@ xft_init(struct swm_region *r) if (!XftColorAllocValue(display, DefaultVisual(display, r->s->idx), DefaultColormap(display, r->s->idx), &color, &bar_font_color)) - warn("unable to allocate Xft color"); + warn("Xft error: unable to allocate color."); bar_height = bar_font->height + 2 * bar_border_width; @@ -2686,6 +2802,7 @@ get_pointer_win(xcb_window_t root) } else { DNPRINTF(SWM_D_EVENT, "get_pointer_win: none.\n"); } + free(r); } return win; @@ -4372,24 +4489,28 @@ get_win_name(xcb_window_t win) XCB_GET_PROPERTY_TYPE_ANY, 0, UINT_MAX); r = xcb_get_property_reply(conn, c, NULL); - if (!r || r->type == XCB_NONE) { - free(r); - /* Use WM_NAME instead; no UTF-8. */ - c = xcb_get_property(conn, 0, win, XCB_ATOM_WM_NAME, - XCB_GET_PROPERTY_TYPE_ANY, 0, UINT_MAX); - r = xcb_get_property_reply(conn, c, NULL); - - if(!r || r->type == XCB_NONE) { + if (r) { + if (r->type == XCB_NONE) { free(r); - return NULL; + /* Use WM_NAME instead; no UTF-8. */ + c = xcb_get_property(conn, 0, win, XCB_ATOM_WM_NAME, + XCB_GET_PROPERTY_TYPE_ANY, 0, UINT_MAX); + r = xcb_get_property_reply(conn, c, NULL); + + if (!r) + return (NULL); + if (r->type == XCB_NONE) { + free(r); + return (NULL); + } } - } + if (r->length > 0) + name = strndup(xcb_get_property_value(r), + xcb_get_property_value_length(r)); - if (r->length > 0) - name = strndup(xcb_get_property_value(r), - xcb_get_property_value_length(r)); + free(r); + } - free(r); return (name); } @@ -4936,7 +5057,7 @@ resize(struct ws_win *win, union arg *args) { xcb_timestamp_t timestamp = 0; struct swm_region *r = NULL; - int resize_step = 0; + int resize_stp = 0; struct swm_geometry g; int top = 0, left = 0, resizing; int dx, dy; @@ -4974,24 +5095,24 @@ resize(struct ws_win *win, union arg *args) switch (args->id) { case SWM_ARG_ID_WIDTHSHRINK: WIDTH(win) -= SWM_RESIZE_STEPS; - resize_step = 1; + resize_stp = 1; break; case SWM_ARG_ID_WIDTHGROW: WIDTH(win) += SWM_RESIZE_STEPS; - resize_step = 1; + resize_stp = 1; break; case SWM_ARG_ID_HEIGHTSHRINK: HEIGHT(win) -= SWM_RESIZE_STEPS; - resize_step = 1; + resize_stp = 1; break; case SWM_ARG_ID_HEIGHTGROW: HEIGHT(win) += SWM_RESIZE_STEPS; - resize_step = 1; + resize_stp = 1; break; default: break; } - if (resize_step) { + if (resize_stp) { constrain_window(win, r, 1); update_window(win); store_float_geom(win,r); @@ -5125,7 +5246,7 @@ void move(struct ws_win *win, union arg *args) { xcb_timestamp_t timestamp = 0; - int move_step = 0, moving; + int move_stp = 0, moving; struct swm_region *r = NULL; xcb_query_pointer_reply_t *qpr; xcb_generic_event_t *evt; @@ -5158,28 +5279,28 @@ move(struct ws_win *win, union arg *args) focus_flush(); - move_step = 0; + move_stp = 0; switch (args->id) { case SWM_ARG_ID_MOVELEFT: X(win) -= (SWM_MOVE_STEPS - border_width); - move_step = 1; + move_stp = 1; break; case SWM_ARG_ID_MOVERIGHT: X(win) += (SWM_MOVE_STEPS - border_width); - move_step = 1; + move_stp = 1; break; case SWM_ARG_ID_MOVEUP: Y(win) -= (SWM_MOVE_STEPS - border_width); - move_step = 1; + move_stp = 1; break; case SWM_ARG_ID_MOVEDOWN: Y(win) += (SWM_MOVE_STEPS - border_width); - move_step = 1; + move_stp = 1; break; default: break; } - if (move_step) { + if (move_stp) { constrain_window(win, r, 0); update_window(win); store_float_geom(win, r); @@ -5253,101 +5374,6 @@ move_step(struct swm_region *r, union arg *args) focus_flush(); } -/* user/key callable function IDs */ -enum keyfuncid { - 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 */ struct keyfunc { char name[SWM_FUNCNAME_LEN]; @@ -5447,14 +5473,6 @@ struct keyfunc { { "dumpwins", dumpwins, {0} }, /* MUST BE LAST */ { "invalid key func", NULL, {0} }, }; -struct key { - RB_ENTRY(key) entry; - unsigned int mod; - KeySym keysym; - enum keyfuncid funcid; - char *spawn_name; -}; -RB_HEAD(key_tree, key); int key_cmp(struct key *kp1, struct key *kp2) @@ -5472,9 +5490,6 @@ key_cmp(struct key *kp1, struct key *kp2) return (0); } -RB_GENERATE(key_tree, key, entry, key_cmp); -struct key_tree keys; - /* mouse */ enum { client_click, root_click }; struct button { @@ -5930,7 +5945,7 @@ setkeybinding(unsigned int mod, KeySym ks, enum keyfuncid kfid, return; } if (kfid == KF_INVALID) { - warnx("error: setkeybinding: cannot find mod/key combination"); + warnx("bind: Key combination already unbound."); DNPRINTF(SWM_D_KEY, "setkeybinding: leave\n"); return; } @@ -6167,7 +6182,7 @@ grabkeys(void) { struct key *kp; int num_screens, k, j; - unsigned int modifiers[3]; + unsigned int modifiers[4]; xcb_keycode_t *code; DNPRINTF(SWM_D_MISC, "grabkeys\n"); @@ -6175,7 +6190,8 @@ grabkeys(void) modifiers[0] = 0; modifiers[1] = numlockmask; - modifiers[2] = numlockmask | XCB_MOD_MASK_LOCK; + modifiers[2] = XCB_MOD_MASK_LOCK; + modifiers[3] = numlockmask | XCB_MOD_MASK_LOCK; num_screens = xcb_setup_roots_length(xcb_get_setup(conn)); for (k = 0; k < num_screens; k++) { @@ -6201,16 +6217,25 @@ grabkeys(void) void grabbuttons(struct ws_win *win) { - int i; + unsigned int modifiers[4]; + int i, j; DNPRINTF(SWM_D_MOUSE, "grabbuttons: win 0x%x\n", win->id); + updatenumlockmask(); + + modifiers[0] = 0; + modifiers[1] = numlockmask; + modifiers[2] = XCB_MOD_MASK_LOCK; + modifiers[3] = numlockmask | XCB_MOD_MASK_LOCK; for (i = 0; i < LENGTH(buttons); i++) if (buttons[i].action == client_click) - xcb_grab_button(conn, 0, win->id, BUTTONMASK, - XCB_GRAB_MODE_SYNC, XCB_GRAB_MODE_ASYNC, - XCB_WINDOW_NONE, XCB_CURSOR_NONE, - buttons[i].button, buttons[i].mask); + for (j = 0; j < LENGTH(modifiers); ++j) + xcb_grab_button(conn, 0, win->id, BUTTONMASK, + XCB_GRAB_MODE_SYNC, XCB_GRAB_MODE_ASYNC, + XCB_WINDOW_NONE, XCB_CURSOR_NONE, + buttons[i].button, buttons[i].mask | + modifiers[j]); } const char *quirkname[] = { @@ -7432,7 +7457,13 @@ buttonpress(xcb_button_press_event_t *e) /* Focus on empty region */ /* If no windows on region if its empty. */ r = root_to_region(e->root, SWM_CK_POINTER); - if (r && TAILQ_EMPTY(&r->ws->winlist)) { + if (r == NULL) { + DNPRINTF(SWM_D_EVENT, "buttonpress: " + "NULL region; ignoring.\n"); + goto out; + } + + if (TAILQ_EMPTY(&r->ws->winlist)) { old_r = root_to_region(e->root, SWM_CK_FOCUS); if (old_r && old_r != r) unfocus_win(old_r->ws->focus); @@ -7641,9 +7672,10 @@ configurerequest(xcb_configure_request_event_t *e) WIDTH(win) = win->g_float.w; HEIGHT(win) = win->g_float.h; - stack_floater(win, win->ws->r); - - focus_flush(); + if (r) { + stack_floater(win, r); + focus_flush(); + } } else { config_win(win, e); xcb_flush(conn); @@ -7806,6 +7838,12 @@ enternotify(xcb_enter_notify_event_t *e) if (e->event == e->root) { /* If no windows on pointer region, then focus root. */ r = root_to_region(e->root, SWM_CK_POINTER); + if (r == NULL) { + DNPRINTF(SWM_D_EVENT, "enterntoify: " + "NULL region; ignoring.\n"); + return; + } + if (TAILQ_EMPTY(&r->ws->winlist)) { old_r = root_to_region(e->root, SWM_CK_FOCUS); if (old_r && old_r != r) @@ -7846,9 +7884,6 @@ leavenotify(xcb_leave_notify_event_t *e) } #endif -/* lets us use one switch statement for arbitrary mode/detail combinations */ -#define MERGE_MEMBERS(a,b) (((a & 0xffff) << 16) | (b & 0xffff)) - void mapnotify(xcb_map_notify_event_t *e) {