[PATCH libinput] gestures: if two fingers are in definitive pinch position, pinch
Peter Hutterer
peter.hutterer at who-t.net
Thu Apr 26 04:09:04 UTC 2018
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 at who-t.net>
---
src/evdev-mt-touchpad-gestures.c | 21 ++++++++++++++++-----
src/evdev.h | 11 +++++++++++
2 files changed, 27 insertions(+), 5 deletions(-)
diff --git a/src/evdev-mt-touchpad-gestures.c b/src/evdev-mt-touchpad-gestures.c
index 37682fb4..8f2dda7f 100644
--- a/src/evdev-mt-touchpad-gestures.c
+++ b/src/evdev-mt-touchpad-gestures.c
@@ -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);
diff --git a/src/evdev.h b/src/evdev.h
index 42d71a05..0c602ea0 100644
--- a/src/evdev.h
+++ b/src/evdev.h
@@ -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 *));
--
2.14.3
More information about the wayland-devel
mailing list