gestures: if two fingers are in definitive pinch position, pinch

Two fingers on the touchpad, they're 40x40mm apart, that's a pinch. But only
after a timeout because we don't want to start a 2fg gesture if the user puts
down the third/fourth finger within the next few ms.

Related to: https://bugs.freedesktop.org/show_bug.cgi?id=99830

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
This commit is contained in:
Peter Hutterer 2018-04-26 11:18:58 +10:00
parent 588105da31
commit 66687902d0
2 changed files with 27 additions and 5 deletions

View file

@ -31,6 +31,7 @@
#define DEFAULT_GESTURE_SWITCH_TIMEOUT ms2us(100)
#define DEFAULT_GESTURE_2FG_SCROLL_TIMEOUT ms2us(150)
#define DEFAULT_GESTURE_2FG_PINCH_TIMEOUT ms2us(75)
static inline const char*
gesture_state_to_str(enum tp_gesture_state state)
@ -328,8 +329,11 @@ tp_gesture_handle_state_unknown(struct tp_dispatch *tp, uint64_t time)
struct tp_touch *first = tp->gesture.touches[0],
*second = tp->gesture.touches[1];
uint32_t dir1, dir2;
int yres = tp->device->abs.absinfo_y->resolution;
int vert_distance;
struct phys_coords mm;
int vert_distance, horiz_distance;
vert_distance = abs(first->point.y - second->point.y);
horiz_distance = abs(first->point.x - second->point.x);
if (time > (tp->gesture.initial_time + DEFAULT_GESTURE_2FG_SCROLL_TIMEOUT)) {
/* for two-finger gestures, if the fingers stay unmoving for a
@ -345,9 +349,10 @@ tp_gesture_handle_state_unknown(struct tp_dispatch *tp, uint64_t time)
/* for 3+ finger gestures, check if one finger is > 20mm
below the others */
vert_distance = abs(first->point.y - second->point.y);
if (vert_distance > 20 * yres &&
tp->gesture.enabled) {
mm = evdev_convert_xy_to_mm(tp->device,
horiz_distance,
vert_distance);
if (mm.y > 20 && tp->gesture.enabled) {
tp_gesture_init_pinch(tp);
return GESTURE_STATE_PINCH;
} else {
@ -355,6 +360,12 @@ tp_gesture_handle_state_unknown(struct tp_dispatch *tp, uint64_t time)
}
}
if (time > (tp->gesture.initial_time + DEFAULT_GESTURE_2FG_SCROLL_TIMEOUT)) {
mm = evdev_convert_xy_to_mm(tp->device, horiz_distance, vert_distance);
if (tp->gesture.finger_count == 2 && mm.x > 40 && mm.y > 40)
return GESTURE_STATE_PINCH;
}
/* Else wait for both fingers to have moved */
dir1 = tp_gesture_get_direction(tp, first, tp->gesture.finger_count);
dir2 = tp_gesture_get_direction(tp, second, tp->gesture.finger_count);

View file

@ -586,6 +586,17 @@ evdev_convert_to_mm(const struct input_absinfo *absinfo, double v)
return value/absinfo->resolution;
}
static inline struct phys_coords
evdev_convert_xy_to_mm(const struct evdev_device *device, int x, int y)
{
struct phys_coords mm;
mm.x = evdev_convert_to_mm(device->abs.absinfo_x, x);
mm.y = evdev_convert_to_mm(device->abs.absinfo_y, y);
return mm;
}
void
evdev_init_left_handed(struct evdev_device *device,
void (*change_to_left_handed)(struct evdev_device *));