diff --git a/Cargo.toml b/Cargo.toml
index fa7164e97e..a4f98ca71a 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -73,7 +73,7 @@ fastrand = "2.4.1"
futures-util = { version = "0.3.32", default-features = false, features = ["std", "io"] }
git-version = "0.3.9"
glam = "0.32.1"
-input = { version = "0.10.0", features = ["libinput_1_21"] }
+input = { version = "0.10.0", features = ["libinput_1_27"] }
keyframe = { version = "1.1.1", default-features = false }
libc = "0.2.185"
libdisplay-info = "0.3.0"
diff --git a/docs/wiki/Configuration:-Input.md b/docs/wiki/Configuration:-Input.md
index 62f70b5a42..ab3305a6cb 100644
--- a/docs/wiki/Configuration:-Input.md
+++ b/docs/wiki/Configuration:-Input.md
@@ -32,7 +32,8 @@ input {
// dwt
// dwtp
// drag false
- // drag-lock
+ // drag-lock // timeout mode
+ // drag-lock "sticky" // sticky mode
natural-scroll
// accel-speed 0.2
// accel-profile "flat"
@@ -247,7 +248,10 @@ Settings specific to `touchpad`s:
- `dwt`: disable-when-typing.
- `dwtp`: disable-when-trackpointing.
- `drag`: Since: 25.05 can be `true` or `false`, controls if tap-and-drag is enabled.
-- `drag-lock`: Since: 25.02 if set, lifting the finger off for a short time while dragging will not drop the dragged item. See the [libinput documentation](https://wayland.freedesktop.org/libinput/doc/latest/tapping.html#tap-and-drag).
+- `drag-lock`: Since: 25.02, explicit modes next release controls drag lock behavior. Can be set as a flag (`drag-lock`), or with an explicit mode (`drag-lock "timeout"` or `drag-lock "sticky"`).
+ - `"timeout"` (default when set as a flag): lifting the finger off for a short time while dragging will not drop the dragged item.
+ - `"sticky"`: the drag continues until you tap again to release.
+ - See the [libinput documentation](https://wayland.freedesktop.org/libinput/doc/latest/tapping.html#tap-and-drag).
- `tap-button-map`: can be `left-right-middle` or `left-middle-right`, controls which button corresponds to a two-finger tap and a three-finger tap.
- `click-method`: can be `button-areas` or `clickfinger`, changes the [click method](https://wayland.freedesktop.org/libinput/doc/latest/clickpad-softbuttons.html).
- `disabled-on-external-mouse`: do not send events while external pointer device is plugged in.
diff --git a/niri-config/src/input.rs b/niri-config/src/input.rs
index dceb5c6ca8..43e88c5e14 100644
--- a/niri-config/src/input.rs
+++ b/niri-config/src/input.rs
@@ -195,8 +195,8 @@ pub struct Touchpad {
pub dwtp: bool,
#[knuffel(child, unwrap(argument))]
pub drag: Option,
- #[knuffel(child)]
- pub drag_lock: bool,
+ #[knuffel(child, unwrap(argument, str, default))]
+ pub drag_lock: Option,
#[knuffel(child)]
pub natural_scroll: bool,
#[knuffel(child, unwrap(argument, str))]
@@ -291,6 +291,26 @@ pub struct Trackball {
pub middle_emulation: bool,
}
+#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
+pub enum DragLock {
+ #[default]
+ Timeout,
+ Sticky,
+}
+
+impl FromStr for DragLock {
+ type Err = miette::Error;
+ fn from_str(s: &str) -> Result {
+ match s {
+ "timeout" => Ok(DragLock::Timeout),
+ "sticky" => Ok(DragLock::Sticky),
+ _ => Err(miette!(
+ r#"invalid drag-lock value, expected \"timeout\" or \"sticky\""#
+ )),
+ }
+ }
+}
+
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ClickMethod {
Clickfinger,
diff --git a/niri-config/src/lib.rs b/niri-config/src/lib.rs
index 329b76696d..f4ed36357d 100644
--- a/niri-config/src/lib.rs
+++ b/niri-config/src/lib.rs
@@ -856,7 +856,7 @@ mod tests {
window-open { off; }
window-close {
- curve "cubic-bezier" 0.05 0.7 0.1 1
+ curve "cubic-bezier" 0.05 0.7 0.1 1
}
recent-windows-close {
@@ -993,7 +993,7 @@ mod tests {
drag: Some(
true,
),
- drag_lock: false,
+ drag_lock: None,
natural_scroll: false,
click_method: Some(
Clickfinger,
diff --git a/resources/default-config.kdl b/resources/default-config.kdl
index ccad1ac22e..1a31995fad 100644
--- a/resources/default-config.kdl
+++ b/resources/default-config.kdl
@@ -34,7 +34,8 @@ input {
// dwt
// dwtp
// drag false
- // drag-lock
+ // drag-lock // timeout mode
+ // drag-lock "sticky" // sticky mode
natural-scroll
// accel-speed 0.2
// accel-profile "flat"
diff --git a/src/input/mod.rs b/src/input/mod.rs
index f1ad49320f..93572c8674 100644
--- a/src/input/mod.rs
+++ b/src/input/mod.rs
@@ -4686,10 +4686,10 @@ pub fn apply_libinput_settings(config: &niri_config::Input, device: &mut input::
let _ = device.config_tap_set_enabled(c.tap);
let _ = device.config_dwt_set_enabled(c.dwt);
let _ = device.config_dwtp_set_enabled(c.dwtp);
- let _ = device.config_tap_set_drag_lock_enabled(if c.drag_lock {
- input::DragLockState::EnabledTimeout
- } else {
- input::DragLockState::Disabled
+ let _ = device.config_tap_set_drag_lock_enabled(match c.drag_lock {
+ Some(niri_config::input::DragLock::Timeout) => input::DragLockState::EnabledTimeout,
+ Some(niri_config::input::DragLock::Sticky) => input::DragLockState::EnabledSticky,
+ None => input::DragLockState::Disabled,
});
let _ = device.config_scroll_set_natural_scroll_enabled(c.natural_scroll);
let _ = device.config_accel_set_speed(c.accel_speed.0);