diff --git a/CODING_STYLE b/CODING_STYLE
index 1a64ffe6..3648a4e2 100644
--- a/CODING_STYLE
+++ b/CODING_STYLE
@@ -62,6 +62,17 @@
useit(c);
}
+- if/else: { on the same line, no curly braces if both blocks are a single
+ statement. If either if or else block are multiple statements, both must
+ have curly braces.
+
+ if (foo) {
+ blah();
+ bar();
+ } else {
+ a = 10;
+ }
+
- public functions MUST be doxygen-commented, use doxygen's @foo rather than
\foo notation
diff --git a/doc/tapping.dox b/doc/tapping.dox
index 1337fc53..483219ad 100644
--- a/doc/tapping.dox
+++ b/doc/tapping.dox
@@ -29,17 +29,24 @@ libinput also supports "tap-and-drag" where a tap immediately followed by a
finger down and that finger being held down emulates a button press. Moving
the finger around can thus drag the selected item on the screen.
+Optional is a feature called "drag lock". With drag lock disabled, lifting
+the finger will stop any drag process. When enabled, libinput will ignore a
+finger up event during a drag process, provided the finger is set down again
+within a implementation-specific timeout. Drag lock can be enabled and
+disabled with libinput_device_config_tap_set_drag_lock_enabled().
+
@image html tap-n-drag.svg "Tap-and-drag process"
The above diagram explains the process, a tap (a) followed by a finger held
down (b) starts the drag process and logically holds the left mouse button
down. A movement of the finger (c) will drag the selected item until the
-finger is relased (e). If needed, the finger's position can be reset by
-lifting and quickly setting it down again on the touchpad (d). This will be
-interpreted as continuing move and is especially useful on small touchpads
-or with slow pointer acceleration.
-The release of the mouse buttons after the finger release (e) is triggered
-by a timeout. To release the button immediately, simply tap again (f).
+finger is relased (e). If needed and drag lock is enabled, the finger's
+position can be reset by lifting and quickly setting it down again on the
+touchpad (d). This will be interpreted as continuing move and is especially
+useful on small touchpads or with slow pointer acceleration.
+If drag lock is enabled, the release of the mouse buttons after the finger
+release (e) is triggered by a timeout. To release the button immediately,
+simply tap again (f).
If two fingers are supported by the hardware, a second finger can be used to
drag while the first is held in-place.
diff --git a/doc/touchpad-tap-state-machine.svg b/doc/touchpad-tap-state-machine.svg
index 39b0b86b..89c34fa0 100644
--- a/doc/touchpad-tap-state-machine.svg
+++ b/doc/touchpad-tap-state-machine.svg
@@ -1,16 +1,14 @@
-
-
diff --git a/src/evdev-mt-touchpad-buttons.c b/src/evdev-mt-touchpad-buttons.c
index 8d4e278e..9c1c096c 100644
--- a/src/evdev-mt-touchpad-buttons.c
+++ b/src/evdev-mt-touchpad-buttons.c
@@ -527,8 +527,8 @@ tp_init_softbuttons(struct tp_dispatch *tp,
xoffset = absinfo_x->minimum,
yoffset = absinfo_y->minimum;
yres = absinfo_y->resolution;
- width = abs(absinfo_x->maximum - absinfo_x->minimum);
- height = abs(absinfo_y->maximum - absinfo_y->minimum);
+ width = device->abs.dimensions.x;
+ height = device->abs.dimensions.y;
/* button height: 10mm or 15% of the touchpad height,
whichever is smaller */
@@ -558,8 +558,8 @@ tp_init_top_softbuttons(struct tp_dispatch *tp,
xoffset = absinfo_x->minimum,
yoffset = absinfo_y->minimum;
yres = absinfo_y->resolution;
- width = abs(absinfo_x->maximum - absinfo_x->minimum);
- height = abs(absinfo_y->maximum - absinfo_y->minimum);
+ width = device->abs.dimensions.x;
+ height = device->abs.dimensions.y;
if (tp->buttons.has_topbuttons) {
/* T440s has the top button line 5mm from the top, event
@@ -741,9 +741,9 @@ tp_init_buttons(struct tp_dispatch *tp,
/* pinned-finger motion threshold, see tp_unpin_finger.
The MAGIC for resolution-less touchpads ends up as 2% of the diagonal */
if (device->abs.fake_resolution) {
- const int BUTTON_MOTION_MAGIC = 0.007;
- width = abs(absinfo_x->maximum - absinfo_x->minimum);
- height = abs(absinfo_y->maximum - absinfo_y->minimum);
+ const double BUTTON_MOTION_MAGIC = 0.007;
+ width = device->abs.dimensions.x;
+ height = device->abs.dimensions.y;
diagonal = sqrt(width*width + height*height);
tp->buttons.motion_dist.x_scale_coeff = diagonal * BUTTON_MOTION_MAGIC;
tp->buttons.motion_dist.y_scale_coeff = diagonal * BUTTON_MOTION_MAGIC;
@@ -838,10 +838,8 @@ tp_check_clickfinger_distance(struct tp_dispatch *tp,
/* Use a maximum of 30% of the touchpad width or height if
* we dont' have resolution. */
- w = tp->device->abs.absinfo_x->maximum -
- tp->device->abs.absinfo_x->minimum;
- h = tp->device->abs.absinfo_y->maximum -
- tp->device->abs.absinfo_y->minimum;
+ w = tp->device->abs.dimensions.x;
+ h = tp->device->abs.dimensions.y;
return (x < w * 0.3 && y < h * 0.3) ? 1 : 0;
} else {
diff --git a/src/evdev-mt-touchpad-edge-scroll.c b/src/evdev-mt-touchpad-edge-scroll.c
index 56f1e8a0..9a9d3b84 100644
--- a/src/evdev-mt-touchpad-edge-scroll.c
+++ b/src/evdev-mt-touchpad-edge-scroll.c
@@ -39,7 +39,7 @@
avoid accidentally locking in scrolling mode when trying to use the entire
touchpad to move the pointer. The user can wait for the timeout to trigger
to do a small scroll. */
-#define DEFAULT_SCROLL_THRESHOLD TP_MM_TO_DPI_NORMALIZED(5)
+#define DEFAULT_SCROLL_THRESHOLD TP_MM_TO_DPI_NORMALIZED(3)
enum scroll_event {
SCROLL_EVENT_TOUCH,
@@ -275,8 +275,8 @@ tp_edge_scroll_init(struct tp_dispatch *tp, struct evdev_device *device)
int width, height;
int edge_width, edge_height;
- width = device->abs.absinfo_x->maximum - device->abs.absinfo_x->minimum;
- height = device->abs.absinfo_y->maximum - device->abs.absinfo_y->minimum;
+ width = device->abs.dimensions.x;
+ height = device->abs.dimensions.y;
switch (tp->model) {
case MODEL_ALPS:
@@ -353,7 +353,7 @@ tp_edge_scroll_post_events(struct tp_dispatch *tp, uint64_t time)
struct tp_touch *t;
enum libinput_pointer_axis axis;
double *delta;
- struct normalized_coords normalized;
+ struct normalized_coords normalized, tmp;
const struct normalized_coords zero = { 0.0, 0.0 };
const struct discrete_coords zero_discrete = { 0.0, 0.0 };
@@ -402,11 +402,14 @@ tp_edge_scroll_post_events(struct tp_dispatch *tp, uint64_t time)
t->scroll.edge_state);
break;
case EDGE_SCROLL_TOUCH_STATE_EDGE_NEW:
+ tmp = normalized;
normalized = tp_normalize_delta(tp,
device_delta(t->point,
t->scroll.initial));
if (fabs(*delta) < DEFAULT_SCROLL_THRESHOLD)
normalized = zero;
+ else
+ normalized = tmp;
break;
case EDGE_SCROLL_TOUCH_STATE_EDGE:
break;
diff --git a/src/evdev-mt-touchpad-tap.c b/src/evdev-mt-touchpad-tap.c
index 2951ee6a..7f241de5 100644
--- a/src/evdev-mt-touchpad-tap.c
+++ b/src/evdev-mt-touchpad-tap.c
@@ -389,8 +389,16 @@ tp_tap_dragging_handle_event(struct tp_dispatch *tp,
tp->tap.state = TAP_STATE_DRAGGING_2;
break;
case TAP_EVENT_RELEASE:
- tp->tap.state = TAP_STATE_DRAGGING_WAIT;
- tp_tap_set_drag_timer(tp, time);
+ if (tp->tap.drag_lock_enabled) {
+ tp->tap.state = TAP_STATE_DRAGGING_WAIT;
+ tp_tap_set_drag_timer(tp, time);
+ } else {
+ tp_tap_notify(tp,
+ time,
+ 1,
+ LIBINPUT_BUTTON_STATE_RELEASED);
+ tp->tap.state = TAP_STATE_IDLE;
+ }
break;
case TAP_EVENT_MOTION:
case TAP_EVENT_TIMEOUT:
@@ -845,6 +853,44 @@ tp_tap_config_get_default(struct libinput_device *device)
return tp_tap_default(evdev);
}
+static enum libinput_config_status
+tp_tap_config_set_draglock_enabled(struct libinput_device *device,
+ enum libinput_config_drag_lock_state enabled)
+{
+ struct evdev_dispatch *dispatch = ((struct evdev_device *) device)->dispatch;
+ struct tp_dispatch *tp = NULL;
+
+ tp = container_of(dispatch, tp, base);
+ tp->tap.drag_lock_enabled = enabled;
+
+ return LIBINPUT_CONFIG_STATUS_SUCCESS;
+}
+
+static enum libinput_config_drag_lock_state
+tp_tap_config_get_draglock_enabled(struct libinput_device *device)
+{
+ struct evdev_device *evdev = (struct evdev_device *)device;
+ struct tp_dispatch *tp = NULL;
+
+ tp = container_of(evdev->dispatch, tp, base);
+
+ return tp->tap.drag_lock_enabled;
+}
+
+static inline enum libinput_config_drag_lock_state
+tp_drag_lock_default(struct evdev_device *device)
+{
+ return LIBINPUT_CONFIG_DRAG_LOCK_DISABLED;
+}
+
+static enum libinput_config_drag_lock_state
+tp_tap_config_get_default_draglock_enabled(struct libinput_device *device)
+{
+ struct evdev_device *evdev = (struct evdev_device *)device;
+
+ return tp_drag_lock_default(evdev);
+}
+
int
tp_init_tap(struct tp_dispatch *tp)
{
@@ -852,10 +898,14 @@ tp_init_tap(struct tp_dispatch *tp)
tp->tap.config.set_enabled = tp_tap_config_set_enabled;
tp->tap.config.get_enabled = tp_tap_config_is_enabled;
tp->tap.config.get_default = tp_tap_config_get_default;
+ tp->tap.config.set_draglock_enabled = tp_tap_config_set_draglock_enabled;
+ tp->tap.config.get_draglock_enabled = tp_tap_config_get_draglock_enabled;
+ tp->tap.config.get_default_draglock_enabled = tp_tap_config_get_default_draglock_enabled;
tp->device->base.config.tap = &tp->tap.config;
tp->tap.state = TAP_STATE_IDLE;
tp->tap.enabled = tp_tap_default(tp->device);
+ tp->tap.drag_lock_enabled = tp_drag_lock_default(tp->device);
libinput_timer_init(&tp->tap.timer,
tp_libinput_context(tp),
diff --git a/src/evdev-mt-touchpad.c b/src/evdev-mt-touchpad.c
index 189a5aa4..f19f434e 100644
--- a/src/evdev-mt-touchpad.c
+++ b/src/evdev-mt-touchpad.c
@@ -426,7 +426,7 @@ tp_process_key(struct tp_dispatch *tp,
static void
tp_unpin_finger(struct tp_dispatch *tp, struct tp_touch *t)
{
- unsigned int xdist, ydist;
+ double xdist, ydist;
if (!t->pinned.is_pinned)
return;
@@ -524,7 +524,7 @@ tp_palm_detect(struct tp_dispatch *tp, struct tp_touch *t, uint64_t time)
int dirs;
if (tp_palm_detect_dwt(tp, t, time))
- goto out;
+ goto out;
/* If labelled a touch as palm, we unlabel as palm when
we move out of the palm edge zone within the timeout, provided
@@ -1403,10 +1403,8 @@ tp_init_palmdetect(struct tp_dispatch *tp,
tp->palm.left_edge = INT_MIN;
tp->palm.vert_center = INT_MIN;
- width = abs(device->abs.absinfo_x->maximum -
- device->abs.absinfo_x->minimum);
- height = abs(device->abs.absinfo_y->maximum -
- device->abs.absinfo_y->minimum);
+ width = device->abs.dimensions.x;
+ height = device->abs.dimensions.y;
/* Wacom doesn't have internal touchpads,
* Apple touchpads are always big enough to warrant palm detection */
@@ -1485,10 +1483,8 @@ tp_init(struct tp_dispatch *tp,
if (tp_init_slots(tp, device) != 0)
return -1;
- width = abs(device->abs.absinfo_x->maximum -
- device->abs.absinfo_x->minimum);
- height = abs(device->abs.absinfo_y->maximum -
- device->abs.absinfo_y->minimum);
+ width = device->abs.dimensions.x;
+ height = device->abs.dimensions.y;
diagonal = sqrt(width*width + height*height);
tp->reports_distance = libevdev_has_event_code(device->evdev,
diff --git a/src/evdev-mt-touchpad.h b/src/evdev-mt-touchpad.h
index 9357969c..36260c68 100644
--- a/src/evdev-mt-touchpad.h
+++ b/src/evdev-mt-touchpad.h
@@ -269,6 +269,8 @@ struct tp_dispatch {
enum tp_tap_state state;
uint32_t buttons_pressed;
uint64_t multitap_last_time;
+
+ bool drag_lock_enabled;
} tap;
struct {
diff --git a/src/evdev.c b/src/evdev.c
index 4695f079..c18279a6 100644
--- a/src/evdev.c
+++ b/src/evdev.c
@@ -29,6 +29,7 @@
#include
#include
#include
+#include
#include "linux/input.h"
#include
#include
@@ -253,6 +254,23 @@ normalize_delta(struct evdev_device *device,
normalized->y = delta->y * DEFAULT_MOUSE_DPI / (double)device->dpi;
}
+static inline bool
+evdev_post_trackpoint_scroll(struct evdev_device *device,
+ struct normalized_coords unaccel,
+ uint64_t time)
+{
+ if (device->scroll.method != LIBINPUT_CONFIG_SCROLL_ON_BUTTON_DOWN ||
+ !hw_is_key_down(device, device->scroll.button))
+ return false;
+
+ if (device->scroll.button_scroll_active)
+ evdev_post_scroll(device, time,
+ LIBINPUT_POINTER_AXIS_SOURCE_CONTINUOUS,
+ &unaccel);
+
+ return true;
+}
+
static void
evdev_flush_pending_event(struct evdev_device *device, uint64_t time)
{
@@ -275,14 +293,8 @@ evdev_flush_pending_event(struct evdev_device *device, uint64_t time)
device->rel.y = 0;
/* Use unaccelerated deltas for pointing stick scroll */
- if (device->scroll.method == LIBINPUT_CONFIG_SCROLL_ON_BUTTON_DOWN &&
- hw_is_key_down(device, device->scroll.button)) {
- if (device->scroll.button_scroll_active)
- evdev_post_scroll(device, time,
- LIBINPUT_POINTER_AXIS_SOURCE_CONTINUOUS,
- &unaccel);
- break;
- }
+ if (evdev_post_trackpoint_scroll(device, unaccel, time))
+ break;
/* Apply pointer acceleration. */
accel = filter_dispatch(device->pointer.filter,
@@ -1497,6 +1509,10 @@ evdev_read_dpi_prop(struct evdev_device *device)
DEFAULT_MOUSE_DPI);
dpi = DEFAULT_MOUSE_DPI;
}
+ log_info(libinput,
+ "Device '%s' set to %d DPI\n",
+ device->devname,
+ dpi);
}
return dpi;
@@ -1762,6 +1778,10 @@ evdev_configure_mt_device(struct evdev_device *device)
device->abs.absinfo_x = libevdev_get_abs_info(evdev, ABS_MT_POSITION_X);
device->abs.absinfo_y = libevdev_get_abs_info(evdev, ABS_MT_POSITION_Y);
+ device->abs.dimensions.x = abs(device->abs.absinfo_x->maximum -
+ device->abs.absinfo_x->minimum);
+ device->abs.dimensions.y = abs(device->abs.absinfo_y->maximum -
+ device->abs.absinfo_y->minimum);
device->is_mt = 1;
/* We only handle the slotted Protocol B in libinput.
@@ -1875,6 +1895,10 @@ evdev_configure_device(struct evdev_device *device)
device->abs.absinfo_y = libevdev_get_abs_info(evdev, ABS_Y);
device->abs.point.x = device->abs.absinfo_x->value;
device->abs.point.y = device->abs.absinfo_y->value;
+ device->abs.dimensions.x = abs(device->abs.absinfo_x->maximum -
+ device->abs.absinfo_x->minimum);
+ device->abs.dimensions.y = abs(device->abs.absinfo_y->maximum -
+ device->abs.absinfo_y->minimum);
if (evdev_is_fake_mt_device(device)) {
udev_tags &= ~EVDEV_UDEV_TAG_TOUCHSCREEN;
@@ -2104,6 +2128,8 @@ evdev_device_create(struct libinput_seat *seat,
device->scroll.wheel_click_angle =
evdev_read_wheel_click_prop(device);
device->model = evdev_read_model(device);
+ device->dpi = evdev_read_dpi_prop(device);
+
/* at most 5 SYN_DROPPED log-messages per 30s */
ratelimit_init(&device->syn_drop_limit, 30ULL * 1000, 5);
@@ -2114,8 +2140,6 @@ evdev_device_create(struct libinput_seat *seat,
if (evdev_configure_device(device) == -1)
goto err;
- device->dpi = evdev_read_dpi_prop(device);
-
if (device->seat_caps == 0) {
unhandled_device = 1;
goto err;
diff --git a/src/evdev.h b/src/evdev.h
index 3dddb8bf..8787d0c7 100644
--- a/src/evdev.h
+++ b/src/evdev.h
@@ -138,6 +138,8 @@ struct evdev_device {
struct matrix calibration;
struct matrix default_calibration; /* from LIBINPUT_CALIBRATION_MATRIX */
struct matrix usermatrix; /* as supplied by the caller */
+
+ struct device_coords dimensions;
} abs;
struct {
diff --git a/src/filter.c b/src/filter.c
index a4142e98..b37ca766 100644
--- a/src/filter.c
+++ b/src/filter.c
@@ -385,11 +385,14 @@ pointer_accel_profile_linear(struct motion_filter *filter,
const double max_accel = accel_filter->accel; /* unitless factor */
const double threshold = accel_filter->threshold; /* units/ms */
const double incline = accel_filter->incline;
+ double factor;
s1 = min(1, 0.3 + speed_in * 4);
s2 = 1 + (speed_in - threshold) * incline;
- return min(max_accel, s2 > 1 ? s2 : s1);
+ factor = min(max_accel, s2 > 1 ? s2 : s1);
+
+ return factor;
}
double
diff --git a/src/libinput-private.h b/src/libinput-private.h
index b687f94a..c6514c6a 100644
--- a/src/libinput-private.h
+++ b/src/libinput-private.h
@@ -121,6 +121,11 @@ struct libinput_device_config_tap {
enum libinput_config_tap_state enable);
enum libinput_config_tap_state (*get_enabled)(struct libinput_device *device);
enum libinput_config_tap_state (*get_default)(struct libinput_device *device);
+
+ enum libinput_config_status (*set_draglock_enabled)(struct libinput_device *device,
+ enum libinput_config_drag_lock_state);
+ enum libinput_config_drag_lock_state (*get_draglock_enabled)(struct libinput_device *device);
+ enum libinput_config_drag_lock_state (*get_default_draglock_enabled)(struct libinput_device *device);
};
struct libinput_device_config_calibration {
diff --git a/src/libinput-util.h b/src/libinput-util.h
index f17842e9..50edb492 100644
--- a/src/libinput-util.h
+++ b/src/libinput-util.h
@@ -95,6 +95,16 @@ int list_empty(const struct list *list);
#define NCHARS(x) ((size_t)(((x) + 7) / 8))
+#ifdef DEBUG_TRACE
+#define debug_trace(...) \
+ do { \
+ printf("%s:%d %s() - ", __FILE__, __LINE__, __func__); \
+ printf(__VA_ARGS__); \
+ } while (0)
+#else
+#define debug_trace(...) { }
+#endif
+
#define LIBINPUT_EXPORT __attribute__ ((visibility("default")))
static inline void *
diff --git a/src/libinput.c b/src/libinput.c
index 08c45e32..7f2c15d1 100644
--- a/src/libinput.c
+++ b/src/libinput.c
@@ -2116,6 +2116,39 @@ libinput_device_config_tap_get_default_enabled(struct libinput_device *device)
return device->config.tap->get_default(device);
}
+LIBINPUT_EXPORT enum libinput_config_status
+libinput_device_config_tap_set_drag_lock_enabled(struct libinput_device *device,
+ enum libinput_config_drag_lock_state enable)
+{
+ if (enable != LIBINPUT_CONFIG_DRAG_LOCK_ENABLED &&
+ enable != LIBINPUT_CONFIG_DRAG_LOCK_DISABLED)
+ return LIBINPUT_CONFIG_STATUS_INVALID;
+
+ if (libinput_device_config_tap_get_finger_count(device) == 0)
+ return enable ? LIBINPUT_CONFIG_STATUS_UNSUPPORTED :
+ LIBINPUT_CONFIG_STATUS_SUCCESS;
+
+ return device->config.tap->set_draglock_enabled(device, enable);
+}
+
+LIBINPUT_EXPORT enum libinput_config_drag_lock_state
+libinput_device_config_tap_get_drag_lock_enabled(struct libinput_device *device)
+{
+ if (libinput_device_config_tap_get_finger_count(device) == 0)
+ return LIBINPUT_CONFIG_DRAG_LOCK_DISABLED;
+
+ return device->config.tap->get_draglock_enabled(device);
+}
+
+LIBINPUT_EXPORT enum libinput_config_drag_lock_state
+libinput_device_config_tap_get_default_drag_lock_enabled(struct libinput_device *device)
+{
+ if (libinput_device_config_tap_get_finger_count(device) == 0)
+ return LIBINPUT_CONFIG_DRAG_LOCK_DISABLED;
+
+ return device->config.tap->get_default_draglock_enabled(device);
+}
+
LIBINPUT_EXPORT int
libinput_device_config_calibration_has_matrix(struct libinput_device *device)
{
diff --git a/src/libinput.h b/src/libinput.h
index ad605feb..f2bc96b4 100644
--- a/src/libinput.h
+++ b/src/libinput.h
@@ -38,6 +38,8 @@ extern "C" {
#define LIBINPUT_ATTRIBUTE_DEPRECATED __attribute__ ((deprecated))
/**
+ * @ingroup base
+ *
* Log priority for internal logging messages.
*/
enum libinput_log_priority {
@@ -2394,6 +2396,85 @@ libinput_device_config_tap_get_enabled(struct libinput_device *device);
enum libinput_config_tap_state
libinput_device_config_tap_get_default_enabled(struct libinput_device *device);
+/**
+ * @ingroup config
+ */
+enum libinput_config_drag_lock_state {
+ /** Drag lock is to be disabled, or is currently disabled */
+ LIBINPUT_CONFIG_DRAG_LOCK_DISABLED,
+ /** Drag lock is to be enabled, or is currently disabled */
+ LIBINPUT_CONFIG_DRAG_LOCK_ENABLED,
+};
+
+/**
+ * @ingroup config
+ *
+ * Enable or disable drag-lock during tapping on this device. When enabled,
+ * a finger may be lifted and put back on the touchpad within a timeout and
+ * the drag process continues. When disabled, lifting the finger during a
+ * tap-and-drag will immediately stop the drag. See @ref tapndrag for
+ * details.
+ *
+ * Enabling drag lock on a device that has tapping disabled is permitted,
+ * but has no effect until tapping is enabled.
+ *
+ * @param device The device to configure
+ * @param enable @ref LIBINPUT_CONFIG_DRAG_LOCK_ENABLED to enable drag lock
+ * or @ref LIBINPUT_CONFIG_DRAG_LOCK_DISABLED to disable drag lock
+ *
+ * @return A config status code. Disabling drag lock on a device that does not
+ * support tapping always succeeds.
+ *
+ * @see libinput_device_config_tap_get_drag_lock_enabled
+ * @see libinput_device_config_tap_get_default_drag_lock_enabled
+ */
+enum libinput_config_status
+libinput_device_config_tap_set_drag_lock_enabled(struct libinput_device *device,
+ enum libinput_config_drag_lock_state enable);
+
+/**
+ * @ingroup config
+ *
+ * Check if drag-lock during tapping is enabled on this device. If the
+ * device does not support tapping, this function always returns
+ * @ref LIBINPUT_CONFIG_DRAG_LOCK_DISABLED.
+ *
+ * Drag lock may be enabled even when tapping is disabled.
+ *
+ * @param device The device to configure
+ *
+ * @retval LIBINPUT_CONFIG_DRAG_LOCK_ENABLED If drag lock is currently enabled
+ * @retval LIBINPUT_CONFIG_DRAG_LOCK_DISABLED If drag lock is currently disabled
+ *
+ * @see libinput_device_config_tap_set_drag_lock_enabled
+ * @see libinput_device_config_tap_get_default_drag_lock_enabled
+ */
+enum libinput_config_drag_lock_state
+libinput_device_config_tap_get_drag_lock_enabled(struct libinput_device *device);
+
+/**
+ * @ingroup config
+ *
+ * Check if drag-lock during tapping is enabled by default on this device.
+ * If the device does not support tapping, this function always returns
+ * @ref LIBINPUT_CONFIG_DRAG_LOCK_DISABLED.
+ *
+ * Drag lock may be enabled by default even when tapping is disabled by
+ * default.
+ *
+ * @param device The device to configure
+ *
+ * @retval LIBINPUT_CONFIG_DRAG_LOCK_ENABLED If drag lock is enabled by
+ * default
+ * @retval LIBINPUT_CONFIG_DRAG_LOCK_DISABLED If drag lock is disabled by
+ * default
+ *
+ * @see libinput_device_config_tap_set_drag_lock_enabled
+ * @see libinput_device_config_tap_get_drag_lock_enabled
+ */
+enum libinput_config_drag_lock_state
+libinput_device_config_tap_get_default_drag_lock_enabled(struct libinput_device *device);
+
/**
* @ingroup config
*
diff --git a/src/libinput.sym b/src/libinput.sym
index 6d21877d..bc2c73e7 100644
--- a/src/libinput.sym
+++ b/src/libinput.sym
@@ -142,6 +142,12 @@ global:
libinput_device_keyboard_has_key;
} LIBINPUT_0.14.0;
+LIBINPUT_0.19.0 {
+ libinput_device_config_tap_set_drag_lock_enabled;
+ libinput_device_config_tap_get_drag_lock_enabled;
+ libinput_device_config_tap_get_default_drag_lock_enabled;
+} LIBINPUT_0.15.0;
+
/* tablet APIs, they are not part of any stable API promise yet.
* keep them separate */
LIBINPUT_TABLET_SUPPORT {
@@ -168,4 +174,4 @@ LIBINPUT_TABLET_SUPPORT {
libinput_tool_ref;
libinput_tool_set_user_data;
libinput_tool_unref;
-} LIBINPUT_0.15.0;
+} LIBINPUT_0.19.0;
diff --git a/src/path.c b/src/path.c
index 92535cda..ab4d0655 100644
--- a/src/path.c
+++ b/src/path.c
@@ -26,6 +26,7 @@
#include
#include
#include
+#include
#include
#include "path.h"
diff --git a/test/litest.h b/test/litest.h
index 50c24f13..4f65208c 100644
--- a/test/litest.h
+++ b/test/litest.h
@@ -455,4 +455,28 @@ void litest_semi_mt_touch_up(struct litest_device *d,
#define ck_assert_notnull(ptr) ck_assert_ptr_ne(ptr, NULL)
#endif
+static inline void
+litest_enable_tap(struct libinput_device *device)
+{
+ enum libinput_config_status status, expected;
+
+ expected = LIBINPUT_CONFIG_STATUS_SUCCESS;
+ status = libinput_device_config_tap_set_enabled(device,
+ LIBINPUT_CONFIG_TAP_ENABLED);
+
+ litest_assert_int_eq(status, expected);
+}
+
+static inline void
+litest_disable_tap(struct libinput_device *device)
+{
+ enum libinput_config_status status, expected;
+
+ expected = LIBINPUT_CONFIG_STATUS_SUCCESS;
+ status = libinput_device_config_tap_set_enabled(device,
+ LIBINPUT_CONFIG_TAP_DISABLED);
+
+ litest_assert_int_eq(status, expected);
+}
+
#endif /* LITEST_H */
diff --git a/test/touchpad-tap.c b/test/touchpad-tap.c
index 22079302..c021f1dc 100644
--- a/test/touchpad-tap.c
+++ b/test/touchpad-tap.c
@@ -32,14 +32,37 @@
#include "libinput-util.h"
#include "litest.h"
+static inline void
+enable_drag_lock(struct libinput_device *device)
+{
+ enum libinput_config_status status, expected;
+
+ expected = LIBINPUT_CONFIG_STATUS_SUCCESS;
+ status = libinput_device_config_tap_set_drag_lock_enabled(device,
+ LIBINPUT_CONFIG_DRAG_LOCK_ENABLED);
+
+ litest_assert_int_eq(status, expected);
+}
+
+static inline void
+disable_drag_lock(struct libinput_device *device)
+{
+ enum libinput_config_status status, expected;
+
+ expected = LIBINPUT_CONFIG_STATUS_SUCCESS;
+ status = libinput_device_config_tap_set_drag_lock_enabled(device,
+ LIBINPUT_CONFIG_DRAG_LOCK_DISABLED);
+
+ litest_assert_int_eq(status, expected);
+}
+
START_TEST(touchpad_1fg_tap)
{
struct litest_device *dev = litest_current_device();
struct libinput *li = dev->libinput;
struct libinput_event *event;
- libinput_device_config_tap_set_enabled(dev->libinput_device,
- LIBINPUT_CONFIG_TAP_ENABLED);
+ litest_enable_tap(dev->libinput_device);
litest_drain_events(li);
@@ -68,8 +91,7 @@ START_TEST(touchpad_1fg_doubletap)
struct libinput_event_pointer *ptrev;
uint32_t oldtime, curtime;
- libinput_device_config_tap_set_enabled(dev->libinput_device,
- LIBINPUT_CONFIG_TAP_ENABLED);
+ litest_enable_tap(dev->libinput_device);
litest_drain_events(li);
@@ -129,8 +151,7 @@ START_TEST(touchpad_1fg_multitap)
int range = _i, /* looped test */
ntaps;
- libinput_device_config_tap_set_enabled(dev->libinput_device,
- LIBINPUT_CONFIG_TAP_ENABLED);
+ litest_enable_tap(dev->libinput_device);
litest_drain_events(li);
@@ -178,8 +199,7 @@ START_TEST(touchpad_1fg_multitap_n_drag_move)
int range = _i, /* looped test */
ntaps;
- libinput_device_config_tap_set_enabled(dev->libinput_device,
- LIBINPUT_CONFIG_TAP_ENABLED);
+ litest_enable_tap(dev->libinput_device);
litest_drain_events(li);
@@ -245,8 +265,7 @@ START_TEST(touchpad_1fg_multitap_n_drag_2fg)
int range = _i,
ntaps;
- libinput_device_config_tap_set_enabled(dev->libinput_device,
- LIBINPUT_CONFIG_TAP_ENABLED);
+ litest_enable_tap(dev->libinput_device);
litest_drain_events(li);
@@ -317,8 +336,7 @@ START_TEST(touchpad_1fg_multitap_n_drag_click)
int range = _i, /* looped test */
ntaps;
- libinput_device_config_tap_set_enabled(dev->libinput_device,
- LIBINPUT_CONFIG_TAP_ENABLED);
+ litest_enable_tap(dev->libinput_device);
litest_drain_events(li);
@@ -378,8 +396,7 @@ START_TEST(touchpad_1fg_multitap_n_drag_timeout)
int range = _i, /* looped test */
ntaps;
- libinput_device_config_tap_set_enabled(dev->libinput_device,
- LIBINPUT_CONFIG_TAP_ENABLED);
+ litest_enable_tap(dev->libinput_device);
litest_drain_events(li);
@@ -449,8 +466,8 @@ START_TEST(touchpad_1fg_multitap_n_drag_tap)
int range = _i, /* looped test */
ntaps;
- libinput_device_config_tap_set_enabled(dev->libinput_device,
- LIBINPUT_CONFIG_TAP_ENABLED);
+ litest_enable_tap(dev->libinput_device);
+ enable_drag_lock(dev->libinput_device);
litest_drain_events(li);
@@ -522,8 +539,8 @@ START_TEST(touchpad_1fg_multitap_n_drag_tap_click)
int range = _i, /* looped test */
ntaps;
- libinput_device_config_tap_set_enabled(dev->libinput_device,
- LIBINPUT_CONFIG_TAP_ENABLED);
+ litest_enable_tap(dev->libinput_device);
+ enable_drag_lock(dev->libinput_device);
litest_drain_events(li);
@@ -600,9 +617,53 @@ START_TEST(touchpad_1fg_tap_n_drag)
{
struct litest_device *dev = litest_current_device();
struct libinput *li = dev->libinput;
+ struct libinput_event *event;
+ struct libinput_event_pointer *ptrev __attribute__((unused));
- libinput_device_config_tap_set_enabled(dev->libinput_device,
- LIBINPUT_CONFIG_TAP_ENABLED);
+ litest_enable_tap(dev->libinput_device);
+ disable_drag_lock(dev->libinput_device);
+
+ litest_drain_events(li);
+
+ litest_touch_down(dev, 0, 50, 50);
+ litest_touch_up(dev, 0);
+ litest_touch_down(dev, 0, 50, 50);
+ litest_touch_move_to(dev, 0, 50, 50, 80, 80, 5, 40);
+
+ libinput_dispatch(li);
+
+ litest_assert_button_event(li, BTN_LEFT,
+ LIBINPUT_BUTTON_STATE_PRESSED);
+
+ libinput_dispatch(li);
+
+ litest_assert_only_typed_events(li, LIBINPUT_EVENT_POINTER_MOTION);
+
+ litest_touch_up(dev, 0);
+
+ /* don't use helper functions here, we expect the event be available
+ * immediately, not after a timeout that the helper functions may
+ * trigger.
+ */
+ libinput_dispatch(li);
+ event = libinput_get_event(li);
+ ck_assert_notnull(event);
+ ptrev = litest_is_button_event(event,
+ BTN_LEFT,
+ LIBINPUT_BUTTON_STATE_RELEASED);
+ libinput_event_destroy(event);
+
+ litest_assert_empty_queue(li);
+}
+END_TEST
+
+START_TEST(touchpad_1fg_tap_n_drag_draglock)
+{
+ struct litest_device *dev = litest_current_device();
+ struct libinput *li = dev->libinput;
+
+ litest_enable_tap(dev->libinput_device);
+ enable_drag_lock(dev->libinput_device);
litest_drain_events(li);
@@ -637,13 +698,13 @@ START_TEST(touchpad_1fg_tap_n_drag)
}
END_TEST
-START_TEST(touchpad_1fg_tap_n_drag_tap)
+START_TEST(touchpad_1fg_tap_n_drag_draglock_tap)
{
struct litest_device *dev = litest_current_device();
struct libinput *li = dev->libinput;
- libinput_device_config_tap_set_enabled(dev->libinput_device,
- LIBINPUT_CONFIG_TAP_ENABLED);
+ litest_enable_tap(dev->libinput_device);
+ enable_drag_lock(dev->libinput_device);
litest_drain_events(li);
@@ -679,13 +740,13 @@ START_TEST(touchpad_1fg_tap_n_drag_tap)
}
END_TEST
-START_TEST(touchpad_1fg_tap_n_drag_tap_click)
+START_TEST(touchpad_1fg_tap_n_drag_draglock_tap_click)
{
struct litest_device *dev = litest_current_device();
struct libinput *li = dev->libinput;
- libinput_device_config_tap_set_enabled(dev->libinput_device,
- LIBINPUT_CONFIG_TAP_ENABLED);
+ litest_enable_tap(dev->libinput_device);
+ enable_drag_lock(dev->libinput_device);
litest_drain_events(li);
@@ -724,13 +785,13 @@ START_TEST(touchpad_1fg_tap_n_drag_tap_click)
}
END_TEST
-START_TEST(touchpad_1fg_tap_n_drag_timeout)
+START_TEST(touchpad_1fg_tap_n_drag_draglock_timeout)
{
struct litest_device *dev = litest_current_device();
struct libinput *li = dev->libinput;
- libinput_device_config_tap_set_enabled(dev->libinput_device,
- LIBINPUT_CONFIG_TAP_ENABLED);
+ litest_enable_tap(dev->libinput_device);
+ enable_drag_lock(dev->libinput_device);
litest_drain_events(li);
@@ -759,8 +820,8 @@ START_TEST(touchpad_2fg_tap_n_drag)
struct litest_device *dev = litest_current_device();
struct libinput *li = dev->libinput;
- libinput_device_config_tap_set_enabled(dev->libinput_device,
- LIBINPUT_CONFIG_TAP_ENABLED);
+ litest_enable_tap(dev->libinput_device);
+ disable_drag_lock(dev->libinput_device);
litest_drain_events(li);
@@ -779,7 +840,6 @@ START_TEST(touchpad_2fg_tap_n_drag)
litest_touch_up(dev, 0);
litest_touch_up(dev, 1);
- /* This will wait for the DRAGGING_WAIT timeout */
litest_assert_button_event(li, BTN_LEFT,
LIBINPUT_BUTTON_STATE_RELEASED);
@@ -796,8 +856,7 @@ START_TEST(touchpad_2fg_tap_n_drag_3fg_btntool)
ABS_MT_SLOT) > 2)
return;
- libinput_device_config_tap_set_enabled(dev->libinput_device,
- LIBINPUT_CONFIG_TAP_ENABLED);
+ litest_enable_tap(dev->libinput_device);
litest_drain_events(li);
@@ -842,8 +901,7 @@ START_TEST(touchpad_2fg_tap_n_drag_3fg)
ABS_MT_SLOT) <= 2)
return;
- libinput_device_config_tap_set_enabled(dev->libinput_device,
- LIBINPUT_CONFIG_TAP_ENABLED);
+ litest_enable_tap(dev->libinput_device);
litest_drain_events(li);
@@ -881,8 +939,7 @@ START_TEST(touchpad_2fg_tap)
struct litest_device *dev = litest_current_device();
struct libinput *li = dev->libinput;
- libinput_device_config_tap_set_enabled(dev->libinput_device,
- LIBINPUT_CONFIG_TAP_ENABLED);
+ litest_enable_tap(dev->libinput_device);
litest_drain_events(dev->libinput);
@@ -908,8 +965,7 @@ START_TEST(touchpad_2fg_tap_inverted)
struct litest_device *dev = litest_current_device();
struct libinput *li = dev->libinput;
- libinput_device_config_tap_set_enabled(dev->libinput_device,
- LIBINPUT_CONFIG_TAP_ENABLED);
+ litest_enable_tap(dev->libinput_device);
litest_drain_events(dev->libinput);
@@ -935,8 +991,7 @@ START_TEST(touchpad_2fg_tap_quickrelease)
struct litest_device *dev = litest_current_device();
struct libinput *li = dev->libinput;
- libinput_device_config_tap_set_enabled(dev->libinput_device,
- LIBINPUT_CONFIG_TAP_ENABLED);
+ litest_enable_tap(dev->libinput_device);
litest_drain_events(dev->libinput);
@@ -967,8 +1022,7 @@ START_TEST(touchpad_1fg_tap_click)
struct litest_device *dev = litest_current_device();
struct libinput *li = dev->libinput;
- libinput_device_config_tap_set_enabled(dev->libinput_device,
- LIBINPUT_CONFIG_TAP_ENABLED);
+ litest_enable_tap(dev->libinput_device);
litest_drain_events(dev->libinput);
@@ -1000,8 +1054,7 @@ START_TEST(touchpad_2fg_tap_click)
struct litest_device *dev = litest_current_device();
struct libinput *li = dev->libinput;
- libinput_device_config_tap_set_enabled(dev->libinput_device,
- LIBINPUT_CONFIG_TAP_ENABLED);
+ litest_enable_tap(dev->libinput_device);
litest_drain_events(dev->libinput);
@@ -1036,8 +1089,7 @@ START_TEST(clickpad_2fg_tap_click)
struct litest_device *dev = litest_current_device();
struct libinput *li = dev->libinput;
- libinput_device_config_tap_set_enabled(dev->libinput_device,
- LIBINPUT_CONFIG_TAP_ENABLED);
+ litest_enable_tap(dev->libinput_device);
litest_drain_events(dev->libinput);
@@ -1068,8 +1120,7 @@ START_TEST(touchpad_2fg_tap_click_apple)
struct litest_device *dev = litest_current_device();
struct libinput *li = dev->libinput;
- libinput_device_config_tap_set_enabled(dev->libinput_device,
- LIBINPUT_CONFIG_TAP_ENABLED);
+ litest_enable_tap(dev->libinput_device);
litest_drain_events(dev->libinput);
@@ -1101,8 +1152,7 @@ START_TEST(touchpad_no_2fg_tap_after_move)
struct litest_device *dev = litest_current_device();
struct libinput *li = dev->libinput;
- libinput_device_config_tap_set_enabled(dev->libinput_device,
- LIBINPUT_CONFIG_TAP_ENABLED);
+ litest_enable_tap(dev->libinput_device);
litest_drain_events(dev->libinput);
/* one finger down, move past threshold,
@@ -1125,8 +1175,7 @@ START_TEST(touchpad_no_2fg_tap_after_timeout)
struct litest_device *dev = litest_current_device();
struct libinput *li = dev->libinput;
- libinput_device_config_tap_set_enabled(dev->libinput_device,
- LIBINPUT_CONFIG_TAP_ENABLED);
+ litest_enable_tap(dev->libinput_device);
litest_drain_events(dev->libinput);
/* one finger down, wait past tap timeout,
@@ -1152,8 +1201,7 @@ START_TEST(touchpad_no_first_fg_tap_after_move)
struct libinput *li = dev->libinput;
struct libinput_event *event;
- libinput_device_config_tap_set_enabled(dev->libinput_device,
- LIBINPUT_CONFIG_TAP_ENABLED);
+ litest_enable_tap(dev->libinput_device);
litest_drain_events(dev->libinput);
@@ -1184,8 +1232,7 @@ START_TEST(touchpad_1fg_double_tap_click)
struct litest_device *dev = litest_current_device();
struct libinput *li = dev->libinput;
- libinput_device_config_tap_set_enabled(dev->libinput_device,
- LIBINPUT_CONFIG_TAP_ENABLED);
+ litest_enable_tap(dev->libinput_device);
litest_drain_events(dev->libinput);
@@ -1220,8 +1267,7 @@ START_TEST(touchpad_1fg_tap_n_drag_click)
struct litest_device *dev = litest_current_device();
struct libinput *li = dev->libinput;
- libinput_device_config_tap_set_enabled(dev->libinput_device,
- LIBINPUT_CONFIG_TAP_ENABLED);
+ litest_enable_tap(dev->libinput_device);
litest_drain_events(dev->libinput);
@@ -1269,8 +1315,7 @@ START_TEST(touchpad_3fg_tap)
ABS_MT_SLOT) <= 2)
return;
- libinput_device_config_tap_set_enabled(dev->libinput_device,
- LIBINPUT_CONFIG_TAP_ENABLED);
+ litest_enable_tap(dev->libinput_device);
for (i = 0; i < 3; i++) {
litest_drain_events(li);
@@ -1307,8 +1352,7 @@ START_TEST(touchpad_3fg_tap_quickrelease)
ABS_MT_SLOT) <= 2)
return;
- libinput_device_config_tap_set_enabled(dev->libinput_device,
- LIBINPUT_CONFIG_TAP_ENABLED);
+ litest_enable_tap(dev->libinput_device);
litest_drain_events(li);
@@ -1348,7 +1392,7 @@ START_TEST(touchpad_3fg_tap_btntool)
ABS_MT_SLOT) > 2)
return;
- libinput_device_config_tap_set_enabled(dev->libinput_device, 1);
+ litest_enable_tap(dev->libinput_device);
litest_drain_events(li);
@@ -1387,7 +1431,7 @@ START_TEST(touchpad_3fg_tap_btntool_inverted)
ABS_MT_SLOT) > 2)
return;
- libinput_device_config_tap_set_enabled(dev->libinput_device, 1);
+ litest_enable_tap(dev->libinput_device);
litest_drain_events(li);
@@ -1427,8 +1471,7 @@ START_TEST(touchpad_4fg_tap)
ABS_MT_SLOT) <= 3)
return;
- libinput_device_config_tap_set_enabled(dev->libinput_device,
- LIBINPUT_CONFIG_TAP_ENABLED);
+ litest_enable_tap(dev->libinput_device);
for (i = 0; i < 4; i++) {
litest_drain_events(li);
@@ -1462,8 +1505,7 @@ START_TEST(touchpad_4fg_tap_quickrelease)
ABS_MT_SLOT) <= 3)
return;
- libinput_device_config_tap_set_enabled(dev->libinput_device,
- LIBINPUT_CONFIG_TAP_ENABLED);
+ litest_enable_tap(dev->libinput_device);
litest_drain_events(li);
@@ -1502,8 +1544,7 @@ START_TEST(touchpad_5fg_tap)
ABS_MT_SLOT) <= 4)
return;
- libinput_device_config_tap_set_enabled(dev->libinput_device,
- LIBINPUT_CONFIG_TAP_ENABLED);
+ litest_enable_tap(dev->libinput_device);
for (i = 0; i < 5; i++) {
litest_drain_events(li);
@@ -1539,8 +1580,7 @@ START_TEST(touchpad_5fg_tap_quickrelease)
ABS_MT_SLOT) <= 4)
return;
- libinput_device_config_tap_set_enabled(dev->libinput_device,
- LIBINPUT_CONFIG_TAP_ENABLED);
+ litest_enable_tap(dev->libinput_device);
litest_drain_events(li);
@@ -1576,8 +1616,7 @@ START_TEST(clickpad_1fg_tap_click)
struct litest_device *dev = litest_current_device();
struct libinput *li = dev->libinput;
- libinput_device_config_tap_set_enabled(dev->libinput_device,
- LIBINPUT_CONFIG_TAP_ENABLED);
+ litest_enable_tap(dev->libinput_device);
litest_drain_events(dev->libinput);
@@ -1660,6 +1699,60 @@ START_TEST(touchpad_tap_invalid)
}
END_TEST
+START_TEST(touchpad_drag_lock_default_disabled)
+{
+ struct litest_device *dev = litest_current_device();
+ struct libinput_device *device = dev->libinput_device;
+ enum libinput_config_status status;
+
+ ck_assert_int_eq(libinput_device_config_tap_get_drag_lock_enabled(device),
+ LIBINPUT_CONFIG_DRAG_LOCK_DISABLED);
+ ck_assert_int_eq(libinput_device_config_tap_get_default_drag_lock_enabled(device),
+ LIBINPUT_CONFIG_DRAG_LOCK_DISABLED);
+
+ status = libinput_device_config_tap_set_drag_lock_enabled(device,
+ LIBINPUT_CONFIG_DRAG_LOCK_ENABLED);
+ ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS);
+
+ status = libinput_device_config_tap_set_drag_lock_enabled(device,
+ LIBINPUT_CONFIG_DRAG_LOCK_DISABLED);
+ ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS);
+
+ status = libinput_device_config_tap_set_drag_lock_enabled(device,
+ LIBINPUT_CONFIG_DRAG_LOCK_ENABLED);
+ ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS);
+
+ status = libinput_device_config_tap_set_drag_lock_enabled(device,
+ 3);
+ ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_INVALID);
+}
+END_TEST
+
+START_TEST(touchpad_drag_lock_default_unavailable)
+{
+ struct litest_device *dev = litest_current_device();
+ struct libinput_device *device = dev->libinput_device;
+ enum libinput_config_status status;
+
+ ck_assert_int_eq(libinput_device_config_tap_get_drag_lock_enabled(device),
+ LIBINPUT_CONFIG_DRAG_LOCK_DISABLED);
+ ck_assert_int_eq(libinput_device_config_tap_get_default_drag_lock_enabled(device),
+ LIBINPUT_CONFIG_DRAG_LOCK_DISABLED);
+
+ status = libinput_device_config_tap_set_drag_lock_enabled(device,
+ LIBINPUT_CONFIG_DRAG_LOCK_ENABLED);
+ ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_UNSUPPORTED);
+
+ status = libinput_device_config_tap_set_drag_lock_enabled(device,
+ LIBINPUT_CONFIG_DRAG_LOCK_DISABLED);
+ ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS);
+
+ status = libinput_device_config_tap_set_drag_lock_enabled(device,
+ 3);
+ ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_INVALID);
+}
+END_TEST
+
void
litest_setup_tests(void)
{
@@ -1674,8 +1767,9 @@ litest_setup_tests(void)
litest_add_ranged("touchpad:tap", touchpad_1fg_multitap_n_drag_2fg, LITEST_TOUCHPAD, LITEST_SINGLE_TOUCH, &multitap_range);
litest_add_ranged("touchpad:tap", touchpad_1fg_multitap_n_drag_click, LITEST_CLICKPAD, LITEST_ANY, &multitap_range);
litest_add("touchpad:tap", touchpad_1fg_tap_n_drag, LITEST_TOUCHPAD, LITEST_ANY);
- litest_add("touchpad:tap", touchpad_1fg_tap_n_drag_tap, LITEST_TOUCHPAD, LITEST_ANY);
- litest_add("touchpad:tap", touchpad_1fg_tap_n_drag_timeout, LITEST_TOUCHPAD, LITEST_ANY);
+ litest_add("touchpad:tap", touchpad_1fg_tap_n_drag_draglock, LITEST_TOUCHPAD, LITEST_ANY);
+ litest_add("touchpad:tap", touchpad_1fg_tap_n_drag_draglock_tap, LITEST_TOUCHPAD, LITEST_ANY);
+ litest_add("touchpad:tap", touchpad_1fg_tap_n_drag_draglock_timeout, LITEST_TOUCHPAD, LITEST_ANY);
litest_add("touchpad:tap", touchpad_2fg_tap_n_drag, LITEST_TOUCHPAD, LITEST_SINGLE_TOUCH);
litest_add("touchpad:tap", touchpad_2fg_tap_n_drag_3fg_btntool, LITEST_TOUCHPAD, LITEST_SINGLE_TOUCH|LITEST_APPLE_CLICKPAD);
litest_add("touchpad:tap", touchpad_2fg_tap_n_drag_3fg, LITEST_TOUCHPAD, LITEST_SINGLE_TOUCH);
@@ -1704,7 +1798,7 @@ litest_setup_tests(void)
litest_add("touchpad:tap", touchpad_1fg_double_tap_click, LITEST_CLICKPAD, LITEST_ANY);
litest_add("touchpad:tap", touchpad_1fg_tap_n_drag_click, LITEST_CLICKPAD, LITEST_ANY);
litest_add_ranged("touchpad:tap", touchpad_1fg_multitap_n_drag_tap_click, LITEST_CLICKPAD, LITEST_ANY, &multitap_range);
- litest_add("touchpad:tap", touchpad_1fg_tap_n_drag_tap_click, LITEST_CLICKPAD, LITEST_ANY);
+ litest_add("touchpad:tap", touchpad_1fg_tap_n_drag_draglock_tap_click, LITEST_CLICKPAD, LITEST_ANY);
litest_add("touchpad:tap", touchpad_tap_default_disabled, LITEST_TOUCHPAD|LITEST_BUTTON, LITEST_ANY);
litest_add("touchpad:tap", touchpad_tap_default_enabled, LITEST_TOUCHPAD, LITEST_BUTTON);
@@ -1715,4 +1809,7 @@ litest_setup_tests(void)
litest_add("touchpad:tap", clickpad_1fg_tap_click, LITEST_CLICKPAD, LITEST_ANY);
litest_add("touchpad:tap", clickpad_2fg_tap_click, LITEST_CLICKPAD, LITEST_SINGLE_TOUCH|LITEST_APPLE_CLICKPAD);
+ litest_add("touchpad:tap", touchpad_drag_lock_default_disabled, LITEST_TOUCHPAD, LITEST_ANY);
+ litest_add("touchpad:tap", touchpad_drag_lock_default_unavailable, LITEST_ANY, LITEST_TOUCHPAD);
+
}
diff --git a/test/touchpad.c b/test/touchpad.c
index 1179d57e..443c8c1f 100644
--- a/test/touchpad.c
+++ b/test/touchpad.c
@@ -39,8 +39,7 @@ START_TEST(touchpad_1fg_motion)
struct libinput_event *event;
struct libinput_event_pointer *ptrev;
- libinput_device_config_tap_set_enabled(dev->libinput_device,
- LIBINPUT_CONFIG_TAP_DISABLED);
+ litest_disable_tap(dev->libinput_device);
litest_drain_events(li);
@@ -683,8 +682,7 @@ START_TEST(clickpad_softbutton_left_tap_n_drag)
struct litest_device *dev = litest_current_device();
struct libinput *li = dev->libinput;
- libinput_device_config_tap_set_enabled(dev->libinput_device,
- LIBINPUT_CONFIG_TAP_ENABLED);
+ litest_enable_tap(dev->libinput_device);
litest_drain_events(li);
@@ -726,8 +724,7 @@ START_TEST(clickpad_softbutton_right_tap_n_drag)
struct litest_device *dev = litest_current_device();
struct libinput *li = dev->libinput;
- libinput_device_config_tap_set_enabled(dev->libinput_device,
- LIBINPUT_CONFIG_TAP_ENABLED);
+ litest_enable_tap(dev->libinput_device);
litest_drain_events(li);
@@ -1675,8 +1672,7 @@ START_TEST(touchpad_palm_detect_at_edge)
if (!touchpad_has_palm_detect_size(dev))
return;
- libinput_device_config_tap_set_enabled(dev->libinput_device,
- LIBINPUT_CONFIG_TAP_DISABLED);
+ litest_disable_tap(dev->libinput_device);
litest_drain_events(li);
@@ -1720,8 +1716,7 @@ START_TEST(touchpad_palm_detect_at_bottom_corners)
if (!touchpad_has_palm_detect_size(dev))
return;
- libinput_device_config_tap_set_enabled(dev->libinput_device,
- LIBINPUT_CONFIG_TAP_DISABLED);
+ litest_disable_tap(dev->libinput_device);
/* Run for non-clickpads only: make sure the bottom corners trigger
palm detection too */
@@ -1747,8 +1742,7 @@ START_TEST(touchpad_palm_detect_at_top_corners)
if (!touchpad_has_palm_detect_size(dev))
return;
- libinput_device_config_tap_set_enabled(dev->libinput_device,
- LIBINPUT_CONFIG_TAP_DISABLED);
+ litest_disable_tap(dev->libinput_device);
/* Run for non-clickpads only: make sure the bottom corners trigger
palm detection too */
@@ -1774,8 +1768,7 @@ START_TEST(touchpad_palm_detect_palm_stays_palm)
if (!touchpad_has_palm_detect_size(dev))
return;
- libinput_device_config_tap_set_enabled(dev->libinput_device,
- LIBINPUT_CONFIG_TAP_DISABLED);
+ litest_disable_tap(dev->libinput_device);
litest_drain_events(li);
@@ -1794,8 +1787,7 @@ START_TEST(touchpad_palm_detect_palm_becomes_pointer)
if (!touchpad_has_palm_detect_size(dev))
return;
- libinput_device_config_tap_set_enabled(dev->libinput_device,
- LIBINPUT_CONFIG_TAP_DISABLED);
+ litest_disable_tap(dev->libinput_device);
litest_drain_events(li);
@@ -1819,8 +1811,7 @@ START_TEST(touchpad_palm_detect_no_palm_moving_into_edges)
if (!touchpad_has_palm_detect_size(dev))
return;
- libinput_device_config_tap_set_enabled(dev->libinput_device,
- LIBINPUT_CONFIG_TAP_DISABLED);
+ litest_disable_tap(dev->libinput_device);
/* moving non-palm into the edge does not label it as palm */
litest_drain_events(li);
@@ -1849,8 +1840,7 @@ START_TEST(touchpad_palm_detect_tap)
if (!touchpad_has_palm_detect_size(dev))
return;
- libinput_device_config_tap_set_enabled(dev->libinput_device,
- LIBINPUT_CONFIG_TAP_ENABLED);
+ litest_enable_tap(dev->libinput_device);
litest_drain_events(li);
@@ -2028,8 +2018,8 @@ START_TEST(touchpad_left_handed_tapping)
struct libinput *li = dev->libinput;
enum libinput_config_status status;
- libinput_device_config_tap_set_enabled(dev->libinput_device,
- LIBINPUT_CONFIG_TAP_ENABLED);
+ litest_enable_tap(dev->libinput_device);
+
status = libinput_device_config_left_handed_set(d, 1);
ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS);
@@ -2059,8 +2049,8 @@ START_TEST(touchpad_left_handed_tapping_2fg)
struct libinput *li = dev->libinput;
enum libinput_config_status status;
- libinput_device_config_tap_set_enabled(dev->libinput_device,
- LIBINPUT_CONFIG_TAP_ENABLED);
+ litest_enable_tap(dev->libinput_device);
+
status = libinput_device_config_left_handed_set(d, 1);
ck_assert_int_eq(status, LIBINPUT_CONFIG_STATUS_SUCCESS);
@@ -3022,8 +3012,7 @@ START_TEST(touchpad_initial_state)
dev = litest_current_device();
libinput1 = dev->libinput;
- libinput_device_config_tap_set_enabled(dev->libinput_device,
- LIBINPUT_CONFIG_TAP_DISABLED);
+ litest_disable_tap(dev->libinput_device);
litest_touch_down(dev, 0, x, y);
litest_touch_up(dev, 0);
@@ -3088,8 +3077,7 @@ START_TEST(touchpad_dwt)
return;
keyboard = litest_add_device(li, LITEST_KEYBOARD);
- libinput_device_config_tap_set_enabled(touchpad->libinput_device,
- LIBINPUT_CONFIG_TAP_DISABLED);
+ litest_disable_tap(touchpad->libinput_device);
litest_drain_events(li);
litest_keyboard_key(keyboard, KEY_A, true);
@@ -3131,8 +3119,7 @@ START_TEST(touchpad_dwt_enable_touch)
return;
keyboard = litest_add_device(li, LITEST_KEYBOARD);
- libinput_device_config_tap_set_enabled(touchpad->libinput_device,
- LIBINPUT_CONFIG_TAP_DISABLED);
+ litest_disable_tap(touchpad->libinput_device);
litest_drain_events(li);
litest_keyboard_key(keyboard, KEY_A, true);
@@ -3170,8 +3157,7 @@ START_TEST(touchpad_dwt_touch_hold)
return;
keyboard = litest_add_device(li, LITEST_KEYBOARD);
- libinput_device_config_tap_set_enabled(touchpad->libinput_device,
- LIBINPUT_CONFIG_TAP_DISABLED);
+ litest_disable_tap(touchpad->libinput_device);
litest_drain_events(li);
litest_keyboard_key(keyboard, KEY_A, true);
@@ -3208,8 +3194,7 @@ START_TEST(touchpad_dwt_key_hold)
return;
keyboard = litest_add_device(li, LITEST_KEYBOARD);
- libinput_device_config_tap_set_enabled(touchpad->libinput_device,
- LIBINPUT_CONFIG_TAP_DISABLED);
+ litest_disable_tap(touchpad->libinput_device);
litest_drain_events(li);
litest_keyboard_key(keyboard, KEY_A, true);
@@ -3237,8 +3222,7 @@ START_TEST(touchpad_dwt_type)
return;
keyboard = litest_add_device(li, LITEST_KEYBOARD);
- libinput_device_config_tap_set_enabled(touchpad->libinput_device,
- LIBINPUT_CONFIG_TAP_DISABLED);
+ litest_disable_tap(touchpad->libinput_device);
litest_drain_events(li);
for (i = 0; i < 5; i++) {
@@ -3276,8 +3260,7 @@ START_TEST(touchpad_dwt_type_short_timeout)
return;
keyboard = litest_add_device(li, LITEST_KEYBOARD);
- libinput_device_config_tap_set_enabled(touchpad->libinput_device,
- LIBINPUT_CONFIG_TAP_DISABLED);
+ litest_disable_tap(touchpad->libinput_device);
litest_drain_events(li);
for (i = 0; i < 5; i++) {
@@ -3314,8 +3297,7 @@ START_TEST(touchpad_dwt_tap)
return;
keyboard = litest_add_device(li, LITEST_KEYBOARD);
- libinput_device_config_tap_set_enabled(touchpad->libinput_device,
- LIBINPUT_CONFIG_TAP_ENABLED);
+ litest_enable_tap(touchpad->libinput_device);
litest_drain_events(li);
litest_keyboard_key(keyboard, KEY_A, true);
@@ -3345,8 +3327,7 @@ START_TEST(touchpad_dwt_tap_drag)
return;
keyboard = litest_add_device(li, LITEST_KEYBOARD);
- libinput_device_config_tap_set_enabled(touchpad->libinput_device,
- LIBINPUT_CONFIG_TAP_ENABLED);
+ litest_enable_tap(touchpad->libinput_device);
litest_drain_events(li);
litest_keyboard_key(keyboard, KEY_A, true);
@@ -3380,8 +3361,7 @@ START_TEST(touchpad_dwt_click)
return;
keyboard = litest_add_device(li, LITEST_KEYBOARD);
- libinput_device_config_tap_set_enabled(touchpad->libinput_device,
- LIBINPUT_CONFIG_TAP_DISABLED);
+ litest_disable_tap(touchpad->libinput_device);
litest_drain_events(li);
litest_keyboard_key(keyboard, KEY_A, true);
diff --git a/tools/event-debug.c b/tools/event-debug.c
index 0655a96d..834a3247 100644
--- a/tools/event-debug.c
+++ b/tools/event-debug.c
@@ -42,27 +42,9 @@
uint32_t start_time;
static const uint32_t screen_width = 100;
static const uint32_t screen_height = 100;
-struct tools_options options;
+struct tools_context context;
static unsigned int stop = 0;
-static int
-open_restricted(const char *path, int flags, void *user_data)
-{
- int fd = open(path, flags);
- return fd < 0 ? -errno : fd;
-}
-
-static void
-close_restricted(int fd, void *user_data)
-{
- close(fd);
-}
-
-static const struct libinput_interface interface = {
- .open_restricted = open_restricted,
- .close_restricted = close_restricted,
-};
-
static void
print_event_header(struct libinput_event *ev)
{
@@ -169,8 +151,13 @@ print_device_notify(struct libinput_event *ev)
if (libinput_device_get_size(dev, &w, &h) == 0)
printf("\tsize %.2f/%.2fmm", w, h);
- if (libinput_device_config_tap_get_finger_count(dev))
+ if (libinput_device_config_tap_get_finger_count(dev)) {
printf(" tap");
+ if (libinput_device_config_tap_get_drag_lock_enabled(dev))
+ printf("(dl on)");
+ else
+ printf("(dl off)");
+ }
if (libinput_device_config_left_handed_is_available(dev))
printf(" left");
if (libinput_device_config_scroll_has_natural_scroll(dev))
@@ -547,7 +534,7 @@ handle_and_print_events(struct libinput *li)
case LIBINPUT_EVENT_DEVICE_REMOVED:
print_device_notify(ev);
tools_device_apply_config(libinput_event_get_device(ev),
- &options);
+ &context.options);
break;
case LIBINPUT_EVENT_KEYBOARD_KEY:
print_key_event(ev);
@@ -638,18 +625,18 @@ main(int argc, char **argv)
struct libinput *li;
struct timespec tp;
- clock_gettime(CLOCK_MONOTONIC, &tp);
- start_time = tp.tv_sec * 1000 + tp.tv_nsec / 1000000;
+ tools_init_context(&context);
- tools_init_options(&options);
-
- if (tools_parse_args(argc, argv, &options))
+ if (tools_parse_args(argc, argv, &context))
return 1;
- li = tools_open_backend(&options, NULL, &interface);
+ li = tools_open_backend(&context);
if (!li)
return 1;
+ clock_gettime(CLOCK_MONOTONIC, &tp);
+ start_time = tp.tv_sec * 1000 + tp.tv_nsec / 1000000;
+
mainloop(li);
libinput_unref(li);
diff --git a/tools/event-gui.c b/tools/event-gui.c
index 697bf9f1..6c9cf03f 100644
--- a/tools/event-gui.c
+++ b/tools/event-gui.c
@@ -44,7 +44,7 @@
#define clip(val_, min_, max_) min((max_), max((min_), (val_)))
-struct tools_options options;
+struct tools_context context;
struct touch {
int active;
@@ -264,6 +264,7 @@ change_ptraccel(struct window *w, double amount)
static void
handle_event_device_notify(struct libinput_event *ev)
{
+ struct tools_context *context;
struct libinput_device *dev = libinput_event_get_device(ev);
struct libinput *li;
struct window *w;
@@ -280,11 +281,12 @@ handle_event_device_notify(struct libinput_event *ev)
libinput_device_get_name(dev),
type);
- tools_device_apply_config(libinput_event_get_device(ev),
- &options);
-
li = libinput_event_get_context(ev);
- w = libinput_get_user_data(li);
+ context = libinput_get_user_data(li);
+ w = context->user_data;
+
+ tools_device_apply_config(libinput_event_get_device(ev),
+ &context->options);
if (libinput_event_get_type(ev) == LIBINPUT_EVENT_DEVICE_ADDED) {
for (i = 0; i < ARRAY_LENGTH(w->devices); i++) {
@@ -430,7 +432,8 @@ static gboolean
handle_event_libinput(GIOChannel *source, GIOCondition condition, gpointer data)
{
struct libinput *li = data;
- struct window *w = libinput_get_user_data(li);
+ struct tools_context *context = libinput_get_user_data(li);
+ struct window *w = context->user_data;
struct libinput_event *ev;
libinput_dispatch(li);
@@ -493,24 +496,6 @@ sockets_init(struct libinput *li)
g_io_add_watch(c, G_IO_IN, handle_event_libinput, li);
}
-static int
-open_restricted(const char *path, int flags, void *user_data)
-{
- int fd = open(path, flags);
- return fd < 0 ? -errno : fd;
-}
-
-static void
-close_restricted(int fd, void *user_data)
-{
- close(fd);
-}
-
-static const struct libinput_interface interface = {
- .open_restricted = open_restricted,
- .close_restricted = close_restricted,
-};
-
int
main(int argc, char *argv[])
{
@@ -520,16 +505,17 @@ main(int argc, char *argv[])
gtk_init(&argc, &argv);
- tools_init_options(&options);
+ tools_init_context(&context);
- if (tools_parse_args(argc, argv, &options) != 0)
+ if (tools_parse_args(argc, argv, &context) != 0)
return 1;
udev = udev_new();
if (!udev)
error("Failed to initialize udev\n");
- li = tools_open_backend(&options, &w, &interface);
+ context.user_data = &w;
+ li = tools_open_backend(&context);
if (!li)
return 1;
diff --git a/tools/libinput-list-devices.c b/tools/libinput-list-devices.c
index d76e5db5..6d162e2f 100644
--- a/tools/libinput-list-devices.c
+++ b/tools/libinput-list-devices.c
@@ -23,7 +23,6 @@
#define _GNU_SOURCE
#include
-#include
#include
#include
#include
@@ -36,27 +35,6 @@
#include "shared.h"
-static int
-open_restricted(const char *path, int flags, void *user_data)
-{
- int fd = open(path, flags);
- if (fd < 0)
- fprintf(stderr, "Failed to open %s (%s)\n",
- path, strerror(errno));
- return fd < 0 ? -errno : fd;
-}
-
-static void
-close_restricted(int fd, void *user_data)
-{
- close(fd);
-}
-
-static const struct libinput_interface interface = {
- .open_restricted = open_restricted,
- .close_restricted = close_restricted,
-};
-
static inline const char*
bool_to_str(bool b)
{
@@ -78,6 +56,18 @@ tap_default(struct libinput_device *device)
return "disabled";
}
+static const char *
+draglock_default(struct libinput_device *device)
+{
+ if (!libinput_device_config_tap_get_finger_count(device))
+ return "n/a";
+
+ if (libinput_device_config_tap_get_default_drag_lock_enabled(device))
+ return "enabled";
+ else
+ return "disabled";
+}
+
static const char*
left_handed_default(struct libinput_device *device)
{
@@ -238,6 +228,7 @@ print_device_notify(struct libinput_event *ev)
printf("\n");
printf("Tap-to-click: %s\n", tap_default(dev));
+ printf("Tap drag lock: %s\n", draglock_default(dev));
printf("Left-handed: %s\n", left_handed_default(dev));
printf("Nat.scrolling: %s\n", nat_scroll_default(dev));
printf("Middle emulation: %s\n", middle_emulation_default(dev));
@@ -277,7 +268,7 @@ int
main(int argc, char **argv)
{
struct libinput *li;
- struct tools_options options;
+ struct tools_context context;
struct libinput_event *ev;
if (argc > 1) {
@@ -293,9 +284,9 @@ main(int argc, char **argv)
}
}
- tools_init_options(&options);
+ tools_init_context(&context);
- li = tools_open_backend(&options, NULL, &interface);
+ li = tools_open_backend(&context);
if (!li)
return 1;
diff --git a/tools/ptraccel-debug.c b/tools/ptraccel-debug.c
index 8b800ee1..c774e3bf 100644
--- a/tools/ptraccel-debug.c
+++ b/tools/ptraccel-debug.c
@@ -95,7 +95,7 @@ print_ptraccel_movement(struct motion_filter *filter,
motion.y = 0;
time += 12; /* pretend 80Hz data */
- filter_dispatch(filter, &motion, NULL, time);
+ motion = filter_dispatch(filter, &motion, NULL, time);
printf("%d %.3f %.3f\n", i, motion.x, dx);
@@ -129,7 +129,7 @@ print_ptraccel_sequence(struct motion_filter *filter,
motion.y = 0;
time += 12; /* pretend 80Hz data */
- filter_dispatch(filter, &motion, NULL, time);
+ motion = filter_dispatch(filter, &motion, NULL, time);
printf("%d %.3f %.3f\n", i, motion.x, *dx);
}
@@ -165,9 +165,9 @@ usage(void)
" delta ... print delta to accelerated delta\n"
" accel ... print accel factor\n"
" sequence ... print motion for custom delta sequence\n"
- "--maxdx=\n ... in motion mode only. Stop increasing dx at maxdx\n"
- "--steps=\n ... in motion and delta modes only. Increase dx by step each round\n"
- "--speed=\n ... accel speed [-1, 1], default 0\n"
+ "--maxdx= ... in motion mode only. Stop increasing dx at maxdx\n"
+ "--steps= ... in motion and delta modes only. Increase dx by step each round\n"
+ "--speed= ... accel speed [-1, 1], default 0\n"
"\n"
"If extra arguments are present and mode is not given, mode defaults to 'sequence'\n"
"and the arguments are interpreted as sequence of delta x coordinates\n"
diff --git a/tools/shared.c b/tools/shared.c
index 1858c93f..64544c5c 100644
--- a/tools/shared.c
+++ b/tools/shared.c
@@ -25,6 +25,7 @@
#include
#include
+#include
#include
#include
#include
@@ -39,10 +40,13 @@
enum options {
OPT_DEVICE,
OPT_UDEV,
+ OPT_GRAB,
OPT_HELP,
OPT_VERBOSE,
OPT_TAP_ENABLE,
OPT_TAP_DISABLE,
+ OPT_DRAG_LOCK_ENABLE,
+ OPT_DRAG_LOCK_DISABLE,
OPT_NATURAL_SCROLL_ENABLE,
OPT_NATURAL_SCROLL_DISABLE,
OPT_LEFT_HANDED_ENABLE,
@@ -75,6 +79,8 @@ tools_usage()
"Features:\n"
"--enable-tap\n"
"--disable-tap.... enable/disable tapping\n"
+ "--enable-drag-lock\n"
+ "--disable-drag-lock.... enable/disable tapping drag lock\n"
"--enable-natural-scrolling\n"
"--disable-natural-scrolling.... enable/disable natural scrolling\n"
"--enable-left-handed\n"
@@ -90,16 +96,22 @@ tools_usage()
"is not explicitly specified it is left at each device's default.\n"
"\n"
"Other options:\n"
+ "--grab .......... Exclusively grab all openend devices\n"
"--verbose ....... Print debugging output.\n"
"--help .......... Print this help.\n",
program_invocation_short_name);
}
void
-tools_init_options(struct tools_options *options)
+tools_init_context(struct tools_context *context)
{
+ struct tools_options *options = &context->options;
+
+ context->user_data = NULL;
+
memset(options, 0, sizeof(*options));
options->tapping = -1;
+ options->drag_lock = -1;
options->natural_scroll = -1;
options->left_handed = -1;
options->middlebutton = -1;
@@ -112,18 +124,23 @@ tools_init_options(struct tools_options *options)
}
int
-tools_parse_args(int argc, char **argv, struct tools_options *options)
+tools_parse_args(int argc, char **argv, struct tools_context *context)
{
+ struct tools_options *options = &context->options;
+
while (1) {
int c;
int option_index = 0;
static struct option opts[] = {
{ "device", 1, 0, OPT_DEVICE },
{ "udev", 0, 0, OPT_UDEV },
+ { "grab", 0, 0, OPT_GRAB },
{ "help", 0, 0, OPT_HELP },
{ "verbose", 0, 0, OPT_VERBOSE },
{ "enable-tap", 0, 0, OPT_TAP_ENABLE },
{ "disable-tap", 0, 0, OPT_TAP_DISABLE },
+ { "enable-drag-lock", 0, 0, OPT_DRAG_LOCK_ENABLE },
+ { "disable-drag-lock", 0, 0, OPT_DRAG_LOCK_DISABLE },
{ "enable-natural-scrolling", 0, 0, OPT_NATURAL_SCROLL_ENABLE },
{ "disable-natural-scrolling", 0, 0, OPT_NATURAL_SCROLL_DISABLE },
{ "enable-left-handed", 0, 0, OPT_LEFT_HANDED_ENABLE },
@@ -142,11 +159,11 @@ tools_parse_args(int argc, char **argv, struct tools_options *options)
break;
switch(c) {
- case 'h': /* --help */
+ case 'h':
case OPT_HELP:
tools_usage();
exit(0);
- case OPT_DEVICE: /* --device */
+ case OPT_DEVICE:
options->backend = BACKEND_DEVICE;
if (!optarg) {
tools_usage();
@@ -154,12 +171,15 @@ tools_parse_args(int argc, char **argv, struct tools_options *options)
}
options->device = optarg;
break;
- case OPT_UDEV: /* --udev */
+ case OPT_UDEV:
options->backend = BACKEND_UDEV;
if (optarg)
options->seat = optarg;
break;
- case OPT_VERBOSE: /* --verbose */
+ case OPT_GRAB:
+ options->grab = 1;
+ break;
+ case OPT_VERBOSE:
options->verbose = 1;
break;
case OPT_TAP_ENABLE:
@@ -168,6 +188,12 @@ tools_parse_args(int argc, char **argv, struct tools_options *options)
case OPT_TAP_DISABLE:
options->tapping = 0;
break;
+ case OPT_DRAG_LOCK_ENABLE:
+ options->drag_lock = 1;
+ break;
+ case OPT_DRAG_LOCK_DISABLE:
+ options->drag_lock = 0;
+ break;
case OPT_NATURAL_SCROLL_ENABLE:
options->natural_scroll = 1;
break;
@@ -331,17 +357,44 @@ open_device(const struct libinput_interface *interface,
return li;
}
+static int
+open_restricted(const char *path, int flags, void *user_data)
+{
+ const struct tools_context *context = user_data;
+ int fd = open(path, flags);
+
+ if (fd < 0)
+ fprintf(stderr, "Failed to open %s (%s)\n",
+ path, strerror(errno));
+ else if (context->options.grab &&
+ ioctl(fd, EVIOCGRAB, (void*)1) == -1)
+ fprintf(stderr, "Grab requested, but failed for %s (%s)\n",
+ path, strerror(errno));
+
+ return fd < 0 ? -errno : fd;
+}
+
+static void
+close_restricted(int fd, void *user_data)
+{
+ close(fd);
+}
+
+static const struct libinput_interface interface = {
+ .open_restricted = open_restricted,
+ .close_restricted = close_restricted,
+};
+
struct libinput *
-tools_open_backend(struct tools_options *options,
- void *userdata,
- const struct libinput_interface *interface)
+tools_open_backend(struct tools_context *context)
{
struct libinput *li = NULL;
+ struct tools_options *options = &context->options;
if (options->backend == BACKEND_UDEV) {
- li = open_udev(interface, userdata, options->seat, options->verbose);
+ li = open_udev(&interface, context, options->seat, options->verbose);
} else if (options->backend == BACKEND_DEVICE) {
- li = open_device(interface, userdata, options->device, options->verbose);
+ li = open_device(&interface, context, options->device, options->verbose);
} else
abort();
@@ -354,6 +407,9 @@ tools_device_apply_config(struct libinput_device *device,
{
if (options->tapping != -1)
libinput_device_config_tap_set_enabled(device, options->tapping);
+ if (options->drag_lock != -1)
+ libinput_device_config_tap_set_drag_lock_enabled(device,
+ options->drag_lock);
if (options->natural_scroll != -1)
libinput_device_config_scroll_set_natural_scroll_enabled(device,
options->natural_scroll);
diff --git a/tools/shared.h b/tools/shared.h
index 3ce2e1ca..a848e2d1 100644
--- a/tools/shared.h
+++ b/tools/shared.h
@@ -35,9 +35,11 @@ struct tools_options {
enum tools_backend backend;
const char *device; /* if backend is BACKEND_DEVICE */
const char *seat; /* if backend is BACKEND_UDEV */
+ int grab; /* EVIOCGRAB */
int verbose;
int tapping;
+ int drag_lock;
int natural_scroll;
int left_handed;
int middlebutton;
@@ -47,11 +49,14 @@ struct tools_options {
double speed;
};
-void tools_init_options(struct tools_options *options);
-int tools_parse_args(int argc, char **argv, struct tools_options *options);
-struct libinput* tools_open_backend(struct tools_options *options,
- void *userdata,
- const struct libinput_interface *interface);
+struct tools_context {
+ struct tools_options options;
+ void *user_data;
+};
+
+void tools_init_context(struct tools_context *context);
+int tools_parse_args(int argc, char **argv, struct tools_context *context);
+struct libinput* tools_open_backend(struct tools_context *context);
void tools_device_apply_config(struct libinput_device *device,
struct tools_options *options);
void tools_usage();
diff --git a/udev/libinput-device-group.c b/udev/libinput-device-group.c
index 50bfbe02..adbd6b7f 100644
--- a/udev/libinput-device-group.c
+++ b/udev/libinput-device-group.c
@@ -10,8 +10,9 @@ int main(int argc, char **argv)
struct udev_device *device = NULL;
const char *syspath,
*phys = NULL;
- char *group,
- *str;
+ const char *product;
+ char group[1024];
+ char *str;
if (argc != 2)
return 1;
@@ -45,9 +46,12 @@ int main(int argc, char **argv)
if (!phys)
goto out;
- group = strdup(phys);
- if (!group)
- goto out;
+ /* udev sets PRODUCT on the same device we find PHYS on, let's rely
+ on that*/
+ product = udev_device_get_property_value(device, "PRODUCT");
+ if (!product)
+ product = "";
+ snprintf(group, sizeof(group), "%s:%s", product, phys);
str = strstr(group, "/input");
if (str)
@@ -64,7 +68,6 @@ int main(int argc, char **argv)
*str = '\0';
printf("%s\n", group);
- free(group);
rc = 0;
out: