Introduction
Introduction Statistics Contact Development Disclaimer Help
dwm-keymodes-20220422.diff - sites - public wiki contents of suckless.org
git clone git://git.suckless.org/sites
Log
Files
Refs
---
dwm-keymodes-20220422.diff (11577B)
---
1 diff --git a/config.def.h b/config.def.h
2 index a2ac963..3bde49d 100644
3 --- a/config.def.h
4 +++ b/config.def.h
5 @@ -47,10 +47,10 @@ static const Layout layouts[] = {
6 /* key definitions */
7 #define MODKEY Mod1Mask
8 #define TAGKEYS(KEY,TAG) \
9 - { MODKEY, KEY, view, {.ui …
10 - { MODKEY|ControlMask, KEY, toggleview, {.ui …
11 - { MODKEY|ShiftMask, KEY, tag, {.ui …
12 - { MODKEY|ControlMask|ShiftMask, KEY, toggletag, {.ui …
13 + { {0,0,0,0}, {KEY,0,0,0}, view, …
14 + { {ControlMask,0,0,0}, {KEY,0,0,0}, toggleview, …
15 + { {ShiftMask,0,0,0}, {KEY,0,0,0}, tag, …
16 + { {ControlMask|ShiftMask,0,0,0}, {KEY,0,0,0}, toggletag, …
17
18 /* helper for spawning shell commands in the pre dwm-5.0 fashion */
19 #define SHCMD(cmd) { .v = (const char*[]){ "/bin/sh", "-c", cmd, NULL }…
20 @@ -62,39 +62,50 @@ static const char *termcmd[] = { "st", NULL };
21
22 static Key keys[] = {
23 /* modifier key function argu…
24 - { MODKEY, XK_p, spawn, {.v …
25 - { MODKEY|ShiftMask, XK_Return, spawn, {.v …
26 - { MODKEY, XK_b, togglebar, {0} …
27 - { MODKEY, XK_j, focusstack, {.i …
28 - { MODKEY, XK_k, focusstack, {.i …
29 - { MODKEY, XK_i, incnmaster, {.i …
30 - { MODKEY, XK_d, incnmaster, {.i …
31 - { MODKEY, XK_h, setmfact, {.f …
32 - { MODKEY, XK_l, setmfact, {.f …
33 - { MODKEY, XK_Return, zoom, {0} …
34 - { MODKEY, XK_Tab, view, {0} …
35 - { MODKEY|ShiftMask, XK_c, killclient, {0} …
36 - { MODKEY, XK_t, setlayout, {.v …
37 - { MODKEY, XK_f, setlayout, {.v …
38 - { MODKEY, XK_m, setlayout, {.v …
39 - { MODKEY, XK_space, setlayout, {0} …
40 - { MODKEY|ShiftMask, XK_space, togglefloating, {0} …
41 - { MODKEY, XK_0, view, {.ui…
42 - { MODKEY|ShiftMask, XK_0, tag, {.ui…
43 - { MODKEY, XK_comma, focusmon, {.i …
44 - { MODKEY, XK_period, focusmon, {.i …
45 - { MODKEY|ShiftMask, XK_comma, tagmon, {.i …
46 - { MODKEY|ShiftMask, XK_period, tagmon, {.i …
47 - TAGKEYS( XK_1, 0)
48 - TAGKEYS( XK_2, 1)
49 - TAGKEYS( XK_3, 2)
50 - TAGKEYS( XK_4, 3)
51 - TAGKEYS( XK_5, 4)
52 - TAGKEYS( XK_6, 5)
53 - TAGKEYS( XK_7, 6)
54 - TAGKEYS( XK_8, 7)
55 - TAGKEYS( XK_9, 8)
56 - { MODKEY|ShiftMask, XK_q, quit, {0} …
57 + { MODKEY, XK_Escape, setkeymode, {.ui…
58 +};
59 +
60 +static Key cmdkeys[] = {
61 + /* modifier keys functio…
62 + { 0, XK_Escape, clearcm…
63 + { ControlMask, XK_g, clearcm…
64 + { 0, XK_i, setkeym…
65 +};
66 +static Command commands[] = {
67 + /* modifier (4 keys) keysyms (4 keys) function …
68 + { {0, 0, 0, 0}, { XK_p, 0, 0, 0}, spawn, …
69 + { {ShiftMask, 0, 0, 0}, { XK_Return, 0, 0, 0}, spawn, …
70 + { {0, 0, 0, 0}, { XK_b, 0, 0, 0}, togglebar…
71 + { {0, 0, 0, 0}, { XK_j, 0, 0, 0}, focusstac…
72 + { {0, 0, 0, 0}, { XK_k, 0, 0, 0}, focusstac…
73 + { {0, 0, 0, 0}, { XK_i, 0, 0, 0}, incnmaste…
74 + { {0, 0, 0, 0}, { XK_d, 0, 0, 0}, incnmaste…
75 + { {0, 0, 0, 0}, { XK_h, 0, 0, 0}, setmfact,…
76 + { {0, 0, 0, 0}, { XK_l, 0, 0, 0}, setmfact,…
77 + { {0, 0, 0, 0}, { XK_Return, 0, 0, 0}, zoom, …
78 + { {ControlMask, 0, 0, 0}, { XK_i, 0, 0, 0}, view, …
79 + { {ShiftMask, 0, 0, 0}, { XK_k, 0, 0, 0}, killclien…
80 + { {0, 0, 0, 0}, { XK_t, 0, 0, 0}, setlayout…
81 + { {0, 0, 0, 0}, { XK_f, 0, 0, 0}, setlayout…
82 + { {0, 0, 0, 0}, { XK_m, 0, 0, 0}, setlayout…
83 + { {0, 0, 0, 0}, { XK_space, 0, 0, 0}, setlayout…
84 + { {ShiftMask, 0, 0, 0}, { XK_space, 0, 0, 0}, toggleflo…
85 + { {0, 0, 0, 0}, { XK_0, 0, 0, 0}, view, …
86 + { {ShiftMask, 0, 0, 0}, { XK_0, 0, 0, 0}, tag, …
87 + { {0, 0, 0, 0}, { XK_comma, 0, 0, 0}, focusmon,…
88 + { {0, 0, 0, 0}, { XK_period, 0, 0, 0}, focusmon,…
89 + { {ShiftMask, 0, 0, 0}, { XK_comma, 0, 0, 0}, tagmon, …
90 + { {ShiftMask, 0, 0, 0}, { XK_period, 0, 0, 0}, tagmon, …
91 + TAGKEYS(XK_1, 0)
92 + TAGKEYS(XK_2, 1)
93 + TAGKEYS(XK_3, 2)
94 + TAGKEYS(XK_4, 3)
95 + TAGKEYS(XK_5, 4)
96 + TAGKEYS(XK_6, 5)
97 + TAGKEYS(XK_7, 6)
98 + TAGKEYS(XK_8, 7)
99 + TAGKEYS(XK_9, 8)
100 + { {ShiftMask, 0, 0, 0}, { XK_q, 0, 0, 0}, quit, …
101 };
102
103 /* button definitions */
104 @@ -113,4 +124,3 @@ static Button buttons[] = {
105 { ClkTagBar, MODKEY, Button1, tag, …
106 { ClkTagBar, MODKEY, Button3, togglet…
107 };
108 -
109 diff --git a/dwm.c b/dwm.c
110 index 0fc328a..487484e 100644
111 --- a/dwm.c
112 +++ b/dwm.c
113 @@ -60,6 +60,7 @@
114 /* enums */
115 enum { CurNormal, CurResize, CurMove, CurLast }; /* cursor */
116 enum { SchemeNorm, SchemeSel }; /* color schemes */
117 +enum { ModeCommand, ModeInsert };
118 enum { NetSupported, NetWMName, NetWMState, NetWMCheck,
119 NetWMFullscreen, NetActiveWindow, NetWMWindowType,
120 NetWMWindowTypeDialog, NetClientList, NetLast }; /* EWMH atoms */
121 @@ -99,6 +100,13 @@ struct Client {
122 Window win;
123 };
124
125 +typedef struct {
126 + unsigned int mod[4];
127 + KeySym keysym[4];
128 + void (*func)(const Arg *);
129 + const Arg arg;
130 +} Command;
131 +
132 typedef struct {
133 unsigned int mod;
134 KeySym keysym;
135 @@ -152,6 +160,7 @@ static void buttonpress(XEvent *e);
136 static void checkotherwm(void);
137 static void cleanup(void);
138 static void cleanupmon(Monitor *mon);
139 +static void clearcmd(const Arg *arg);
140 static void clientmessage(XEvent *e);
141 static void configure(Client *c);
142 static void configurenotify(XEvent *e);
143 @@ -177,6 +186,7 @@ static void grabbuttons(Client *c, int focused);
144 static void grabkeys(void);
145 static void incnmaster(const Arg *arg);
146 static void keypress(XEvent *e);
147 +static void keypresscmd(XEvent *e);
148 static void killclient(const Arg *arg);
149 static void manage(Window w, XWindowAttributes *wa);
150 static void mappingnotify(XEvent *e);
151 @@ -200,6 +210,8 @@ static void sendmon(Client *c, Monitor *m);
152 static void setclientstate(Client *c, long state);
153 static void setfocus(Client *c);
154 static void setfullscreen(Client *c, int fullscreen);
155 +static void setinsertmode(void);
156 +static void setkeymode(const Arg *arg);
157 static void setlayout(const Arg *arg);
158 static void setmfact(const Arg *arg);
159 static void setup(void);
160 @@ -243,6 +255,8 @@ static int sw, sh; /* X display screen geo…
161 static int bh, blw = 0; /* bar geometry */
162 static int lrpad; /* sum of left and right padding for text …
163 static int (*xerrorxlib)(Display *, XErrorEvent *);
164 +static unsigned int cmdmod[4];
165 +static unsigned int keymode = ModeCommand;
166 static unsigned int numlockmask = 0;
167 static void (*handler[LASTEvent]) (XEvent *) = {
168 [ButtonPress] = buttonpress,
169 @@ -266,6 +280,7 @@ static Cur *cursor[CurLast];
170 static Clr **scheme;
171 static Display *dpy;
172 static Drw *drw;
173 +static KeySym cmdkeysym[4];
174 static Monitor *mons, *selmon;
175 static Window root, wmcheckwin;
176
177 @@ -513,6 +528,17 @@ cleanupmon(Monitor *mon)
178 free(mon);
179 }
180
181 +void
182 +clearcmd(const Arg *arg)
183 +{
184 + unsigned int i;
185 +
186 + for (i = 0; i < LENGTH(cmdkeysym); i++) {
187 + cmdkeysym[i] = 0;
188 + cmdmod[i] = 0;
189 + }
190 +}
191 +
192 void
193 clientmessage(XEvent *e)
194 {
195 @@ -955,6 +981,13 @@ grabbuttons(Client *c, int focused)
196 void
197 grabkeys(void)
198 {
199 + if (keymode == ModeCommand) {
200 + XUngrabKey(dpy, AnyKey, AnyModifier, root);
201 + XGrabKeyboard(dpy, root, True, GrabModeAsync, GrabModeA…
202 + return;
203 + }
204 +
205 + XUngrabKeyboard(dpy, CurrentTime);
206 updatenumlockmask();
207 {
208 unsigned int i, j;
209 @@ -996,6 +1029,11 @@ keypress(XEvent *e)
210 KeySym keysym;
211 XKeyEvent *ev;
212
213 + if (keymode == ModeCommand) {
214 + keypresscmd(e);
215 + return;
216 + }
217 +
218 ev = &e->xkey;
219 keysym = XKeycodeToKeysym(dpy, (KeyCode)ev->keycode, 0);
220 for (i = 0; i < LENGTH(keys); i++)
221 @@ -1005,6 +1043,53 @@ keypress(XEvent *e)
222 keys[i].func(&(keys[i].arg));
223 }
224
225 +void
226 +keypresscmd(XEvent *e) {
227 + unsigned int i, j;
228 + int matches = 0;
229 + KeySym keysym;
230 + XKeyEvent *ev;
231 +
232 + ev = &e->xkey;
233 + keysym = XKeycodeToKeysym(dpy, (KeyCode)ev->keycode, 0);
234 + if (XK_Shift_L <= keysym && keysym <= XK_Hyper_R) {
235 + return;
236 + }
237 +
238 + for (i = 0; i < LENGTH(cmdkeys); i++) {
239 + if (keysym == cmdkeys[i].keysym
240 + && CLEANMASK(cmdkeys[i].mod) == CLEANMASK(ev->state)
241 + && cmdkeys[i].func) {
242 + cmdkeys[i].func(&(cmdkeys[i].arg));
243 + return;
244 + }
245 + }
246 +
247 + for (j = 0; j < LENGTH(cmdkeysym); j++) {
248 + if (cmdkeysym[j] == 0) {
249 + cmdkeysym[j] = keysym;
250 + cmdmod[j] = ev->state;
251 + break;
252 + }
253 + }
254 +
255 + for (i = 0; i < LENGTH(commands); i++) {
256 + matches = 0;
257 + for (j = 0; j < LENGTH(cmdkeysym); j++) {
258 + if (cmdkeysym[j] == commands[i].keysym[j]
259 + && CLEANMASK(cmdmod[j]) == CLEANMASK(commands[i…
260 + matches++;
261 + }
262 + if (matches == LENGTH(cmdkeysym)) {
263 + if (commands[i].func)
264 + commands[i].func(&(commands[i].arg));
265 + clearcmd(NULL);
266 + return;
267 + }
268 + }
269 +}
270 +
271 +
272 void
273 killclient(const Arg *arg)
274 {
275 @@ -1438,6 +1523,24 @@ setclientstate(Client *c, long state)
276 PropModeReplace, (unsigned char *)data, 2);
277 }
278
279 +void
280 +setinsertmode()
281 +{
282 + keymode = ModeInsert;
283 + clearcmd(NULL);
284 + grabkeys();
285 +}
286 +
287 +void
288 +setkeymode(const Arg *arg)
289 +{
290 + if(!arg)
291 + return;
292 + keymode = arg->ui;
293 + clearcmd(NULL);
294 + grabkeys();
295 +}
296 +
297 int
298 sendevent(Client *c, Atom proto)
299 {
300 @@ -1645,6 +1748,7 @@ sigchld(int unused)
301 void
302 spawn(const Arg *arg)
303 {
304 + setinsertmode();
305 if (arg->v == dmenucmd)
306 dmenumon[0] = '0' + selmon->num;
307 if (fork() == 0) {
You are viewing proxied material from suckless.org. The copyright of proxied material belongs to its original authors. Any comments or complaints in relation to proxied material should be directed to the original authors of the content concerned. Please see the disclaimer for more details.