summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Hutterer <peter.hutterer@who-t.net>2016-02-08 11:48:51 +1000
committerPeter Hutterer <peter.hutterer@who-t.net>2016-02-10 08:21:59 +1000
commit216c6aae54903af12898a4cc4ed2c80b8048f742 (patch)
tree3ad189b6f663320577916f2b7c2ccf1fb92ab66b
parentb09856aea8f49fd5455cac7e0f6c39ec500f58a5 (diff)
touchpad: fix dwt disabling while a key is still down
If dwt is disabled on the commandline, e.g. by setting an xinput property it may be disabled before the release event comes in. This caused the timer to refresh indefinitely since the key state mask was still on for that key. Always updating the key state mask (even when dwt is disabled) fixes that. If a key is held down while dwt is disabled, this can still cause a indefinite timer refresh, so in the timer func, check if dwt is enabled before refreshing the timer. https://bugs.freedesktop.org/show_bug.cgi?id=94015 Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net> Reviewed-by: Hans de Goede <hdegoede@redhat.com> (cherry picked from commit 0e87dc9af2be104fd6cfa50e5f013068e42666d4)
-rw-r--r--src/evdev-mt-touchpad.c9
-rw-r--r--test/touchpad.c68
2 files changed, 73 insertions, 4 deletions
diff --git a/src/evdev-mt-touchpad.c b/src/evdev-mt-touchpad.c
index 91fb7a9e..d0bc52d7 100644
--- a/src/evdev-mt-touchpad.c
+++ b/src/evdev-mt-touchpad.c
@@ -1185,7 +1185,8 @@ tp_keyboard_timeout(uint64_t now, void *data)
{
struct tp_dispatch *tp = data;
- if (long_any_bit_set(tp->dwt.key_mask,
+ if (tp->dwt.dwt_enabled &&
+ long_any_bit_set(tp->dwt.key_mask,
ARRAY_LENGTH(tp->dwt.key_mask))) {
libinput_timer_set(&tp->dwt.keyboard_timer,
now + DEFAULT_KEYBOARD_ACTIVITY_TIMEOUT_2);
@@ -1240,9 +1241,6 @@ tp_keyboard_event(uint64_t time, struct libinput_event *event, void *data)
unsigned int timeout;
unsigned int key;
- if (!tp->dwt.dwt_enabled)
- return;
-
if (event->type != LIBINPUT_EVENT_KEYBOARD_KEY)
return;
@@ -1256,6 +1254,9 @@ tp_keyboard_event(uint64_t time, struct libinput_event *event, void *data)
return;
}
+ if (!tp->dwt.dwt_enabled)
+ return;
+
/* modifier keys don't trigger disable-while-typing so things like
* ctrl+zoom or ctrl+click are possible */
if (tp_key_ignore_for_dwt(key))
diff --git a/test/touchpad.c b/test/touchpad.c
index 195937fb..7ff3a96d 100644
--- a/test/touchpad.c
+++ b/test/touchpad.c
@@ -3114,6 +3114,72 @@ START_TEST(touchpad_dwt_disable_before_touch)
}
END_TEST
+START_TEST(touchpad_dwt_disable_during_key_release)
+{
+ struct litest_device *touchpad = litest_current_device();
+ struct litest_device *keyboard;
+ struct libinput *li = touchpad->libinput;
+
+ if (!has_disable_while_typing(touchpad))
+ return;
+
+ enable_dwt(touchpad);
+
+ keyboard = dwt_init_paired_keyboard(li, touchpad);
+ litest_disable_tap(touchpad->libinput_device);
+ litest_drain_events(li);
+
+ litest_keyboard_key(keyboard, KEY_A, true);
+ litest_assert_only_typed_events(li, LIBINPUT_EVENT_KEYBOARD_KEY);
+
+ disable_dwt(touchpad);
+ libinput_dispatch(li);
+ litest_keyboard_key(keyboard, KEY_A, false);
+ litest_assert_only_typed_events(li, LIBINPUT_EVENT_KEYBOARD_KEY);
+
+ /* touch down during timeout, wait, should generate events */
+ litest_touch_down(touchpad, 0, 50, 50);
+ libinput_dispatch(li);
+ litest_timeout_dwt_long();
+ litest_touch_move_to(touchpad, 0, 70, 50, 50, 50, 10, 1);
+ litest_assert_only_typed_events(li, LIBINPUT_EVENT_POINTER_MOTION);
+
+ litest_delete_device(keyboard);
+}
+END_TEST
+
+START_TEST(touchpad_dwt_disable_during_key_hold)
+{
+ struct litest_device *touchpad = litest_current_device();
+ struct litest_device *keyboard;
+ struct libinput *li = touchpad->libinput;
+
+ if (!has_disable_while_typing(touchpad))
+ return;
+
+ enable_dwt(touchpad);
+
+ keyboard = dwt_init_paired_keyboard(li, touchpad);
+ litest_disable_tap(touchpad->libinput_device);
+ litest_drain_events(li);
+
+ litest_keyboard_key(keyboard, KEY_A, true);
+ litest_assert_only_typed_events(li, LIBINPUT_EVENT_KEYBOARD_KEY);
+
+ disable_dwt(touchpad);
+ libinput_dispatch(li);
+
+ /* touch down during timeout, wait, should generate events */
+ litest_touch_down(touchpad, 0, 50, 50);
+ libinput_dispatch(li);
+ litest_timeout_dwt_long();
+ litest_touch_move_to(touchpad, 0, 70, 50, 50, 50, 10, 1);
+ litest_assert_only_typed_events(li, LIBINPUT_EVENT_POINTER_MOTION);
+
+ litest_delete_device(keyboard);
+}
+END_TEST
+
START_TEST(touchpad_dwt_enable_during_touch)
{
struct litest_device *touchpad = litest_current_device();
@@ -3925,6 +3991,8 @@ litest_setup_tests(void)
litest_add("touchpad:dwt", touchpad_dwt_disabled, LITEST_TOUCHPAD, LITEST_ANY);
litest_add("touchpad:dwt", touchpad_dwt_disable_during_touch, LITEST_TOUCHPAD, LITEST_ANY);
litest_add("touchpad:dwt", touchpad_dwt_disable_before_touch, LITEST_TOUCHPAD, LITEST_ANY);
+ litest_add("touchpad:dwt", touchpad_dwt_disable_during_key_release, LITEST_TOUCHPAD, LITEST_ANY);
+ litest_add("touchpad:dwt", touchpad_dwt_disable_during_key_hold, LITEST_TOUCHPAD, LITEST_ANY);
litest_add("touchpad:dwt", touchpad_dwt_enable_during_touch, LITEST_TOUCHPAD, LITEST_ANY);
litest_add("touchpad:dwt", touchpad_dwt_enable_before_touch, LITEST_TOUCHPAD, LITEST_ANY);
litest_add("touchpad:dwt", touchpad_dwt_enable_during_tap, LITEST_TOUCHPAD, LITEST_ANY);