Hi
I wrote a patch, so that you can specify for key commands to run on
KeyRelease instead of KeyPress.

The motivation for me was to be able to set a keybinding to run scrot,
however there may be other reasons to use this.

This thread from the mailing list is a couple years old, and describes
the problem in more detail.
http://www.mail-archive.com/[email protected]/msg09202.html
Apologies if that's not the appropriate way to cite an old thread, I
don't consider myself mailing list-savvy.

After applying the patch, to get something to run on KeyRelease, just
add a '1' to the end of your assignment in the keys array of config.h
like this:
{MODKEY,                          XK_Print, spawn, {.v = shootcmd}, 1 },

Feedback welcome. Enjoy.

-- 
Martin Miller
witsquash.com

diff --git a/dwm.c b/dwm.c
index d9443da..e5dec78 100644
--- a/dwm.c
+++ b/dwm.c
@@ -118,6 +118,7 @@ typedef struct {
        KeySym keysym;
        void (*func)(const Arg *);
        const Arg arg;
+    short onRelease; 
 } Key;
 
 typedef struct {
@@ -195,6 +196,7 @@ static void grabkeys(void);
 static void incnmaster(const Arg *arg);
 static void initfont(const char *fontstr);
 static void keypress(XEvent *e);
+static void keyrelease(XEvent *e);
 static void killclient(const Arg *arg);
 static void manage(Window w, XWindowAttributes *wa);
 static void mappingnotify(XEvent *e);
@@ -1084,10 +1086,27 @@ keypress(XEvent *e) {
        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].onRelease != 1)
                        keys[i].func(&(keys[i].arg));
 }
 
+void 
+keyrelease(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].onRelease == 1)
+            keys[i].func(&(keys[i].arg));
+}
+
 void
 killclient(const Arg *arg) {
        if(!selmon->sel)

Reply via email to