~kris/suckless

slock

e378f735d857f7da124177e3540912d920be5022 — Quentin Rameau 10 years ago 1f66885
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.
1 files changed, 38 insertions(+), 22 deletions(-)

M slock.c
M slock.c => slock.c +38 -22
@@ 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