tp_want_dwt(struct evdev_device *touchpad,
struct evdev_device *keyboard)
{
- unsigned int bus_tp = libevdev_get_id_bustype(touchpad->evdev),
- bus_kbd = libevdev_get_id_bustype(keyboard->evdev);
unsigned int vendor_tp = evdev_device_get_id_vendor(touchpad);
unsigned int vendor_kbd = evdev_device_get_id_vendor(keyboard);
unsigned int product_tp = evdev_device_get_id_product(touchpad);
considered a happy couple */
if (touchpad->tags & EVDEV_TAG_EXTERNAL_TOUCHPAD)
return vendor_tp == vendor_kbd && product_tp == product_kbd;
+ else if (keyboard->tags & EVDEV_TAG_INTERNAL_KEYBOARD)
+ return true;
- /* If the touchpad is on serio, the keyboard is too, so ignore any
- other devices */
- if (bus_tp == BUS_I8042 && bus_kbd != bus_tp)
- return false;
-
- /* For Apple touchpads, always use its internal keyboard */
- if (vendor_tp == VENDOR_ID_APPLE) {
- return vendor_kbd == vendor_tp &&
- keyboard->tags & EVDEV_TAG_INTERNAL_KEYBOARD;
- }
-
- /* everything else we don't really know, so we have to assume
- they go together */
-
- return true;
+ /* keyboard is not tagged as internal keyboard and it's not part of
+ * a combo */
+ return false;
}
static void
struct evdev_device *keyboard)
{
struct tp_dispatch *tp = (struct tp_dispatch*)touchpad->dispatch;
- unsigned int bus_kbd = libevdev_get_id_bustype(keyboard->evdev);
+
+ if (tp->dwt.keyboard)
+ return;
if ((keyboard->tags & EVDEV_TAG_KEYBOARD) == 0)
return;
if (!tp_want_dwt(touchpad, keyboard))
return;
- /* If we already have a keyboard paired, override it if the new one
- * is a serio device. Otherwise keep the current one */
- if (tp->dwt.keyboard) {
- if (bus_kbd != BUS_I8042)
- return;
-
- memset(tp->dwt.key_mask, 0, sizeof(tp->dwt.key_mask));
- memset(tp->dwt.mod_mask, 0, sizeof(tp->dwt.mod_mask));
- libinput_device_remove_event_listener(&tp->dwt.keyboard_listener);
- }
-
libinput_device_add_event_listener(&keyboard->base,
- &tp->dwt.keyboard_listener,
- tp_keyboard_event, tp);
+ &tp->dwt.keyboard_listener,
+ tp_keyboard_event, tp);
tp->dwt.keyboard = keyboard;
tp->dwt.keyboard_active = false;
}
END_TEST
-START_TEST(touchpad_dwt_update_keyboard)
+START_TEST(touchpad_dwt_ext_and_int_keyboard)
{
struct litest_device *touchpad = litest_current_device();
struct litest_device *keyboard, *yubikey;
}
END_TEST
-START_TEST(touchpad_dwt_update_keyboard_with_state)
-{
- struct litest_device *touchpad = litest_current_device();
- struct litest_device *keyboard, *yubikey;
- struct libinput *li = touchpad->libinput;
-
- if (!has_disable_while_typing(touchpad))
- return;
-
- litest_disable_tap(touchpad->libinput_device);
-
- /* Yubikey is initialized first */
- yubikey = litest_add_device(li, LITEST_YUBIKEY);
- litest_drain_events(li);
-
- litest_keyboard_key(yubikey, KEY_A, true);
- litest_keyboard_key(yubikey, KEY_A, false);
- litest_keyboard_key(yubikey, KEY_A, true);
- litest_assert_only_typed_events(li, LIBINPUT_EVENT_KEYBOARD_KEY);
-
- litest_touch_down(touchpad, 0, 50, 50);
- litest_touch_move_to(touchpad, 0, 50, 50, 70, 50, 10, 1);
- litest_touch_up(touchpad, 0);
- litest_assert_empty_queue(li);
-
- litest_keyboard_key(yubikey, KEY_A, false);
- litest_keyboard_key(yubikey, KEY_A, true);
- litest_drain_events(li);
-
- /* yubikey still has A down */
- keyboard = dwt_init_paired_keyboard(li, touchpad);
- litest_drain_events(li);
-
- /* expected repairing, dwt should be disabled */
- litest_touch_down(touchpad, 0, 50, 50);
- litest_touch_move_to(touchpad, 0, 50, 50, 70, 50, 10, 1);
- litest_touch_up(touchpad, 0);
- litest_assert_only_typed_events(li, LIBINPUT_EVENT_POINTER_MOTION);
-
- /* release remaining key */
- litest_keyboard_key(yubikey, KEY_A, false);
- litest_assert_only_typed_events(li, LIBINPUT_EVENT_KEYBOARD_KEY);
-
- litest_touch_down(touchpad, 0, 50, 50);
- litest_touch_move_to(touchpad, 0, 50, 50, 70, 50, 10, 1);
- litest_touch_up(touchpad, 0);
- litest_assert_only_typed_events(li, LIBINPUT_EVENT_POINTER_MOTION);
-
- litest_delete_device(keyboard);
- litest_delete_device(yubikey);
-}
-END_TEST
START_TEST(touchpad_dwt_enable_touch)
{
struct litest_device *touchpad = litest_current_device();
START_TEST(touchpad_dwt_apple)
{
struct litest_device *touchpad = litest_current_device();
- struct litest_device *keyboard, *apple_keyboard;
+ struct litest_device *apple_keyboard;
struct libinput *li = touchpad->libinput;
ck_assert(has_disable_while_typing(touchpad));
- /* Only the apple keyboard can trigger DWT */
- keyboard = litest_add_device(li, LITEST_KEYBOARD);
- litest_drain_events(li);
-
- litest_keyboard_key(keyboard, KEY_A, true);
- litest_keyboard_key(keyboard, KEY_A, false);
- litest_assert_only_typed_events(li, LIBINPUT_EVENT_KEYBOARD_KEY);
-
- litest_touch_down(touchpad, 0, 50, 50);
- litest_touch_move_to(touchpad, 0, 50, 50, 70, 50, 10, 1);
- litest_touch_up(touchpad, 0);
- litest_assert_only_typed_events(li, LIBINPUT_EVENT_POINTER_MOTION);
-
apple_keyboard = litest_add_device(li, LITEST_APPLE_KEYBOARD);
litest_drain_events(li);
libinput_dispatch(li);
litest_assert_empty_queue(li);
- litest_delete_device(keyboard);
litest_delete_device(apple_keyboard);
}
END_TEST
litest_add_ranged("touchpad:state", touchpad_initial_state, LITEST_TOUCHPAD, LITEST_ANY, &axis_range);
litest_add("touchpad:dwt", touchpad_dwt, LITEST_TOUCHPAD, LITEST_ANY);
- litest_add_for_device("touchpad:dwt", touchpad_dwt_update_keyboard, LITEST_SYNAPTICS_I2C);
- litest_add_for_device("touchpad:dwt", touchpad_dwt_update_keyboard_with_state, LITEST_SYNAPTICS_I2C);
+ litest_add_for_device("touchpad:dwt", touchpad_dwt_ext_and_int_keyboard, LITEST_SYNAPTICS_I2C);
litest_add("touchpad:dwt", touchpad_dwt_enable_touch, LITEST_TOUCHPAD, LITEST_ANY);
litest_add("touchpad:dwt", touchpad_dwt_touch_hold, LITEST_TOUCHPAD, LITEST_ANY);
litest_add("touchpad:dwt", touchpad_dwt_key_hold, LITEST_TOUCHPAD, LITEST_ANY);