[PATCH] Don't release passive grabs unless all buttons are up

Peter Hutterer peter.hutterer at who-t.net
Sun Jan 4 22:07:43 PST 2009


On Sun, Dec 21, 2008 at 10:14:53PM +0100, Thomas Jaeger wrote:
> This turned out to be a little bit trickier than I initially thought,
> since buttonsDown counts the number of physical buttons that are down,
> before they are mapped to logical buttons.
> 
> The thing I'm unsure about (as should be evident from the patch), is
> where to stick the declaration for the new function AllButtonsAreUp.
> 
> Thanks,
> Tom
> 
> Thomas Jaeger wrote:
> > I can't see any reason why we would treat buttons > 5 differently.  This
> > patch simplifies client code by eliminating the need to call XGrabDevice
> > after a button has been pressed and prevents race conditions that could
> > result from that.


Following up on that:
Both the core protocol and the XI protocol spec state that a passive grab is
to be released when all buttons are logically up, regardless of modifiers.
This is where the magic number 5 comes in. Core allows for 5 buttons, XI
allows for more.

This puts us in a difficult position. Core requires us to release the grab if,
say, only button 6 is down. XI requires us to maintain the grab.
I think we need a more complex solution than the one you proposed: test
whether the passive grab is a core or an XI grab and release depending on this
condition.
Something like 
if ((grab->coreGrab && !button->state) && ... ||
    (!grab->coreGrab && AllButtonsAreUp(b))

Keith, any opinions on this?

Cheers,
  Peter

> From 86c2f7e8c37532287772aae1c2554da5fd5eda86 Mon Sep 17 00:00:00 2001
> From: Thomas Jaeger <ThJaeger at gmail.com>
> Date: Sat, 20 Dec 2008 16:17:02 +0100
> Subject: [PATCH] Don't release grabs unless all buttons are up
> 
> Previously, only buttons <= 5 would count here.
> ---
>  Xi/exevents.c      |    2 +-
>  dix/devices.c      |   18 ++++++++++++++++++
>  dix/events.c       |    2 +-
>  include/inputstr.h |    3 +++
>  4 files changed, 23 insertions(+), 2 deletions(-)
> 
> diff --git a/Xi/exevents.c b/Xi/exevents.c
> index 083bb2f..07b7341 100644
> --- a/Xi/exevents.c
> +++ b/Xi/exevents.c
> @@ -1069,7 +1069,7 @@ ProcessOtherEvent(xEventPtr xE, DeviceIntPtr device, int count)
>  	    xE->u.u.detail = key;
>  	    return;
>  	}
> -        if (!b->state && device->deviceGrab.fromPassiveGrab)
> +        if (device->deviceGrab.fromPassiveGrab && AllButtonsAreUp(b))
>              deactivateDeviceGrab = TRUE;
>      }
>  
> diff --git a/dix/devices.c b/dix/devices.c
> index d89f6c3..10dca2e 100644
> --- a/dix/devices.c
> +++ b/dix/devices.c
> @@ -1996,6 +1996,24 @@ NoteLedState(DeviceIntPtr keybd, int led, Bool on)
>  	ctrl->leds &= ~((Leds)1 << (led - 1));
>  }
>  
> +Bool
> +AllButtonsAreUp(ButtonClassPtr butc)
> +{
> +    int key;
> +    int missingButtons = butc->buttonsDown;
> +
> +    for (key = 0; missingButtons && key < butc->numButtons; key++)
> +    {
> +	int bit = 1 << (key & 7);
> +	if (butc->down[key >> 3] & bit) {
> +	    if (butc->map[key])
> +		return False;
> +	    missingButtons--;
> +	}
> +    }
> +    return True;
> +}
> +
>  _X_EXPORT int
>  Ones(unsigned long mask)             /* HACKMEM 169 */
>  {
> diff --git a/dix/events.c b/dix/events.c
> index d7618c2..0105e82 100644
> --- a/dix/events.c
> +++ b/dix/events.c
> @@ -3846,7 +3846,7 @@ ProcessPointerEvent (xEvent *xE, DeviceIntPtr mouse, int count)
>  	    if (xE->u.u.detail == 0)
>  		return;
>              filters[mouse->id][Motion_Filter(butc)] = MotionNotify;
> -	    if (!butc->state && mouse->deviceGrab.fromPassiveGrab)
> +	    if (mouse->deviceGrab.fromPassiveGrab && AllButtonsAreUp(butc))
>  		deactivateGrab = TRUE;
>  	    break;
>  	default:
> diff --git a/include/inputstr.h b/include/inputstr.h
> index 9591d2f..a94ea01 100644
> --- a/include/inputstr.h
> +++ b/include/inputstr.h
> @@ -200,6 +200,9 @@ typedef struct _ButtonClassRec {
>  #endif
>  } ButtonClassRec, *ButtonClassPtr;
>  
> +extern Bool AllButtonsAreUp(
> +    ButtonClassPtr /*butc*/);
> +
>  typedef struct _FocusClassRec {
>      WindowPtr	win; /* May be set to a int constant (e.g. PointerRootWin)! */
>      int		revert;
> -- 
> 1.5.6.3




More information about the xorg mailing list