diff --git a/src/evdev-mt-touchpad-buttons.c b/src/evdev-mt-touchpad-buttons.c index d8438b84..8d4e278e 100644 --- a/src/evdev-mt-touchpad-buttons.c +++ b/src/evdev-mt-touchpad-buttons.c @@ -678,6 +678,35 @@ tp_button_config_click_get_default_method(struct libinput_device *device) return tp_click_get_default_method(tp); } +static inline void +tp_init_middlebutton_emulation(struct tp_dispatch *tp, + struct evdev_device *device) +{ + bool enable_by_default, + want_config_option; + + if (tp->buttons.is_clickpad) + return; + + /* init middle button emulation on non-clickpads, but only if we + * don't have a middle button. Exception: ALPS touchpads don't know + * if they have a middle button, so we always want the option there + * and enabled by default. + */ + if (!libevdev_has_event_code(device->evdev, EV_KEY, BTN_MIDDLE)) { + enable_by_default = true; + want_config_option = false; + } else if (device->model == EVDEV_MODEL_ALPS_TOUCHPAD) { + enable_by_default = true; + want_config_option = true; + } else + return; + + evdev_init_middlebutton(tp->device, + enable_by_default, + want_config_option); +} + int tp_init_buttons(struct tp_dispatch *tp, struct evdev_device *device) @@ -734,9 +763,7 @@ tp_init_buttons(struct tp_dispatch *tp, tp_init_top_softbuttons(tp, device, 1.0); - if (!tp->buttons.is_clickpad && - !libevdev_has_event_code(device->evdev, EV_KEY, BTN_MIDDLE)) - evdev_init_middlebutton(tp->device, true, false); + tp_init_middlebutton_emulation(tp, device); tp_for_each_touch(tp, t) { t->button.state = BUTTON_STATE_NONE; diff --git a/src/evdev.c b/src/evdev.c index 6f457b8d..7e1e5c80 100644 --- a/src/evdev.c +++ b/src/evdev.c @@ -1516,6 +1516,7 @@ evdev_read_model(struct evdev_device *device) { "LIBINPUT_MODEL_CLEVO_W740SU", EVDEV_MODEL_CLEVO_W740SU }, { "LIBINPUT_MODEL_APPLE_TOUCHPAD", EVDEV_MODEL_APPLE_TOUCHPAD }, { "LIBINPUT_MODEL_WACOM_TOUCHPAD", EVDEV_MODEL_WACOM_TOUCHPAD }, + { "LIBINPUT_MODEL_ALPS_TOUCHPAD", EVDEV_MODEL_ALPS_TOUCHPAD }, { NULL, EVDEV_MODEL_DEFAULT }, }; const struct model_map *m = model_map; diff --git a/src/evdev.h b/src/evdev.h index ff35a8d2..566b0a44 100644 --- a/src/evdev.h +++ b/src/evdev.h @@ -106,6 +106,7 @@ enum evdev_device_model { EVDEV_MODEL_CLEVO_W740SU, EVDEV_MODEL_APPLE_TOUCHPAD, EVDEV_MODEL_WACOM_TOUCHPAD, + EVDEV_MODEL_ALPS_TOUCHPAD, }; struct mt_slot { diff --git a/test/pointer.c b/test/pointer.c index 90977d7e..688b6b0b 100644 --- a/test/pointer.c +++ b/test/pointer.c @@ -1279,6 +1279,11 @@ START_TEST(middlebutton_default_touchpad) struct libinput_device *device = dev->libinput_device; enum libinput_config_middle_emulation_state state; int available; + const char *name = libinput_device_get_name(dev->libinput_device); + + if (streq(name, "litest AlpsPS/2 ALPS GlidePoint") || + streq(name, "litest AlpsPS/2 ALPS DualPoint TouchPad")) + return; available = libinput_device_config_middle_emulation_is_available(device); ck_assert(!available); @@ -1295,6 +1300,25 @@ START_TEST(middlebutton_default_touchpad) } END_TEST +START_TEST(middlebutton_default_alps) +{ + struct litest_device *dev = litest_current_device(); + struct libinput_device *device = dev->libinput_device; + enum libinput_config_middle_emulation_state state; + int available; + + available = libinput_device_config_middle_emulation_is_available(device); + ck_assert(available); + + state = libinput_device_config_middle_emulation_get_enabled( + device); + ck_assert_int_eq(state, LIBINPUT_CONFIG_MIDDLE_EMULATION_ENABLED); + state = libinput_device_config_middle_emulation_get_default_enabled( + device); + ck_assert_int_eq(state, LIBINPUT_CONFIG_MIDDLE_EMULATION_ENABLED); +} +END_TEST + START_TEST(middlebutton_default_disabled) { struct litest_device *dev = litest_current_device(); @@ -1360,6 +1384,7 @@ litest_setup_tests(void) litest_add("pointer:middlebutton", middlebutton_default_clickpad, LITEST_CLICKPAD, LITEST_ANY); litest_add("pointer:middlebutton", middlebutton_default_touchpad, LITEST_TOUCHPAD, LITEST_CLICKPAD); litest_add("pointer:middlebutton", middlebutton_default_disabled, LITEST_ANY, LITEST_BUTTON); + litest_add_for_device("pointer:middlebutton", middlebutton_default_alps, LITEST_ALPS_SEMI_MT); litest_add_ranged("pointer:state", pointer_absolute_initial_state, LITEST_ABSOLUTE, LITEST_ANY, &axis_range); } diff --git a/udev/90-libinput-model-quirks.hwdb b/udev/90-libinput-model-quirks.hwdb index 7442f828..cf57e9c9 100644 --- a/udev/90-libinput-model-quirks.hwdb +++ b/udev/90-libinput-model-quirks.hwdb @@ -15,6 +15,13 @@ # # Sort by brand, model +########################################## +# ALPS +########################################## +libinput:name:*AlpsPS/2 ALPS DualPoint TouchPad:dmi:* +libinput:name:*AlpsPS/2 ALPS GlidePoint:dmi:* + LIBINPUT_MODEL_ALPS_TOUCHPAD=1 + ########################################## # Apple ##########################################