Hi,

On 23-02-15 03:56, Peter Hutterer wrote:
On Wed, Feb 18, 2015 at 01:26:50PM +0100, Hans de Goede wrote:
Handle everything which is not handeld by the tap, (soft)button or edge-scroll

typo: handled


Fixed.

code/statemachines in a unified way. Everything is treated as a X-finger
gesture now, and the action to take on finger movement is decided by
the gesture.finger_mode setting. Pointer control now simply is seen as a
1 finger gesture, and 2fg scrolling as a 2fg gesture.

This removed the need for special casing things like switching back to

special-casing, I think (i.e. with a -)


Fixed.

pointer mode when lifting a finger in 2fg scrolling mode, and also lays the
groundwork for adding 3+ fg gesture support.

Note that 1 test-case needs to be updated to wait for the finger mode
switching when switching mode while a gesture has already been started.
This is actually an improvement as this stops sending spurious pointer
motion events at the end of 2fg scrolling when not lifting both fingers at
exactly the same time.

Signed-off-by: Hans de Goede <hdego...@redhat.com>

only comment I have here: can we rename finger_mode to finger_count? it's
less ambiguous.

Done in my personal tree.



Reviewed-by: Peter Hutterer <peter.hutte...@who-t.net>
for the series up to here.

Regards,

Hans



Cheers,
    Peter

---
  src/Makefile.am                     |   1 +
  src/evdev-mt-touchpad-buttons.c     |   1 -
  src/evdev-mt-touchpad-edge-scroll.c |   1 -
  src/evdev-mt-touchpad-gestures.c    | 146 ++++++++++++++++++++++++++++++++++++
  src/evdev-mt-touchpad.c             | 129 ++++++-------------------------
  src/evdev-mt-touchpad.h             |  47 +++++++++---
  test/litest.c                       |   6 ++
  test/litest.h                       |   1 +
  test/touchpad.c                     |  12 +++
  9 files changed, 225 insertions(+), 119 deletions(-)
  create mode 100644 src/evdev-mt-touchpad-gestures.c

diff --git a/src/Makefile.am b/src/Makefile.am
index b5eba73..ff65ff7 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -15,6 +15,7 @@ libinput_la_SOURCES =                 \
        evdev-mt-touchpad-tap.c         \
        evdev-mt-touchpad-buttons.c     \
        evdev-mt-touchpad-edge-scroll.c \
+       evdev-mt-touchpad-gestures.c    \
        filter.c                        \
        filter.h                        \
        filter-private.h                \
diff --git a/src/evdev-mt-touchpad-buttons.c b/src/evdev-mt-touchpad-buttons.c
index 9dbb513..12f8023 100644
--- a/src/evdev-mt-touchpad-buttons.c
+++ b/src/evdev-mt-touchpad-buttons.c
@@ -156,7 +156,6 @@ tp_button_set_state(struct tp_dispatch *tp, struct tp_touch 
*t,
                break;
        case BUTTON_STATE_AREA:
                t->button.curr = BUTTON_EVENT_IN_AREA;
-               tp_set_pointer(tp, t);
                break;
        case BUTTON_STATE_BOTTOM:
                t->button.curr = event;
diff --git a/src/evdev-mt-touchpad-edge-scroll.c 
b/src/evdev-mt-touchpad-edge-scroll.c
index df181d5..28f29c2 100644
--- a/src/evdev-mt-touchpad-edge-scroll.c
+++ b/src/evdev-mt-touchpad-edge-scroll.c
@@ -86,7 +86,6 @@ tp_edge_scroll_set_state(struct tp_dispatch *tp,
                break;
        case EDGE_SCROLL_TOUCH_STATE_AREA:
                t->scroll.edge = EDGE_NONE;
-               tp_set_pointer(tp, t);
                break;
        }
  }
diff --git a/src/evdev-mt-touchpad-gestures.c b/src/evdev-mt-touchpad-gestures.c
new file mode 100644
index 0000000..28ac74b
--- /dev/null
+++ b/src/evdev-mt-touchpad-gestures.c
@@ -0,0 +1,146 @@
+/*
+ * Copyright © 2015 Red Hat, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and
+ * its documentation for any purpose is hereby granted without fee, provided
+ * that the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of the copyright holders not be used in
+ * advertising or publicity pertaining to distribution of the software
+ * without specific, written prior permission.  The copyright holders make
+ * no representations about the suitability of this software for any
+ * purpose.  It is provided "as is" without express or implied warranty.
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
+ * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "config.h"
+
+#include <assert.h>
+#include <math.h>
+#include <stdbool.h>
+#include <limits.h>
+
+#include "evdev-mt-touchpad.h"
+
+#define DEFAULT_GESTURE_SWITCH_TIMEOUT 100 /* ms */
+
+void
+tp_gesture_start(struct tp_dispatch *tp, uint64_t time)
+{
+       if (tp->gesture.started)
+               return;
+
+       switch (tp->gesture.finger_mode) {
+       case 2:
+               /* NOP */
+               break;
+       }
+       tp->gesture.started = true;
+}
+
+void
+tp_gesture_post_events(struct tp_dispatch *tp, uint64_t time)
+{
+       if (tp->gesture.finger_mode == 0)
+               return;
+
+       /* When tap-and-dragging, or a clickpad is clicked force 1fg mode */
+       if (tp_tap_dragging(tp) || (tp->buttons.is_clickpad && 
tp->buttons.state)) {
+               tp_gesture_stop(tp, time);
+               tp->gesture.finger_mode = 1;
+               tp->gesture.finger_mode_pending = 0;
+       }
+
+       /* Don't send events when we're unsure in which mode we are */
+       if (tp->gesture.finger_mode_pending)
+               return;
+
+       switch (tp->gesture.finger_mode) {
+       case 1:
+               tp_gesture_post_pointer_motion(tp, time);
+               break;
+       case 2:
+               tp_gesture_post_twofinger_scroll(tp, time);
+               break;
+       }
+}
+
+void
+tp_gesture_stop(struct tp_dispatch *tp, uint64_t time)
+{
+       if (!tp->gesture.started)
+               return;
+
+       switch (tp->gesture.finger_mode) {
+       case 2:
+               tp_gesture_stop_twofinger_scroll(tp, time);
+               break;
+       }
+       tp->gesture.started = false;
+}
+
+static void
+tp_gesture_finger_mode_switch_timeout(uint64_t now, void *data)
+{
+       struct tp_dispatch *tp = data;
+
+       if (!tp->gesture.finger_mode_pending)
+               return;
+
+       tp_gesture_stop(tp, now); /* End current gesture */
+       tp->gesture.finger_mode = tp->gesture.finger_mode_pending;
+       tp->gesture.finger_mode_pending = 0;
+}
+
+void
+tp_gesture_handle_state(struct tp_dispatch *tp, uint64_t time)
+{
+       unsigned int active_touches = 0;
+       struct tp_touch *t;
+
+       tp_for_each_touch(tp, t)
+               if (tp_touch_active(tp, t))
+                       active_touches++;
+
+       if (active_touches != tp->gesture.finger_mode) {
+               /* If all fingers are lifted immediately end the gesture */
+               if (active_touches == 0) {
+                       tp_gesture_stop(tp, time);
+                       tp->gesture.finger_mode = 0;
+                       tp->gesture.finger_mode_pending = 0;
+               /* Immediately switch to new mode to avoid initial latency */
+               } else if (!tp->gesture.started) {
+                       tp->gesture.finger_mode = active_touches;
+                       tp->gesture.finger_mode_pending = 0;
+               /* Else debounce finger changes */
+               } else if (active_touches != tp->gesture.finger_mode_pending) {
+                       tp->gesture.finger_mode_pending = active_touches;
+                       
libinput_timer_set(&tp->gesture.finger_mode_switch_timer,
+                               time + DEFAULT_GESTURE_SWITCH_TIMEOUT);
+               }
+       } else {
+                tp->gesture.finger_mode_pending = 0;
+       }
+}
+
+int
+tp_init_gesture(struct tp_dispatch *tp)
+{
+       libinput_timer_init(&tp->gesture.finger_mode_switch_timer,
+                           tp->device->base.seat->libinput,
+                           tp_gesture_finger_mode_switch_timeout, tp);
+       return 0;
+}
+
+void
+tp_remove_gesture(struct tp_dispatch *tp)
+{
+       libinput_timer_cancel(&tp->gesture.finger_mode_switch_timer);
+}
diff --git a/src/evdev-mt-touchpad.c b/src/evdev-mt-touchpad.c
index c6c48d3..947678a 100644
--- a/src/evdev-mt-touchpad.c
+++ b/src/evdev-mt-touchpad.c
@@ -227,7 +227,6 @@ tp_end_touch(struct tp_dispatch *tp, struct tp_touch *t, 
uint64_t time)
        }

        t->dirty = true;
-       t->is_pointer = false;
        t->palm.is_palm = false;
        t->state = TOUCH_END;
        t->pinned.is_pinned = false;
@@ -424,7 +423,6 @@ tp_unpin_finger(struct tp_dispatch *tp, struct tp_touch *t)
        if (xdist * xdist + ydist * ydist >=
                        tp->buttons.motion_dist * tp->buttons.motion_dist) {
                t->pinned.is_pinned = false;
-               tp_set_pointer(tp, t);
                return;
        }

@@ -439,14 +437,13 @@ tp_pin_fingers(struct tp_dispatch *tp)
        struct tp_touch *t;

        tp_for_each_touch(tp, t) {
-               t->is_pointer = false;
                t->pinned.is_pinned = true;
                t->pinned.center_x = t->x;
                t->pinned.center_y = t->y;
        }
  }

-static int
+int
  tp_touch_active(struct tp_dispatch *tp, struct tp_touch *t)
  {
        return (t->state == TOUCH_BEGIN || t->state == TOUCH_UPDATE) &&
@@ -456,21 +453,6 @@ tp_touch_active(struct tp_dispatch *tp, struct tp_touch *t)
                tp_edge_scroll_touch_active(tp, t);
  }

-void
-tp_set_pointer(struct tp_dispatch *tp, struct tp_touch *t)
-{
-       struct tp_touch *tmp = NULL;
-
-       /* Only set the touch as pointer if we don't have one yet */
-       tp_for_each_touch(tp, tmp) {
-               if (tmp->is_pointer)
-                       return;
-       }
-
-       if (tp_touch_active(tp, t))
-               t->is_pointer = true;
-}
-
  static void
  tp_palm_detect(struct tp_dispatch *tp, struct tp_touch *t, uint64_t time)
  {
@@ -487,7 +469,6 @@ tp_palm_detect(struct tp_dispatch *tp, struct tp_touch *t, 
uint64_t time)
                        int dirs = vector_get_direction(t->x - t->palm.x, t->y - 
t->palm.y);
                        if ((dirs & DIRECTIONS) && !(dirs & ~DIRECTIONS)) {
                                t->palm.is_palm = false;
-                               tp_set_pointer(tp, t);
                        }
                }
                return;
@@ -530,8 +511,6 @@ tp_get_average_touches_delta(struct tp_dispatch *tp, double 
*dx, double *dy)
                        *dx += tmpx;
                        *dy += tmpy;
                }
-               /* Stop spurious MOTION events at the end of scrolling */
-               t->is_pointer = false;
        }

        if (nchanged == 0)
@@ -541,80 +520,30 @@ tp_get_average_touches_delta(struct tp_dispatch *tp, 
double *dx, double *dy)
        *dy /= nchanged;
  }

-static void
-tp_post_twofinger_scroll(struct tp_dispatch *tp, uint64_t time)
+void
+tp_gesture_post_twofinger_scroll(struct tp_dispatch *tp, uint64_t time)
  {
        double dx = 0, dy =0;

        tp_get_average_touches_delta(tp, &dx, &dy);
        tp_filter_motion(tp, &dx, &dy, NULL, NULL, time);

+       if (dx == 0.0 && dy == 0.0)
+               return; 
+
+       tp_gesture_start(tp, time);
        evdev_post_scroll(tp->device,
                          time,
                          LIBINPUT_POINTER_AXIS_SOURCE_FINGER,
                          dx, dy);
-       tp->scroll.twofinger_state = TWOFINGER_SCROLL_STATE_ACTIVE;
  }

-static void
-tp_twofinger_stop_scroll(struct tp_dispatch *tp, uint64_t time)
+void
+tp_gesture_stop_twofinger_scroll(struct tp_dispatch *tp, uint64_t time)
  {
-       struct tp_touch *t, *ptr = NULL;
-       int nfingers_down = 0;
-
        evdev_stop_scroll(tp->device,
                          time,
                          LIBINPUT_POINTER_AXIS_SOURCE_FINGER);
-
-       /* If we were scrolling and now there's exactly 1 active finger,
-          switch back to pointer movement */
-       if (tp->scroll.twofinger_state == TWOFINGER_SCROLL_STATE_ACTIVE) {
-               tp_for_each_touch(tp, t) {
-                       if (tp_touch_active(tp, t)) {
-                               nfingers_down++;
-                               if (ptr == NULL)
-                                       ptr = t;
-                       }
-               }
-
-               if (nfingers_down == 1)
-                       tp_set_pointer(tp, ptr);
-       }
-
-       tp->scroll.twofinger_state = TWOFINGER_SCROLL_STATE_NONE;
-}
-
-static int
-tp_twofinger_scroll_post_events(struct tp_dispatch *tp, uint64_t time)
-{
-       struct tp_touch *t;
-       int nfingers_down = 0;
-
-       if (tp->scroll.method != LIBINPUT_CONFIG_SCROLL_2FG)
-               return 0;
-
-       /* No 2fg scrolling during tap-n-drag */
-       if (tp_tap_dragging(tp))
-               return 0;
-
-       /* No 2fg scrolling while a clickpad is clicked */
-       if (tp->buttons.is_clickpad && tp->buttons.state)
-               return 0;
-
-       /* Only count active touches for 2 finger scrolling */
-       tp_for_each_touch(tp, t) {
-               if (tp_touch_active(tp, t))
-                       nfingers_down++;
-       }
-
-       if (nfingers_down == 2) {
-               tp_post_twofinger_scroll(tp, time);
-               return 1;
-       }
-
-       tp_twofinger_stop_scroll(tp, time);
-
-       return 0;
  }

  static void
@@ -718,6 +647,8 @@ tp_process_state(struct tp_dispatch *tp, uint64_t time)
        if ((tp->queued & TOUCHPAD_EVENT_BUTTON_PRESS) &&
            tp->buttons.is_clickpad)
                tp_pin_fingers(tp);
+
+       tp_gesture_handle_state(tp, time);
  }

  static void
@@ -749,24 +680,6 @@ tp_post_process_state(struct tp_dispatch *tp, uint64_t 
time)
  }

  static void
-tp_get_pointer_delta(struct tp_dispatch *tp, double *dx, double *dy)
-{
-       struct tp_touch *t = tp_current_touch(tp);
-
-       if (!t->is_pointer) {
-               tp_for_each_touch(tp, t) {
-                       if (t->is_pointer)
-                               break;
-               }
-       }
-
-       if (!t->is_pointer || !t->dirty)
-               return;
-
-       tp_get_delta(t, dx, dy);
-}
-
-static void
  tp_get_combined_touches_delta(struct tp_dispatch *tp, double *dx, double *dy)
  {
        struct tp_touch *t;
@@ -785,8 +698,8 @@ tp_get_combined_touches_delta(struct tp_dispatch *tp, 
double *dx, double *dy)
        }
  }

-static void
-tp_post_pointer_motion(struct tp_dispatch *tp, uint64_t time)
+void
+tp_gesture_post_pointer_motion(struct tp_dispatch *tp, uint64_t time)
  {
        double dx = 0.0, dy = 0.0;
        double dx_unaccel, dy_unaccel;
@@ -795,7 +708,7 @@ tp_post_pointer_motion(struct tp_dispatch *tp, uint64_t 
time)
        if (tp->buttons.is_clickpad && tp->buttons.state)
                tp_get_combined_touches_delta(tp, &dx, &dy);
        else
-               tp_get_pointer_delta(tp, &dx, &dy);
+               tp_get_average_touches_delta(tp, &dx, &dy);

        tp_filter_motion(tp, &dx, &dy, &dx_unaccel, &dy_unaccel, time);

@@ -821,16 +734,14 @@ tp_post_events(struct tp_dispatch *tp, uint64_t time)

        if (filter_motion || tp->sendevents.trackpoint_active) {
                tp_edge_scroll_stop_events(tp, time);
-               tp_twofinger_stop_scroll(tp, time);
+               tp_gesture_stop(tp, time);
                return;
        }

        if (tp_edge_scroll_post_events(tp, time) != 0)
                return;
-       if (tp_twofinger_scroll_post_events(tp, time) != 0)
-               return;

-       tp_post_pointer_motion(tp, time);
+       tp_gesture_post_events(tp, time);
  }

  static void
@@ -887,6 +798,7 @@ tp_remove(struct evdev_dispatch *dispatch)
        tp_remove_buttons(tp);
        tp_remove_sendevents(tp);
        tp_remove_edge_scroll(tp);
+       tp_remove_gesture(tp);
  }

  static void
@@ -980,7 +892,7 @@ tp_trackpoint_event(uint64_t time, struct libinput_event 
*event, void *data)

        if (!tp->sendevents.trackpoint_active) {
                tp_edge_scroll_stop_events(tp, time);
-               tp_twofinger_stop_scroll(tp, time);
+               tp_gesture_stop(tp, time);
                tp_tap_suspend(tp, time);
                tp->sendevents.trackpoint_active = true;
        }
@@ -1221,7 +1133,7 @@ tp_scroll_config_scroll_method_set_method(struct 
libinput_device *device,
                return LIBINPUT_CONFIG_STATUS_SUCCESS;

        tp_edge_scroll_stop_events(tp, time);
-       tp_twofinger_stop_scroll(tp, time);
+       tp_gesture_stop_twofinger_scroll(tp, time);

        tp->scroll.method = method;

@@ -1359,6 +1271,9 @@ tp_init(struct tp_dispatch *tp,
        if (tp_init_scroll(tp, device) != 0)
                return -1;

+       if (tp_init_gesture(tp) != 0)
+               return -1;
+
        device->seat_caps |= EVDEV_DEVICE_POINTER;

        return 0;
diff --git a/src/evdev-mt-touchpad.h b/src/evdev-mt-touchpad.h
index 3479e5e..4d8e875 100644
--- a/src/evdev-mt-touchpad.h
+++ b/src/evdev-mt-touchpad.h
@@ -118,11 +118,6 @@ enum tp_edge_scroll_touch_state {
        EDGE_SCROLL_TOUCH_STATE_AREA,
  };

-enum tp_twofinger_scroll_state {
-       TWOFINGER_SCROLL_STATE_NONE,
-       TWOFINGER_SCROLL_STATE_ACTIVE,
-};
-
  struct tp_motion {
        int32_t x;
        int32_t y;
@@ -133,7 +128,6 @@ struct tp_touch {
        enum touch_state state;
        bool has_ended;                         /* TRACKING_ID == -1 */
        bool dirty;
-       bool is_pointer;                        /* the pointer-controlling 
touch */
        int32_t x;
        int32_t y;
        uint64_t millis;
@@ -217,6 +211,13 @@ struct tp_dispatch {
        } accel;

        struct {
+               bool started;
+               unsigned int finger_mode;
+               unsigned int finger_mode_pending;
+               struct libinput_timer finger_mode_switch_timer;
+       } gesture;
+
+       struct {
                bool is_clickpad;               /* true for clickpads */
                bool has_topbuttons;
                bool use_clickfinger;           /* number of fingers decides 
button number */
@@ -253,7 +254,6 @@ struct tp_dispatch {
                enum libinput_config_scroll_method method;
                int32_t right_edge;
                int32_t bottom_edge;
-               enum tp_twofinger_scroll_state twofinger_state;
        } scroll;

        enum touchpad_event queued;
@@ -288,15 +288,15 @@ void
  tp_get_delta(struct tp_touch *t, double *dx, double *dy);

  void
-tp_set_pointer(struct tp_dispatch *tp, struct tp_touch *t);
-
-void
  tp_filter_motion(struct tp_dispatch *tp,
                 double *dx, double *dy,
                 double *dx_unaccel, double *dy_unaccel,
                 uint64_t time);

  int
+tp_touch_active(struct tp_dispatch *tp, struct tp_touch *t);
+
+int
  tp_tap_handle_state(struct tp_dispatch *tp, uint64_t time);

  int
@@ -368,4 +368,31 @@ tp_edge_scroll_stop_events(struct tp_dispatch *tp, 
uint64_t time);
  int
  tp_edge_scroll_touch_active(struct tp_dispatch *tp, struct tp_touch *t);

+int
+tp_init_gesture(struct tp_dispatch *tp);
+
+void
+tp_remove_gesture(struct tp_dispatch *tp);
+
+void
+tp_gesture_start(struct tp_dispatch *tp, uint64_t time);
+
+void
+tp_gesture_stop(struct tp_dispatch *tp, uint64_t time);
+
+void
+tp_gesture_handle_state(struct tp_dispatch *tp, uint64_t time);
+
+void
+tp_gesture_post_events(struct tp_dispatch *tp, uint64_t time);
+
+void
+tp_gesture_post_twofinger_scroll(struct tp_dispatch *tp, uint64_t time);
+
+void
+tp_gesture_stop_twofinger_scroll(struct tp_dispatch *tp, uint64_t time);
+
+void
+tp_gesture_post_pointer_motion(struct tp_dispatch *tp, uint64_t time);
+
  #endif
diff --git a/test/litest.c b/test/litest.c
index b938cce..cf12424 100644
--- a/test/litest.c
+++ b/test/litest.c
@@ -1385,6 +1385,12 @@ litest_timeout_buttonscroll(void)
  }

  void
+litest_timeout_finger_switch(void)
+{
+       msleep(120);
+}
+
+void
  litest_push_event_frame(struct litest_device *dev)
  {
        assert(!dev->skip_ev_syn);
diff --git a/test/litest.h b/test/litest.h
index 60ec458..d78bf0e 100644
--- a/test/litest.h
+++ b/test/litest.h
@@ -180,6 +180,7 @@ struct libevdev_uinput * 
litest_create_uinput_abs_device(const char *name,
  void litest_timeout_tap(void);
  void litest_timeout_softbuttons(void);
  void litest_timeout_buttonscroll(void);
+void litest_timeout_finger_switch(void);

  void litest_push_event_frame(struct litest_device *dev);
  void litest_pop_event_frame(struct litest_device *dev);
diff --git a/test/touchpad.c b/test/touchpad.c
index 9c34b50..3627352 100644
--- a/test/touchpad.c
+++ b/test/touchpad.c
@@ -1871,9 +1871,15 @@ START_TEST(touchpad_2fg_scroll_return_to_motion)

        /* 2fg scroll */
        litest_touch_down(dev, 1, 53, 50);
+       libinput_dispatch(li);
+       litest_timeout_finger_switch();
+       libinput_dispatch(li);
        litest_touch_move_to(dev, 0, 47, 50, 47, 70, 5, 0);
        litest_touch_move_to(dev, 1, 53, 50, 53, 70, 5, 0);
        litest_touch_up(dev, 1);
+       libinput_dispatch(li);
+       litest_timeout_finger_switch();
+       libinput_dispatch(li);
        litest_assert_only_typed_events(li, LIBINPUT_EVENT_POINTER_AXIS);

        litest_touch_move_to(dev, 0, 47, 70, 47, 50, 10, 0);
@@ -1881,9 +1887,15 @@ START_TEST(touchpad_2fg_scroll_return_to_motion)

        /* back to 2fg scroll, lifting the other finger */
        litest_touch_down(dev, 1, 50, 50);
+       libinput_dispatch(li);
+       litest_timeout_finger_switch();
+       libinput_dispatch(li);
        litest_touch_move_to(dev, 0, 47, 50, 47, 70, 5, 0);
        litest_touch_move_to(dev, 1, 53, 50, 53, 70, 5, 0);
        litest_touch_up(dev, 0);
+       libinput_dispatch(li);
+       litest_timeout_finger_switch();
+       libinput_dispatch(li);
        litest_assert_only_typed_events(li, LIBINPUT_EVENT_POINTER_AXIS);

        /* move with second finger */
--
2.1.0

_______________________________________________
wayland-devel mailing list
wayland-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/wayland-devel

_______________________________________________
wayland-devel mailing list
wayland-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/wayland-devel

Reply via email to