mirror of
https://gitlab.freedesktop.org/libinput/libinput.git
synced 2026-03-21 12:10:39 +01:00
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 <peter.hutterer@who-t.net>
This commit is contained in:
parent
9847329d2c
commit
655f565fba
4 changed files with 103 additions and 0 deletions
|
|
@ -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);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue