mirror of
https://gitlab.freedesktop.org/libinput/libinput.git
synced 2025-12-20 04:30:06 +01:00
touchpad: add configurable timeouts to disable-while-typing
Touchpads that don't give us useful palm detection data are getting more common (see e.g. our ABS_MT_TOOL_TYPE quirks). On those touchpads we can only rely on dwt and palm edge detection which means those two must be more spot on than ever before. DWT in particular is more prone to user-specific requirements, the current timeouts have been insufficient for a number of users. So let's make them more configurable. Currently limited to >100ms and <5 seconds to avoid DWT being used in the xkcd workflow style. Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1372>
This commit is contained in:
parent
2003ab3aef
commit
20851b5020
7 changed files with 141 additions and 5 deletions
|
|
@ -2156,8 +2156,7 @@ tp_keyboard_timeout(uint64_t now, void *data)
|
|||
|
||||
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);
|
||||
libinput_timer_set(&tp->dwt.keyboard_timer, now + tp->dwt.timeout);
|
||||
tp->dwt.keyboard_last_press_time = now;
|
||||
evdev_log_debug(tp->device, "palm: keyboard timeout refresh\n");
|
||||
return;
|
||||
|
|
@ -2272,7 +2271,7 @@ tp_keyboard_event(uint64_t time, struct libinput_event *event, void *data)
|
|||
tp->dwt.keyboard_active = true;
|
||||
timeout = DEFAULT_KEYBOARD_ACTIVITY_TIMEOUT_1;
|
||||
} else {
|
||||
timeout = DEFAULT_KEYBOARD_ACTIVITY_TIMEOUT_2;
|
||||
timeout = tp->dwt.timeout;
|
||||
}
|
||||
|
||||
tp->dwt.keyboard_last_press_time = time;
|
||||
|
|
@ -3170,6 +3169,29 @@ tp_dwt_config_get_default(struct libinput_device *device)
|
|||
: LIBINPUT_CONFIG_DWT_DISABLED;
|
||||
}
|
||||
|
||||
static enum libinput_config_status
|
||||
tp_dwt_config_set_timeout(struct libinput_device *device, uint64_t timeout)
|
||||
{
|
||||
struct evdev_device *evdev = evdev_device(device);
|
||||
struct tp_dispatch *tp = (struct tp_dispatch *)evdev->dispatch;
|
||||
|
||||
if (timeout <= ms2us(100) || timeout >= ms2us(5000))
|
||||
return LIBINPUT_CONFIG_STATUS_INVALID;
|
||||
|
||||
tp->dwt.timeout = timeout;
|
||||
|
||||
return LIBINPUT_CONFIG_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static uint64_t
|
||||
tp_dwt_config_get_timeout(struct libinput_device *device)
|
||||
{
|
||||
struct evdev_device *evdev = evdev_device(device);
|
||||
struct tp_dispatch *tp = (struct tp_dispatch *)evdev->dispatch;
|
||||
|
||||
return tp->dwt.timeout;
|
||||
}
|
||||
|
||||
static int
|
||||
tp_dwtp_config_is_available(struct libinput_device *device)
|
||||
{
|
||||
|
|
@ -3258,7 +3280,10 @@ tp_init_dwt(struct tp_dispatch *tp, struct evdev_device *device)
|
|||
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.config.set_timeout = tp_dwt_config_set_timeout;
|
||||
tp->dwt.config.get_timeout = tp_dwt_config_get_timeout;
|
||||
tp->dwt.dwt_enabled = tp_dwt_default_enabled(tp);
|
||||
tp->dwt.timeout = DEFAULT_KEYBOARD_ACTIVITY_TIMEOUT_2;
|
||||
device->base.config.dwt = &tp->dwt.config;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -486,6 +486,7 @@ struct tp_dispatch {
|
|||
struct {
|
||||
struct libinput_device_config_dwt config;
|
||||
bool dwt_enabled;
|
||||
uint64_t timeout;
|
||||
|
||||
/* We have to allow for more than one device node to be the
|
||||
* internal dwt keyboard (Razer Blade). But they're the same
|
||||
|
|
|
|||
|
|
@ -463,6 +463,9 @@ struct libinput_device_config_dwt {
|
|||
enum libinput_config_dwt_state (*get_enabled)(struct libinput_device *device);
|
||||
enum libinput_config_dwt_state (*get_default_enabled)(
|
||||
struct libinput_device *device);
|
||||
enum libinput_config_status (*set_timeout)(struct libinput_device *device,
|
||||
uint64_t timeout);
|
||||
uint64_t (*get_timeout)(struct libinput_device *device);
|
||||
};
|
||||
|
||||
struct libinput_device_config_dwtp {
|
||||
|
|
|
|||
|
|
@ -4916,6 +4916,27 @@ libinput_device_config_dwt_get_default_enabled(struct libinput_device *device)
|
|||
return device->config.dwt->get_default_enabled(device);
|
||||
}
|
||||
|
||||
LIBINPUT_EXPORT enum libinput_config_status
|
||||
libinput_device_config_dwt_set_timeout(struct libinput_device *device, uint32_t millis)
|
||||
{
|
||||
if (millis == 0)
|
||||
return LIBINPUT_CONFIG_STATUS_INVALID;
|
||||
|
||||
if (!libinput_device_config_dwt_is_available(device))
|
||||
return LIBINPUT_CONFIG_STATUS_UNSUPPORTED;
|
||||
|
||||
return device->config.dwt->set_timeout(device, ms2us(millis));
|
||||
}
|
||||
|
||||
LIBINPUT_EXPORT uint32_t
|
||||
libinput_device_config_dwt_get_timeout(struct libinput_device *device)
|
||||
{
|
||||
if (!libinput_device_config_dwt_is_available(device))
|
||||
return 0;
|
||||
|
||||
return us2ms(device->config.dwt->get_timeout(device));
|
||||
}
|
||||
|
||||
LIBINPUT_EXPORT int
|
||||
libinput_device_config_dwtp_is_available(struct libinput_device *device)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -6668,6 +6668,8 @@ enum libinput_config_dwt_state {
|
|||
* @see libinput_device_config_dwt_set_enabled
|
||||
* @see libinput_device_config_dwt_get_enabled
|
||||
* @see libinput_device_config_dwt_get_default_enabled
|
||||
* @see libinput_device_config_dwt_get_timeout
|
||||
* @see libinput_device_config_dwt_set_timeout
|
||||
*/
|
||||
int
|
||||
libinput_device_config_dwt_is_available(struct libinput_device *device);
|
||||
|
|
@ -6692,6 +6694,8 @@ libinput_device_config_dwt_is_available(struct libinput_device *device);
|
|||
* @see libinput_device_config_dwt_is_available
|
||||
* @see libinput_device_config_dwt_get_enabled
|
||||
* @see libinput_device_config_dwt_get_default_enabled
|
||||
* @see libinput_device_config_dwt_get_timeout
|
||||
* @see libinput_device_config_dwt_set_timeout
|
||||
*/
|
||||
enum libinput_config_status
|
||||
libinput_device_config_dwt_set_enabled(struct libinput_device *device,
|
||||
|
|
@ -6711,6 +6715,8 @@ libinput_device_config_dwt_set_enabled(struct libinput_device *device,
|
|||
* @see libinput_device_config_dwt_is_available
|
||||
* @see libinput_device_config_dwt_set_enabled
|
||||
* @see libinput_device_config_dwt_get_default_enabled
|
||||
* @see libinput_device_config_dwt_get_timeout
|
||||
* @see libinput_device_config_dwt_set_timeout
|
||||
*/
|
||||
enum libinput_config_dwt_state
|
||||
libinput_device_config_dwt_get_enabled(struct libinput_device *device);
|
||||
|
|
@ -6729,10 +6735,51 @@ libinput_device_config_dwt_get_enabled(struct libinput_device *device);
|
|||
* @see libinput_device_config_dwt_is_available
|
||||
* @see libinput_device_config_dwt_set_enabled
|
||||
* @see libinput_device_config_dwt_get_enabled
|
||||
* @see libinput_device_config_dwt_get_timeout
|
||||
* @see libinput_device_config_dwt_set_timeout
|
||||
*/
|
||||
enum libinput_config_dwt_state
|
||||
libinput_device_config_dwt_get_default_enabled(struct libinput_device *device);
|
||||
|
||||
/**
|
||||
* @ingroup config
|
||||
*
|
||||
* Set the disable-while-typing timeout. This timeout denotes the time
|
||||
* in milliseconds between the last key event and the touchpad re-enabling.
|
||||
*
|
||||
* The timeout only takes effect if disable-while-typing is enabled. libinput
|
||||
* implements implementation-defined minimum/maximum timeout values, setting
|
||||
* a timeout outside of those returns @ref LIBINPUT_CONFIG_STATUS_INVALID.
|
||||
* Normal use-cases should never hit these limits.
|
||||
*
|
||||
* @note The timeout is not the only condition for disable-while-typing, expiry of
|
||||
* the timeout does not guarantee that the touchpad is re-enabled.
|
||||
*
|
||||
* @see libinput_device_config_dwt_is_available
|
||||
* @see libinput_device_config_dwt_set_enabled
|
||||
* @see libinput_device_config_dwt_get_enabled
|
||||
* @see libinput_device_config_dwt_get_timeout
|
||||
*
|
||||
* @since 1.31
|
||||
*/
|
||||
enum libinput_config_status
|
||||
libinput_device_config_dwt_set_timeout(struct libinput_device *device, uint32_t millis);
|
||||
|
||||
/**
|
||||
* @ingroup config
|
||||
*
|
||||
* Get the current disable-while-typing timeout.
|
||||
*
|
||||
* @see libinput_device_config_dwt_is_available
|
||||
* @see libinput_device_config_dwt_set_enabled
|
||||
* @see libinput_device_config_dwt_get_enabled
|
||||
* @see libinput_device_config_dwt_set_timeout
|
||||
*
|
||||
* @since 1.31
|
||||
*/
|
||||
uint32_t
|
||||
libinput_device_config_dwt_get_timeout(struct libinput_device *device);
|
||||
|
||||
/**
|
||||
* @ingroup config
|
||||
*
|
||||
|
|
|
|||
|
|
@ -380,3 +380,8 @@ LIBINPUT_1.30 {
|
|||
libinput_plugin_system_append_path;
|
||||
libinput_plugin_system_load_plugins;
|
||||
} LIBINPUT_1.29;
|
||||
|
||||
LIBINPUT_1.31 {
|
||||
libinput_device_config_dwt_get_timeout;
|
||||
libinput_device_config_dwt_set_timeout;
|
||||
} LIBINPUT_1.30;
|
||||
|
|
|
|||
|
|
@ -3975,6 +3975,7 @@ START_TEST(touchpad_dwt_type)
|
|||
struct litest_device *keyboard;
|
||||
struct libinput *li = touchpad->libinput;
|
||||
int i;
|
||||
uint32_t timeout = litest_test_param_get_u32(test_env->params, "timeout");
|
||||
|
||||
if (!has_disable_while_typing(touchpad))
|
||||
return LITEST_NOT_APPLICABLE;
|
||||
|
|
@ -3984,6 +3985,13 @@ START_TEST(touchpad_dwt_type)
|
|||
litest_disable_hold_gestures(touchpad->libinput_device);
|
||||
litest_drain_events(li);
|
||||
|
||||
if (timeout) {
|
||||
auto status = libinput_device_config_dwt_set_timeout(
|
||||
touchpad->libinput_device,
|
||||
timeout);
|
||||
litest_assert_enum_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS);
|
||||
}
|
||||
|
||||
for (i = 0; i < 5; i++) {
|
||||
litest_keyboard_key(keyboard, KEY_A, true);
|
||||
litest_keyboard_key(keyboard, KEY_A, false);
|
||||
|
|
@ -3997,7 +4005,12 @@ START_TEST(touchpad_dwt_type)
|
|||
litest_touch_up(touchpad, 0);
|
||||
litest_assert_empty_queue(li);
|
||||
|
||||
if (timeout) {
|
||||
litest_timeout(li, timeout);
|
||||
} else {
|
||||
litest_timeout_dwt_long(li);
|
||||
}
|
||||
|
||||
litest_touch_down(touchpad, 0, 50, 50);
|
||||
litest_touch_move_to(touchpad, 0, 50, 50, 70, 50, 5);
|
||||
litest_touch_up(touchpad, 0);
|
||||
|
|
@ -4499,6 +4512,9 @@ START_TEST(touchpad_dwt_config_default_on)
|
|||
state = libinput_device_config_dwt_get_default_enabled(device);
|
||||
litest_assert_enum_eq(state, LIBINPUT_CONFIG_DWT_ENABLED);
|
||||
|
||||
uint32_t timeout = libinput_device_config_dwt_get_timeout(device);
|
||||
litest_assert_int_eq(timeout, 500U);
|
||||
|
||||
status = libinput_device_config_dwt_set_enabled(device,
|
||||
LIBINPUT_CONFIG_DWT_ENABLED);
|
||||
litest_assert_enum_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS);
|
||||
|
|
@ -4508,6 +4524,22 @@ START_TEST(touchpad_dwt_config_default_on)
|
|||
|
||||
status = libinput_device_config_dwt_set_enabled(device, 3);
|
||||
litest_assert_enum_eq(status, LIBINPUT_CONFIG_STATUS_INVALID);
|
||||
|
||||
/* Configurable even if disabled */
|
||||
status = libinput_device_config_dwt_set_timeout(device, 600);
|
||||
litest_assert_enum_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS);
|
||||
timeout = libinput_device_config_dwt_get_timeout(device);
|
||||
litest_assert_int_eq(timeout, 600U);
|
||||
|
||||
/* Too short, too long */
|
||||
status = libinput_device_config_dwt_set_timeout(device, 10);
|
||||
litest_assert_enum_eq(status, LIBINPUT_CONFIG_STATUS_INVALID);
|
||||
timeout = libinput_device_config_dwt_get_timeout(device);
|
||||
litest_assert_int_eq(timeout, 600U);
|
||||
status = libinput_device_config_dwt_set_timeout(device, 5000);
|
||||
litest_assert_enum_eq(status, LIBINPUT_CONFIG_STATUS_INVALID);
|
||||
timeout = libinput_device_config_dwt_get_timeout(device);
|
||||
litest_assert_int_eq(timeout, 600U);
|
||||
}
|
||||
END_TEST
|
||||
|
||||
|
|
@ -7169,7 +7201,9 @@ TEST_COLLECTION(touchpad_dwt)
|
|||
litest_add(touchpad_dwt_key_hold_timeout, LITEST_TOUCHPAD, LITEST_ANY);
|
||||
litest_add(touchpad_dwt_key_hold_timeout_existing_touch, LITEST_TOUCHPAD, LITEST_ANY);
|
||||
litest_add(touchpad_dwt_key_hold_timeout_existing_touch_cornercase, LITEST_TOUCHPAD, LITEST_ANY);
|
||||
litest_add(touchpad_dwt_type, LITEST_TOUCHPAD, LITEST_ANY);
|
||||
litest_with_parameters(params, "timeout", 'u', 4, 0, 120, 300, 900) {
|
||||
litest_add_parametrized(touchpad_dwt_type, LITEST_TOUCHPAD, LITEST_ANY, params);
|
||||
}
|
||||
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);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue