aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--slock.c60
1 files changed, 38 insertions, 22 deletions
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)
223 return; 223 return;
224 224
225 XUngrabPointer(dpy, CurrentTime); 225 XUngrabPointer(dpy, CurrentTime);
226 XUngrabKeyboard(dpy, CurrentTime);
226 XFreeColors(dpy, DefaultColormap(dpy, lock->screen), lock->colors, NUMCOLS, 0); 227 XFreeColors(dpy, DefaultColormap(dpy, lock->screen), lock->colors, NUMCOLS, 0);
227 XFreePixmap(dpy, lock->pmap); 228 XFreePixmap(dpy, lock->pmap);
228 XDestroyWindow(dpy, lock->win); 229 XDestroyWindow(dpy, lock->win);
@@ -241,7 +242,7 @@ static Lock *
241lockscreen(Display *dpy, int screen) 242lockscreen(Display *dpy, int screen)
242{ 243{
243 char curs[] = {0, 0, 0, 0, 0, 0, 0, 0}; 244 char curs[] = {0, 0, 0, 0, 0, 0, 0, 0};
244 int i; 245 int i, ptgrab, kbgrab;
245 Lock *lock; 246 Lock *lock;
246 XColor color, dummy; 247 XColor color, dummy;
247 XSetWindowAttributes wa; 248 XSetWindowAttributes wa;
@@ -268,30 +269,45 @@ lockscreen(Display *dpy, int screen)
268 invisible = XCreatePixmapCursor(dpy, lock->pmap, lock->pmap, &color, &color, 0, 0); 269 invisible = XCreatePixmapCursor(dpy, lock->pmap, lock->pmap, &color, &color, 0, 0);
269 XDefineCursor(dpy, lock->win, invisible); 270 XDefineCursor(dpy, lock->win, invisible);
270 271
271 /* Try to grab mouse pointer *and* keyboard, else fail the lock */ 272 /* Try to grab mouse pointer *and* keyboard for 600ms, else fail the lock */
272 if (XGrabPointer(dpy, lock->root, False, ButtonPressMask | 273 for (i = 6, ptgrab = kbgrab = -1; i; --i) {
273 ButtonReleaseMask | PointerMotionMask, GrabModeAsync, GrabModeAsync, 274 if (ptgrab != GrabSuccess) {
274 None, invisible, CurrentTime) != GrabSuccess) { 275 ptgrab = XGrabPointer(dpy, lock->root, False,
275 fprintf(stderr, "slock: unable to grab mouse pointer for screen %d\n", screen); 276 ButtonPressMask | ButtonReleaseMask |
276 running = 0; 277 PointerMotionMask, GrabModeAsync,
277 unlockscreen(dpy, lock); 278 GrabModeAsync, None, invisible, CurrentTime);
278 return NULL; 279 }
279 } 280 if (kbgrab != GrabSuccess) {
281 kbgrab = XGrabKeyboard(dpy, lock->root, True,
282 GrabModeAsync, GrabModeAsync, CurrentTime);
283 }
280 284
281 if (XGrabKeyboard(dpy, lock->root, True, GrabModeAsync, GrabModeAsync, 285 /* input is grabbed: we can lock the screen */
282 CurrentTime) != GrabSuccess) { 286 if (ptgrab == GrabSuccess && kbgrab == GrabSuccess) {
283 fprintf(stderr, "slock: unable to grab keyboard for screen %d\n", screen); 287 XMapRaised(dpy, lock->win);
284 running = 0; 288 if (rr)
285 unlockscreen(dpy, lock); 289 XRRSelectInput(dpy, lock->win, RRScreenChangeNotifyMask);
286 return NULL; 290
287 } 291 XSelectInput(dpy, lock->root, SubstructureNotifyMask);
292 return lock;
293 }
288 294
289 XMapRaised(dpy, lock->win); 295 /* retry on AlreadyGrabbed but fail on other errors */
290 if (rr) 296 if ((ptgrab != AlreadyGrabbed && ptgrab != GrabSuccess) ||
291 XRRSelectInput(dpy, lock->win, RRScreenChangeNotifyMask); 297 (kbgrab != AlreadyGrabbed && kbgrab != GrabSuccess))
298 break;
292 299
293 XSelectInput(dpy, lock->root, SubstructureNotifyMask); 300 usleep(100000);
294 return lock; 301 }
302
303 /* we couldn't grab all input: fail out */
304 if (ptgrab != GrabSuccess)
305 fprintf(stderr, "slock: unable to grab mouse pointer for screen %d\n", screen);
306 if (kbgrab != GrabSuccess)
307 fprintf(stderr, "slock: unable to grab keyboard for screen %d\n", screen);
308 running = 0;
309 unlockscreen(dpy, lock);
310 return NULL;
295} 311}
296 312
297static void 313static void