[PATCH libinput 2/5] touchpad: Avoid spurious motion event for scroll movement below threshold

Hans de Goede hdegoede at redhat.com
Tue Jun 24 07:23:10 PDT 2014


If the user puts down to fingers to scroll, then changes his mind and
lifts them, without having them moved past the initial scroll threshold in
either direction, then any movement which he has done will cause a spurious
scroll event when the second finger down is lifted first.

The problem is that t->is_pointer was not being set to false in this case,
since that is done in tp_post_twofinger_scroll after checking scroll.state
which never gets set in this scenario.

Instead of changing the order, simply completely remove scroll.state completely
it is a boolean, and everywhere we check for it we also check for the axis bits
in state.direction, so it is not necessary.

Also add a check to ensure there are no spurious motion events.

Signed-off-by: Hans de Goede <hdegoede at redhat.com>
---
 src/evdev-mt-touchpad.c | 17 +++--------------
 src/evdev-mt-touchpad.h |  6 ------
 test/touchpad.c         | 27 ++++++++++++++++++++-------
 3 files changed, 23 insertions(+), 27 deletions(-)

diff --git a/src/evdev-mt-touchpad.c b/src/evdev-mt-touchpad.c
index 4811bf3..04ea93c 100644
--- a/src/evdev-mt-touchpad.c
+++ b/src/evdev-mt-touchpad.c
@@ -464,17 +464,11 @@ tp_post_twofinger_scroll(struct tp_dispatch *tp, uint64_t time)
 	tp_filter_motion(tp, &dx, &dy, time);
 
 	/* Require at least three px scrolling to start */
-	if (dy <= -3.0 || dy >= 3.0) {
-		tp->scroll.state = SCROLL_STATE_SCROLLING;
+	if (dy <= -3.0 || dy >= 3.0)
 		tp->scroll.direction |= (1 << LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL);
-	}
-	if (dx <= -3.0 || dx >= 3.0) {
-		tp->scroll.state = SCROLL_STATE_SCROLLING;
-		tp->scroll.direction |= (1 << LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL);
-	}
 
-	if (tp->scroll.state == SCROLL_STATE_NONE)
-		return;
+	if (dx <= -3.0 || dx >= 3.0)
+		tp->scroll.direction |= (1 << LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL);
 
 	/* Stop spurious MOTION events at the end of scrolling */
 	tp_for_each_touch(tp, t)
@@ -500,9 +494,6 @@ tp_post_twofinger_scroll(struct tp_dispatch *tp, uint64_t time)
 static void
 tp_stop_scroll_events(struct tp_dispatch *tp, uint64_t time)
 {
-	if (tp->scroll.state == SCROLL_STATE_NONE)
-		return;
-
 	/* terminate scrolling with a zero scroll event */
 	if (tp->scroll.direction & (1 << LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL))
 		pointer_notify_axis(&tp->device->base,
@@ -515,7 +506,6 @@ tp_stop_scroll_events(struct tp_dispatch *tp, uint64_t time)
 				    LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL,
 				    0);
 
-	tp->scroll.state = SCROLL_STATE_NONE;
 	tp->scroll.direction = 0;
 }
 
@@ -732,7 +722,6 @@ static int
 tp_init_scroll(struct tp_dispatch *tp)
 {
 	tp->scroll.direction = 0;
-	tp->scroll.state = SCROLL_STATE_NONE;
 
 	return 0;
 }
diff --git a/src/evdev-mt-touchpad.h b/src/evdev-mt-touchpad.h
index 83a4b5b..494725a 100644
--- a/src/evdev-mt-touchpad.h
+++ b/src/evdev-mt-touchpad.h
@@ -72,11 +72,6 @@ enum button_state {
 	BUTTON_STATE_IGNORE,
 };
 
-enum scroll_state {
-	SCROLL_STATE_NONE,
-	SCROLL_STATE_SCROLLING
-};
-
 enum tp_tap_state {
 	TAP_STATE_IDLE = 4,
 	TAP_STATE_TOUCH,
@@ -202,7 +197,6 @@ struct tp_dispatch {
 	} buttons;				/* physical buttons */
 
 	struct {
-		enum scroll_state state;
 		enum libinput_pointer_axis direction;
 	} scroll;
 
diff --git a/test/touchpad.c b/test/touchpad.c
index 585c1d2..d04d12c 100644
--- a/test/touchpad.c
+++ b/test/touchpad.c
@@ -1073,16 +1073,27 @@ START_TEST(clickpad_topsoftbuttons_move_out_ignore)
 END_TEST
 
 static void
-test_2fg_scroll(struct litest_device *dev, int dx, int dy)
+test_2fg_scroll(struct litest_device *dev, int dx, int dy, int sleep)
 {
+	struct libinput *li = dev->libinput;
+
 	litest_touch_down(dev, 0, 47, 50);
 	litest_touch_down(dev, 1, 53, 50);
 
 	litest_touch_move_to(dev, 0, 47, 50, 47 + dx, 50 + dy, 5);
 	litest_touch_move_to(dev, 1, 53, 50, 53 + dx, 50 + dy, 5);
 
+	/* Avoid a small scroll being seen as a tap */
+	if (sleep) {
+		libinput_dispatch(li);
+		msleep(sleep);
+		libinput_dispatch(li);
+	}
+
 	litest_touch_up(dev, 1);
 	litest_touch_up(dev, 0);
+
+	libinput_dispatch(li);
 }
 
 static void
@@ -1092,8 +1103,6 @@ check_2fg_scroll(struct litest_device *dev, int axis, int dir)
 	struct libinput_event *event, *next_event;
 	struct libinput_event_pointer *ptrev;
 
-	libinput_dispatch(li);
-
 	event = libinput_get_event(li);
 	next_event = libinput_get_event(li);
 	ck_assert(next_event != NULL); /* At least 1 scroll + stop scroll */
@@ -1137,14 +1146,18 @@ START_TEST(touchpad_2fg_scroll)
 
 	/* Note this mixes in a tiny amount of movement in the wrong direction,
 	   which should be ignored */
-	test_2fg_scroll(dev, 1, 40);
+	test_2fg_scroll(dev, 1, 40, 0);
 	check_2fg_scroll(dev, LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL, 10);
-	test_2fg_scroll(dev, 1, -40);
+	test_2fg_scroll(dev, 1, -40, 0);
 	check_2fg_scroll(dev, LIBINPUT_POINTER_AXIS_SCROLL_VERTICAL, -10);
-	test_2fg_scroll(dev, 40, 1);
+	test_2fg_scroll(dev, 40, 1, 0);
 	check_2fg_scroll(dev, LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL, 10);
-	test_2fg_scroll(dev, -40, 1);
+	test_2fg_scroll(dev, -40, 1, 0);
 	check_2fg_scroll(dev, LIBINPUT_POINTER_AXIS_SCROLL_HORIZONTAL, -10);
+
+	/* 2fg scroll smaller then the threshold should not generate events */
+	test_2fg_scroll(dev, 1, 1, 200);
+	litest_assert_empty_queue(li);
 }
 END_TEST
 
-- 
2.0.0



More information about the wayland-devel mailing list