diff --git a/src/evdev-mt-touchpad.c b/src/evdev-mt-touchpad.c index e7f327c1..628fa979 100644 --- a/src/evdev-mt-touchpad.c +++ b/src/evdev-mt-touchpad.c @@ -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; } diff --git a/src/evdev-mt-touchpad.h b/src/evdev-mt-touchpad.h index f0053bee..f7901555 100644 --- a/src/evdev-mt-touchpad.h +++ b/src/evdev-mt-touchpad.h @@ -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 diff --git a/src/libinput-private.h b/src/libinput-private.h index b49a5838..9bb5425d 100644 --- a/src/libinput-private.h +++ b/src/libinput-private.h @@ -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 { diff --git a/src/libinput.c b/src/libinput.c index af0593f6..7036739f 100644 --- a/src/libinput.c +++ b/src/libinput.c @@ -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) { diff --git a/src/libinput.h b/src/libinput.h index d2895d35..541230d6 100644 --- a/src/libinput.h +++ b/src/libinput.h @@ -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 * diff --git a/src/libinput.sym b/src/libinput.sym index 74955ecd..dd8a0575 100644 --- a/src/libinput.sym +++ b/src/libinput.sym @@ -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; diff --git a/test/test-touchpad.c b/test/test-touchpad.c index 02e52c03..1ae7cc58 100644 --- a/test/test-touchpad.c +++ b/test/test-touchpad.c @@ -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); - litest_timeout_dwt_long(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);