+ '(dwt)' \
'--enable-dwt[Enable disable-while-typing]' \
'--disable-dwt[Disable disable-while-typing]'
+ + '(dwtp)' \
+ '--enable-dwtp[Enable disable-while-trackpointing]' \
+ '--disable-dwtp[Disable disable-while-trackpointing]'
}
(( $+functions[_libinput_debug-gui] )) || _libinput_debug-gui()
most touchpads.
------------------------------------------------------------------------------
+Disable while trackpointing
+------------------------------------------------------------------------------
+
+DWTP is a form of palm detecion for devices that have a trackpoint (like
+Thinkpads). While the user is using the trackpoint, the touchpad is disabled,
+being enabled again after a timeout. See :ref:`disable-while-trackpointing` for
+more info.
+
+Disable-while-trackpointing can be enabled or disabled, it is enabled by
+default.
+
+------------------------------------------------------------------------------
Calibration
------------------------------------------------------------------------------
- :ref:`palm_exclusion_zones`
- :ref:`trackpoint-disabling`
- :ref:`disable-while-typing`
+- :ref:`disable-while-trackpointing`
- :ref:`stylus-touch-arbitration`
Palm detection is always enabled, with the exception of
Disable-while-typing can be enabled and disabled by calling
**libinput_device_config_dwt_set_enabled()**.
+.. _disable-while-trackpointing:
+
+------------------------------------------------------------------------------
+Disable-while-trackpointing
+------------------------------------------------------------------------------
+
+libinput automatically disables the touchpad for a timeout after the trackpoint
+is moved, a feature referred to as "disable while trackpointing". libinput does
+not require an external command and the feature is currently enabled for all
+touchpads.
+
+Disable-while-trackpointing can be enabled and disabled by calling
+**libinput_device_config_dwtp_set_enabled()**.
+
.. _stylus-touch-arbitration:
------------------------------------------------------------------------------
{
struct tp_dispatch *tp = data;
+ if (!tp->palm.dwtp_enabled)
+ return;
+
/* Buttons do not count as trackpad activity, as people may use
the trackpoint buttons in combination with the touchpad. */
if (event->type == LIBINPUT_EVENT_POINTER_BUTTON)
LIBINPUT_CONFIG_DWT_DISABLED;
}
+static int
+tp_dwtp_config_is_available(struct libinput_device *device)
+{
+ return 1;
+}
+
+static enum libinput_config_status
+tp_dwtp_config_set(struct libinput_device *device,
+ enum libinput_config_dwtp_state enable)
+{
+ struct evdev_device *evdev = evdev_device(device);
+ struct tp_dispatch *tp = (struct tp_dispatch*)evdev->dispatch;
+
+ switch(enable) {
+ case LIBINPUT_CONFIG_DWTP_ENABLED:
+ case LIBINPUT_CONFIG_DWTP_DISABLED:
+ break;
+ default:
+ return LIBINPUT_CONFIG_STATUS_INVALID;
+ }
+
+ tp->palm.dwtp_enabled = (enable == LIBINPUT_CONFIG_DWTP_ENABLED);
+
+ return LIBINPUT_CONFIG_STATUS_SUCCESS;
+}
+
+static enum libinput_config_dwtp_state
+tp_dwtp_config_get(struct libinput_device *device)
+{
+ struct evdev_device *evdev = evdev_device(device);
+ struct tp_dispatch *tp = (struct tp_dispatch*)evdev->dispatch;
+
+ return tp->palm.dwtp_enabled ?
+ LIBINPUT_CONFIG_DWTP_ENABLED :
+ LIBINPUT_CONFIG_DWTP_DISABLED;
+}
+
+static bool
+tp_dwtp_default_enabled(struct tp_dispatch *tp)
+{
+ return true;
+}
+
+static enum libinput_config_dwtp_state
+tp_dwtp_config_get_default(struct libinput_device *device)
+{
+ struct evdev_device *evdev = evdev_device(device);
+ struct tp_dispatch *tp = (struct tp_dispatch*)evdev->dispatch;
+
+ return tp_dwtp_default_enabled(tp) ?
+ LIBINPUT_CONFIG_DWTP_ENABLED :
+ LIBINPUT_CONFIG_DWTP_DISABLED;
+}
+
static inline bool
tp_is_tpkb_combo_below(struct evdev_device *device)
{
device->base.config.dwt = &tp->dwt.config;
}
+static void
+tp_init_dwtp(struct tp_dispatch *tp,
+ struct evdev_device *device)
+{
+ tp->palm.dwtp_enabled = tp_dwtp_default_enabled(tp);
+
+ if (device->tags & EVDEV_TAG_EXTERNAL_TOUCHPAD)
+ return;
+
+ tp->palm.config.is_available = tp_dwtp_config_is_available;
+ tp->palm.config.set_enabled = tp_dwtp_config_set;
+ tp->palm.config.get_enabled = tp_dwtp_config_get;
+ tp->palm.config.get_default_enabled = tp_dwtp_config_get_default;
+ device->base.config.dwtp = &tp->palm.config;
+}
+
static inline void
tp_init_palmdetect_edge(struct tp_dispatch *tp,
struct evdev_device *device)
tp_init_tap(tp);
tp_init_buttons(tp, device);
tp_init_dwt(tp, device);
+ tp_init_dwtp(tp, device);
tp_init_palmdetect(tp, device);
tp_init_sendevents(tp, device);
tp_init_scroll(tp, device);
} tap;
struct {
+ struct libinput_device_config_dwtp config;
+ bool dwtp_enabled;
+
int32_t right_edge; /* in device coordinates */
int32_t left_edge; /* in device coordinates */
int32_t upper_edge; /* in device coordinates */
struct libinput_device *device);
};
+struct libinput_device_config_dwtp {
+ int (*is_available)(struct libinput_device *device);
+ enum libinput_config_status (*set_enabled)(
+ struct libinput_device *device,
+ enum libinput_config_dwtp_state enable);
+ enum libinput_config_dwtp_state (*get_enabled)(
+ struct libinput_device *device);
+ enum libinput_config_dwtp_state (*get_default_enabled)(
+ struct libinput_device *device);
+};
+
struct libinput_device_config_rotation {
int (*is_available)(struct libinput_device *device);
enum libinput_config_status (*set_angle)(
struct libinput_device_config_click_method *click_method;
struct libinput_device_config_middle_emulation *middle_emulation;
struct libinput_device_config_dwt *dwt;
+ struct libinput_device_config_dwtp *dwtp;
struct libinput_device_config_rotation *rotation;
struct libinput_device_config_gesture *gesture;
};
ASSERT_INT_SIZE(enum libinput_config_middle_emulation_state);
ASSERT_INT_SIZE(enum libinput_config_scroll_method);
ASSERT_INT_SIZE(enum libinput_config_dwt_state);
+ASSERT_INT_SIZE(enum libinput_config_dwtp_state);
static inline const char *
event_type_to_str(enum libinput_event_type type)
}
LIBINPUT_EXPORT int
+libinput_device_config_dwtp_is_available(struct libinput_device *device)
+{
+ if (!device->config.dwtp)
+ return 0;
+
+ return device->config.dwtp->is_available(device);
+}
+
+LIBINPUT_EXPORT enum libinput_config_status
+libinput_device_config_dwtp_set_enabled(struct libinput_device *device,
+ enum libinput_config_dwtp_state enable)
+{
+ if (enable != LIBINPUT_CONFIG_DWTP_ENABLED &&
+ enable != LIBINPUT_CONFIG_DWTP_DISABLED)
+ return LIBINPUT_CONFIG_STATUS_INVALID;
+
+ if (!libinput_device_config_dwtp_is_available(device))
+ return enable ? LIBINPUT_CONFIG_STATUS_UNSUPPORTED :
+ LIBINPUT_CONFIG_STATUS_SUCCESS;
+
+ return device->config.dwtp->set_enabled(device, enable);
+}
+
+LIBINPUT_EXPORT enum libinput_config_dwtp_state
+libinput_device_config_dwtp_get_enabled(struct libinput_device *device)
+{
+ if (!libinput_device_config_dwtp_is_available(device))
+ return LIBINPUT_CONFIG_DWTP_DISABLED;
+
+ return device->config.dwtp->get_enabled(device);
+}
+
+LIBINPUT_EXPORT enum libinput_config_dwtp_state
+libinput_device_config_dwtp_get_default_enabled(struct libinput_device *device)
+{
+ if (!libinput_device_config_dwtp_is_available(device))
+ return LIBINPUT_CONFIG_DWTP_DISABLED;
+
+ return device->config.dwtp->get_default_enabled(device);
+}
+
+LIBINPUT_EXPORT int
libinput_device_config_rotation_is_available(struct libinput_device *device)
{
if (!device->config.rotation)
/**
* @ingroup config
*
+ * Possible states for the disable-while-trackpointing feature.
+ *
+ * @since 1.21
+ */
+enum libinput_config_dwtp_state {
+ LIBINPUT_CONFIG_DWTP_DISABLED,
+ LIBINPUT_CONFIG_DWTP_ENABLED,
+};
+
+/**
+ * @ingroup config
+ *
+ * Check if this device supports configurable disable-while-trackpointing
+ * feature. This feature is usually available on Thinkpads and disables the
+ * touchpad while using the trackpoint. See the libinput documentation for
+ * details.
+ *
+ * @param device The device to configure
+ * @return 0 if this device does not support disable-while-trackpointing, or 1
+ * otherwise.
+ *
+ * @see libinput_device_config_dwtp_set_enabled
+ * @see libinput_device_config_dwtp_get_enabled
+ * @see libinput_device_config_dwtp_get_default_enabled
+ *
+ * @since 1.21
+ */
+int
+libinput_device_config_dwtp_is_available(struct libinput_device *device);
+
+/**
+ * @ingroup config
+ *
+ * Enable or disable the disable-while-trackpointing feature. When enabled, the
+ * device will be disabled while using the trackpoint and for a short period
+ * after. See the libinput documentation for details.
+ *
+ * @note Enabling or disabling disable-while-trackpointing may not take effect
+ * immediately.
+ *
+ * @param device The device to configure
+ * @param enable @ref LIBINPUT_CONFIG_DWTP_DISABLED to disable
+ * disable-while-trackpointing, @ref LIBINPUT_CONFIG_DWTP_ENABLED to enable
+ *
+ * @return A config status code. Disabling disable-while-trackpointing on a
+ * device that does not support the feature always succeeds.
+ *
+ * @see libinput_device_config_dwtp_is_available
+ * @see libinput_device_config_dwtp_get_enabled
+ * @see libinput_device_config_dwtp_get_default_enabled
+ *
+ * @since 1.21
+ */
+enum libinput_config_status
+libinput_device_config_dwtp_set_enabled(struct libinput_device *device,
+ enum libinput_config_dwtp_state enable);
+
+/**
+ * @ingroup config
+ *
+ * Check if the disable-while trackpointing feature is currently enabled on
+ * this device. If the device does not support disable-while-trackpointing,
+ * this function returns @ref LIBINPUT_CONFIG_DWTP_DISABLED.
+ *
+ * @param device The device to configure
+ * @return @ref LIBINPUT_CONFIG_DWTP_DISABLED if disabled, @ref
+ * LIBINPUT_CONFIG_DWTP_ENABLED if enabled.
+ *
+ * @see libinput_device_config_dwtp_is_available
+ * @see libinput_device_config_dwtp_set_enabled
+ * @see libinput_device_config_dwtp_get_default_enabled
+ *
+ * @since 1.21
+ */
+enum libinput_config_dwtp_state
+libinput_device_config_dwtp_get_enabled(struct libinput_device *device);
+
+/**
+ * @ingroup config
+ *
+ * Check if the disable-while trackpointing feature is enabled on this device
+ * by default. If the device does not support disable-while-trackpointing, this
+ * function returns @ref LIBINPUT_CONFIG_DWTP_DISABLED.
+ *
+ * @param device The device to configure
+ * @return @ref LIBINPUT_CONFIG_DWTP_DISABLED if disabled, @ref
+ * LIBINPUT_CONFIG_DWTP_ENABLED if enabled.
+ *
+ * @see libinput_device_config_dwtp_is_available
+ * @see libinput_device_config_dwtp_set_enabled
+ * @see libinput_device_config_dwtp_get_enabled
+ *
+ * @since 1.21
+ */
+enum libinput_config_dwtp_state
+libinput_device_config_dwtp_get_default_enabled(struct libinput_device *device);
+
+/**
+ * @ingroup config
+ *
* Check whether a device can have a custom rotation applied.
*
* @param device The device to configure
libinput_event_pointer_get_scroll_value_v120;
libinput_event_pointer_get_scroll_value;
} LIBINPUT_1.15;
+
+LIBINPUT_1.21 {
+ libinput_device_config_dwtp_is_available;
+ libinput_device_config_dwtp_set_enabled;
+ libinput_device_config_dwtp_get_enabled;
+ libinput_device_config_dwtp_get_default_enabled;
+} LIBINPUT_1.19;
}
END_TEST
+START_TEST(touchpad_dwtp_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_dwtp_state state;
+
+ if (litest_touchpad_is_external(dev)) {
+ ck_assert(!libinput_device_config_dwtp_is_available(device));
+ return;
+ }
+
+ ck_assert(libinput_device_config_dwtp_is_available(device));
+ state = libinput_device_config_dwtp_get_enabled(device);
+ ck_assert_int_eq(state, LIBINPUT_CONFIG_DWTP_ENABLED);
+ state = libinput_device_config_dwtp_get_default_enabled(device);
+ ck_assert_int_eq(state, LIBINPUT_CONFIG_DWTP_ENABLED);
+
+ status = libinput_device_config_dwtp_set_enabled(device,
+ LIBINPUT_CONFIG_DWTP_ENABLED);
+ ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS);
+ status = libinput_device_config_dwtp_set_enabled(device,
+ LIBINPUT_CONFIG_DWTP_DISABLED);
+ ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS);
+
+ status = libinput_device_config_dwtp_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();
}
END_TEST
+START_TEST(touchpad_dwtp_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_dwtp_state state;
+
+ ck_assert(!libinput_device_config_dwtp_is_available(device));
+ state = libinput_device_config_dwtp_get_enabled(device);
+ ck_assert_int_eq(state, LIBINPUT_CONFIG_DWTP_DISABLED);
+ state = libinput_device_config_dwtp_get_default_enabled(device);
+ ck_assert_int_eq(state, LIBINPUT_CONFIG_DWTP_DISABLED);
+
+ status = libinput_device_config_dwtp_set_enabled(device,
+ LIBINPUT_CONFIG_DWTP_ENABLED);
+ ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_UNSUPPORTED);
+ status = libinput_device_config_dwtp_set_enabled(device,
+ LIBINPUT_CONFIG_DWTP_DISABLED);
+ ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS);
+
+ status = libinput_device_config_dwtp_set_enabled(device, 3);
+ ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_INVALID);
+}
+END_TEST
+
static inline void
disable_dwt(struct litest_device *dev)
{
litest_add(touchpad_dwt_enable_before_touch, LITEST_TOUCHPAD, LITEST_ANY);
litest_add(touchpad_dwt_enable_during_tap, LITEST_TOUCHPAD, LITEST_ANY);
litest_add(touchpad_dwt_remove_kbd_while_active, LITEST_TOUCHPAD, LITEST_ANY);
+ litest_add(touchpad_dwtp_config_default_on, LITEST_TOUCHPAD, LITEST_ANY);
+ litest_add(touchpad_dwtp_config_default_off, LITEST_ANY, LITEST_TOUCHPAD);
litest_add_for_device(touchpad_dwt_apple, LITEST_BCM5974);
litest_add_for_device(touchpad_dwt_acer_hawaii, LITEST_ACER_HAWAII_TOUCHPAD);
litest_add_for_device(touchpad_dwt_multiple_keyboards, LITEST_SYNAPTICS_I2C);
#include "libinput-util.h"
#include "litest.h"
+static inline bool
+has_disable_while_trackpointing(struct litest_device *device)
+{
+ return libinput_device_config_dwtp_is_available(device->libinput_device);
+}
+
START_TEST(trackpoint_middlebutton)
{
struct litest_device *dev = litest_current_device();
}
END_TEST
+static inline void
+enable_dwtp(struct litest_device *dev)
+{
+ enum libinput_config_status status,
+ expected = LIBINPUT_CONFIG_STATUS_SUCCESS;
+ status = libinput_device_config_dwtp_set_enabled(dev->libinput_device,
+ LIBINPUT_CONFIG_DWTP_ENABLED);
+ litest_assert_int_eq(status, expected);
+}
+
+static inline void
+disable_dwtp(struct litest_device *dev)
+{
+ enum libinput_config_status status,
+ expected = LIBINPUT_CONFIG_STATUS_SUCCESS;
+ status = libinput_device_config_dwtp_set_enabled(dev->libinput_device,
+ LIBINPUT_CONFIG_DWTP_DISABLED);
+ litest_assert_int_eq(status, expected);
+}
+
+
START_TEST(trackpoint_palmdetect)
{
struct litest_device *trackpoint = litest_current_device();
int i;
touchpad = litest_add_device(li, LITEST_SYNAPTICS_I2C);
+ if (has_disable_while_trackpointing(touchpad))
+ enable_dwtp(touchpad);
+
litest_disable_hold_gestures(touchpad->libinput_device);
litest_drain_events(li);
}
END_TEST
+START_TEST(trackpoint_palmdetect_dwtp_disabled)
+{
+ struct litest_device *trackpoint = litest_current_device();
+ struct litest_device *touchpad;
+ struct libinput *li = trackpoint->libinput;
+ int i;
+
+ touchpad = litest_add_device(li, LITEST_SYNAPTICS_I2C);
+ if (has_disable_while_trackpointing(touchpad))
+ disable_dwtp(touchpad);
+
+ litest_disable_hold_gestures(touchpad->libinput_device);
+ litest_drain_events(li);
+
+ for (i = 0; i < 10; i++) {
+ litest_event(trackpoint, EV_REL, REL_X, 1);
+ litest_event(trackpoint, EV_REL, REL_Y, 1);
+ litest_event(trackpoint, EV_SYN, SYN_REPORT, 0);
+ libinput_dispatch(li);
+ }
+ litest_drain_events(li);
+
+ litest_touch_down(touchpad, 0, 30, 30);
+ litest_touch_move_to(touchpad, 0, 30, 30, 80, 80, 10);
+ litest_touch_up(touchpad, 0);
+ litest_assert_only_typed_events(li, LIBINPUT_EVENT_POINTER_MOTION);
+
+ litest_delete_device(touchpad);
+}
+END_TEST
+
START_TEST(trackpoint_palmdetect_resume_touch)
{
struct litest_device *trackpoint = litest_current_device();
int i;
touchpad = litest_add_device(li, LITEST_SYNAPTICS_I2C);
+
+ if (has_disable_while_trackpointing(touchpad))
+ enable_dwtp(touchpad);
+
litest_disable_hold_gestures(touchpad->libinput_device);
litest_drain_events(li);
struct libinput *li = trackpoint->libinput;
touchpad = litest_add_device(li, LITEST_SYNAPTICS_I2C);
+
+ if (has_disable_while_trackpointing(touchpad))
+ enable_dwtp(touchpad);
+
litest_disable_hold_gestures(touchpad->libinput_device);
litest_drain_events(li);
struct libinput *li = trackpoint->libinput;
touchpad = litest_add_device(li, LITEST_SYNAPTICS_I2C);
+
+ if (has_disable_while_trackpointing(touchpad))
+ enable_dwtp(touchpad);
+
litest_disable_hold_gestures(touchpad->libinput_device);
litest_drain_events(li);
litest_add(trackpoint_topsoftbuttons_left_handed_both, LITEST_TOPBUTTONPAD, LITEST_ANY);
litest_add(trackpoint_palmdetect, LITEST_POINTINGSTICK, LITEST_ANY);
+ litest_add(trackpoint_palmdetect_dwtp_disabled, LITEST_POINTINGSTICK, LITEST_ANY);
litest_add(trackpoint_palmdetect_resume_touch, LITEST_POINTINGSTICK, LITEST_ANY);
litest_add(trackpoint_palmdetect_require_min_events, LITEST_POINTINGSTICK, LITEST_ANY);
litest_add(trackpoint_palmdetect_require_min_events_timeout, LITEST_POINTINGSTICK, LITEST_ANY);
printq(" dwt-off)");
}
+ if (libinput_device_config_dwtp_is_available(dev)) {
+ if (libinput_device_config_dwtp_get_enabled(dev) ==
+ LIBINPUT_CONFIG_DWTP_ENABLED)
+ printq(" dwtp-on");
+ else
+ printq(" dwtp-off)");
+ }
+
if (libinput_device_has_capability(dev,
LIBINPUT_DEVICE_CAP_TABLET_PAD)) {
int nbuttons, nstrips, nrings, ngroups;
.B \-\-enable\-dwt|\-\-disable\-dwt
Enable or disable disable-while-typing
.TP 8
+.B \-\-enable\-dwtp|\-\-disable\-dwtp
+Enable or disable disable-while-trackpointing
+.TP 8
.B \-\-enable\-scroll-button-lock|\-\-disable\-scroll-button-lock
Enable or disable the scroll button lock
.TP 8
return "disabled";
}
+static const char *
+dwtp_default(struct libinput_device *device)
+{
+ if (!libinput_device_config_dwtp_is_available(device))
+ return "n/a";
+
+ if (libinput_device_config_dwtp_get_default_enabled(device))
+ return "enabled";
+
+ return "disabled";
+}
+
static char *
rotation_default(struct libinput_device *device)
{
free(str);
printf("Disable-w-typing: %s\n", dwt_default(dev));
+ printf("Disable-w-trackpointing: %s\n", dwtp_default(dev));
str = accel_profiles(dev);
printf("Accel profiles: %s\n", str);
options->left_handed = -1;
options->middlebutton = -1;
options->dwt = -1;
+ options->dwtp = -1;
options->click_method = -1;
options->scroll_method = -1;
options->scroll_button = -1;
case OPT_DWT_DISABLE:
options->dwt = LIBINPUT_CONFIG_DWT_DISABLED;
break;
+ case OPT_DWTP_ENABLE:
+ options->dwtp = LIBINPUT_CONFIG_DWTP_ENABLED;
+ break;
+ case OPT_DWTP_DISABLE:
+ options->dwtp = LIBINPUT_CONFIG_DWTP_DISABLED;
+ break;
case OPT_CLICK_METHOD:
if (!optarg)
return 1;
OPT_MIDDLEBUTTON_DISABLE,
OPT_DWT_ENABLE,
OPT_DWT_DISABLE,
+ OPT_DWTP_ENABLE,
+ OPT_DWTP_DISABLE,
OPT_CLICK_METHOD,
OPT_SCROLL_METHOD,
OPT_SCROLL_BUTTON,
{ "disable-middlebutton", no_argument, 0, OPT_MIDDLEBUTTON_DISABLE }, \
{ "enable-dwt", no_argument, 0, OPT_DWT_ENABLE }, \
{ "disable-dwt", no_argument, 0, OPT_DWT_DISABLE }, \
+ { "enable-dwtp", no_argument, 0, OPT_DWTP_ENABLE }, \
+ { "disable-dwtp", no_argument, 0, OPT_DWTP_DISABLE }, \
{ "enable-scroll-button-lock", no_argument, 0, OPT_SCROLL_BUTTON_LOCK_ENABLE }, \
{ "disable-scroll-button-lock",no_argument, 0, OPT_SCROLL_BUTTON_LOCK_DISABLE }, \
{ "set-click-method", required_argument, 0, OPT_CLICK_METHOD }, \
int scroll_button_lock;
double speed;
int dwt;
+ int dwtp;
enum libinput_config_accel_profile profile;
char disable_pattern[64];
};
"natural-scrolling",
"left-handed",
"dwt",
+ "dwtp",
],
# options with distinct values
"enums": {