summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/evdev-mt-touchpad-buttons.c15
-rw-r--r--test/test-touchpad-buttons.c47
2 files changed, 61 insertions, 1 deletions
diff --git a/src/evdev-mt-touchpad-buttons.c b/src/evdev-mt-touchpad-buttons.c
index d7f075c0..be399bc7 100644
--- a/src/evdev-mt-touchpad-buttons.c
+++ b/src/evdev-mt-touchpad-buttons.c
@@ -943,9 +943,22 @@ tp_guess_clickpad(const struct tp_dispatch *tp, struct evdev_device *device)
has_middle = libevdev_has_event_code(device->evdev, EV_KEY, BTN_MIDDLE),
has_right = libevdev_has_event_code(device->evdev, EV_KEY, BTN_RIGHT);
-
is_clickpad = libevdev_has_property(device->evdev, INPUT_PROP_BUTTONPAD);
+ /* A non-clickpad without a right button is a clickpad, assume the
+ * kernel is wrong.
+ * Exceptions here:
+ * - The one-button Apple touchpad (discontinued in 2008) has a
+ * single physical button
+ * - Wacom touch devices have neither left nor right buttons
+ */
+ if (!is_clickpad && has_left && !has_right &&
+ (tp->device->model_flags & EVDEV_MODEL_APPLE_TOUCHPAD_ONEBUTTON) == 0) {
+ evdev_log_bug_kernel(device,
+ "missing right button, assuming it is a clickpad.\n");
+ is_clickpad = true;
+ }
+
if (has_middle || has_right) {
if (is_clickpad)
evdev_log_bug_kernel(device,
diff --git a/test/test-touchpad-buttons.c b/test/test-touchpad-buttons.c
index e0a8ddf2..6af571d9 100644
--- a/test/test-touchpad-buttons.c
+++ b/test/test-touchpad-buttons.c
@@ -2053,6 +2053,51 @@ START_TEST(clickpad_middleemulation_click_disable_while_down)
}
END_TEST
+START_TEST(touchpad_non_clickpad_detection)
+{
+ struct libinput *li;
+ struct libinput_device *device;
+ struct libevdev_uinput *uinput;
+ static struct input_absinfo absinfo[] = {
+ { ABS_X, 1472, 5472, 0, 0, 75 },
+ { ABS_Y, 1408, 4448, 0, 0, 129 },
+ { 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, 1472, 5472, 0, 0, 75 },
+ { ABS_MT_POSITION_Y, 1408, 4448, 0, 0, 129 },
+ { ABS_MT_TRACKING_ID, 0, 65535, 0, 0, 0 },
+ { ABS_MT_PRESSURE, 0, 255, 0, 0, 0 },
+ { .value = -1 }
+ };
+ uint32_t methods;
+
+ /* Create a touchpad with only a left button but missing
+ * INPUT_PROP_BUTTONPAD. We should treat this as clickpad.
+ */
+ uinput = litest_create_uinput_abs_device("litest NonClickpad",
+ NULL,
+ absinfo,
+ EV_KEY, BTN_LEFT,
+ EV_KEY, BTN_TOOL_FINGER,
+ EV_KEY, BTN_TOUCH,
+ -1);
+
+ li = litest_create_context();
+ device = libinput_path_add_device(li,
+ libevdev_uinput_get_devnode(uinput));
+
+ methods = libinput_device_config_click_get_methods(device);
+ ck_assert(methods & LIBINPUT_CONFIG_CLICK_METHOD_BUTTON_AREAS);
+ ck_assert(methods & LIBINPUT_CONFIG_CLICK_METHOD_CLICKFINGER);
+
+
+ libinput_path_remove_device(device);
+ libevdev_uinput_destroy(uinput);
+ litest_destroy_context(li);
+}
+END_TEST
+
TEST_COLLECTION(touchpad_buttons)
{
struct range finger_count = {1, 4};
@@ -2122,4 +2167,6 @@ TEST_COLLECTION(touchpad_buttons)
litest_add(clickpad_middleemulation_click_middle_right, LITEST_CLICKPAD, LITEST_ANY);
litest_add(clickpad_middleemulation_click_enable_while_down, LITEST_CLICKPAD, LITEST_ANY);
litest_add(clickpad_middleemulation_click_disable_while_down, LITEST_CLICKPAD, LITEST_ANY);
+
+ litest_add_no_device(touchpad_non_clickpad_detection);
}