diff -r 131d4f6a8a1e config.def.h --- a/config.def.h Fri Jul 29 20:01:22 2011 +0200 +++ b/config.def.h Sun Jul 31 08:52:30 2011 -0400 @@ -34,7 +34,22 @@ }; /* key definitions */ +#define MODBUT Mod1Mask #define MODKEY Mod1Mask + +/* use prefix key if defined, modifiers if undefined */ +#define PREKEY XK_t +#define MODPRE ControlMask + +/* Prefix keys setup */ +#ifdef PREKEY +#define MODKEY 0 +#define prekeys prefixkeys +#else +#define MODKEY MODKBD +#define prekeys keys +#endif + #define TAGKEYS(KEY,TAG) \ { MODKEY, KEY, view, {.ui = 1 << TAG} }, \ { MODKEY|ControlMask, KEY, toggleview, {.ui = 1 << TAG} }, \ @@ -50,6 +65,9 @@ static Key keys[] = { /* modifier key function argument */ +#ifdef PREKEY + { MODPRE, PREKEY, prefixlit, {0} }, +#endif { MODKEY, XK_p, spawn, {.v = dmenucmd } }, { MODKEY|ShiftMask, XK_Return, spawn, {.v = termcmd } }, { MODKEY, XK_b, togglebar, {0} }, @@ -83,6 +101,10 @@ { MODKEY|ShiftMask, XK_q, quit, {0} }, }; +static Key prefixkeys[] = { + { MODPRE, XK_t, prefix, {0} }, +}; + /* button definitions */ /* click can be ClkLtSymbol, ClkStatusText, ClkWinTitle, ClkClientWin, or ClkRootWin */ static Button buttons[] = { @@ -91,12 +113,12 @@ { ClkLtSymbol, 0, Button3, setlayout, {.v = &layouts[2]} }, { ClkWinTitle, 0, Button2, zoom, {0} }, { ClkStatusText, 0, Button2, spawn, {.v = termcmd } }, - { ClkClientWin, MODKEY, Button1, movemouse, {0} }, - { ClkClientWin, MODKEY, Button2, togglefloating, {0} }, - { ClkClientWin, MODKEY, Button3, resizemouse, {0} }, + { ClkClientWin, MODBUT, Button1, movemouse, {0} }, + { ClkClientWin, MODBUT, Button2, togglefloating, {0} }, + { ClkClientWin, MODBUT, Button3, resizemouse, {0} }, { ClkTagBar, 0, Button1, view, {0} }, { ClkTagBar, 0, Button3, toggleview, {0} }, - { ClkTagBar, MODKEY, Button1, tag, {0} }, - { ClkTagBar, MODKEY, Button3, toggletag, {0} }, + { ClkTagBar, MODBUT, Button1, tag, {0} }, + { ClkTagBar, MODBUT, Button3, toggletag, {0} }, }; diff -r 131d4f6a8a1e dwm.c --- a/dwm.c Fri Jul 29 20:01:22 2011 +0200 +++ b/dwm.c Sun Jul 31 08:52:30 2011 -0400 @@ -191,6 +191,7 @@ static void grabkeys(void); static void initfont(const char *fontstr); static void keypress(XEvent *e); +static int keysymfunc(Key *ks, unsigned int l, KeySym keysym, unsigned int state); static void killclient(const Arg *arg); static void manage(Window w, XWindowAttributes *wa); static void mappingnotify(XEvent *e); @@ -201,6 +202,8 @@ static void pop(Client *); static void propertynotify(XEvent *e); static Monitor *ptrtomon(int x, int y); +static void prefix(const Arg *arg); +static void prefixlit(const Arg *arg); static void quit(const Arg *arg); static void resize(Client *c, int x, int y, int w, int h, Bool interact); static void resizeclient(Client *c, int x, int y, int w, int h); @@ -1015,10 +1018,10 @@ KeyCode code; XUngrabKey(dpy, AnyKey, AnyModifier, root); - for(i = 0; i < LENGTH(keys); i++) - if((code = XKeysymToKeycode(dpy, keys[i].keysym))) + for(i = 0; i < LENGTH(prekeys); i++) + if((code = XKeysymToKeycode(dpy, prekeys[i].keysym))) for(j = 0; j < LENGTH(modifiers); j++) - XGrabKey(dpy, code, keys[i].mod | modifiers[j], root, + XGrabKey(dpy, code, prekeys[i].mod | modifiers[j], root, True, GrabModeAsync, GrabModeAsync); } } @@ -1070,17 +1073,26 @@ void keypress(XEvent *e) { - unsigned int i; KeySym keysym; - XKeyEvent *ev; - ev = &e->xkey; - keysym = XKeycodeToKeysym(dpy, (KeyCode)ev->keycode, 0); - for(i = 0; i < LENGTH(keys); i++) - if(keysym == keys[i].keysym - && CLEANMASK(keys[i].mod) == CLEANMASK(ev->state) - && keys[i].func) - keys[i].func(&(keys[i].arg)); + keysym = XKeycodeToKeysym(dpy, (KeyCode)e->xkey.keycode, 0); + keysymfunc(prekeys,LENGTH(prekeys),keysym,e->xkey.state); + /* Ignore return value. */ +} + +int +keysymfunc(Key *ks,unsigned int l,KeySym keysym,unsigned int state) { + unsigned int i; + + for(i = 0; i < l; i++) + if(keysym == ks[i].keysym + && CLEANMASK(ks[i].mod) == CLEANMASK(state) + && ks[i].func) { + ks[i].func(&(ks[i].arg)); + return 1; + } + + return 0; } void @@ -1609,6 +1621,55 @@ } void +prefix(const Arg *arg) { + XEvent ev; + KeySym keysym; + Window win; + + if (selmon->sel) { + win = selmon->sel->win; + } + else { + XSetInputFocus(dpy, root, RevertToPointerRoot, CurrentTime); + win = root; + } + XGrabPointer (dpy, win, True, 0, + GrabModeAsync, GrabModeAsync, + None, cursor[CurMove], CurrentTime); + XGrabKeyboard(dpy, win, False, GrabModeAsync, GrabModeAsync, CurrentTime); + + do { + if (!running) + return; + XMaskEvent(dpy, KeyPressMask|KeyRelease, &ev); + keysym = XKeycodeToKeysym(dpy, (KeyCode)ev.xkey.keycode, 0); + } while (IsModifierKey(keysym) || KeyRelease == ev.xkey.type); + + XUngrabKeyboard(dpy, CurrentTime); + XUngrabPointer(dpy, CurrentTime); + + keysymfunc(keys,LENGTH(keys),keysym,ev.xkey.state); + /* Ignore return value. */ +} + +void +prefixlit(const Arg *arg) { + XEvent ev; + + if (!selmon->sel || !selmon->sel->win) + return; + + ev.xkey.type = KeyPress; + ev.xkey.display = dpy; + ev.xkey.window = selmon->sel->win; + ev.xkey.state = MODPRE; + ev.xkey.keycode = XKeysymToKeycode(dpy, PREKEY); + + XSendEvent(dpy, selmon->sel->win, False, KeyPressMask, &ev); + XSync (dpy, False); +} + +void spawn(const Arg *arg) { if(fork() == 0) { if(dpy)