dwm-keymodes-5.8.2.diff (8503B)
1 diff -up ../dwm-5.8.2-0/config.def.h ./config.def.h 2 --- ../dwm-5.8.2-0/config.def.h 2010-06-10 22:47:51.660949000 +0200 3 +++ ./config.def.h 2010-06-11 00:18:55.082073000 +0200 4 @@ -16,6 +16,9 @@ static const Bool topbar = Tr 5 /* tagging */ 6 static const char *tags[] = { "1", "2", "3", "4", "5", "6", "7", "8", "9" }; 7 8 +/* include(s) defining functions */ 9 +#include "keymodes.pre.h" 10 + 11 static const Rule rules[] = { 12 /* class instance title tags mask isfloating monitor */ 13 { "Gimp", NULL, NULL, 0, True, -1 }, 14 @@ -47,9 +50,11 @@ static const Layout layouts[] = { 15 /* commands */ 16 static const char *dmenucmd[] = { "dmenu_run", "-fn", font, "-nb", normbgcolor, "-nf", normfgcolor, "-sb", selbgcolor, "-sf", selfgcolor, NULL }; 17 static const char *termcmd[] = { "uxterm", NULL }; 18 +static const char *helpcmd[] = { "uxterm", "-e", "man", "dwm", NULL }; 19 20 static Key keys[] = { 21 /* modifier key function argument */ 22 + { MODKEY, XK_Escape, setkeymode, {.ui = COMMANDMODE} }, 23 { MODKEY, XK_p, spawn, {.v = dmenucmd } }, 24 { MODKEY|ShiftMask, XK_Return, spawn, {.v = termcmd } }, 25 { MODKEY, XK_b, togglebar, {0} }, 26 @@ -83,6 +88,30 @@ static Key keys[] = { 27 { MODKEY|ShiftMask, XK_q, quit, {0} }, 28 }; 29 30 +static Key cmdkeys[] = { 31 + /* modifier keys function argument */ 32 + { 0, XK_Escape, clearcmd, {0} }, 33 + { ControlMask, XK_c, clearcmd, {0} }, 34 + { 0, XK_i, setkeymode, {.ui = INSERTMODE} }, 35 +}; 36 +static Command commands[] = { 37 + /* modifier (4 keys) keysyms (4 keys) function argument */ 38 + { {ControlMask, ShiftMask, 0, 0}, {XK_w, XK_h, 0, 0}, setlayout, {.v = &layouts[0]} }, 39 + { {ControlMask, 0, 0, 0}, {XK_w, XK_o, 0, 0}, setlayout, {.v = &layouts[2]} }, 40 + { {ControlMask, ShiftMask, 0, 0}, {XK_w, XK_o, 0, 0}, onlyclient, {0} }, 41 + { {ControlMask, 0, 0, 0}, {XK_w, XK_v, 0, 0}, setlayout, {.v = &layouts[0]} }, 42 + { {ControlMask, 0, 0, 0}, {XK_w, XK_less, 0, 0}, setmfact, {.f = -0.05} }, 43 + { {ControlMask, ShiftMask, 0, 0}, {XK_w, XK_less, 0, 0}, setmfact, {.f = +0.05} }, 44 + { {ControlMask, ShiftMask, 0, 0}, {XK_w, XK_0, 0, 0}, setmfact, {.f = +1.50} }, 45 + { {ShiftMask, 0, 0, 0}, {XK_period, XK_e, 0, 0}, spawn, {.v = dmenucmd} }, 46 + { {ShiftMask, 0, 0, 0}, {XK_period, XK_o, 0, 0}, spawn, {.v = dmenucmd} }, 47 + { {ShiftMask, 0, 0, 0}, {XK_period, XK_h, XK_Return, 0}, spawn, {.v = helpcmd} }, 48 + { {ShiftMask, 0, 0, 0}, {XK_period, XK_q, XK_Return, 0}, quit, {0} }, 49 + { {ShiftMask, 0, 0, 0}, {XK_period, XK_b, XK_d, XK_Return}, killclient, {0} }, 50 + { {ShiftMask, 0, 0, 0}, {XK_period, XK_b, XK_n, XK_Return}, focusstack, {.i = +1} }, 51 + { {ShiftMask, 0, ShiftMask, 0}, {XK_period, XK_b, XK_n, XK_Return}, focusstack, {.i = -1} }, 52 +}; 53 + 54 /* button definitions */ 55 /* click can be ClkLtSymbol, ClkStatusText, ClkWinTitle, ClkClientWin, or ClkRootWin */ 56 static Button buttons[] = { 57 @@ -100,3 +129,5 @@ static Button buttons[] = { 58 { ClkTagBar, MODKEY, Button3, toggletag, {0} }, 59 }; 60 61 +/* include(s) depending on the configuration variables */ 62 +#include "keymodes.post.h" 63 diff -up ../dwm-5.8.2-0/dwm.c ./dwm.c 64 --- ../dwm-5.8.2-0/dwm.c 2010-06-10 22:47:51.669677000 +0200 65 +++ ./dwm.c 2010-06-11 00:18:55.106090000 +0200 66 @@ -970,7 +970,7 @@ grabbuttons(Client *c, Bool focused) { 67 } 68 69 void 70 -grabkeys(void) { 71 +grabdefkeys(void) { 72 updatenumlockmask(); 73 { 74 unsigned int i, j; 75 @@ -1052,7 +1052,7 @@ isuniquegeom(XineramaScreenInfo *unique, 76 #endif /* XINERAMA */ 77 78 void 79 -keypress(XEvent *e) { 80 +defkeypress(XEvent *e) { 81 unsigned int i; 82 KeySym keysym; 83 XKeyEvent *ev; 84 diff -up ../dwm-5.8.2-0/keymodes.post.h ./keymodes.post.h 85 --- ../dwm-5.8.2-0/keymodes.post.h 2010-06-11 00:21:46.000000000 +0200 86 +++ ./keymodes.post.h 2010-06-11 00:18:55.119222000 +0200 87 @@ -0,0 +1,124 @@ 88 +/* See LICENSE file for copyright and license details. */ 89 +/* © 2010 joten <joten@freenet.de> */ 90 + 91 +/* function implementations */ 92 +void 93 +clearcmd(const Arg *arg) { 94 + unsigned int i; 95 + 96 + for(i = 0; i < LENGTH(cmdkeysym); i++) { 97 + cmdkeysym[i] = 0; 98 + cmdmod[i] = 0; 99 + } 100 +} 101 + 102 +void 103 +grabkeys(void) { 104 + if(keymode == INSERTMODE) { 105 + grabdefkeys(); 106 + } else if(keymode == COMMANDMODE) { 107 + XUngrabKey(dpy, AnyKey, AnyModifier, root); 108 + XGrabKey(dpy, AnyKey, AnyModifier, root, 109 + True, GrabModeAsync, GrabModeAsync); 110 + } 111 +} 112 + 113 +void 114 +keypress(XEvent *e) { 115 + unsigned int i, j; 116 + Arg a = {0}; 117 + Bool ismatch = False, maybematch = False; 118 + KeySym keysym; 119 + XKeyEvent *ev; 120 + 121 + if(keymode == INSERTMODE) 122 + defkeypress(e); 123 + else if(keymode == COMMANDMODE) { 124 + ev = &e->xkey; 125 + keysym = XKeycodeToKeysym(dpy, (KeyCode)ev->keycode, 0); 126 + if(keysym < XK_Shift_L || keysym > XK_Hyper_R) { 127 + for(i = 0; i < LENGTH(cmdkeys); i++) 128 + if(keysym == cmdkeys[i].keysym 129 + && CLEANMASK(cmdkeys[i].mod) == CLEANMASK(ev->state) 130 + && cmdkeys[i].func) { 131 + cmdkeys[i].func(&(cmdkeys[i].arg)); 132 + ismatch = True; 133 + break; 134 + } 135 + if(!ismatch) { 136 + for(j = 0; j < LENGTH(cmdkeysym); j++) 137 + if(cmdkeysym[j] == 0) { 138 + cmdkeysym[j] = keysym; 139 + cmdmod[j] = ev->state; 140 + break; 141 + } 142 + for(i = 0; i < LENGTH(commands); i++) { 143 + for(j = 0; j < LENGTH(cmdkeysym); j++) { 144 + if(cmdkeysym[j] == commands[i].keysym[j] 145 + && CLEANMASK(cmdmod[j]) == CLEANMASK(commands[i].mod[j])) 146 + ismatch = True; 147 + else if(cmdkeysym[j] == 0 148 + && cmdmod[j] == 0) { 149 + ismatch = False; 150 + maybematch = True; 151 + break; 152 + } else { 153 + ismatch = False; 154 + break; 155 + } 156 + } 157 + if(ismatch) { 158 + if(commands[i].func) 159 + commands[i].func(&(commands[i].arg)); 160 + clearcmd(&a); 161 + break; 162 + } 163 + 164 + } 165 + if(!maybematch) 166 + clearcmd(&a); 167 + } 168 + } 169 + } 170 +} 171 + 172 +void 173 +onlyclient(const Arg *arg) { 174 + Client *c; 175 + XEvent ev; 176 + 177 + if(!selmon->sel) 178 + return; 179 + for(c = selmon->clients; c; c = c->next) 180 + if(c != selmon->sel && ISVISIBLE(c)) { 181 + if(isprotodel(c)) { 182 + ev.type = ClientMessage; 183 + ev.xclient.window = c->win; 184 + ev.xclient.message_type = wmatom[WMProtocols]; 185 + ev.xclient.format = 32; 186 + ev.xclient.data.l[0] = wmatom[WMDelete]; 187 + ev.xclient.data.l[1] = CurrentTime; 188 + XSendEvent(dpy, c->win, False, NoEventMask, &ev); 189 + } 190 + else { 191 + XGrabServer(dpy); 192 + XSetErrorHandler(xerrordummy); 193 + XSetCloseDownMode(dpy, DestroyAll); 194 + XKillClient(dpy, c->win); 195 + XSync(dpy, False); 196 + XSetErrorHandler(xerror); 197 + XUngrabServer(dpy); 198 + } 199 + } 200 +} 201 + 202 +void 203 +setkeymode(const Arg *arg) { 204 + Arg a = {0}; 205 + 206 + if(!arg) 207 + return; 208 + keymode = arg->ui; 209 + clearcmd(&a); 210 + grabkeys(); 211 +} 212 diff -up ../dwm-5.8.2-0/keymodes.pre.h ./keymodes.pre.h 213 --- ../dwm-5.8.2-0/keymodes.pre.h 2010-06-11 00:21:38.000000000 +0200 214 +++ ./keymodes.pre.h 2010-06-11 00:18:55.121759000 +0200 215 @@ -0,0 +1,24 @@ 216 +/* See LICENSE file for copyright and license details. */ 217 +/* © 2010 joten <joten@freenet.de> */ 218 + 219 +#define COMMANDMODE 1 220 +#define INSERTMODE 2 221 + 222 +typedef struct { 223 + unsigned int mod[4]; 224 + KeySym keysym[4]; 225 + void (*func)(const Arg *); 226 + const Arg arg; 227 +} Command; 228 + 229 +/* function declarations */ 230 +static void clearcmd(const Arg *arg); 231 +static void defkeypress(XEvent *e); 232 +static void grabdefkeys(void); 233 +static void onlyclient(const Arg *arg); 234 +static void setkeymode(const Arg *arg); 235 + 236 +/* variables */ 237 +static unsigned int cmdmod[4]; 238 +static unsigned int keymode = COMMANDMODE; 239 +static KeySym cmdkeysym[4];