@ -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 ) {
if ( XGrabKeyboard ( dpy , lock - > root , True , GrabModeAsync , GrabModeAsync ,
kbgrab = XGrabKeyboard ( dpy , lock - > root , True ,
CurrentTime ) ! = GrabSuccess ) {
GrabModeAsync , GrabModeAsync , CurrentTime ) ;
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 )
{
{