Commit cfa92125 authored by Peter Hutterer's avatar Peter Hutterer

touchpad: ignore palm touches when handling clickfingers

https://bugs.freedesktop.org/show_bug.cgi?id=104188Signed-off-by: Peter Hutterer's avatarPeter Hutterer <peter.hutterer@who-t.net>
parent 2d845789
......@@ -999,16 +999,11 @@ static uint32_t
tp_clickfinger_set_button(struct tp_dispatch *tp)
{
uint32_t button;
unsigned int nfingers = tp->nfingers_down;
unsigned int nfingers = 0;
struct tp_touch *t;
struct tp_touch *first = NULL,
*second = NULL;
if (nfingers != 2)
goto out;
/* two fingers down on the touchpad. Check for distance
* between the fingers. */
tp_for_each_touch(tp, t) {
if (t->state != TOUCH_BEGIN && t->state != TOUCH_UPDATE)
continue;
......@@ -1016,16 +1011,21 @@ tp_clickfinger_set_button(struct tp_dispatch *tp)
if (t->thumb.state == THUMB_STATE_YES)
continue;
if (t->palm.state != PALM_NONE)
continue;
nfingers++;
if (!first)
first = t;
else if (!second)
second = t;
}
if (!first || !second) {
nfingers = 1;
/* Only check for finger distance when there are 2 fingers on the
* touchpad */
if (nfingers != 2)
goto out;
}
if (tp_clickfinger_within_distance(tp, first, second))
nfingers = 2;
......
......@@ -781,8 +781,8 @@ START_TEST(touchpad_clickfinger_3fg_tool_position)
litest_drain_events(li);
/* one in thumb area, one in normal area + TRIPLETAP. spread is wide
* but any 3fg touch+click counts as middle */
litest_touch_down(dev, 0, 5, 99);
* but any non-palm 3fg touch+click counts as middle */
litest_touch_down(dev, 0, 20, 99);
litest_touch_down(dev, 1, 90, 15);
litest_event(dev, EV_KEY, BTN_TOOL_DOUBLETAP, 0);
litest_event(dev, EV_KEY, BTN_TOOL_TRIPLETAP, 1);
......
......@@ -1720,6 +1720,154 @@ START_TEST(touchpad_palm_detect_pressure_after_dwt)
}
END_TEST
START_TEST(touchpad_palm_clickfinger_pressure)
{
struct litest_device *dev = litest_current_device();
struct libinput *li = dev->libinput;
struct axis_replacement axes[] = {
{ ABS_MT_PRESSURE, 75 },
{ -1, 0 }
};
if (!touchpad_has_palm_pressure(dev))
return;
litest_enable_clickfinger(dev);
litest_disable_tap(dev->libinput_device);
litest_drain_events(li);
litest_touch_down_extended(dev, 0, 50, 95, axes);
litest_touch_down(dev, 1, 50, 50);
litest_button_click(dev, BTN_LEFT, true);
litest_button_click(dev, BTN_LEFT, false);
litest_touch_up(dev, 1);
litest_touch_up(dev, 0);
litest_assert_button_event(li, BTN_LEFT, LIBINPUT_BUTTON_STATE_PRESSED);
litest_assert_button_event(li, BTN_LEFT, LIBINPUT_BUTTON_STATE_RELEASED);
litest_assert_empty_queue(li);
}
END_TEST
START_TEST(touchpad_palm_clickfinger_pressure_2fg)
{
struct litest_device *dev = litest_current_device();
struct libinput *li = dev->libinput;
struct axis_replacement axes[] = {
{ ABS_MT_PRESSURE, 75 },
{ -1, 0 }
};
if (!touchpad_has_palm_pressure(dev))
return;
if (libevdev_get_num_slots(dev->evdev) < 3)
return;
litest_enable_clickfinger(dev);
litest_disable_tap(dev->libinput_device);
litest_drain_events(li);
litest_touch_down_extended(dev, 0, 50, 95, axes);
litest_touch_down(dev, 1, 50, 50);
litest_touch_down(dev, 2, 50, 60);
litest_button_click(dev, BTN_LEFT, true);
litest_button_click(dev, BTN_LEFT, false);
litest_touch_up(dev, 1);
litest_touch_up(dev, 2);
litest_touch_up(dev, 0);
litest_assert_button_event(li, BTN_RIGHT, LIBINPUT_BUTTON_STATE_PRESSED);
litest_assert_button_event(li, BTN_RIGHT, LIBINPUT_BUTTON_STATE_RELEASED);
litest_assert_empty_queue(li);
}
END_TEST
static inline bool
touchpad_has_touch_size(struct litest_device *dev)
{
struct libevdev *evdev = dev->evdev;
if (!libevdev_has_event_code(evdev, EV_ABS, ABS_MT_TOUCH_MAJOR))
return false;
if (libevdev_get_id_vendor(evdev) == VENDOR_ID_APPLE)
return true;
return false;
}
START_TEST(touchpad_palm_clickfinger_size)
{
struct litest_device *dev = litest_current_device();
struct libinput *li = dev->libinput;
struct axis_replacement axes[] = {
{ ABS_MT_TOUCH_MAJOR, 0 },
{ ABS_MT_TOUCH_MINOR, 0 },
{ ABS_MT_ORIENTATION, 0 },
{ -1, 0 }
};
if (!touchpad_has_touch_size(dev))
return;
litest_enable_clickfinger(dev);
litest_disable_tap(dev->libinput_device);
litest_drain_events(li);
litest_touch_down_extended(dev, 0, 50, 95, axes);
litest_touch_down(dev, 1, 50, 50);
litest_button_click(dev, BTN_LEFT, true);
litest_button_click(dev, BTN_LEFT, false);
litest_touch_up(dev, 1);
litest_touch_up(dev, 0);
litest_assert_button_event(li, BTN_LEFT, LIBINPUT_BUTTON_STATE_PRESSED);
litest_assert_button_event(li, BTN_LEFT, LIBINPUT_BUTTON_STATE_RELEASED);
litest_assert_empty_queue(li);
}
END_TEST
START_TEST(touchpad_palm_clickfinger_size_2fg)
{
struct litest_device *dev = litest_current_device();
struct libinput *li = dev->libinput;
struct axis_replacement axes[] = {
{ ABS_MT_TOUCH_MAJOR, 0 },
{ ABS_MT_TOUCH_MINOR, 0 },
{ ABS_MT_ORIENTATION, 0 },
{ -1, 0 }
};
if (!touchpad_has_touch_size(dev))
return;
if (libevdev_get_num_slots(dev->evdev) < 3)
return;
litest_enable_clickfinger(dev);
litest_disable_tap(dev->libinput_device);
litest_drain_events(li);
litest_touch_down_extended(dev, 0, 50, 95, axes);
litest_touch_down(dev, 1, 50, 50);
litest_touch_down(dev, 2, 50, 60);
litest_button_click(dev, BTN_LEFT, true);
litest_button_click(dev, BTN_LEFT, false);
litest_touch_up(dev, 1);
litest_touch_up(dev, 2);
litest_touch_up(dev, 0);
litest_assert_button_event(li, BTN_RIGHT, LIBINPUT_BUTTON_STATE_PRESSED);
litest_assert_button_event(li, BTN_RIGHT, LIBINPUT_BUTTON_STATE_RELEASED);
litest_assert_empty_queue(li);
}
END_TEST
START_TEST(touchpad_left_handed)
{
struct litest_device *dev = litest_current_device();
......@@ -5579,20 +5727,6 @@ START_TEST(touchpad_pressure_semi_mt_2fg_goes_light)
}
END_TEST
static inline bool
touchpad_has_touch_size(struct litest_device *dev)
{
struct libevdev *evdev = dev->evdev;
if (!libevdev_has_event_code(evdev, EV_ABS, ABS_MT_TOUCH_MAJOR))
return false;
if (libevdev_get_id_vendor(evdev) == VENDOR_ID_APPLE)
return true;
return false;
}
START_TEST(touchpad_touch_size)
{
struct litest_device *dev = litest_current_device();
......@@ -5857,6 +5991,11 @@ TEST_COLLECTION(touchpad)
litest_add("touchpad:palm", touchpad_palm_detect_pressure_after_edge, LITEST_TOUCHPAD, LITEST_SINGLE_TOUCH);
litest_add("touchpad:palm", touchpad_palm_detect_pressure_after_dwt, LITEST_TOUCHPAD, LITEST_SINGLE_TOUCH);
litest_add("touchpad:palm", touchpad_palm_clickfinger_pressure, LITEST_CLICKPAD, LITEST_ANY);
litest_add("touchpad:palm", touchpad_palm_clickfinger_pressure_2fg, LITEST_CLICKPAD, LITEST_ANY);
litest_add("touchpad:palm", touchpad_palm_clickfinger_size, LITEST_CLICKPAD, LITEST_ANY);
litest_add("touchpad:palm", touchpad_palm_clickfinger_size_2fg, LITEST_CLICKPAD, LITEST_ANY);
litest_add("touchpad:left-handed", touchpad_left_handed, LITEST_TOUCHPAD|LITEST_BUTTON, LITEST_CLICKPAD);
litest_add_for_device("touchpad:left-handed", touchpad_left_handed_appletouch, LITEST_APPLETOUCH);
litest_add("touchpad:left-handed", touchpad_left_handed_clickpad, LITEST_CLICKPAD, LITEST_APPLE_CLICKPAD);
......
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