mirror of
https://gitlab.freedesktop.org/libinput/libinput.git
synced 2026-02-03 13:30:27 +01:00
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>
This commit is contained in:
parent
3dcfae3fb6
commit
939a022cbc
2 changed files with 42 additions and 3 deletions
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue