diff options
| -rw-r--r-- | slock.c | 60 |
1 files changed, 38 insertions, 22 deletions
| @@ -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 * | |||
| 241 | lockscreen(Display *dpy, int screen) | 242 | lockscreen(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 | ||
| 297 | static void | 313 | static void |
