From 8326f71df5f2246f2547cd849676ca4aa1e6aa19 Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Mon, 17 Jun 2024 14:07:17 +1000 Subject: [PATCH] touchpad: special-case shift as modifier for dwt We ignore modifiers for disable-while-typing because we don't want to disable the touchpad for things like shift-click or ctrl-click. We also do remember the modifier state so that we don't disable the touchpad for once-offs like ctrl+s. Shift is however a special case - shift + something else is means the user is typing and we should disable the touchpad for that. Closes #1005 Part-of: --- src/evdev-mt-touchpad.c | 14 +++++++++-- test/test-touchpad.c | 51 ++++++++++++++++++++++++++++++++++++----- 2 files changed, 57 insertions(+), 8 deletions(-) diff --git a/src/evdev-mt-touchpad.c b/src/evdev-mt-touchpad.c index 845e408d..9bc6bf6a 100644 --- a/src/evdev-mt-touchpad.c +++ b/src/evdev-mt-touchpad.c @@ -2248,6 +2248,12 @@ tp_keyboard_timeout(uint64_t now, void *data) evdev_log_debug(tp->device, "palm: keyboard timeout\n"); } +static inline bool +tp_key_is_shift(unsigned int keycode) +{ + return keycode == KEY_LEFTSHIFT || keycode == KEY_RIGHTSHIFT; +} + static inline bool tp_key_is_modifier(unsigned int keycode) { @@ -2320,10 +2326,14 @@ tp_keyboard_event(uint64_t time, struct libinput_event *event, void *data) return; /* modifier keys don't trigger disable-while-typing so things like - * ctrl+zoom or ctrl+click are possible */ + * ctrl+zoom or ctrl+click are possible. + * The exception is shift which we don't trigger DWT for on its own + * but we do trigger DWT for once we type some other key. + */ is_modifier = tp_key_is_modifier(key); if (is_modifier) { - long_set_bit(tp->dwt.mod_mask, key); + if (!tp_key_is_shift(key)) + long_set_bit(tp->dwt.mod_mask, key); return; } diff --git a/test/test-touchpad.c b/test/test-touchpad.c index 6d5436a2..07353082 100644 --- a/test/test-touchpad.c +++ b/test/test-touchpad.c @@ -4259,6 +4259,50 @@ START_TEST(touchpad_dwt_modifier_no_dwt) } END_TEST +START_TEST(touchpad_dwt_shift_combo_triggers_dwt) +{ + struct litest_device *touchpad = litest_current_device(); + struct litest_device *keyboard; + struct libinput *li = touchpad->libinput; + unsigned int modifiers[] = { + KEY_LEFTSHIFT, + KEY_RIGHTSHIFT, + }; + + if (!has_disable_while_typing(touchpad)) + return; + + keyboard = dwt_init_paired_keyboard(li, touchpad); + litest_disable_tap(touchpad->libinput_device); + litest_disable_hold_gestures(touchpad->libinput_device); + litest_drain_events(li); + + ARRAY_FOR_EACH(modifiers, key) { + litest_keyboard_key(keyboard, *key, true); + litest_keyboard_key(keyboard, KEY_A, true); + litest_keyboard_key(keyboard, KEY_A, false); + litest_keyboard_key(keyboard, *key, false); + libinput_dispatch(li); + + 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, 5); + litest_touch_up(touchpad, 0); + litest_assert_empty_queue(li); + } + + litest_timeout_dwt_long(); + libinput_dispatch(li); + litest_touch_down(touchpad, 0, 50, 50); + litest_touch_move_to(touchpad, 0, 50, 50, 70, 50, 5); + litest_touch_up(touchpad, 0); + litest_assert_only_typed_events(li, LIBINPUT_EVENT_POINTER_MOTION); + + litest_delete_device(keyboard); +} +END_TEST + START_TEST(touchpad_dwt_modifier_combo_no_dwt) { struct litest_device *touchpad = litest_current_device(); @@ -4269,8 +4313,6 @@ START_TEST(touchpad_dwt_modifier_combo_no_dwt) KEY_RIGHTCTRL, KEY_LEFTALT, KEY_RIGHTALT, - KEY_LEFTSHIFT, - KEY_RIGHTSHIFT, KEY_FN, KEY_CAPSLOCK, KEY_TAB, @@ -4318,8 +4360,6 @@ START_TEST(touchpad_dwt_modifier_combo_dwt_after) KEY_RIGHTCTRL, KEY_LEFTALT, KEY_RIGHTALT, - KEY_LEFTSHIFT, - KEY_RIGHTSHIFT, KEY_FN, KEY_CAPSLOCK, KEY_TAB, @@ -4371,8 +4411,6 @@ START_TEST(touchpad_dwt_modifier_combo_dwt_remains) KEY_RIGHTCTRL, KEY_LEFTALT, KEY_RIGHTALT, - KEY_LEFTSHIFT, - KEY_RIGHTSHIFT, KEY_FN, KEY_CAPSLOCK, KEY_TAB, @@ -7372,6 +7410,7 @@ TEST_COLLECTION(touchpad) litest_add(touchpad_dwt_key_hold_timeout_existing_touch_cornercase, LITEST_TOUCHPAD, LITEST_ANY); litest_add(touchpad_dwt_type, LITEST_TOUCHPAD, LITEST_ANY); litest_add(touchpad_dwt_type_short_timeout, LITEST_TOUCHPAD, LITEST_ANY); + litest_add(touchpad_dwt_shift_combo_triggers_dwt, LITEST_TOUCHPAD, LITEST_ANY); litest_add(touchpad_dwt_modifier_no_dwt, LITEST_TOUCHPAD, LITEST_ANY); litest_add(touchpad_dwt_modifier_combo_no_dwt, LITEST_TOUCHPAD, LITEST_ANY); litest_add(touchpad_dwt_modifier_combo_dwt_after, LITEST_TOUCHPAD, LITEST_ANY);