[PATCH xserver] xwayland: use wayland axis_discrete event

Peter Hutterer peter.hutterer at who-t.net
Thu Aug 30 08:03:49 UTC 2018


On Wed, Aug 15, 2018 at 08:54:25PM +1200, Scott Anderson wrote:
> On 6/08/18 6:09 PM, Scott Anderson wrote:
> > This prevents multiple scroll events happening for wayland compositors
> > which send axis values other than 10. For example, libinput will
> > typically return 15 for each scroll wheel step, and if a wayland
> > compositor sends those to xwayland without normalising them, 2 scroll
> > wheel steps will end up as 3 xorg scroll events. By listening for the
> > discrete_axis event, this will now correctly send only 2 xorg scroll
> > events.
> > 
> > The wayland protocol gurantees that there will always be an axis event
> > following an axis_discrete event. However, it does not gurantee that
> > other events (including other axis_discrete+axis pairs) will not happen
> > in between them. So we must keep a list of outstanding axis_discrete
> > events.
> > 
> > Signed-off-by: Scott Anderson <scott at anderso.nz>
> > ---
> >   hw/xwayland/xwayland-input.c | 41 +++++++++++++++++++++++++++++++++++-
> >   hw/xwayland/xwayland.h       |  1 +
> >   2 files changed, 41 insertions(+), 1 deletion(-)
> > 
> > diff --git a/hw/xwayland/xwayland-input.c b/hw/xwayland/xwayland-input.c
> > index a602f0887..6fd3c416b 100644
> > --- a/hw/xwayland/xwayland-input.c
> > +++ b/hw/xwayland/xwayland-input.c
> > @@ -37,6 +37,12 @@
> >   #include <misc.h>
> >   #include "tablet-unstable-v2-client-protocol.h"
> > +struct axis_discrete_pending {
> > +    struct xorg_list l;
> > +    uint32_t axis;
> > +    int32_t discrete;
> > +};
> > +
> >   struct sync_pending {
> >       struct xorg_list l;
> >       DeviceIntPtr pending_dev;
> > @@ -565,6 +571,8 @@ pointer_handle_axis(void *data, struct wl_pointer *pointer,
> >       int index;
> >       const int divisor = 10;
> >       ValuatorMask mask;
> > +    struct axis_discrete_pending *pending = NULL;
> > +    struct axis_discrete_pending *iter;
> >       switch (axis) {
> >       case WL_POINTER_AXIS_VERTICAL_SCROLL:
> > @@ -577,8 +585,22 @@ pointer_handle_axis(void *data, struct wl_pointer *pointer,
> >           return;
> >       }
> > +    xorg_list_for_each_entry(iter, &xwl_seat->axis_discrete_pending, l) {
> > +        if (iter->axis == axis) {
> > +            pending = iter;
> > +            break;
> > +        }
> > +    }
> > +
> >       valuator_mask_zero(&mask);
> > -    valuator_mask_set_double(&mask, index, wl_fixed_to_double(value) / divisor);
> > +
> > +    if (pending) {
> > +        valuator_mask_set(&mask, index, pending->discrete);
> > +        xorg_list_del(&pending->l);
> > +        free(pending);
> > +    } else {
> > +        valuator_mask_set_double(&mask, index, wl_fixed_to_double(value) / divisor);
> > +    }
> >       QueuePointerEvents(xwl_seat->pointer, MotionNotify, 0, POINTER_RELATIVE, &mask);
> >   }
> > @@ -608,6 +630,16 @@ static void
> >   pointer_handle_axis_discrete(void *data, struct wl_pointer *wl_pointer,
> >                                uint32_t axis, int32_t discrete)
> >   {
> > +    struct xwl_seat *xwl_seat = data;
> > +
> > +    struct axis_discrete_pending *pending = malloc(sizeof *pending);
> > +    if (!pending)
> > +        return;
> > +
> > +    pending->axis = axis;
> > +    pending->discrete = discrete;
> > +
> > +    xorg_list_add(&pending->l, &xwl_seat->axis_discrete_pending);
> >   }
> >   static const struct wl_pointer_listener pointer_listener = {
> > @@ -1337,6 +1369,7 @@ create_input_device(struct xwl_screen *xwl_screen, uint32_t id, uint32_t version
> >       wl_array_init(&xwl_seat->keys);
> >       xorg_list_init(&xwl_seat->touches);
> > +    xorg_list_init(&xwl_seat->axis_discrete_pending);
> >       xorg_list_init(&xwl_seat->sync_pending);
> >   }
> > @@ -1345,6 +1378,7 @@ xwl_seat_destroy(struct xwl_seat *xwl_seat)
> >   {
> >       struct xwl_touch *xwl_touch, *next_xwl_touch;
> >       struct sync_pending *p, *npd;
> > +    struct axis_discrete_pending *ad, *ad_next;
> >       xorg_list_for_each_entry_safe(xwl_touch, next_xwl_touch,
> >                                     &xwl_seat->touches, link_touch) {
> > @@ -1357,6 +1391,11 @@ xwl_seat_destroy(struct xwl_seat *xwl_seat)
> >           free (p);
> >       }
> > +    xorg_list_for_each_entry_safe(ad, ad_next, &xwl_seat->axis_discrete_pending, l) {
> > +        xorg_list_del(&ad->l);
> > +        free(ad);
> > +    }
> > +
> >       release_tablet_manager_seat(xwl_seat);
> >       release_grab(xwl_seat);
> > diff --git a/hw/xwayland/xwayland.h b/hw/xwayland/xwayland.h
> > index d70ad54bf..1a6e2f380 100644
> > --- a/hw/xwayland/xwayland.h
> > +++ b/hw/xwayland/xwayland.h
> > @@ -272,6 +272,7 @@ struct xwl_seat {
> >       char *keymap;
> >       struct wl_surface *keyboard_focus;
> > +    struct xorg_list axis_discrete_pending;
> >       struct xorg_list sync_pending;
> >       struct xwl_pointer_warp_emulator *pointer_warp_emulator;
> > 
> 
> Ping.

sorry, this is pushed now.

   f79e53685..cd285922c  master -> master

Cheers,
   Peter



More information about the xorg-devel mailing list