aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorIvan Molodetskikh <yalterz@gmail.com>2024-03-23 20:23:21 +0400
committerIvan Molodetskikh <yalterz@gmail.com>2024-03-23 20:30:45 +0400
commita16a0f0e52d6df8abd602baa15cee44e0656d790 (patch)
tree821c7c4a71975dd5b23e8b4d0ddd4f12465b0c0c /src
parent6ba195211bf60c3b753e4167b047b055dd5c129d (diff)
downloadniri-a16a0f0e52d6df8abd602baa15cee44e0656d790.tar.gz
niri-a16a0f0e52d6df8abd602baa15cee44e0656d790.tar.bz2
niri-a16a0f0e52d6df8abd602baa15cee44e0656d790.zip
Implement TouchpadScroll binds
Diffstat (limited to 'src')
-rw-r--r--src/input.rs90
-rw-r--r--src/niri.rs16
-rw-r--r--src/ui/hotkey_overlay.rs6
3 files changed, 109 insertions, 3 deletions
diff --git a/src/input.rs b/src/input.rs
index 850fb76a..a47f9151 100644
--- a/src/input.rs
+++ b/src/input.rs
@@ -1178,11 +1178,84 @@ impl State {
}
}
- let horizontal_amount = event.amount(Axis::Horizontal).unwrap_or_else(|| {
+ let horizontal_amount = event.amount(Axis::Horizontal);
+ let vertical_amount = event.amount(Axis::Vertical);
+
+ // Handle touchpad scroll bindings.
+ if source == AxisSource::Finger {
+ let mods = self.niri.seat.get_keyboard().unwrap().modifier_state();
+ let modifiers = modifiers_from_state(mods);
+ if self.niri.mods_with_finger_scroll_binds.contains(&modifiers) {
+ let comp_mod = self.backend.mod_key();
+
+ let horizontal = horizontal_amount.unwrap_or(0.);
+ let ticks = self
+ .niri
+ .horizontal_finger_scroll_tracker
+ .accumulate(horizontal);
+ if ticks != 0 {
+ let config = self.niri.config.borrow();
+ let bindings = &config.binds;
+ let bind_left =
+ find_configured_bind(bindings, comp_mod, Trigger::TouchpadScrollLeft, mods);
+ let bind_right = find_configured_bind(
+ bindings,
+ comp_mod,
+ Trigger::TouchpadScrollRight,
+ mods,
+ );
+ drop(config);
+
+ if let Some(right) = bind_right {
+ for _ in 0..ticks {
+ self.handle_bind(right.clone());
+ }
+ }
+ if let Some(left) = bind_left {
+ for _ in ticks..0 {
+ self.handle_bind(left.clone());
+ }
+ }
+ }
+
+ let vertical = vertical_amount.unwrap_or(0.);
+ let ticks = self
+ .niri
+ .vertical_finger_scroll_tracker
+ .accumulate(vertical);
+ if ticks != 0 {
+ let config = self.niri.config.borrow();
+ let bindings = &config.binds;
+ let bind_up =
+ find_configured_bind(bindings, comp_mod, Trigger::TouchpadScrollUp, mods);
+ let bind_down =
+ find_configured_bind(bindings, comp_mod, Trigger::TouchpadScrollDown, mods);
+ drop(config);
+
+ if let Some(down) = bind_down {
+ for _ in 0..ticks {
+ self.handle_bind(down.clone());
+ }
+ }
+ if let Some(up) = bind_up {
+ for _ in ticks..0 {
+ self.handle_bind(up.clone());
+ }
+ }
+ }
+
+ return;
+ } else {
+ self.niri.horizontal_finger_scroll_tracker.reset();
+ self.niri.vertical_finger_scroll_tracker.reset();
+ }
+ }
+
+ let horizontal_amount = horizontal_amount.unwrap_or_else(|| {
// Winit backend, discrete scrolling.
horizontal_amount_v120.unwrap_or(0.0) / 120. * 15.
});
- let vertical_amount = event.amount(Axis::Vertical).unwrap_or_else(|| {
+ let vertical_amount = vertical_amount.unwrap_or_else(|| {
// Winit backend, discrete scrolling.
vertical_amount_v120.unwrap_or(0.0) / 120. * 15.
});
@@ -2067,6 +2140,19 @@ pub fn mods_with_wheel_binds(comp_mod: CompositorMod, binds: &Binds) -> HashSet<
)
}
+pub fn mods_with_finger_scroll_binds(comp_mod: CompositorMod, binds: &Binds) -> HashSet<Modifiers> {
+ mods_with_binds(
+ comp_mod,
+ binds,
+ &[
+ Trigger::TouchpadScrollUp,
+ Trigger::TouchpadScrollDown,
+ Trigger::TouchpadScrollLeft,
+ Trigger::TouchpadScrollRight,
+ ],
+ )
+}
+
#[cfg(test)]
mod tests {
use super::*;
diff --git a/src/niri.rs b/src/niri.rs
index e2b83930..363c2ae6 100644
--- a/src/niri.rs
+++ b/src/niri.rs
@@ -97,7 +97,9 @@ use crate::dbus::gnome_shell_screenshot::{NiriToScreenshot, ScreenshotToNiri};
use crate::dbus::mutter_screen_cast::{self, ScreenCastToNiri};
use crate::frame_clock::FrameClock;
use crate::handlers::configure_lock_surface;
-use crate::input::{apply_libinput_settings, mods_with_wheel_binds, TabletData};
+use crate::input::{
+ apply_libinput_settings, mods_with_finger_scroll_binds, mods_with_wheel_binds, TabletData,
+};
use crate::ipc::server::IpcServer;
use crate::layout::{Layout, MonitorRenderElement};
use crate::protocols::foreign_toplevel::{self, ForeignToplevelManagerState};
@@ -209,6 +211,9 @@ pub struct Niri {
pub vertical_wheel_tracker: ScrollTracker,
pub horizontal_wheel_tracker: ScrollTracker,
pub mods_with_wheel_binds: HashSet<Modifiers>,
+ pub vertical_finger_scroll_tracker: ScrollTracker,
+ pub horizontal_finger_scroll_tracker: ScrollTracker,
+ pub mods_with_finger_scroll_binds: HashSet<Modifiers>,
pub lock_state: LockState,
@@ -856,6 +861,8 @@ impl State {
self.niri.hotkey_overlay.on_hotkey_config_updated();
self.niri.mods_with_wheel_binds =
mods_with_wheel_binds(self.backend.mod_key(), &config.binds);
+ self.niri.mods_with_finger_scroll_binds =
+ mods_with_finger_scroll_binds(self.backend.mod_key(), &config.binds);
}
if config.window_rules != old_config.window_rules {
@@ -1166,6 +1173,8 @@ impl Niri {
CursorManager::new(&config_.cursor.xcursor_theme, config_.cursor.xcursor_size);
let mods_with_wheel_binds = mods_with_wheel_binds(backend.mod_key(), &config_.binds);
+ let mods_with_finger_scroll_binds =
+ mods_with_finger_scroll_binds(backend.mod_key(), &config_.binds);
let (tx, rx) = calloop::channel::channel();
event_loop
@@ -1325,6 +1334,11 @@ impl Niri {
horizontal_wheel_tracker: ScrollTracker::new(120),
mods_with_wheel_binds,
+ // 10 is copied from Clutter: DISCRETE_SCROLL_STEP.
+ vertical_finger_scroll_tracker: ScrollTracker::new(10),
+ horizontal_finger_scroll_tracker: ScrollTracker::new(10),
+ mods_with_finger_scroll_binds,
+
lock_state: LockState::Unlocked,
screenshot_ui,
diff --git a/src/ui/hotkey_overlay.rs b/src/ui/hotkey_overlay.rs
index 2f658dc3..3db3879a 100644
--- a/src/ui/hotkey_overlay.rs
+++ b/src/ui/hotkey_overlay.rs
@@ -226,6 +226,8 @@ fn render(config: &Config, comp_mod: CompositorMod, scale: i32) -> anyhow::Resul
// Only show binds with Mod or Super to filter out stuff like volume up/down.
&& (bind.key.modifiers.contains(Modifiers::COMPOSITOR)
|| bind.key.modifiers.contains(Modifiers::SUPER))
+ // Also filter out wheel and touchpad scroll binds.
+ && matches!(bind.key.trigger, Trigger::Keysym(_))
}) {
let action = &bind.action;
@@ -421,6 +423,10 @@ fn key_name(comp_mod: CompositorMod, key: &Key) -> String {
Trigger::WheelScrollUp => String::from("Wheel Scroll Up"),
Trigger::WheelScrollLeft => String::from("Wheel Scroll Left"),
Trigger::WheelScrollRight => String::from("Wheel Scroll Right"),
+ Trigger::TouchpadScrollDown => String::from("Touchpad Scroll Down"),
+ Trigger::TouchpadScrollUp => String::from("Touchpad Scroll Up"),
+ Trigger::TouchpadScrollLeft => String::from("Touchpad Scroll Left"),
+ Trigger::TouchpadScrollRight => String::from("Touchpad Scroll Right"),
};
name.push_str(&pretty);