[PATCH libinput 12/19] touchpad: require minimum scroll distance and lock scroll direction

Peter Hutterer peter.hutterer at who-t.net
Sun Feb 16 22:48:31 PST 2014


This is a fairly rough approach, but can be handled more fine-grained later.
Require a minimum of 1 unit to start scrolling and lock the scrolling in the
initial direction, so further scroll events are limited to that direction
only.

Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
---
 src/evdev-mt-touchpad.c | 82 +++++++++++++++++++++++++++++++++++++++++--------
 src/evdev-mt-touchpad.h | 10 ++++++
 2 files changed, 79 insertions(+), 13 deletions(-)

diff --git a/src/evdev-mt-touchpad.c b/src/evdev-mt-touchpad.c
index 873ddf0..14fb7f3 100644
--- a/src/evdev-mt-touchpad.c
+++ b/src/evdev-mt-touchpad.c
@@ -310,16 +310,64 @@ tp_post_twofinger_scroll(struct tp_dispatch *tp, uint32_t time)
 
 	tp_filter_motion(tp, &dx, &dy, time);
 
-	if (dx != 0.0)
-		pointer_notify_axis(&tp->device->base,
-				    time,
-				    LIBINPUT_POINTER_AXIS_HORIZONTAL_SCROLL,
-				    li_fixed_from_double(dx));
-	if (dy != 0.0)
+	if (tp->scroll.state == SCROLL_STATE_NONE) {
+		/* Require at least one px scrolling to start */
+		if (dx <= -1.0 || dx >= 1.0) {
+			tp->scroll.state = SCROLL_STATE_SCROLLING;
+			tp->scroll.direction |= (1 << LIBINPUT_POINTER_AXIS_HORIZONTAL_SCROLL);
+		}
+
+		if (dy <= -1.0 || dy >= 1.0) {
+			tp->scroll.state = SCROLL_STATE_SCROLLING;
+			tp->scroll.direction |= (1 << LIBINPUT_POINTER_AXIS_VERTICAL_SCROLL);
+		}
+
+		if (tp->scroll.state == SCROLL_STATE_NONE)
+			return;
+	}
+
+	if (dy != 0.0 &&
+	    (tp->scroll.direction & (1 << LIBINPUT_POINTER_AXIS_VERTICAL_SCROLL))) {
 		pointer_notify_axis(&tp->device->base,
 				    time,
 				    LIBINPUT_POINTER_AXIS_VERTICAL_SCROLL,
 				    li_fixed_from_double(dy));
+	}
+
+	if (dx != 0.0 &&
+	    (tp->scroll.direction & (1 << LIBINPUT_POINTER_AXIS_HORIZONTAL_SCROLL))) {
+		pointer_notify_axis(&tp->device->base,
+				    time,
+				    LIBINPUT_POINTER_AXIS_HORIZONTAL_SCROLL,
+				    li_fixed_from_double(dx));
+	}
+}
+
+static int
+tp_post_scroll_events(struct tp_dispatch *tp, uint32_t time)
+{
+	if (tp->nfingers_down != 2) {
+		/* terminate scrolling with a zero scroll event to notify
+		 * caller that it really ended now */
+		if (tp->scroll.state != SCROLL_STATE_NONE) {
+			tp->scroll.state = SCROLL_STATE_NONE;
+			tp->scroll.direction = 0;
+			if (tp->scroll.direction & LIBINPUT_POINTER_AXIS_VERTICAL_SCROLL)
+				pointer_notify_axis(&tp->device->base,
+						    time,
+						    LIBINPUT_POINTER_AXIS_VERTICAL_SCROLL,
+						    0);
+			if (tp->scroll.direction & LIBINPUT_POINTER_AXIS_HORIZONTAL_SCROLL)
+				pointer_notify_axis(&tp->device->base,
+						    time,
+						    LIBINPUT_POINTER_AXIS_HORIZONTAL_SCROLL,
+						    0);
+		}
+	} else {
+		tp_post_twofinger_scroll(tp, time);
+		return 1;
+	}
+	return 0;
 }
 
 static void
@@ -362,16 +410,12 @@ tp_post_events(struct tp_dispatch *tp, uint32_t time)
 	struct tp_touch *t = tp_current_touch(tp);
 	double dx, dy;
 
-	if (tp->nfingers_down > 2) {
-		return;
-	} else if (tp->nfingers_down == 2) {
-		tp_post_twofinger_scroll(tp, time);
-		return;
-	}
-
 	if (tp_tap_handle_state(tp, time) != 0)
 		return;
 
+	if (tp_post_scroll_events(tp, time) != 0)
+		return;
+
 	if (t->history.count >= TOUCHPAD_MIN_SAMPLES) {
 		tp_get_delta(t, &dx, &dy);
 		tp_filter_motion(tp, &dx, &dy, time);
@@ -464,6 +508,15 @@ tp_init_accel(struct tp_dispatch *touchpad, double diagonal)
 }
 
 static int
+tp_init_scroll(struct tp_dispatch *tp)
+{
+	tp->scroll.direction = 0;
+	tp->scroll.state = SCROLL_STATE_NONE;
+
+	return 0;
+}
+
+static int
 tp_init(struct tp_dispatch *tp,
 	struct evdev_device *device)
 {
@@ -485,6 +538,9 @@ tp_init(struct tp_dispatch *tp,
 	tp->hysteresis.margin_y =
 		diagonal / DEFAULT_HYSTERESIS_MARGIN_DENOMINATOR;
 
+	if (tp_init_scroll(tp) != 0)
+		return -1;
+
 	if (tp_init_accel(tp, diagonal) != 0)
 		return -1;
 
diff --git a/src/evdev-mt-touchpad.h b/src/evdev-mt-touchpad.h
index a5cfaa6..17e9055 100644
--- a/src/evdev-mt-touchpad.h
+++ b/src/evdev-mt-touchpad.h
@@ -46,6 +46,11 @@ enum touch_state {
 	TOUCH_END
 };
 
+enum scroll_state {
+	SCROLL_STATE_NONE,
+	SCROLL_STATE_SCROLLING
+};
+
 enum tp_tap_state {
 	TAP_STATE_IDLE = 4,
 	TAP_STATE_TOUCH,
@@ -113,6 +118,11 @@ struct tp_dispatch {
 		uint32_t old_state;
 	} buttons;				/* physical buttons */
 
+	struct {
+		enum scroll_state state;
+		enum libinput_pointer_axis direction;
+	} scroll;
+
 	enum touchpad_event queued;
 
 	struct {
-- 
1.8.4.2



More information about the wayland-devel mailing list