diff --git a/doc/user/device-quirks.rst b/doc/user/device-quirks.rst index 9adbbe43..e3bedd32 100644 --- a/doc/user/device-quirks.rst +++ b/doc/user/device-quirks.rst @@ -161,11 +161,15 @@ AttrTouchSizeRange=N:M, AttrPalmSizeThreshold=O Specifies the touch size required to trigger a press (N) and to trigger a release (M). O > N > M. See :ref:`touchpad_touch_size_hwdb` for more details. + An AttrPalmSizeThreshold of zero unsets any threshold that has been + inherited from another quirk. AttrPressureRange=N:M, AttrPalmPressureThreshold=O, AttrThumbPressureThreshold=P Specifies the touch pressure required to trigger a press (N) and to trigger a release (M), when a palm touch is triggered (O) and when a thumb touch is triggered (P). O > P > N > M. See :ref:`touchpad_pressure_hwdb` for more details. + An AttrPalmPressureThreshold of zero unsets any threshold that has been + inherited from another quirk. AttrLidSwitchReliability=reliable|unreliable|write_open Indicates the reliability of the lid switch. This is a string enum. Very few devices need this, if in doubt do not set. See :ref:`switches_lid` diff --git a/meson.build b/meson.build index 70cc3037..1b3b8d32 100644 --- a/meson.build +++ b/meson.build @@ -796,6 +796,7 @@ if get_option('tests') 'test/litest-device-thinkpad-extrabuttons.c', 'test/litest-device-trackpoint.c', 'test/litest-device-touch-screen.c', + 'test/litest-device-touchpad-palm-threshold-zero.c', 'test/litest-device-touchscreen-invalid-range.c', 'test/litest-device-touchscreen-fuzz.c', 'test/litest-device-touchscreen-mt-tool.c', diff --git a/src/evdev-mt-touchpad.c b/src/evdev-mt-touchpad.c index d0f9a506..d9b7ca5f 100644 --- a/src/evdev-mt-touchpad.c +++ b/src/evdev-mt-touchpad.c @@ -3409,11 +3409,13 @@ tp_init_palmdetect_pressure(struct tp_dispatch *tp, } tp->palm.pressure_threshold = tp_read_palm_pressure_prop(tp, device); - tp->palm.use_pressure = true; + if (tp->palm.pressure_threshold != 0) { + tp->palm.use_pressure = true; - evdev_log_debug(device, - "palm: pressure threshold is %d\n", - tp->palm.pressure_threshold); + evdev_log_debug(device, + "palm: pressure threshold is %d\n", + tp->palm.pressure_threshold); + } } static inline void @@ -3430,11 +3432,7 @@ tp_init_palmdetect_size(struct tp_dispatch *tp, return; if (quirks_get_uint32(q, QUIRK_ATTR_PALM_SIZE_THRESHOLD, &threshold)) { - if (threshold == 0) { - evdev_log_bug_client(device, - "palm: ignoring invalid threshold %d\n", - threshold); - } else { + if (threshold != 0) { tp->palm.use_size = true; tp->palm.size_threshold = threshold; } diff --git a/test/litest-device-touchpad-palm-threshold-zero.c b/test/litest-device-touchpad-palm-threshold-zero.c new file mode 100644 index 00000000..698b30dc --- /dev/null +++ b/test/litest-device-touchpad-palm-threshold-zero.c @@ -0,0 +1,123 @@ +/* + * Copyright © 2015 Red Hat, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include "config.h" + +#include "litest.h" +#include "litest-int.h" + +static struct input_event down[] = { + { .type = EV_ABS, .code = ABS_X, .value = LITEST_AUTO_ASSIGN }, + { .type = EV_ABS, .code = ABS_Y, .value = LITEST_AUTO_ASSIGN }, + { .type = EV_ABS, .code = ABS_PRESSURE, .value = LITEST_AUTO_ASSIGN }, + { .type = EV_ABS, .code = ABS_MT_SLOT, .value = LITEST_AUTO_ASSIGN }, + { .type = EV_ABS, .code = ABS_MT_TRACKING_ID, .value = LITEST_AUTO_ASSIGN }, + { .type = EV_ABS, .code = ABS_MT_POSITION_X, .value = LITEST_AUTO_ASSIGN }, + { .type = EV_ABS, .code = ABS_MT_POSITION_Y, .value = LITEST_AUTO_ASSIGN }, + { .type = EV_ABS, .code = ABS_MT_PRESSURE, .value = LITEST_AUTO_ASSIGN }, + { .type = EV_SYN, .code = SYN_REPORT, .value = 0 }, + { .type = -1, .code = -1 }, +}; + +static struct input_event move[] = { + { .type = EV_ABS, .code = ABS_MT_SLOT, .value = LITEST_AUTO_ASSIGN }, + { .type = EV_ABS, .code = ABS_X, .value = LITEST_AUTO_ASSIGN }, + { .type = EV_ABS, .code = ABS_Y, .value = LITEST_AUTO_ASSIGN }, + { .type = EV_ABS, .code = ABS_PRESSURE, .value = LITEST_AUTO_ASSIGN }, + { .type = EV_ABS, .code = ABS_MT_POSITION_X, .value = LITEST_AUTO_ASSIGN }, + { .type = EV_ABS, .code = ABS_MT_POSITION_Y, .value = LITEST_AUTO_ASSIGN }, + { .type = EV_ABS, .code = ABS_MT_PRESSURE, .value = LITEST_AUTO_ASSIGN }, + { .type = EV_SYN, .code = SYN_REPORT, .value = 0 }, + { .type = -1, .code = -1 }, +}; + +static int +get_axis_default(struct litest_device *d, unsigned int evcode, int32_t *value) +{ + switch (evcode) { + case ABS_PRESSURE: + case ABS_MT_PRESSURE: + *value = 30; + return 0; + } + return 1; +} + +static struct litest_device_interface interface = { + .touch_down_events = down, + .touch_move_events = move, + + .get_axis_default = get_axis_default, +}; + +static struct input_id input_id = { + .bustype = 0x11, + .vendor = 0x2, + .product = 0x7, +}; + +static int events[] = { + EV_KEY, BTN_LEFT, + EV_KEY, BTN_TOOL_FINGER, + EV_KEY, BTN_TOOL_QUINTTAP, + EV_KEY, BTN_TOUCH, + EV_KEY, BTN_TOOL_DOUBLETAP, + EV_KEY, BTN_TOOL_TRIPLETAP, + EV_KEY, BTN_TOOL_QUADTAP, + EV_KEY, BTN_0, + EV_KEY, BTN_1, + EV_KEY, BTN_2, + INPUT_PROP_MAX, INPUT_PROP_POINTER, + INPUT_PROP_MAX, INPUT_PROP_BUTTONPAD, + -1, -1, +}; + +static struct input_absinfo absinfo[] = { + { ABS_X, 1266, 5676, 0, 0, 45 }, + { ABS_Y, 1096, 4758, 0, 0, 68 }, + { ABS_PRESSURE, 0, 255, 0, 0, 0 }, + { ABS_TOOL_WIDTH, 0, 15, 0, 0, 0 }, + { ABS_MT_SLOT, 0, 1, 0, 0, 0 }, + { ABS_MT_POSITION_X, 1266, 5676, 0, 0, 45 }, + { ABS_MT_POSITION_Y, 1096, 4758, 0, 0, 68 }, + { ABS_MT_TRACKING_ID, 0, 65535, 0, 0, 0 }, + { ABS_MT_PRESSURE, 0, 255, 0, 0, 0 }, + { .value = -1 } +}; + +static const char quirk_file[] = +"[litest TouchpadPalmPressure Zero]\n" +"MatchName=litest Touchpad PalmPressureThreshold 0\n" +"AttrPalmPressureThreshold=0\n"; + +TEST_DEVICE("touchpad-palmpressure-zero", + .type = LITEST_TOUCHPAD_PALMPRESSURE_ZERO, + .features = LITEST_IGNORED, /* Only use for specific tests */ + .interface = &interface, + + .name = "Touchpad PalmPressureThreshold 0", + .id = &input_id, + .events = events, + .absinfo = absinfo, + .quirk_file = quirk_file, +) diff --git a/test/litest.h b/test/litest.h index 1e23bf61..672e6ef5 100644 --- a/test/litest.h +++ b/test/litest.h @@ -251,6 +251,7 @@ enum litest_device_type { LITEST_SYNAPTICS_RMI4, LITEST_SYNAPTICS_TOPBUTTONPAD, LITEST_SYNAPTICS_TOUCHPAD, + LITEST_TOUCHPAD_PALMPRESSURE_ZERO, LITEST_WACOM_FINGER, /* Touchscreens */ diff --git a/test/test-touchpad.c b/test/test-touchpad.c index 2e057898..ccfd125d 100644 --- a/test/test-touchpad.c +++ b/test/test-touchpad.c @@ -2194,6 +2194,28 @@ START_TEST(touchpad_palm_detect_pressure_after_dwt) } END_TEST +START_TEST(touchpad_palm_ignore_threshold_zero) +{ + struct litest_device *dev = litest_current_device(); + struct libinput *li = dev->libinput; + struct axis_replacement axes[] = { + { ABS_MT_PRESSURE, 75 }, + { -1, 0 } + }; + + litest_disable_tap(dev->libinput_device); + litest_disable_hold_gestures(dev->libinput_device); + litest_drain_events(li); + + litest_touch_down_extended(dev, 0, 50, 99, axes); + litest_touch_move_to(dev, 0, 50, 50, 80, 99, 10); + litest_touch_up(dev, 0); + + libinput_dispatch(li); + litest_assert_only_typed_events(li, LIBINPUT_EVENT_POINTER_MOTION); +} +END_TEST + START_TEST(touchpad_palm_clickfinger_pressure) { struct litest_device *dev = litest_current_device(); @@ -7292,6 +7314,8 @@ TEST_COLLECTION(touchpad) litest_add(touchpad_palm_detect_pressure_keep_palm, LITEST_TOUCHPAD, LITEST_SINGLE_TOUCH); litest_add(touchpad_palm_detect_pressure_after_edge, LITEST_TOUCHPAD, LITEST_SINGLE_TOUCH); litest_add(touchpad_palm_detect_pressure_after_dwt, LITEST_TOUCHPAD, LITEST_SINGLE_TOUCH); + litest_add_for_device(touchpad_palm_ignore_threshold_zero, LITEST_TOUCHPAD_PALMPRESSURE_ZERO); + litest_add(touchpad_palm_clickfinger_pressure, LITEST_CLICKPAD, LITEST_ANY); litest_add(touchpad_palm_clickfinger_pressure_2fg, LITEST_CLICKPAD, LITEST_ANY); litest_add(touchpad_palm_clickfinger_size, LITEST_CLICKPAD, LITEST_ANY);