JasonWoof Got questions, comments, patches, etc.? Contact Jason Woofenden
fix keys pressed while kbspawn key is still down master
authorJason Woofenden <jason@jasonwoof.com>
Wed, 14 Aug 2019 21:01:58 +0000 (17:01 -0400)
committerJason Woofenden <jason@jasonwoof.com>
Wed, 14 Aug 2019 21:01:58 +0000 (17:01 -0400)
dwm.c

diff --git a/dwm.c b/dwm.c
index e4237a4..898b917 100644 (file)
--- a/dwm.c
+++ b/dwm.c
@@ -243,7 +243,8 @@ static int xerrorstart(Display *dpy, XErrorEvent *ee);
 static void zoom(const Arg *arg);
 
 // variables
-static Bool key_buffering = False;
+enum { KeyBufferingOff, KeyBufferingAwaitingWindow, KeyBufferingAwaitingFocus };
+static unsigned int key_buffering = 0;
 static const char broken[] = "broken";
 static char stext[256];
 static int screen;
@@ -891,8 +892,7 @@ focus(Client *c) {
                grabbuttons(c, True);
                XSetWindowBorder(dpy, c->win, scheme[SchemeSel].border->rgb);
                setfocus(c);
-       }
-       else {
+       } else {
                XSetInputFocus(dpy, root, RevertToPointerRoot, CurrentTime);
                XDeleteProperty(dpy, root, netatom[NetActiveWindow]);
        }
@@ -910,6 +910,19 @@ focusin(XEvent *e) { /* there are some broken focus acquiring clients */
 
        if(selmon->sel && ev->window != selmon->sel->win)
                setfocus(selmon->sel);
+
+       if(key_buffering == KeyBufferingAwaitingFocus) {
+               key_buffering = KeyBufferingOff;
+               // there's a few ways to release the grab, with different effects (below)
+               // In this example F2 is mapped to kbspawn
+               //     XAllowEvents(dpy, AsyncKeyboard, CurrentTime);
+               //         swallows key presses while F2 is still down.
+               //     XAllowEvents(dpy, ReplayKeyboard, CurrentTime);
+               //         sends the F2 keydown and all the queued events
+               //     XUngrabKeyboard(dpy, CurrentTime);
+               //         sends everything queued and the F2 key_UP_
+               XUngrabKeyboard(dpy, CurrentTime);
+       }
 }
 
 void
@@ -1061,7 +1074,8 @@ grabkeys(void) {
                        if((code = XKeysymToKeycode(dpy, keys[i].keysym)))
                                for(j = 0; j < LENGTH(modifiers); j++)
                                        XGrabKey(dpy, code, keys[i].mod | modifiers[j], root,
-                                                True, GrabModeAsync,
+                                                False, // report keys to focused window too?
+                                                GrabModeAsync, // mouse grab mode
                                                 keys[i].func == kbspawn ? GrabModeSync : GrabModeAsync);
        }
 }
@@ -1181,9 +1195,9 @@ manage(Window w, XWindowAttributes *wa) {
        arrange(c->mon);
        XMapWindow(dpy, c->win);
        focus(c);
-       if(key_buffering) {
-               key_buffering = False;
-               XAllowEvents(dpy, AsyncKeyboard, CurrentTime);
+       if(key_buffering == KeyBufferingAwaitingWindow) {
+               // almost there! but wait until we are notified that it has focus
+               key_buffering = KeyBufferingAwaitingFocus;
        }
 }
 
@@ -1591,8 +1605,8 @@ setfocus(Client *c) {
        if(!c->neverfocus) {
                XSetInputFocus(dpy, c->win, RevertToPointerRoot, CurrentTime);
                XChangeProperty(dpy, root, netatom[NetActiveWindow],
-                               XA_WINDOW, 32, PropModeReplace,
-                               (unsigned char *) &(c->win), 1);
+                               XA_WINDOW, 32, PropModeReplace,
+                               (unsigned char *) &(c->win), 1);
        }
        sendevent(c, wmatom[WMTakeFocus]);
 }