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: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1015>
This commit is contained in:
Peter Hutterer 2024-06-17 14:07:17 +10:00 committed by Marge Bot
parent 82322a4c57
commit 8326f71df5
2 changed files with 57 additions and 8 deletions

View file

@ -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;
}

View file

@ -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);