From d79df47289fd9754e2c84d54ada0ac42d8d93c8b Mon Sep 17 00:00:00 2001 From: Per Cederqvist Date: Thu, 7 Feb 2013 15:21:33 +0100 Subject: Added support for backtabbing. Thanks ceder! --- config.h | 3 ++- mcwm.c | 82 ++++++++++++++++++++++++++++++++++++++++++++++++++-------------- mcwm.man | 6 +++++ 3 files changed, 72 insertions(+), 19 deletions(-) diff --git a/config.h b/config.h index f26fa6b..941f12e 100644 --- a/config.h +++ b/config.h @@ -63,7 +63,7 @@ /* * Keysym codes for window operations. Look in X11/keysymdefs.h for - * actual symbols. + * actual symbols. Use XK_VoidSymbol to disable a function. */ #define USERKEY_FIX XK_F #define USERKEY_MOVE_LEFT XK_H @@ -75,6 +75,7 @@ #define USERKEY_TERMINAL XK_Return #define USERKEY_MAX XK_X #define USERKEY_CHANGE XK_Tab +#define USERKEY_BACKCHANGE XK_VoidSymbol #define USERKEY_WS1 XK_1 #define USERKEY_WS2 XK_2 #define USERKEY_WS3 XK_3 diff --git a/mcwm.c b/mcwm.c index c8764e4..3fcfa5e 100644 --- a/mcwm.c +++ b/mcwm.c @@ -110,6 +110,7 @@ typedef enum { KEY_RET, KEY_X, KEY_TAB, + KEY_BACKTAB, KEY_1, KEY_2, KEY_3, @@ -238,6 +239,7 @@ struct keys { USERKEY_TERMINAL, 0 }, { USERKEY_MAX, 0 }, { USERKEY_CHANGE, 0 }, + { USERKEY_BACKCHANGE, 0 }, { USERKEY_WS1, 0 }, { USERKEY_WS2, 0 }, { USERKEY_WS3, 0 }, @@ -331,7 +333,7 @@ static void raiseorlower(struct client *client); static void movelim(struct client *client); static void movewindow(xcb_drawable_t win, uint16_t x, uint16_t y); static struct client *findclient(xcb_drawable_t win); -static void focusnext(void); +static void focusnext(bool reverse); static void setunfocus(xcb_drawable_t win); static void setfocus(struct client *client); static int start(char *program); @@ -1268,6 +1270,12 @@ int setupkeys(void) /* Now grab the rest of the keys with the MODKEY modifier. */ for (i = KEY_F; i < KEY_MAX; i ++) { + if (XK_VoidSymbol == keys[i].keysym) + { + keys[i].keycode = 0; + continue; + } + keys[i].keycode = keysymtokeycode(keys[i].keysym, keysyms); if (0 == keys[i].keycode) { @@ -1910,7 +1918,7 @@ void movewindow(xcb_drawable_t win, uint16_t x, uint16_t y) } /* Change focus to next in window ring. */ -void focusnext(void) +void focusnext(bool reverse) { struct client *client = NULL; @@ -1954,25 +1962,54 @@ void focusnext(void) } else { - if (NULL == focuswin->wsitem[curws]->next) + if (reverse) { - /* - * We were at the end of list. Focusing on first window in - * list unless we were already there. - */ - if (focuswin->wsitem[curws] != wslist[curws]->data) + if (NULL == focuswin->wsitem[curws]->prev) + { + /* + * We were at the head of list. Focusing on last + * window in list unless we were already there. + */ + struct item *last = wslist[curws]; + while (NULL != last->next) + last = last->next; + if (focuswin->wsitem[curws] != last->data) + { + PDEBUG("Beginning of list. Focusing last in list: %p\n", + last); + client = last->data; + } + } + else { - PDEBUG("End of list. Focusing first in list: %p\n", - wslist[curws]); - client = wslist[curws]->data; + /* Otherwise, focus the next in list. */ + PDEBUG("Tabbing. Focusing next: %p.\n", + focuswin->wsitem[curws]->prev); + client = focuswin->wsitem[curws]->prev->data; } } else { - /* Otherwise, focus the next in list. */ - PDEBUG("Tabbing. Focusing next: %p.\n", - focuswin->wsitem[curws]->next); - client = focuswin->wsitem[curws]->next->data; + if (NULL == focuswin->wsitem[curws]->next) + { + /* + * We were at the end of list. Focusing on first window in + * list unless we were already there. + */ + if (focuswin->wsitem[curws] != wslist[curws]->data) + { + PDEBUG("End of list. Focusing first in list: %p\n", + wslist[curws]); + client = wslist[curws]->data; + } + } + else + { + /* Otherwise, focus the next in list. */ + PDEBUG("Tabbing. Focusing next: %p.\n", + focuswin->wsitem[curws]->next); + client = focuswin->wsitem[curws]->next->data; + } } } /* if NULL focuswin */ @@ -2960,9 +2997,10 @@ void handle_keypress(xcb_key_press_event_t *ev) for (key = KEY_MAX, i = KEY_F; i < KEY_MAX; i ++) { - if (ev->detail == keys[i].keycode) + if (ev->detail == keys[i].keycode && 0 != keys[i].keycode) { key = i; + break; } } if (key == KEY_MAX) @@ -2979,7 +3017,7 @@ void handle_keypress(xcb_key_press_event_t *ev) return; } - if (MCWM_TABBING == mode && key != KEY_TAB) + if (MCWM_TABBING == mode && key != KEY_TAB && key != KEY_BACKTAB) { /* First finish tabbing around. Then deal with the next key. */ finishtabbing(); @@ -3006,6 +3044,10 @@ void handle_keypress(xcb_key_press_event_t *ev) resizestep(focuswin, 'l'); break; + case KEY_TAB: /* shifted tab counts as backtab */ + focusnext(true); + break; + default: /* Ignore other shifted keys. */ break; @@ -3040,7 +3082,11 @@ void handle_keypress(xcb_key_press_event_t *ev) break; case KEY_TAB: /* tab */ - focusnext(); + focusnext(false); + break; + + case KEY_BACKTAB: /* backtab */ + focusnext(true); break; case KEY_M: /* m */ diff --git a/mcwm.man b/mcwm.man index b006860..24304ab 100644 --- a/mcwm.man +++ b/mcwm.man @@ -132,6 +132,12 @@ MODKEY or press another command key mcwm will change focus to the new window. A new press of MODKEY + Tab will bring you back to the window where you last had focus. .IP \(bu 2 +.B Shift-Tab +go to previous window in the current workspace window ring. This is +most useful while you are tabbing: if you accidentally pressed Tab one +time too many, you can move back by pressing Shift + TAB (all the +while holding down the MODKEY). +.IP \(bu 2 .B f fix window so it is visible on all workspaces (toggles). Note that this is also used to move windows between workspaces: First fix the -- cgit v1.2.3