commit e378f735d857f7da124177e3540912d920be5022
Author:     Quentin Rameau <quinq@fifth.space>
AuthorDate: Thu Sep 1 13:46:51 2016 +0200
Commit:     Markus Teich <markus.te...@stusta.mhn.de>
CommitDate: Fri Sep 2 10:50:32 2016 +0200

    Re-introduce the waiting loop for input grabbing
    
    We actually “need” to wait a little for input to be released before
    locking for cases where slock is spawned from other graphical
    applications using keybindings.
    This undoes the misbehaviour I introduced in c2f9757, sorry for the mess.

diff --git a/slock.c b/slock.c
index 4980325..97c7489 100644
--- a/slock.c
+++ b/slock.c
@@ -223,6 +223,7 @@ unlockscreen(Display *dpy, Lock *lock)
                return;
 
        XUngrabPointer(dpy, CurrentTime);
+       XUngrabKeyboard(dpy, CurrentTime);
        XFreeColors(dpy, DefaultColormap(dpy, lock->screen), lock->colors, 
NUMCOLS, 0);
        XFreePixmap(dpy, lock->pmap);
        XDestroyWindow(dpy, lock->win);
@@ -241,7 +242,7 @@ static Lock *
 lockscreen(Display *dpy, int screen)
 {
        char curs[] = {0, 0, 0, 0, 0, 0, 0, 0};
-       int i;
+       int i, ptgrab, kbgrab;
        Lock *lock;
        XColor color, dummy;
        XSetWindowAttributes wa;
@@ -268,30 +269,45 @@ lockscreen(Display *dpy, int screen)
        invisible = XCreatePixmapCursor(dpy, lock->pmap, lock->pmap, &color, 
&color, 0, 0);
        XDefineCursor(dpy, lock->win, invisible);
 
-       /* Try to grab mouse pointer *and* keyboard, else fail the lock */
-       if (XGrabPointer(dpy, lock->root, False, ButtonPressMask |
-           ButtonReleaseMask | PointerMotionMask, GrabModeAsync, GrabModeAsync,
-           None, invisible, CurrentTime) != GrabSuccess) {
-               fprintf(stderr, "slock: unable to grab mouse pointer for screen 
%d\n", screen);
-               running = 0;
-               unlockscreen(dpy, lock);
-               return NULL;
-       }
+       /* Try to grab mouse pointer *and* keyboard for 600ms, else fail the 
lock */
+       for (i = 6, ptgrab = kbgrab = -1; i; --i) {
+               if (ptgrab != GrabSuccess) {
+                       ptgrab = XGrabPointer(dpy, lock->root, False,
+                                ButtonPressMask | ButtonReleaseMask |
+                                PointerMotionMask, GrabModeAsync,
+                                GrabModeAsync, None, invisible, CurrentTime);
+               }
+               if (kbgrab != GrabSuccess) {
+                       kbgrab = XGrabKeyboard(dpy, lock->root, True,
+                                GrabModeAsync, GrabModeAsync, CurrentTime);
+               }
 
-       if (XGrabKeyboard(dpy, lock->root, True, GrabModeAsync, GrabModeAsync,
-           CurrentTime) != GrabSuccess) {
-               fprintf(stderr, "slock: unable to grab keyboard for screen 
%d\n", screen);
-               running = 0;
-               unlockscreen(dpy, lock);
-               return NULL;
-       }
+               /* input is grabbed: we can lock the screen */
+               if (ptgrab == GrabSuccess && kbgrab == GrabSuccess) {
+                       XMapRaised(dpy, lock->win);
+                       if (rr)
+                               XRRSelectInput(dpy, lock->win, 
RRScreenChangeNotifyMask);
+
+                       XSelectInput(dpy, lock->root, SubstructureNotifyMask);
+                       return lock;
+               }
 
-       XMapRaised(dpy, lock->win);
-       if (rr)
-               XRRSelectInput(dpy, lock->win, RRScreenChangeNotifyMask);
+               /* retry on AlreadyGrabbed but fail on other errors */
+               if ((ptgrab != AlreadyGrabbed && ptgrab != GrabSuccess) ||
+                   (kbgrab != AlreadyGrabbed && kbgrab != GrabSuccess))
+                       break;
 
-       XSelectInput(dpy, lock->root, SubstructureNotifyMask);
-       return lock;
+               usleep(100000);
+       }
+
+       /* we couldn't grab all input: fail out */
+       if (ptgrab != GrabSuccess)
+               fprintf(stderr, "slock: unable to grab mouse pointer for screen 
%d\n", screen);
+       if (kbgrab != GrabSuccess)
+               fprintf(stderr, "slock: unable to grab keyboard for screen 
%d\n", screen);
+       running = 0;
+       unlockscreen(dpy, lock);
+       return NULL;
 }
 
 static void

Reply via email to