mirror of
https://gitlab.freedesktop.org/libinput/libinput.git
synced 2026-02-03 14:40:26 +01:00
touchpad: hook up disable-while-typing configuration
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@who-t.net> Reviewed-by: Hans de Goede <hdegoede@redhat.com>
This commit is contained in:
parent
55974dcac5
commit
5571f2d2cc
3 changed files with 381 additions and 16 deletions
|
|
@ -528,7 +528,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;
|
||||
|
|
@ -1127,6 +1128,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;
|
||||
|
||||
|
|
@ -1157,6 +1161,22 @@ tp_keyboard_event(uint64_t time, struct libinput_event *event, void *data)
|
|||
time + timeout);
|
||||
}
|
||||
|
||||
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)
|
||||
|
|
@ -1164,11 +1184,8 @@ tp_want_dwt(struct evdev_device *touchpad,
|
|||
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
|
||||
|
|
@ -1176,10 +1193,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 */
|
||||
|
||||
|
|
@ -1499,6 +1512,77 @@ tp_init_scroll(struct tp_dispatch *tp, struct evdev_device *device)
|
|||
return 0;
|
||||
}
|
||||
|
||||
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)
|
||||
|
|
@ -1674,6 +1758,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;
|
||||
|
||||
|
|
|
|||
|
|
@ -322,6 +322,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;
|
||||
|
|
|
|||
287
test/touchpad.c
287
test/touchpad.c
|
|
@ -2205,12 +2205,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)
|
||||
|
|
@ -2623,6 +2618,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)
|
||||
{
|
||||
|
|
@ -3197,6 +3464,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);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue