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:
parent
1f66885fbf
commit
e378f735d8
1 changed files with 39 additions and 23 deletions
62
slock.c
62
slock.c
|
@ -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,30 +269,45 @@ 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,
|
||||||
|
ButtonPressMask | ButtonReleaseMask |
|
||||||
|
PointerMotionMask, GrabModeAsync,
|
||||||
|
GrabModeAsync, None, invisible, CurrentTime);
|
||||||
|
}
|
||||||
|
if (kbgrab != GrabSuccess) {
|
||||||
|
kbgrab = XGrabKeyboard(dpy, lock->root, True,
|
||||||
|
GrabModeAsync, GrabModeAsync, CurrentTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 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);
|
fprintf(stderr, "slock: unable to grab mouse pointer for screen %d\n", screen);
|
||||||
running = 0;
|
if (kbgrab != GrabSuccess)
|
||||||
unlockscreen(dpy, lock);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (XGrabKeyboard(dpy, lock->root, True, GrabModeAsync, GrabModeAsync,
|
|
||||||
CurrentTime) != GrabSuccess) {
|
|
||||||
fprintf(stderr, "slock: unable to grab keyboard for screen %d\n", screen);
|
fprintf(stderr, "slock: unable to grab keyboard for screen %d\n", screen);
|
||||||
running = 0;
|
running = 0;
|
||||||
unlockscreen(dpy, lock);
|
unlockscreen(dpy, lock);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
|
||||||
|
|
||||||
XMapRaised(dpy, lock->win);
|
|
||||||
if (rr)
|
|
||||||
XRRSelectInput(dpy, lock->win, RRScreenChangeNotifyMask);
|
|
||||||
|
|
||||||
XSelectInput(dpy, lock->root, SubstructureNotifyMask);
|
|
||||||
return lock;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
Loading…
Reference in a new issue