Re-introduce the waiting loop for input grabbing - slock - simple X display loc… | |
git clone git://git.suckless.org/slock | |
Log | |
Files | |
Refs | |
README | |
LICENSE | |
--- | |
commit e378f735d857f7da124177e3540912d920be5022 | |
parent 1f66885fbf36c726b7615060d3c98cbf74218d13 | |
Author: Quentin Rameau <[email protected]> | |
Date: Thu, 1 Sep 2016 13:46:51 +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. | |
Diffstat: | |
M slock.c | 60 ++++++++++++++++++++---------… | |
1 file changed, 38 insertions(+), 22 deletions(-) | |
--- | |
diff --git 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, NUM… | |
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, &… | |
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, GrabModeAsyn… | |
- None, invisible, CurrentTime) != GrabSuccess) { | |
- fprintf(stderr, "slock: unable to grab mouse pointer for scree… | |
- running = 0; | |
- unlockscreen(dpy, lock); | |
- return NULL; | |
- } | |
+ /* Try to grab mouse pointer *and* keyboard for 600ms, else fail the l… | |
+ 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\… | |
- 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, RRScreenChangeN… | |
+ | |
+ 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 scree… | |
+ if (kbgrab != GrabSuccess) | |
+ fprintf(stderr, "slock: unable to grab keyboard for screen %d\… | |
+ running = 0; | |
+ unlockscreen(dpy, lock); | |
+ return NULL; | |
} | |
static void |