[PATCH xserver] xwayland: Don't send KeyRelease events on wl_keyboard::leave

Peter Hutterer peter.hutterer at who-t.net
Tue Nov 29 08:46:44 UTC 2016


On Thu, Nov 24, 2016 at 07:56:18PM +0100, Rui Matos wrote:
> Commits 816015648ffe660ddaa0f7d4d192e555b723c372 and
> fee0827a9a695600765f3d04376fc9babe497401 made it so that
> wl_keyboard::enter doesn't result in X clients getting KeyPress events
> while still updating our internal xkb state to be in sync with the
> host compositor.
> 
> wl_keyboard::leave needs to be handled in the same way as its
> semantics from an X client POV should be the same as an X grab getting
> triggered, i.e. X clients shouldn't get KeyRelease events for keys
> that are still down at that point.
> 
> This patch uses LeaveNotify for these events on wl_keyboard::leave and
> changes the current use of KeymapNotify to EnterNotify instead just to
> keep some symmetry between both cases.
> 
> On ProcessDeviceEvent() we still need to deactivate X grabs if needed
> for KeyReleases.
> 
> Signed-off-by: Rui Matos <tiagomatos at gmail.com>

thanks, pushed

   2de37eb..5611585  master -> master

Cheers,
   Peter

> ---
> 
> v2: Daniel Stone pointed out on IRC that I should leave the early exit
>     for press events, otherwise we could activate passive grabs (in
>     CheckDeviceGrabs) which is wrong in this case.
> 
>  Xi/exevents.c                | 22 +++++++++++++---------
>  dix/getevents.c              |  5 ++++-
>  hw/xwayland/xwayland-input.c |  8 ++------
>  3 files changed, 19 insertions(+), 16 deletions(-)
> 
> diff --git a/Xi/exevents.c b/Xi/exevents.c
> index fc5298e..17d751e 100644
> --- a/Xi/exevents.c
> +++ b/Xi/exevents.c
> @@ -1798,15 +1798,19 @@ ProcessDeviceEvent(InternalEvent *ev, DeviceIntPtr device)
>          break;
>      }
>  
> -    if (grab)
> -        DeliverGrabbedEvent((InternalEvent *) event, device,
> -                            deactivateDeviceGrab);
> -    else if (device->focus && !IsPointerEvent(ev))
> -        DeliverFocusedEvent(device, (InternalEvent *) event,
> -                            GetSpriteWindow(device));
> -    else
> -        DeliverDeviceEvents(GetSpriteWindow(device), (InternalEvent *) event,
> -                            NullGrab, NullWindow, device);
> +    /* Don't deliver focus events (e.g. from KeymapNotify when running
> +     * nested) to clients. */
> +    if (event->source_type != EVENT_SOURCE_FOCUS) {
> +        if (grab)
> +            DeliverGrabbedEvent((InternalEvent *) event, device,
> +                                deactivateDeviceGrab);
> +        else if (device->focus && !IsPointerEvent(ev))
> +            DeliverFocusedEvent(device, (InternalEvent *) event,
> +                                GetSpriteWindow(device));
> +        else
> +            DeliverDeviceEvents(GetSpriteWindow(device), (InternalEvent *) event,
> +                                NullGrab, NullWindow, device);
> +    }
>  
>      if (deactivateDeviceGrab == TRUE) {
>          (*device->deviceGrab.DeactivateGrab) (device);
> diff --git a/dix/getevents.c b/dix/getevents.c
> index 4d06818..0d87453 100644
> --- a/dix/getevents.c
> +++ b/dix/getevents.c
> @@ -1101,9 +1101,12 @@ GetKeyboardEvents(InternalEvent *events, DeviceIntPtr pDev, int type,
>      }
>  #endif
>  
> -    if (type == KeymapNotify) {
> +    if (type == EnterNotify) {
>          source_type = EVENT_SOURCE_FOCUS;
>          type = KeyPress;
> +    } else if (type == LeaveNotify) {
> +        source_type = EVENT_SOURCE_FOCUS;
> +        type = KeyRelease;
>      }
>  
>      /* refuse events from disabled devices */
> diff --git a/hw/xwayland/xwayland-input.c b/hw/xwayland/xwayland-input.c
> index d6eadad..5671b50 100644
> --- a/hw/xwayland/xwayland-input.c
> +++ b/hw/xwayland/xwayland-input.c
> @@ -655,7 +655,7 @@ keyboard_handle_enter(void *data, struct wl_keyboard *keyboard,
>  
>      wl_array_copy(&xwl_seat->keys, keys);
>      wl_array_for_each(k, &xwl_seat->keys)
> -        QueueKeyboardEvents(xwl_seat->keyboard, KeymapNotify, *k + 8);
> +        QueueKeyboardEvents(xwl_seat->keyboard, EnterNotify, *k + 8);
>  }
>  
>  static void
> @@ -667,12 +667,8 @@ keyboard_handle_leave(void *data, struct wl_keyboard *keyboard,
>  
>      xwl_seat->xwl_screen->serial = serial;
>  
> -    /* Unlike keymap_handle_enter above, this time we _do_ want to trigger
> -     * full release, as we don't know how long we'll be out of focus for.
> -     * Notify clients that the keys have been released, disable autorepeat,
> -     * etc. */
>      wl_array_for_each(k, &xwl_seat->keys)
> -        QueueKeyboardEvents(xwl_seat->keyboard, KeyRelease, *k + 8);
> +        QueueKeyboardEvents(xwl_seat->keyboard, LeaveNotify, *k + 8);
>  
>      xwl_seat->keyboard_focus = NULL;
>  }
> -- 
> 2.9.3
> 


More information about the xorg-devel mailing list