[PATCH libinput 2/2] touchpad: hook up disable-while-typing configuration
Peter Hutterer
peter.hutterer at who-t.net
Sun Jul 12 19:46:27 PDT 2015
This is not a frequent toggle, so we don't need to jump through too many hoops
here. We simply enable/disable on command and once any current timeouts have
expired the new setting takes effect.
Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
---
src/evdev-mt-touchpad.c | 107 ++++++++++++++++--
src/evdev-mt-touchpad.h | 3 +
test/touchpad.c | 287 +++++++++++++++++++++++++++++++++++++++++++++++-
3 files changed, 381 insertions(+), 16 deletions(-)
diff --git a/src/evdev-mt-touchpad.c b/src/evdev-mt-touchpad.c
index 3f5daba..55cde5a 100644
--- a/src/evdev-mt-touchpad.c
+++ b/src/evdev-mt-touchpad.c
@@ -495,7 +495,8 @@ tp_palm_tap_is_palm(struct tp_dispatch *tp, struct tp_touch *t)
static int
tp_palm_detect_dwt(struct tp_dispatch *tp, struct tp_touch *t, uint64_t time)
{
- if (tp->dwt.keyboard_active &&
+ if (tp->dwt.dwt_enabled &&
+ tp->dwt.keyboard_active &&
t->state == TOUCH_BEGIN) {
t->palm.state = PALM_TYPING;
t->palm.first = t->point;
@@ -1069,6 +1070,9 @@ tp_keyboard_event(uint64_t time, struct libinput_event *event, void *data)
struct libinput_event_keyboard *kbdev;
unsigned int timeout;
+ if (!tp->dwt.dwt_enabled)
+ return;
+
if (event->type != LIBINPUT_EVENT_KEYBOARD_KEY)
return;
@@ -1100,17 +1104,30 @@ tp_keyboard_event(uint64_t time, struct libinput_event *event, void *data)
}
static bool
+tp_dwt_device_is_blacklisted(struct evdev_device *device)
+{
+ unsigned int bus = libevdev_get_id_bustype(device->evdev);
+
+ /* evemu will set the right bus type */
+ if (bus == BUS_BLUETOOTH || bus == BUS_VIRTUAL)
+ return true;
+
+ /* Wacom makes touchpads, but not internal ones */
+ if (libevdev_get_id_vendor(device->evdev) == VENDOR_ID_WACOM)
+ return true;
+
+ return false;
+}
+
+static bool
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);
- if (bus_tp == BUS_BLUETOOTH || bus_kbd == BUS_BLUETOOTH)
- return false;
-
- /* evemu will set the right bus type */
- if (bus_tp == BUS_VIRTUAL || bus_kbd == BUS_VIRTUAL)
+ if (tp_dwt_device_is_blacklisted(touchpad) ||
+ tp_dwt_device_is_blacklisted(keyboard))
return false;
/* If the touchpad is on serio, the keyboard is too, so ignore any
@@ -1118,10 +1135,6 @@ tp_want_dwt(struct evdev_device *touchpad,
if (bus_tp == BUS_I8042 && bus_kbd != bus_tp)
return false;
- /* Wacom makes touchpads, but not internal ones */
- if (libevdev_get_id_vendor(touchpad->evdev) == VENDOR_ID_WACOM)
- return false;
-
/* everything else we don't really know, so we have to assume
they go together */
@@ -1459,6 +1472,77 @@ tp_init_scroll(struct tp_dispatch *tp, struct evdev_device *device)
}
static int
+tp_dwt_config_is_available(struct libinput_device *device)
+{
+ return 1;
+}
+
+static enum libinput_config_status
+tp_dwt_config_set(struct libinput_device *device,
+ enum libinput_config_dwt_state enable)
+{
+ struct evdev_device *evdev = (struct evdev_device*)device;
+ struct tp_dispatch *tp = (struct tp_dispatch*)evdev->dispatch;
+
+ switch(enable) {
+ case LIBINPUT_CONFIG_DWT_ENABLED:
+ case LIBINPUT_CONFIG_DWT_DISABLED:
+ break;
+ default:
+ return LIBINPUT_CONFIG_STATUS_INVALID;
+ }
+
+ tp->dwt.dwt_enabled = (enable == LIBINPUT_CONFIG_DWT_ENABLED);
+
+ return LIBINPUT_CONFIG_STATUS_SUCCESS;
+}
+
+static enum libinput_config_dwt_state
+tp_dwt_config_get(struct libinput_device *device)
+{
+ struct evdev_device *evdev = (struct evdev_device*)device;
+ struct tp_dispatch *tp = (struct tp_dispatch*)evdev->dispatch;
+
+ return tp->dwt.dwt_enabled ?
+ LIBINPUT_CONFIG_DWT_ENABLED :
+ LIBINPUT_CONFIG_DWT_DISABLED;
+}
+
+static bool
+tp_dwt_default_enabled(struct tp_dispatch *tp)
+{
+ return true;
+}
+
+static enum libinput_config_dwt_state
+tp_dwt_config_get_default(struct libinput_device *device)
+{
+ struct evdev_device *evdev = (struct evdev_device*)device;
+ struct tp_dispatch *tp = (struct tp_dispatch*)evdev->dispatch;
+
+ return tp_dwt_default_enabled(tp) ?
+ LIBINPUT_CONFIG_DWT_ENABLED :
+ LIBINPUT_CONFIG_DWT_DISABLED;
+}
+
+static int
+tp_init_dwt(struct tp_dispatch *tp,
+ struct evdev_device *device)
+{
+ if (tp_dwt_device_is_blacklisted(device))
+ return 0;
+
+ tp->dwt.config.is_available = tp_dwt_config_is_available;
+ tp->dwt.config.set_enabled = tp_dwt_config_set;
+ tp->dwt.config.get_enabled = tp_dwt_config_get;
+ tp->dwt.config.get_default_enabled = tp_dwt_config_get_default;
+ tp->dwt.dwt_enabled = tp_dwt_default_enabled(tp);
+ device->base.config.dwt = &tp->dwt.config;
+
+ return 0;
+}
+
+static int
tp_init_palmdetect(struct tp_dispatch *tp,
struct evdev_device *device)
{
@@ -1604,6 +1688,9 @@ tp_init(struct tp_dispatch *tp,
if (tp_init_buttons(tp, device) != 0)
return -1;
+ if (tp_init_dwt(tp, device) != 0)
+ return -1;
+
if (tp_init_palmdetect(tp, device) != 0)
return -1;
diff --git a/src/evdev-mt-touchpad.h b/src/evdev-mt-touchpad.h
index eda17a9..35df46f 100644
--- a/src/evdev-mt-touchpad.h
+++ b/src/evdev-mt-touchpad.h
@@ -314,6 +314,9 @@ struct tp_dispatch {
} sendevents;
struct {
+ struct libinput_device_config_dwt config;
+ bool dwt_enabled;
+
bool keyboard_active;
struct libinput_event_listener keyboard_listener;
struct libinput_timer keyboard_timer;
diff --git a/test/touchpad.c b/test/touchpad.c
index 78c084e..d7e859c 100644
--- a/test/touchpad.c
+++ b/test/touchpad.c
@@ -3329,12 +3329,7 @@ END_TEST
static inline bool
has_disable_while_typing(struct litest_device *device)
{
- if (libevdev_get_id_vendor(device->evdev) == VENDOR_ID_WACOM)
- return false;
- if (libevdev_get_id_bustype(device->evdev) == BUS_BLUETOOTH)
- return false;
-
- return true;
+ return libinput_device_config_dwt_is_available(device->libinput_device);
}
START_TEST(touchpad_dwt)
@@ -3747,6 +3742,278 @@ START_TEST(touchpad_dwt_edge_scroll_interrupt)
}
END_TEST
+START_TEST(touchpad_dwt_config_default_on)
+{
+ struct litest_device *dev = litest_current_device();
+ struct libinput_device *device = dev->libinput_device;
+ enum libinput_config_status status;
+ enum libinput_config_dwt_state state;
+
+ if (libevdev_get_id_vendor(dev->evdev) == VENDOR_ID_WACOM ||
+ libevdev_get_id_bustype(dev->evdev) == BUS_BLUETOOTH) {
+ ck_assert(!libinput_device_config_dwt_is_available(device));
+ return;
+ }
+
+ ck_assert(libinput_device_config_dwt_is_available(device));
+ state = libinput_device_config_dwt_get_enabled(device);
+ ck_assert_int_eq(state, LIBINPUT_CONFIG_DWT_ENABLED);
+ state = libinput_device_config_dwt_get_default_enabled(device);
+ ck_assert_int_eq(state, LIBINPUT_CONFIG_DWT_ENABLED);
+
+ status = libinput_device_config_dwt_set_enabled(device,
+ LIBINPUT_CONFIG_DWT_ENABLED);
+ ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS);
+ status = libinput_device_config_dwt_set_enabled(device,
+ LIBINPUT_CONFIG_DWT_DISABLED);
+ ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS);
+
+ status = libinput_device_config_dwt_set_enabled(device, 3);
+ ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_INVALID);
+}
+END_TEST
+
+START_TEST(touchpad_dwt_config_default_off)
+{
+ struct litest_device *dev = litest_current_device();
+ struct libinput_device *device = dev->libinput_device;
+ enum libinput_config_status status;
+ enum libinput_config_dwt_state state;
+
+ ck_assert(!libinput_device_config_dwt_is_available(device));
+ state = libinput_device_config_dwt_get_enabled(device);
+ ck_assert_int_eq(state, LIBINPUT_CONFIG_DWT_DISABLED);
+ state = libinput_device_config_dwt_get_default_enabled(device);
+ ck_assert_int_eq(state, LIBINPUT_CONFIG_DWT_DISABLED);
+
+ status = libinput_device_config_dwt_set_enabled(device,
+ LIBINPUT_CONFIG_DWT_ENABLED);
+ ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_UNSUPPORTED);
+ status = libinput_device_config_dwt_set_enabled(device,
+ LIBINPUT_CONFIG_DWT_DISABLED);
+ ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS);
+
+ status = libinput_device_config_dwt_set_enabled(device, 3);
+ ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_INVALID);
+}
+END_TEST
+
+static inline void
+disable_dwt(struct litest_device *dev)
+{
+ enum libinput_config_status status,
+ expected = LIBINPUT_CONFIG_STATUS_SUCCESS;
+ status = libinput_device_config_dwt_set_enabled(dev->libinput_device,
+ LIBINPUT_CONFIG_DWT_DISABLED);
+ litest_assert_int_eq(status, expected);
+}
+
+static inline void
+enable_dwt(struct litest_device *dev)
+{
+ enum libinput_config_status status,
+ expected = LIBINPUT_CONFIG_STATUS_SUCCESS;
+ status = libinput_device_config_dwt_set_enabled(dev->libinput_device,
+ LIBINPUT_CONFIG_DWT_ENABLED);
+ litest_assert_int_eq(status, expected);
+}
+
+START_TEST(touchpad_dwt_disabled)
+{
+ struct litest_device *touchpad = litest_current_device();
+ struct litest_device *keyboard;
+ struct libinput *li = touchpad->libinput;
+
+ if (!has_disable_while_typing(touchpad))
+ return;
+
+ disable_dwt(touchpad);
+
+ keyboard = litest_add_device(li, LITEST_KEYBOARD);
+ litest_disable_tap(touchpad->libinput_device);
+ 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);
+
+ litest_delete_device(keyboard);
+}
+END_TEST
+
+START_TEST(touchpad_dwt_disable_during_touch)
+{
+ 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 = litest_add_device(li, LITEST_KEYBOARD);
+ litest_disable_tap(touchpad->libinput_device);
+ 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_assert_empty_queue(li);
+
+ disable_dwt(touchpad);
+
+ /* touch already down -> keeps being ignored */
+ litest_touch_move_to(touchpad, 0, 70, 50, 50, 70, 10, 1);
+ litest_touch_up(touchpad, 0);
+
+ litest_assert_empty_queue(li);
+
+ litest_delete_device(keyboard);
+}
+END_TEST
+
+START_TEST(touchpad_dwt_disable_before_touch)
+{
+ 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 = litest_add_device(li, LITEST_KEYBOARD);
+ litest_disable_tap(touchpad->libinput_device);
+ 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);
+
+ disable_dwt(touchpad);
+ libinput_dispatch(li);
+
+ /* touch down during timeout -> still discarded */
+ litest_touch_down(touchpad, 0, 50, 50);
+ litest_touch_move_to(touchpad, 0, 50, 50, 70, 50, 10, 1);
+ litest_assert_empty_queue(li);
+
+ litest_delete_device(keyboard);
+}
+END_TEST
+
+START_TEST(touchpad_dwt_enable_during_touch)
+{
+ struct litest_device *touchpad = litest_current_device();
+ struct litest_device *keyboard;
+ struct libinput *li = touchpad->libinput;
+
+ if (!has_disable_while_typing(touchpad))
+ return;
+
+ disable_dwt(touchpad);
+
+ keyboard = litest_add_device(li, LITEST_KEYBOARD);
+ litest_disable_tap(touchpad->libinput_device);
+ 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_assert_only_typed_events(li, LIBINPUT_EVENT_POINTER_MOTION);
+
+ enable_dwt(touchpad);
+
+ /* touch already down -> still sends events */
+ litest_touch_move_to(touchpad, 0, 70, 50, 50, 70, 10, 1);
+ 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_enable_before_touch)
+{
+ struct litest_device *touchpad = litest_current_device();
+ struct litest_device *keyboard;
+ struct libinput *li = touchpad->libinput;
+
+ if (!has_disable_while_typing(touchpad))
+ return;
+
+ disable_dwt(touchpad);
+
+ keyboard = litest_add_device(li, LITEST_KEYBOARD);
+ litest_disable_tap(touchpad->libinput_device);
+ 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);
+
+ enable_dwt(touchpad);
+ libinput_dispatch(li);
+
+ litest_touch_down(touchpad, 0, 50, 50);
+ litest_touch_move_to(touchpad, 0, 50, 50, 70, 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_tap)
+{
+ struct litest_device *touchpad = litest_current_device();
+ struct litest_device *keyboard;
+ struct libinput *li = touchpad->libinput;
+
+ if (!has_disable_while_typing(touchpad))
+ return;
+
+ litest_enable_tap(touchpad->libinput_device);
+ disable_dwt(touchpad);
+
+ 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);
+ libinput_dispatch(li);
+ enable_dwt(touchpad);
+ libinput_dispatch(li);
+ litest_touch_up(touchpad, 0);
+ libinput_dispatch(li);
+
+ litest_timeout_tap();
+ litest_assert_only_typed_events(li, LIBINPUT_EVENT_POINTER_BUTTON);
+
+ 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);
+}
+END_TEST
static int
has_thumb_detect(struct litest_device *dev)
{
@@ -4243,6 +4510,14 @@ litest_setup_tests(void)
litest_add("touchpad:dwt", touchpad_dwt_click, LITEST_TOUCHPAD, LITEST_ANY);
litest_add("touchpad:dwt", touchpad_dwt_edge_scroll, LITEST_TOUCHPAD, LITEST_CLICKPAD);
litest_add("touchpad:dwt", touchpad_dwt_edge_scroll_interrupt, LITEST_TOUCHPAD, LITEST_CLICKPAD);
+ litest_add("touchpad:dwt", touchpad_dwt_config_default_on, LITEST_TOUCHPAD, LITEST_ANY);
+ litest_add("touchpad:dwt", touchpad_dwt_config_default_off, LITEST_ANY, LITEST_TOUCHPAD);
+ 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_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);
litest_add("touchpad:thumb", touchpad_thumb_begin_no_motion, LITEST_TOUCHPAD, LITEST_ANY);
litest_add("touchpad:thumb", touchpad_thumb_update_no_motion, LITEST_TOUCHPAD, LITEST_ANY);
--
2.4.3
More information about the wayland-devel
mailing list