diff options
author | novenary <streetwalkermc@gmail.com> | 2021-04-04 18:30:41 +0300 |
---|---|---|
committer | Peter Hutterer <peter.hutterer@who-t.net> | 2021-05-19 05:12:58 +0000 |
commit | 939a022cbc8e5c17901646fc2c33b1d1f81e4d9d (patch) | |
tree | 24fb397a3b5cd281b9fa9a21c3371a52756367c3 | |
parent | 3dcfae3fb699bc72c34099f5a567a61e075971b5 (diff) | |
download | libinput-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.c | 39 | ||||
-rw-r--r-- | test/test-touchpad.c | 6 |
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); |