[PATCH libinput 03/11] touchpad: ignore hovering touches when tapping
Peter Hutterer
peter.hutterer at who-t.net
Mon Jan 30 00:58:39 UTC 2017
We need to remember whether a tap was down or just hovering, otherwise we mess
up the state machine when we send tap release events for taps that never
switched to TOUCH_BEGIN. This is quick fix, really we should have a new state
here, but that's a lot harder to implement.
Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
---
src/evdev-mt-touchpad-tap.c | 6 +++++-
src/evdev-mt-touchpad.c | 2 ++
src/evdev-mt-touchpad.h | 3 +++
test/test-touchpad.c | 19 +++++++++++++++++++
4 files changed, 29 insertions(+), 1 deletion(-)
diff --git a/src/evdev-mt-touchpad-tap.c b/src/evdev-mt-touchpad-tap.c
index 9fba521..c163599 100644
--- a/src/evdev-mt-touchpad-tap.c
+++ b/src/evdev-mt-touchpad-tap.c
@@ -774,6 +774,9 @@ tp_tap_handle_state(struct tp_dispatch *tp, uint64_t time)
if (t->tap.is_thumb)
continue;
+ if (t->state == TOUCH_HOVERING)
+ continue;
+
if (t->state == TOUCH_BEGIN) {
/* The simple version: if a touch is a thumb on
* begin we ignore it. All other thumb touches
@@ -795,7 +798,8 @@ tp_tap_handle_state(struct tp_dispatch *tp, uint64_t time)
tp_tap_handle_event(tp, t, TAP_EVENT_MOTION, time);
} else if (t->state == TOUCH_END) {
- tp_tap_handle_event(tp, t, TAP_EVENT_RELEASE, time);
+ if (t->was_down)
+ tp_tap_handle_event(tp, t, TAP_EVENT_RELEASE, time);
t->tap.state = TAP_TOUCH_STATE_IDLE;
} else if (tp->tap.state != TAP_STATE_IDLE &&
tp_tap_exceeds_motion_threshold(tp, t)) {
diff --git a/src/evdev-mt-touchpad.c b/src/evdev-mt-touchpad.c
index 56822df..a47c59f 100644
--- a/src/evdev-mt-touchpad.c
+++ b/src/evdev-mt-touchpad.c
@@ -214,6 +214,7 @@ tp_new_touch(struct tp_dispatch *tp, struct tp_touch *t, uint64_t time)
tp_motion_history_reset(t);
t->dirty = true;
t->has_ended = false;
+ t->was_down = false;
t->state = TOUCH_HOVERING;
t->pinned.is_pinned = false;
t->millis = time;
@@ -226,6 +227,7 @@ tp_begin_touch(struct tp_dispatch *tp, struct tp_touch *t, uint64_t time)
t->dirty = true;
t->state = TOUCH_BEGIN;
t->millis = time;
+ t->was_down = true;
tp->nfingers_down++;
t->palm.time = time;
t->thumb.state = THUMB_STATE_MAYBE;
diff --git a/src/evdev-mt-touchpad.h b/src/evdev-mt-touchpad.h
index fb15956..abe885f 100644
--- a/src/evdev-mt-touchpad.h
+++ b/src/evdev-mt-touchpad.h
@@ -156,6 +156,9 @@ struct tp_touch {
int distance; /* distance == 0 means touch */
int pressure;
+ bool was_down; /* if distance == 0, false for pure hovering
+ touches */
+
struct {
/* A quirk mostly used on Synaptics touchpads. In a
transition to/from fake touches > num_slots, the current
diff --git a/test/test-touchpad.c b/test/test-touchpad.c
index ee8cd7f..b8ca0b9 100644
--- a/test/test-touchpad.c
+++ b/test/test-touchpad.c
@@ -2152,6 +2152,24 @@ START_TEST(touchpad_hover_2fg_1fg_down)
}
END_TEST
+START_TEST(touchpad_hover_1fg_tap)
+{
+ struct litest_device *dev = litest_current_device();
+ struct libinput *li = dev->libinput;
+
+ litest_enable_tap(dev->libinput_device);
+
+ litest_drain_events(li);
+
+ litest_hover_start(dev, 0, 50, 50);
+ litest_hover_end(dev, 0);
+
+ libinput_dispatch(li);
+ litest_assert_empty_queue(li);
+
+}
+END_TEST
+
static void
assert_btnevent_from_device(struct litest_device *device,
unsigned int button,
@@ -4740,6 +4758,7 @@ litest_setup_tests_touchpad(void)
litest_add("touchpad:hover", touchpad_hover_down_hover_down, LITEST_TOUCHPAD|LITEST_HOVER, LITEST_ANY);
litest_add("touchpad:hover", touchpad_hover_2fg_noevent, LITEST_TOUCHPAD|LITEST_HOVER, LITEST_ANY);
litest_add("touchpad:hover", touchpad_hover_2fg_1fg_down, LITEST_TOUCHPAD|LITEST_HOVER, LITEST_ANY);
+ litest_add("touchpad:hover", touchpad_hover_1fg_tap, LITEST_TOUCHPAD|LITEST_HOVER, LITEST_ANY);
litest_add_for_device("touchpad:trackpoint", touchpad_trackpoint_buttons, LITEST_SYNAPTICS_TRACKPOINT_BUTTONS);
litest_add_for_device("touchpad:trackpoint", touchpad_trackpoint_mb_scroll, LITEST_SYNAPTICS_TRACKPOINT_BUTTONS);
--
2.9.3
More information about the wayland-devel
mailing list