Commit 655f565f authored by Peter Hutterer's avatar Peter Hutterer

touchpad: if two fingers are within the lower thumb area, they're not thumbs

The shape of the average hand implies that two fingers down within the lower
thumb area (the bottom few mm of the touchpad) cannot be thumbs without
significant contortion. So let's not mark them as thumb.

Fixes #126
Signed-off-by: Peter Hutterer's avatarPeter Hutterer <peter.hutterer@who-t.net>
parent 9847329d
Pipeline #5417 failed with stages
in 2 minutes and 58 seconds
......@@ -1143,6 +1143,28 @@ tp_thumb_detect(struct tp_dispatch *tp, struct tp_touch *t, uint64_t time)
}
}
/* If the finger is below the upper thumb line and we have another
* finger in the same area, neither finger is a thumb (unless we've
* already labeled it as such).
*/
if (t->point.y > tp->thumb.upper_thumb_line &&
tp->nfingers_down > 1) {
struct tp_touch *other;
tp_for_each_touch(tp, other) {
if (other->state != TOUCH_BEGIN &&
other->state != TOUCH_UPDATE)
continue;
if (other->point.y > tp->thumb.upper_thumb_line) {
t->thumb.state = THUMB_STATE_NO;
if (other->thumb.state == THUMB_STATE_MAYBE)
other->thumb.state = THUMB_STATE_NO;
break;
}
}
}
/* Note: a thumb at the edge of the touchpad won't trigger the
* threshold, the surface area is usually too small. So we have a
* two-stage detection: pressure and time within the area.
......
......@@ -3570,6 +3570,12 @@ litest_timeout_hysteresis(void)
msleep(90);
}
void
litest_timeout_thumb(void)
{
msleep(320);
}
void
litest_push_event_frame(struct litest_device *dev)
{
......
......@@ -819,6 +819,9 @@ litest_timeout_touch_arbitration(void);
void
litest_timeout_hysteresis(void);
void
litest_timeout_thumb(void);
void
litest_push_event_frame(struct litest_device *dev);
......
......@@ -5199,6 +5199,76 @@ START_TEST(touchpad_thumb_move_and_tap)
}
END_TEST
START_TEST(touchpad_thumb_no_doublethumb)
{
struct litest_device *dev = litest_current_device();
struct libinput *li = dev->libinput;
litest_disable_tap(dev->libinput_device);
litest_enable_clickfinger(dev);
if (!has_thumb_detect(dev))
return;
litest_drain_events(li);
litest_touch_down(dev, 0, 50, 99);
litest_touch_down(dev, 1, 70, 99);
/* move touch to trigger the thumb detection */
litest_touch_move(dev, 0, 50, 99.2);
libinput_dispatch(li);
litest_timeout_thumb();
libinput_dispatch(li);
/* move touch to trigger the thumb detection */
litest_touch_move(dev, 1, 70, 99.2);
libinput_dispatch(li);
litest_touch_move_two_touches(dev, 50, 99, 70, 99, 0, -20, 10);
litest_touch_up(dev, 0);
litest_touch_up(dev, 1);
litest_assert_only_typed_events(li, LIBINPUT_EVENT_POINTER_AXIS);
}
END_TEST
START_TEST(touchpad_thumb_no_doublethumb_with_timeout)
{
struct litest_device *dev = litest_current_device();
struct libinput *li = dev->libinput;
litest_disable_tap(dev->libinput_device);
litest_enable_clickfinger(dev);
if (!has_thumb_detect(dev))
return;
litest_drain_events(li);
litest_touch_down(dev, 0, 50, 99.9);
libinput_dispatch(li);
litest_timeout_thumb();
libinput_dispatch(li);
/* Thumbs don't have a timeout handler, so we have to move the thumb
* a bit to trigger. */
litest_touch_move(dev, 0, 50, 99.8);
/* first touch should now be a thumb */
litest_touch_down(dev, 1, 70, 99.9);
libinput_dispatch(li);
litest_timeout_thumb();
libinput_dispatch(li);
litest_touch_move(dev, 1, 70, 99.8);
litest_touch_move_two_touches(dev, 50, 99, 70, 99, 0, -20, 10);
litest_touch_up(dev, 0);
litest_touch_up(dev, 1);
litest_assert_only_typed_events(li, LIBINPUT_EVENT_POINTER_MOTION);
}
END_TEST
START_TEST(touchpad_tool_tripletap_touch_count)
{
struct litest_device *dev = litest_current_device();
......@@ -6783,6 +6853,8 @@ TEST_COLLECTION(touchpad)
litest_add("touchpad:thumb", touchpad_thumb_tap_hold_2ndfg, LITEST_CLICKPAD, LITEST_SINGLE_TOUCH);
litest_add("touchpad:thumb", touchpad_thumb_tap_hold_2ndfg_tap, LITEST_CLICKPAD, LITEST_SINGLE_TOUCH);
litest_add("touchpad:thumb", touchpad_thumb_move_and_tap, LITEST_CLICKPAD, LITEST_ANY);
litest_add("touchpad:thumb", touchpad_thumb_no_doublethumb, LITEST_CLICKPAD, LITEST_ANY);
litest_add("touchpad:thumb", touchpad_thumb_no_doublethumb_with_timeout, LITEST_CLICKPAD, LITEST_ANY);
litest_add_for_device("touchpad:bugs", touchpad_tool_tripletap_touch_count, LITEST_SYNAPTICS_TOPBUTTONPAD);
litest_add_for_device("touchpad:bugs", touchpad_tool_tripletap_touch_count_late, LITEST_SYNAPTICS_TOPBUTTONPAD);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment