diff options
-rw-r--r-- | src/evdev-mt-touchpad-buttons.c | 15 | ||||
-rw-r--r-- | test/test-touchpad-buttons.c | 47 |
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); } |