summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authornovenary <streetwalkermc@gmail.com>2021-04-04 18:30:41 +0300
committerPeter Hutterer <peter.hutterer@who-t.net>2021-05-19 05:12:58 +0000
commit939a022cbc8e5c17901646fc2c33b1d1f81e4d9d (patch)
tree24fb397a3b5cd281b9fa9a21c3371a52756367c3
parent3dcfae3fb699bc72c34099f5a567a61e075971b5 (diff)
downloadlibinput-939a022cbc8e5c17901646fc2c33b1d1f81e4d9d.tar.gz
Improve disambiguation between two-finger pinch and scroll
A pinch is defined as two fingers moving in different directions, and a scroll as two fingers moving in the same direction. Often enough when the user is trying to pinch, we may initially see both fingers moving in the same direction and decide that they want to scroll. Add a grace period during which we may transition to a pinch in those situations. Test fix: touchpad_trackpoint_buttons_2fg_scroll emits movements that change the distance between fingers, which triggers this new transition and makes the test fail; correct this. Signed-off-by: novenary <streetwalkermc@gmail.com>
-rw-r--r--src/evdev-mt-touchpad-gestures.c39
-rw-r--r--test/test-touchpad.c6
2 files changed, 42 insertions, 3 deletions
diff --git a/src/evdev-mt-touchpad-gestures.c b/src/evdev-mt-touchpad-gestures.c
index 2f9e2136..16841308 100644
--- a/src/evdev-mt-touchpad-gestures.c
+++ b/src/evdev-mt-touchpad-gestures.c
@@ -32,6 +32,8 @@
#define DEFAULT_GESTURE_SWIPE_TIMEOUT ms2us(150)
#define DEFAULT_GESTURE_PINCH_TIMEOUT ms2us(150)
+#define PINCH_DISAMBIGUATION_MOVE_THRESHOLD 1.5 /* mm */
+
static inline const char*
gesture_state_to_str(enum tp_gesture_state state)
{
@@ -546,6 +548,33 @@ tp_gesture_detect_motion_gestures(struct tp_dispatch *tp, uint64_t time)
return GESTURE_STATE_PINCH;
}
+static bool
+tp_gesture_is_pinch(struct tp_dispatch *tp)
+{
+ struct tp_touch *first = tp->gesture.touches[0],
+ *second = tp->gesture.touches[1];
+ uint32_t dir1, dir2;
+ struct phys_coords first_moved, second_moved;
+ double first_mm, second_mm;
+
+ dir1 = tp_gesture_get_direction(tp, first);
+ dir2 = tp_gesture_get_direction(tp, second);
+ if (tp_gesture_same_directions(dir1, dir2))
+ return false;
+
+ first_moved = tp_gesture_mm_moved(tp, first);
+ first_mm = hypot(first_moved.x, first_moved.y);
+ if (first_mm < PINCH_DISAMBIGUATION_MOVE_THRESHOLD)
+ return false;
+
+ second_moved = tp_gesture_mm_moved(tp, second);
+ second_mm = hypot(second_moved.x, second_moved.y);
+ if (second_mm < PINCH_DISAMBIGUATION_MOVE_THRESHOLD)
+ return false;
+
+ return true;
+}
+
static enum tp_gesture_state
tp_gesture_handle_state_none(struct tp_dispatch *tp, uint64_t time)
{
@@ -624,6 +653,16 @@ tp_gesture_handle_state_scroll(struct tp_dispatch *tp, uint64_t time)
if (tp->scroll.method != LIBINPUT_CONFIG_SCROLL_2FG)
return GESTURE_STATE_SCROLL;
+ /* We may confuse a pinch for a scroll initially,
+ * allow ourselves to correct our guess.
+ */
+ if (time < (tp->gesture.initial_time + DEFAULT_GESTURE_PINCH_TIMEOUT) &&
+ tp_gesture_is_pinch(tp)) {
+ tp_gesture_cancel(tp, time);
+ tp_gesture_init_pinch(tp);
+ return GESTURE_STATE_PINCH;
+ }
+
raw = tp_get_average_touches_delta(tp);
/* scroll is not accelerated */
diff --git a/test/test-touchpad.c b/test/test-touchpad.c
index faa4fd58..7afd8882 100644
--- a/test/test-touchpad.c
+++ b/test/test-touchpad.c
@@ -3401,9 +3401,9 @@ START_TEST(touchpad_trackpoint_buttons_2fg_scroll)
litest_drain_events(li);
- litest_touch_down(touchpad, 0, 49, 70);
- litest_touch_down(touchpad, 1, 51, 70);
- litest_touch_move_two_touches(touchpad, 49, 70, 51, 70, 0, -40, 10);
+ litest_touch_down(touchpad, 0, 40, 70);
+ litest_touch_down(touchpad, 1, 60, 70);
+ litest_touch_move_two_touches(touchpad, 40, 70, 60, 70, 0, -40, 10);
libinput_dispatch(li);
litest_wait_for_event(li);