On Thu, Oct 04, 2007 at 03:01:12PM +0330, Ali Gholami Rudi wrote:
> I've written a patch to allow prefixed keys.
> 
> With this patch you can bind ``C-t k`` (where ``C-t`` is your prefix),
> for instance, to kill window or ``C-t 1`` to ``view("1")``.  You can
> change the prefix by editing the line that contains the ``setprefix``
> function in the config file.
> 
> I've written this patch because:
> 
> * Some of dwm's default keys conflict with emacs keybinding
> * Some emacs users, including me, don't like to push three buttons at
>   the same time very oftern
> * If ``? x`` (? is the prefix and x is a tag) is bound to view("x"),
>   letters can be a tag like digits.
> * Prefixed and normal keys can coexist
> 
> I didn't know dwm's policy for submitting patches; so I've attached
> the outcome of ``hg export``.

In the last patch prefixed keys could not contain modifiers such as
``? shift-1`` (where ``?`` is the prefix).  This patch fixes it.
So now one can bind:

* C-; x -> view("x")
* C-; shift-x -> tag("x")
* C-; C-x -> toggleview("x")
* C-; C-shift-x -> toggletag("x")

for both letters and digits (where ``C-;`` is the prefix).


--Ali
# HG changeset patch
# User Ali Gholami Rudi <[EMAIL PROTECTED]>
# Date 1191574032 -12600
# Node ID f66c2d9024734507164a26603a6fd29db54710ad
# Parent  3027df4b2c0d6a894818f23643ae453b99e98591
Added prefixed keys

diff --git a/config.def.h b/config.def.h
--- a/config.def.h
+++ b/config.def.h
@@ -90,4 +90,12 @@ Key keys[] = { \
 	{ MODKEY|ControlMask|ShiftMask,	XK_8,		toggletag,	tags[7] }, \
 	{ MODKEY|ControlMask|ShiftMask,	XK_9,		toggletag,	tags[8] }, \
 	{ MODKEY|ShiftMask,		XK_q,		quit,		NULL }, \
+	{ ControlMask,			XK_t,		setprefix,	NULL }, \
 };
+
+#define PREFIXEDKEYS \
+Key prefixedkeys[] = { \
+	/* modifier			key		function	argument */ \
+	{ 0,				XK_1,		view,		tags[0] }, \
+	{ ShiftMask,			XK_1,		tag,		tags[0] }, \
+};
diff --git a/dwm.c b/dwm.c
--- a/dwm.c
+++ b/dwm.c
@@ -143,6 +143,7 @@ long getstate(Window w);
 long getstate(Window w);
 Bool gettextprop(Window w, Atom atom, char *text, unsigned int size);
 void grabbuttons(Client *c, Bool focused);
+void handlekey(Key keys[], unsigned int len, XEvent *e);
 unsigned int idxoftag(const char *tag);
 void initfont(const char *fontstr);
 Bool isarrange(void (*func)());
@@ -167,6 +168,7 @@ void setclientstate(Client *c, long stat
 void setclientstate(Client *c, long state);
 void setlayout(const char *arg);
 void setmwfact(const char *arg);
+void setprefix(const char *arg);
 void setup(void);
 void spawn(const char *arg);
 void tag(const char *arg);
@@ -228,6 +230,7 @@ DC dc = {0};
 DC dc = {0};
 Window barwin, root;
 Regs *regs = NULL;
+Bool prefix = False;
 
 /* configuration, allows nested code to access above variables */
 #include "config.h"
@@ -840,6 +843,23 @@ grabbuttons(Client *c, Bool focused) {
 				GrabModeAsync, GrabModeSync, None, None);
 }
 
+void
+handlekey(Key keys[], unsigned int len, XEvent *e) {
+	XKeyEvent *ev;
+	KeySym keysym;
+	unsigned int i;
+
+	ev = &e->xkey;
+	keysym = XKeycodeToKeysym(dpy, (KeyCode)ev->keycode, 0);
+	for(i = 0; i < len; i++)
+		if(keysym == keys[i].keysym
+		&& CLEANMASK(keys[i].mod) == CLEANMASK(ev->state))
+		{
+			if(keys[i].func)
+				keys[i].func(keys[i].arg);
+		}
+}
+
 unsigned int
 idxoftag(const char *tag) {
 	unsigned int i;
@@ -936,13 +956,20 @@ void
 void
 keypress(XEvent *e) {
 	KEYS
+	PREFIXEDKEYS
 	unsigned int len = sizeof keys / sizeof keys[0];
+	unsigned int prefixedlen = sizeof prefixedkeys / sizeof prefixedkeys[0];
 	unsigned int i;
 	KeyCode code;
 	KeySym keysym;
 	XKeyEvent *ev;
 
 	if(!e) { /* grabkeys */
+		if (prefix) {
+			XGrabKey(dpy, AnyKey, AnyModifier, root, True,
+					GrabModeAsync, GrabModeAsync);
+			return;
+		}
 		XUngrabKey(dpy, AnyKey, AnyModifier, root);
 		for(i = 0; i < len; i++) {
 			code = XKeysymToKeycode(dpy, keys[i].keysym);
@@ -957,15 +984,17 @@ keypress(XEvent *e) {
 		}
 		return;
 	}
-	ev = &e->xkey;
-	keysym = XKeycodeToKeysym(dpy, (KeyCode)ev->keycode, 0);
-	for(i = 0; i < len; i++)
-		if(keysym == keys[i].keysym
-		&& CLEANMASK(keys[i].mod) == CLEANMASK(ev->state))
-		{
-			if(keys[i].func)
-				keys[i].func(keys[i].arg);
-		}
+	if (prefix) {
+		ev = &e->xkey;
+		keysym = XKeycodeToKeysym(dpy, (KeyCode)ev->keycode, 0);
+		if (!IsModifierKey(keysym)) {
+			handlekey(prefixedkeys, prefixedlen, e);
+			prefix = False;
+			keypress(NULL);
+		}
+	}
+	else
+		handlekey(keys, len, e);
 }
 
 void
@@ -1418,6 +1447,12 @@ setmwfact(const char *arg) {
 }
 
 void
+setprefix(const char *arg) {
+	prefix = True;
+	keypress(NULL);
+}
+
+void
 setup(void) {
 	int d;
 	unsigned int i, j, mask;

Attachment: signature.asc
Description: Digital signature

Reply via email to