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.
This commit is contained in:
Quentin Rameau 2016-09-01 13:46:51 +02:00 committed by Markus Teich
parent 1f66885fbf
commit e378f735d8

50
slock.c
View file

@ -223,6 +223,7 @@ unlockscreen(Display *dpy, Lock *lock)
return; return;
XUngrabPointer(dpy, CurrentTime); XUngrabPointer(dpy, CurrentTime);
XUngrabKeyboard(dpy, CurrentTime);
XFreeColors(dpy, DefaultColormap(dpy, lock->screen), lock->colors, NUMCOLS, 0); XFreeColors(dpy, DefaultColormap(dpy, lock->screen), lock->colors, NUMCOLS, 0);
XFreePixmap(dpy, lock->pmap); XFreePixmap(dpy, lock->pmap);
XDestroyWindow(dpy, lock->win); XDestroyWindow(dpy, lock->win);
@ -241,7 +242,7 @@ static Lock *
lockscreen(Display *dpy, int screen) lockscreen(Display *dpy, int screen)
{ {
char curs[] = {0, 0, 0, 0, 0, 0, 0, 0}; char curs[] = {0, 0, 0, 0, 0, 0, 0, 0};
int i; int i, ptgrab, kbgrab;
Lock *lock; Lock *lock;
XColor color, dummy; XColor color, dummy;
XSetWindowAttributes wa; XSetWindowAttributes wa;
@ -268,24 +269,21 @@ lockscreen(Display *dpy, int screen)
invisible = XCreatePixmapCursor(dpy, lock->pmap, lock->pmap, &color, &color, 0, 0); invisible = XCreatePixmapCursor(dpy, lock->pmap, lock->pmap, &color, &color, 0, 0);
XDefineCursor(dpy, lock->win, invisible); XDefineCursor(dpy, lock->win, invisible);
/* Try to grab mouse pointer *and* keyboard, else fail the lock */ /* Try to grab mouse pointer *and* keyboard for 600ms, else fail the lock */
if (XGrabPointer(dpy, lock->root, False, ButtonPressMask | for (i = 6, ptgrab = kbgrab = -1; i; --i) {
ButtonReleaseMask | PointerMotionMask, GrabModeAsync, GrabModeAsync, if (ptgrab != GrabSuccess) {
None, invisible, CurrentTime) != GrabSuccess) { ptgrab = XGrabPointer(dpy, lock->root, False,
fprintf(stderr, "slock: unable to grab mouse pointer for screen %d\n", screen); ButtonPressMask | ButtonReleaseMask |
running = 0; PointerMotionMask, GrabModeAsync,
unlockscreen(dpy, lock); GrabModeAsync, None, invisible, CurrentTime);
return NULL; }
} if (kbgrab != GrabSuccess) {
kbgrab = XGrabKeyboard(dpy, lock->root, True,
if (XGrabKeyboard(dpy, lock->root, True, GrabModeAsync, GrabModeAsync, GrabModeAsync, GrabModeAsync, CurrentTime);
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); XMapRaised(dpy, lock->win);
if (rr) if (rr)
XRRSelectInput(dpy, lock->win, RRScreenChangeNotifyMask); XRRSelectInput(dpy, lock->win, RRScreenChangeNotifyMask);
@ -294,6 +292,24 @@ lockscreen(Display *dpy, int screen)
return lock; return lock;
} }
/* retry on AlreadyGrabbed but fail on other errors */
if ((ptgrab != AlreadyGrabbed && ptgrab != GrabSuccess) ||
(kbgrab != AlreadyGrabbed && kbgrab != GrabSuccess))
break;
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 static void
usage(void) usage(void)
{ {