[PATCH 1/2] DIX/Xi: Pass correct client to CheckDeviceGrabAndHintWindow()

Peter Hutterer peter.hutterer at who-t.net
Thu Aug 15 22:35:35 PDT 2013


On Thu, Aug 15, 2013 at 03:49:20PM +0200, Egbert Eich wrote:
> If we have a client which has registered for a DeviceButton grab
> be sure to pass this to CheckDeviceGrabAndHintWindow(). Since the
> order of clients is arbitrary there is no guarantee that the last
> client in the list is the one that belongs to this class.

whoah. good find. fwiw, we're contravening the spec already because we're
allowing a client to select for DeviceButtonPress after another client 
selected for DeviceButtonPressGrab. Specs say this should return BadAccess
but the behaviour has been like that for ages (I think) so we can't change
this part anymore.

> Signed-off-by: Egbert Eich <eich at freedesktop.org>
> ---
>  dix/events.c | 18 +++++++++++-------
>  1 file changed, 11 insertions(+), 7 deletions(-)
> 
> diff --git a/dix/events.c b/dix/events.c
> index 40673ce..36708bf 100644
> --- a/dix/events.c
> +++ b/dix/events.c
> @@ -2149,6 +2149,7 @@ DeliverEventToInputClients(DeviceIntPtr dev, InputClients * inputclients,
>  {
>      int attempt;
>      enum EventDeliveryState rc = EVENT_NOT_DELIVERED;
> +    Bool HaveDeviceButtonGrabClassClient = FALSE;

lowercase with underscores please. only function calls and globals use this
scheme here.

>  
>      for (; inputclients; inputclients = inputclients->next) {
>          Mask mask;
> @@ -2168,13 +2169,16 @@ DeliverEventToInputClients(DeviceIntPtr dev, InputClients * inputclients,
>                                              events, count,
>                                              mask, filter, grab))) {
>              if (attempt > 0) {
> -                rc = EVENT_DELIVERED;
> -                *client_return = client;
> -                *mask_return = mask;
> -                /* Success overrides non-success, so if we've been
> -                 * successful on one client, return that */
> -            }
> -            else if (rc == EVENT_NOT_DELIVERED)
> +                if (!HaveDeviceButtonGrabClassClient) {
> +                    rc = EVENT_DELIVERED;
> +                    *client_return = client;
> +                    *mask_return = mask;
> +                    /* Success overrides non-success, so if we've been
> +                     * successful on one client, return that */
> +                    if (mask & DeviceButtonGrabMask)
> +                        HaveDeviceButtonGrabClassClient = TRUE;
> +                }
> +            } else if (rc == EVENT_NOT_DELIVERED)
>                  rc = EVENT_REJECTED;

ACK, but this needs a comment in the code for future unsuspecting readers.

Cheers,
   Peter

>          }
>      }
> -- 
> 1.8.1.4
> 


More information about the xorg-devel mailing list