X-Git-Url: https://jasonwoof.com/gitweb/?a=blobdiff_plain;ds=sidebyside;f=spectrwm.c;h=a6ef35f8456e78e3c33aaad594139050ebc1892b;hb=749dbb28b26faa84871dcd745ca4b4e6150c3955;hp=5ad56a7e6a47987da979dc62ec8f4b4f02123d51;hpb=417c9ef016f696666123beba0973bf544002f88a;p=spectrwm.git diff --git a/spectrwm.c b/spectrwm.c index 5ad56a7..a6ef35f 100644 --- a/spectrwm.c +++ b/spectrwm.c @@ -577,6 +577,8 @@ union arg { #define SWM_ARG_ID_CYCLERG_DOWN (43) #define SWM_ARG_ID_CYCLEWS_UP_ALL (44) #define SWM_ARG_ID_CYCLEWS_DOWN_ALL (45) +#define SWM_ARG_ID_CYCLEWS_MOVE_UP (46) +#define SWM_ARG_ID_CYCLEWS_MOVE_DOWN (47) #define SWM_ARG_ID_STACKINC (50) #define SWM_ARG_ID_STACKDEC (51) #define SWM_ARG_ID_SS_ALL (60) @@ -831,8 +833,10 @@ enum keyfuncid { KF_WS_22, KF_WS_NEXT, KF_WS_NEXT_ALL, + KF_WS_NEXT_MOVE, KF_WS_PREV, KF_WS_PREV_ALL, + KF_WS_PREV_MOVE, KF_WS_PRIOR, KF_DUMPWINS, /* MUST BE LAST */ KF_INVALID @@ -991,10 +995,10 @@ struct swm_region *root_to_region(xcb_window_t, int); void screenchange(xcb_randr_screen_change_notify_event_t *); void scan_xrandr(int); void search_do_resp(void); -void search_resp_name_workspace(const char *, unsigned long); +void search_resp_name_workspace(const char *, size_t); void search_resp_search_window(const char *); void search_resp_search_workspace(const char *); -void search_resp_uniconify(const char *, unsigned long); +void search_resp_uniconify(const char *, size_t); void search_win(struct swm_region *, union arg *); void search_win_cleanup(void); void search_workspace(struct swm_region *, union arg *); @@ -2975,6 +2979,8 @@ root_to_region(xcb_window_t root, int check) if (r == NULL && check & SWM_CK_FALLBACK) r = TAILQ_FIRST(&screens[i].rl); + DNPRINTF(SWM_D_MISC, "root_to_region: idx: %d\n", get_region_index(r)); + return (r); } @@ -3408,7 +3414,7 @@ focus_region(struct swm_region *r) if (old_r) unfocus_win(old_r->ws->focus); - xcb_set_input_focus(conn, XCB_INPUT_FOCUS_PARENT, r->s->root, + xcb_set_input_focus(conn, XCB_INPUT_FOCUS_PARENT, r->id, XCB_CURRENT_TIME); /* Clear bar since empty. */ @@ -3474,17 +3480,16 @@ switchws(struct swm_region *r, union arg *args) if (old_ws->r && focus_mode != SWM_FOCUS_FOLLOW) { if (new_ws->focus_pending) { focus_win(new_ws->focus_pending); - } else { - /* Empty region, focus on root. */ - xcb_set_input_focus(conn, XCB_INPUT_FOCUS_PARENT, - new_ws->r->s[new_ws->r->s->idx].root, - XCB_CURRENT_TIME); + new_ws->focus_pending = NULL; } } - /* Clear bar if new ws is empty. */ - if (new_ws->focus_pending == NULL) + /* Clear bar and set focus on region input win if new ws is empty. */ + if (new_ws->focus_pending == NULL && new_ws->focus == NULL) { + xcb_set_input_focus(conn, XCB_INPUT_FOCUS_PARENT, r->id, + XCB_CURRENT_TIME); bar_draw(); + } focus_flush(); @@ -3497,30 +3502,32 @@ cyclews(struct swm_region *r, union arg *args) union arg a; struct swm_screen *s = r->s; int cycle_all = 0; + int move = 0; DNPRINTF(SWM_D_WS, "cyclews: id: %d, screen[%d]:%dx%d+%d+%d, ws: %d\n", args->id, r->s->idx, WIDTH(r), HEIGHT(r), X(r), Y(r), r->ws->idx); a.id = r->ws->idx; + do { switch (args->id) { + case SWM_ARG_ID_CYCLEWS_MOVE_UP: + move = 1; + /* FALLTHROUGH */ case SWM_ARG_ID_CYCLEWS_UP_ALL: cycle_all = 1; /* FALLTHROUGH */ case SWM_ARG_ID_CYCLEWS_UP: - if (a.id < workspace_limit - 1) - a.id++; - else - a.id = 0; + a.id = (a.id < workspace_limit - 1) ? a.id + 1 : 0; break; + case SWM_ARG_ID_CYCLEWS_MOVE_DOWN: + move = 1; + /* FALLTHROUGH */ case SWM_ARG_ID_CYCLEWS_DOWN_ALL: cycle_all = 1; /* FALLTHROUGH */ case SWM_ARG_ID_CYCLEWS_DOWN: - if (a.id > 0) - a.id--; - else - a.id = workspace_limit - 1; + a.id = (a.id > 0) ? a.id - 1 : workspace_limit - 1; break; default: return; @@ -3532,6 +3539,9 @@ cyclews(struct swm_region *r, union arg *args) if (!cycle_visible && s->ws[a.id].r != NULL) continue; + if (move) + send_to_ws(r, &a); + switchws(r, &a); } while (a.id != r->ws->idx); } @@ -4489,6 +4499,8 @@ max_stack(struct workspace *ws, struct swm_geometry *g) win = ws->focus_pending; else if (ws->focus) win = ws->focus; + else if (ws->focus_prev) + win = ws->focus_prev; else win = TAILQ_FIRST(&ws->winlist); @@ -4623,11 +4635,10 @@ send_to_ws(struct swm_region *r, union arg *args) unfocus_win(parent); - if (focus_mode != SWM_FOCUS_FOLLOW) + if (focus_mode != SWM_FOCUS_FOLLOW) { pws->focus = pws->focus_pending; - - if (focus_mode != SWM_FOCUS_FOLLOW) pws->focus_pending = NULL; + } } /* Don't unmap parent if new ws is visible */ @@ -4672,8 +4683,14 @@ send_to_ws(struct swm_region *r, union arg *args) stack(); if (focus_mode != SWM_FOCUS_FOLLOW) { - focus_win(ws->focus_pending); - ws->focus_pending = NULL; + if (ws->focus_pending) { + focus_win(ws->focus_pending); + ws->focus_pending = NULL; + } else { + xcb_set_input_focus(conn, + XCB_INPUT_FOCUS_PARENT, r->id, + XCB_CURRENT_TIME); + } } focus_flush(); @@ -4985,7 +5002,7 @@ search_win(struct swm_region *r, union arg *args) } void -search_resp_uniconify(const char *resp, unsigned long len) +search_resp_uniconify(const char *resp, size_t len) { char *name; struct ws_win *win; @@ -5015,7 +5032,7 @@ search_resp_uniconify(const char *resp, unsigned long len) } void -search_resp_name_workspace(const char *resp, unsigned long len) +search_resp_name_workspace(const char *resp, size_t len) { struct workspace *ws; @@ -5111,7 +5128,7 @@ search_do_resp(void) { ssize_t rbytes; char *resp; - unsigned long len; + size_t len; DNPRINTF(SWM_D_MISC, "search_do_resp:\n"); @@ -5762,8 +5779,10 @@ struct keyfunc { { "ws_22", switchws, {.id = 21} }, { "ws_next", cyclews, {.id = SWM_ARG_ID_CYCLEWS_UP} }, { "ws_next_all", cyclews, {.id = SWM_ARG_ID_CYCLEWS_UP_ALL} }, + { "ws_next_move", cyclews, {.id = SWM_ARG_ID_CYCLEWS_MOVE_UP} }, { "ws_prev", cyclews, {.id = SWM_ARG_ID_CYCLEWS_DOWN} }, { "ws_prev_all", cyclews, {.id = SWM_ARG_ID_CYCLEWS_DOWN_ALL} }, + { "ws_prev_move", cyclews, {.id = SWM_ARG_ID_CYCLEWS_MOVE_DOWN} }, { "ws_prior", priorws, {0} }, { "dumpwins", dumpwins, {0} }, /* MUST BE LAST */ { "invalid key func", NULL, {0} }, @@ -6452,6 +6471,8 @@ setup_keys(void) 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_SHIFT, XK_Up, KF_WS_NEXT_MOVE,NULL); + setkeybinding(MODKEY_SHIFT, XK_Down, KF_WS_PREV_MOVE,NULL); setkeybinding(MODKEY, XK_a, KF_WS_PRIOR, NULL); #ifdef SWM_DEBUG setkeybinding(MODKEY_SHIFT, XK_d, KF_DUMPWINS, NULL); @@ -6549,6 +6570,16 @@ grabkeys(void) xcb_ungrab_key(conn, XCB_GRAB_ANY, screens[k].root, XCB_MOD_MASK_ANY); RB_FOREACH(kp, key_tree, &keys) { + /* Skip unused ws binds. */ + if ((int)kp->funcid > KF_WS_1 + workspace_limit - 1 && + kp->funcid <= KF_WS_22) + continue; + + /* Skip unused mvws binds. */ + if ((int)kp->funcid > KF_MVWS_1 + workspace_limit - 1 && + kp->funcid <= KF_MVWS_22) + continue; + if ((code = xcb_key_symbols_get_keycode(syms, kp->keysym))) { for (j = 0; j < LENGTH(modifiers); j++) @@ -8174,6 +8205,9 @@ destroynotify(xcb_destroy_notify_event_t *e) if (win->ws->focus_pending) { focus_win(win->ws->focus_pending); win->ws->focus_pending = NULL; + } else if (win == win->ws->focus && win->ws->r) { + xcb_set_input_focus(conn, XCB_INPUT_FOCUS_PARENT, + win->ws->r->id, XCB_CURRENT_TIME); } } @@ -8415,6 +8449,9 @@ motionnotify(xcb_motion_notify_event_t *e) last_event_time = e->time; + if (focus_mode == SWM_FOCUS_MANUAL) + return; + num_screens = get_screen_count(); for (i = 0; i < num_screens; i++) if (screens[i].root == e->root) @@ -8466,6 +8503,7 @@ void propertynotify(xcb_property_notify_event_t *e) { struct ws_win *win; + struct workspace *ws; #ifdef SWM_DEBUG char *name; @@ -8479,28 +8517,39 @@ propertynotify(xcb_property_notify_event_t *e) if (win == NULL) return; + ws = win->ws; + last_event_time = e->time; if (e->atom == a_swm_iconic) { if (e->state == XCB_PROPERTY_NEW_VALUE) { if (focus_mode != SWM_FOCUS_FOLLOW) - win->ws->focus_pending = get_focus_prev(win); + ws->focus_pending = get_focus_prev(win); unfocus_win(win); unmap_window(win); - if (win->ws->r) { + if (ws->r) { stack(); + if (focus_mode != SWM_FOCUS_FOLLOW) { - focus_win(win->ws->focus_pending); - win->ws->focus_pending = NULL; + if (ws->focus_pending) { + focus_win(ws->focus_pending); + ws->focus_pending = NULL; + } else { + xcb_set_input_focus(conn, + XCB_INPUT_FOCUS_PARENT, + ws->r->id, + XCB_CURRENT_TIME); + } } + focus_flush(); } } else if (e->state == XCB_PROPERTY_DELETE) { /* The window is no longer iconic, restack ws. */ if (focus_mode != SWM_FOCUS_FOLLOW) - win->ws->focus_pending = get_focus_magic(win); + ws->focus_pending = get_focus_magic(win); stack(); @@ -8512,9 +8561,9 @@ propertynotify(xcb_property_notify_event_t *e) if (e->state == XCB_PROPERTY_NEW_VALUE) { if (focus_mode != SWM_FOCUS_FOLLOW) { if (win->mapped && - win->ws->focus_pending == win) { - focus_win(win->ws->focus_pending); - win->ws->focus_pending = NULL; + ws->focus_pending == win) { + focus_win(ws->focus_pending); + ws->focus_pending = NULL; } } } @@ -8569,11 +8618,12 @@ unmapnotify(xcb_unmap_notify_event_t *e) if (focus_mode == SWM_FOCUS_FOLLOW) { if (ws->r) focus_win(get_pointer_win(ws->r->s->root)); - } else { - if (ws->focus_pending) { - focus_win(ws->focus_pending); - ws->focus_pending = NULL; - } + } else if (ws->focus_pending) { + focus_win(ws->focus_pending); + ws->focus_pending = NULL; + } else if (ws->focus == NULL && ws->r) { + xcb_set_input_focus(conn, XCB_INPUT_FOCUS_PARENT, + ws->r->id, XCB_CURRENT_TIME); } }