clean up patches
This commit is contained in:
parent
44fbc7a4d4
commit
81fbae91d0
6 changed files with 221 additions and 207 deletions
|
|
@ -68,7 +68,7 @@ in
|
||||||
arg = "fht-compositor ipc action reload-config; ${session-programs}";
|
arg = "fht-compositor ipc action reload-config; ${session-programs}";
|
||||||
};
|
};
|
||||||
|
|
||||||
# Runs when Super is tapped on its own (patched in, see lone-modifier-and-scroll.patch)
|
# Runs when Super is tapped on its own (patched in, see lone-modifier.patch)
|
||||||
Super_L = {
|
Super_L = {
|
||||||
action = "run-command";
|
action = "run-command";
|
||||||
arg = "walker";
|
arg = "walker";
|
||||||
|
|
@ -148,9 +148,8 @@ in
|
||||||
(old: {
|
(old: {
|
||||||
patches = (old.patches or [ ]) ++ [
|
patches = (old.patches or [ ]) ++ [
|
||||||
./resize-tiled-windows.patch
|
./resize-tiled-windows.patch
|
||||||
./lone-modifier-and-scroll.patch
|
./lone-modifier.patch
|
||||||
# Fixes screencasting (e.g. OBS window capture) being rejected by xdg-desktop-portal
|
./scroll-accumulation.patch
|
||||||
./portal-version.patch
|
|
||||||
];
|
];
|
||||||
|
|
||||||
nativeBuildInputs = (old.nativeBuildInputs or [ ]) ++ [ pkgs.makeWrapper ];
|
nativeBuildInputs = (old.nativeBuildInputs or [ ]) ++ [ pkgs.makeWrapper ];
|
||||||
|
|
|
||||||
|
|
@ -1,187 +0,0 @@
|
||||||
--- a/src/input/mod.rs
|
|
||||||
+++ b/src/input/mod.rs
|
|
||||||
@@ -3,6 +3,7 @@
|
|
||||||
pub mod resize_tile_grab;
|
|
||||||
pub mod swap_tile_grab;
|
|
||||||
|
|
||||||
+use std::cell::Cell;
|
|
||||||
use std::collections::HashMap;
|
|
||||||
use std::time::Duration;
|
|
||||||
|
|
||||||
@@ -32,6 +33,15 @@
|
|
||||||
use crate::output::OutputExt;
|
|
||||||
use crate::state::State;
|
|
||||||
|
|
||||||
+thread_local! {
|
|
||||||
+ /// A modifier key that was pressed on its own, with no other key, button or scroll since.
|
|
||||||
+ /// Keybinds on just a modifier key (e.g. `Super_L`) run when it's released in that state.
|
|
||||||
+ static LONE_MODIFIER: Cell<Option<Keysym>> = const { Cell::new(None) };
|
|
||||||
+ /// Accumulated high-resolution scroll (in 1/120ths of a wheel notch) for scroll bindings,
|
|
||||||
+ /// so that they trigger once per notch rather than once per event.
|
|
||||||
+ static SCROLL_ACCUMULATOR: Cell<(f64, f64)> = const { Cell::new((0.0, 0.0)) };
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
impl State {
|
|
||||||
fn handle_focus_follows_mouse(&mut self, under: Option<&PointerFocus>) {
|
|
||||||
if !self.fht.config.general.focus_follows_mouse {
|
|
||||||
@@ -244,6 +254,7 @@
|
|
||||||
})
|
|
||||||
.map(|inhibitor| inhibitor.is_active())
|
|
||||||
.unwrap_or(false);
|
|
||||||
+ let mut lone_modifier_action = None;
|
|
||||||
let action = keyboard.input(
|
|
||||||
self,
|
|
||||||
keycode,
|
|
||||||
@@ -272,6 +283,20 @@
|
|
||||||
return FilterResult::Forward;
|
|
||||||
}
|
|
||||||
|
|
||||||
+ // Lone modifier taps. The key release is still forwarded to clients, and the
|
|
||||||
+ // action is run after the input is processed.
|
|
||||||
+ if let Some(raw) = raw {
|
|
||||||
+ if key_state == KeyState::Pressed {
|
|
||||||
+ LONE_MODIFIER.set(raw.is_modifier_key().then_some(raw));
|
|
||||||
+ } else if LONE_MODIFIER.take() == Some(raw) {
|
|
||||||
+ lone_modifier_action = find_keyaction(
|
|
||||||
+ &state.fht.config.keybinds,
|
|
||||||
+ &ModifiersState::default(),
|
|
||||||
+ raw,
|
|
||||||
+ );
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
// Handle repeating keybinds
|
|
||||||
// FIXME: handle this properly, this breaks if there are two repeating keybinds
|
|
||||||
if key_state == KeyState::Released {
|
|
||||||
@@ -331,6 +356,9 @@
|
|
||||||
if let Some((key_pattern, key_action)) = action {
|
|
||||||
self.process_key_action(key_action, key_pattern);
|
|
||||||
}
|
|
||||||
+ if let Some((key_pattern, key_action)) = lone_modifier_action {
|
|
||||||
+ self.process_key_action(key_action, key_pattern);
|
|
||||||
+ }
|
|
||||||
}
|
|
||||||
|
|
||||||
fn on_pointer_motion<B: InputBackend>(&mut self, event: B::PointerMotionEvent) {
|
|
||||||
@@ -505,6 +533,11 @@
|
|
||||||
let state = wl_pointer::ButtonState::from(event.state());
|
|
||||||
let pointer = self.fht.pointer.clone();
|
|
||||||
|
|
||||||
+ if state == wl_pointer::ButtonState::Pressed {
|
|
||||||
+ // e.g. Super+click shouldn't count as a lone Super tap
|
|
||||||
+ LONE_MODIFIER.set(None);
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
if state == wl_pointer::ButtonState::Pressed && !pointer.is_grabbed() {
|
|
||||||
let pointer_loc = pointer.current_location();
|
|
||||||
let focus = self.fht.get_pointer_focus(pointer_loc);
|
|
||||||
@@ -567,62 +600,67 @@
|
|
||||||
// Check for mouse axis bindings FIRST
|
|
||||||
let modifiers = self.fht.keyboard.modifier_state().into();
|
|
||||||
let mut handled = false;
|
|
||||||
+ // e.g. Super+scroll shouldn't count as a lone Super tap
|
|
||||||
+ LONE_MODIFIER.set(None);
|
|
||||||
+
|
|
||||||
+ // High-resolution wheels send several events per notch, each with part of the 120 units
|
|
||||||
+ // of a notch, so accumulate them and only trigger the binding once per full notch.
|
|
||||||
+ let (mut horizontal_accumulated, mut vertical_accumulated) = SCROLL_ACCUMULATOR.get();
|
|
||||||
+ let accumulate = |accumulated: &mut f64, discrete: f64| {
|
|
||||||
+ if accumulated.signum() != discrete.signum() {
|
|
||||||
+ // Changed direction, start over
|
|
||||||
+ *accumulated = 0.0;
|
|
||||||
+ }
|
|
||||||
+ *accumulated += discrete;
|
|
||||||
+ if accumulated.abs() >= 120.0 {
|
|
||||||
+ *accumulated -= 120.0 * accumulated.signum();
|
|
||||||
+ true
|
|
||||||
+ } else {
|
|
||||||
+ false
|
|
||||||
+ }
|
|
||||||
+ };
|
|
||||||
|
|
||||||
// Check vertical axis bindings using discrete amounts
|
|
||||||
- if let Some(discrete) = vertical_amount_discrete {
|
|
||||||
- if discrete > 0.0 {
|
|
||||||
- let mouse_pattern = fht_compositor_config::MousePattern(
|
|
||||||
- modifiers,
|
|
||||||
- fht_compositor_config::MouseInput::Axis(
|
|
||||||
- fht_compositor_config::MouseAxis::WheelUp,
|
|
||||||
- ),
|
|
||||||
- );
|
|
||||||
- if let Some(action) = self.fht.config.mousebinds.get(&mouse_pattern).cloned() {
|
|
||||||
- self.process_mouse_action(0, action, SERIAL_COUNTER.next_serial());
|
|
||||||
- handled = true;
|
|
||||||
- }
|
|
||||||
- } else if discrete < 0.0 {
|
|
||||||
- let mouse_pattern = fht_compositor_config::MousePattern(
|
|
||||||
- modifiers,
|
|
||||||
- fht_compositor_config::MouseInput::Axis(
|
|
||||||
- fht_compositor_config::MouseAxis::WheelDown,
|
|
||||||
- ),
|
|
||||||
- );
|
|
||||||
- if let Some(action) = self.fht.config.mousebinds.get(&mouse_pattern).cloned() {
|
|
||||||
+ if let Some(discrete) = vertical_amount_discrete.filter(|discrete| *discrete != 0.0) {
|
|
||||||
+ let mouse_axis = if discrete > 0.0 {
|
|
||||||
+ fht_compositor_config::MouseAxis::WheelUp
|
|
||||||
+ } else {
|
|
||||||
+ fht_compositor_config::MouseAxis::WheelDown
|
|
||||||
+ };
|
|
||||||
+ let mouse_pattern = fht_compositor_config::MousePattern(
|
|
||||||
+ modifiers,
|
|
||||||
+ fht_compositor_config::MouseInput::Axis(mouse_axis),
|
|
||||||
+ );
|
|
||||||
+ if let Some(action) = self.fht.config.mousebinds.get(&mouse_pattern).cloned() {
|
|
||||||
+ handled = true;
|
|
||||||
+ if accumulate(&mut vertical_accumulated, discrete) {
|
|
||||||
self.process_mouse_action(0, action, SERIAL_COUNTER.next_serial());
|
|
||||||
- handled = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check horizontal axis bindings using discrete amounts
|
|
||||||
if !handled {
|
|
||||||
- if let Some(discrete) = horizontal_amount_discrete {
|
|
||||||
- if discrete > 0.0 {
|
|
||||||
- let mouse_pattern = fht_compositor_config::MousePattern(
|
|
||||||
- modifiers,
|
|
||||||
- fht_compositor_config::MouseInput::Axis(
|
|
||||||
- fht_compositor_config::MouseAxis::WheelRight,
|
|
||||||
- ),
|
|
||||||
- );
|
|
||||||
- if let Some(action) = self.fht.config.mousebinds.get(&mouse_pattern).cloned() {
|
|
||||||
- self.process_mouse_action(0, action, SERIAL_COUNTER.next_serial());
|
|
||||||
- handled = true;
|
|
||||||
- }
|
|
||||||
- } else if discrete < 0.0 {
|
|
||||||
- let mouse_pattern = fht_compositor_config::MousePattern(
|
|
||||||
- modifiers,
|
|
||||||
- fht_compositor_config::MouseInput::Axis(
|
|
||||||
- fht_compositor_config::MouseAxis::WheelLeft,
|
|
||||||
- ),
|
|
||||||
- );
|
|
||||||
- if let Some(action) = self.fht.config.mousebinds.get(&mouse_pattern).cloned() {
|
|
||||||
+ if let Some(discrete) = horizontal_amount_discrete.filter(|discrete| *discrete != 0.0)
|
|
||||||
+ {
|
|
||||||
+ let mouse_axis = if discrete > 0.0 {
|
|
||||||
+ fht_compositor_config::MouseAxis::WheelRight
|
|
||||||
+ } else {
|
|
||||||
+ fht_compositor_config::MouseAxis::WheelLeft
|
|
||||||
+ };
|
|
||||||
+ let mouse_pattern = fht_compositor_config::MousePattern(
|
|
||||||
+ modifiers,
|
|
||||||
+ fht_compositor_config::MouseInput::Axis(mouse_axis),
|
|
||||||
+ );
|
|
||||||
+ if let Some(action) = self.fht.config.mousebinds.get(&mouse_pattern).cloned() {
|
|
||||||
+ handled = true;
|
|
||||||
+ if accumulate(&mut horizontal_accumulated, discrete) {
|
|
||||||
self.process_mouse_action(0, action, SERIAL_COUNTER.next_serial());
|
|
||||||
- handled = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+ SCROLL_ACCUMULATOR.set((horizontal_accumulated, vertical_accumulated));
|
|
||||||
|
|
||||||
// Only forward to pointer if we didn't handle it with a binding
|
|
||||||
if !handled {
|
|
||||||
83
clients/quadraticpc/fht-compositor/lone-modifier.patch
Normal file
83
clients/quadraticpc/fht-compositor/lone-modifier.patch
Normal file
|
|
@ -0,0 +1,83 @@
|
||||||
|
--- a/src/state.rs
|
||||||
|
+++ b/src/state.rs
|
||||||
|
@@ -724,6 +724,9 @@
|
||||||
|
// We store both the timer and the keysym used to trigger the key action.
|
||||||
|
// When we remove the keysym from suppressed keys we stop it.
|
||||||
|
pub repeated_keyaction_timer: Option<(RegistrationToken, Keysym)>,
|
||||||
|
+ // A modifier key that was pressed on its own, with no other key, button or scroll since.
|
||||||
|
+ // Keybinds on just a modifier key (e.g. `Super_L`) run when it's released in that state.
|
||||||
|
+ pub lone_modifier: Option<Keysym>,
|
||||||
|
// To focus a layer-surface with an OnDemand keyboard exclusivity mode, the user must click
|
||||||
|
// on the layer surface. Then, when we update the keyboard focus, we check against the clicked
|
||||||
|
// layer surface
|
||||||
|
@@ -962,6 +965,7 @@
|
||||||
|
clock,
|
||||||
|
suppressed_keys: HashMap::new(),
|
||||||
|
repeated_keyaction_timer: None,
|
||||||
|
+ lone_modifier: None,
|
||||||
|
seat,
|
||||||
|
devices: vec![],
|
||||||
|
seat_state,
|
||||||
|
--- a/src/input/mod.rs
|
||||||
|
+++ b/src/input/mod.rs
|
||||||
|
@@ -244,6 +244,7 @@
|
||||||
|
})
|
||||||
|
.map(|inhibitor| inhibitor.is_active())
|
||||||
|
.unwrap_or(false);
|
||||||
|
+ let mut lone_modifier_action = None;
|
||||||
|
let action = keyboard.input(
|
||||||
|
self,
|
||||||
|
keycode,
|
||||||
|
@@ -272,6 +273,20 @@
|
||||||
|
return FilterResult::Forward;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ // Lone modifier taps. The key release is still forwarded to clients, and the
|
||||||
|
+ // action is run after the input is processed.
|
||||||
|
+ if let Some(raw) = raw {
|
||||||
|
+ if key_state == KeyState::Pressed {
|
||||||
|
+ state.fht.lone_modifier = raw.is_modifier_key().then_some(raw);
|
||||||
|
+ } else if state.fht.lone_modifier.take() == Some(raw) {
|
||||||
|
+ lone_modifier_action = find_keyaction(
|
||||||
|
+ &state.fht.config.keybinds,
|
||||||
|
+ &ModifiersState::default(),
|
||||||
|
+ raw,
|
||||||
|
+ );
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
// Handle repeating keybinds
|
||||||
|
// FIXME: handle this properly, this breaks if there are two repeating keybinds
|
||||||
|
if key_state == KeyState::Released {
|
||||||
|
@@ -331,6 +346,9 @@
|
||||||
|
if let Some((key_pattern, key_action)) = action {
|
||||||
|
self.process_key_action(key_action, key_pattern);
|
||||||
|
}
|
||||||
|
+ if let Some((key_pattern, key_action)) = lone_modifier_action {
|
||||||
|
+ self.process_key_action(key_action, key_pattern);
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
|
||||||
|
fn on_pointer_motion<B: InputBackend>(&mut self, event: B::PointerMotionEvent) {
|
||||||
|
@@ -505,6 +523,11 @@
|
||||||
|
let state = wl_pointer::ButtonState::from(event.state());
|
||||||
|
let pointer = self.fht.pointer.clone();
|
||||||
|
|
||||||
|
+ if state == wl_pointer::ButtonState::Pressed {
|
||||||
|
+ // e.g. Super+click shouldn't count as a lone Super tap
|
||||||
|
+ self.fht.lone_modifier = None;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
if state == wl_pointer::ButtonState::Pressed && !pointer.is_grabbed() {
|
||||||
|
let pointer_loc = pointer.current_location();
|
||||||
|
let focus = self.fht.get_pointer_focus(pointer_loc);
|
||||||
|
@@ -555,6 +578,9 @@
|
||||||
|
}
|
||||||
|
|
||||||
|
fn on_pointer_axis<B: InputBackend>(&mut self, event: B::PointerAxisEvent) {
|
||||||
|
+ // e.g. Super+scroll shouldn't count as a lone Super tap
|
||||||
|
+ self.fht.lone_modifier = None;
|
||||||
|
+
|
||||||
|
let horizontal_amount_discrete = event.amount_v120(Axis::Horizontal);
|
||||||
|
let vertical_amount_discrete = event.amount_v120(Axis::Vertical);
|
||||||
|
let horizontal_amount = event
|
||||||
|
|
@ -1,13 +0,0 @@
|
||||||
--- a/src/portals/screencast.rs
|
|
||||||
+++ b/src/portals/screencast.rs
|
|
||||||
@@ -165,7 +165,9 @@
|
|
||||||
(CursorMode::HIDDEN | CursorMode::EMBEDDED).bits()
|
|
||||||
}
|
|
||||||
|
|
||||||
- #[zbus(property)]
|
|
||||||
+ // The spec calls this "version" (zbus would otherwise publish it as "Version"), and
|
|
||||||
+ // xdg-desktop-portal treats the portal as version 0 without it, rejecting cursor modes.
|
|
||||||
+ #[zbus(property, name = "version")]
|
|
||||||
pub fn version(&self) -> u32 {
|
|
||||||
PORTAL_VERSION
|
|
||||||
}
|
|
||||||
132
clients/quadraticpc/fht-compositor/scroll-accumulation.patch
Normal file
132
clients/quadraticpc/fht-compositor/scroll-accumulation.patch
Normal file
|
|
@ -0,0 +1,132 @@
|
||||||
|
--- a/src/state.rs
|
||||||
|
+++ b/src/state.rs
|
||||||
|
@@ -719,6 +719,9 @@
|
||||||
|
pub seat: Seat<State>,
|
||||||
|
pub keyboard: KeyboardHandle<State>,
|
||||||
|
pub pointer: PointerHandle<State>,
|
||||||
|
+ // Accumulated high-resolution scroll (in 1/120ths of a wheel notch), horizontal then vertical,
|
||||||
|
+ // for scroll bindings, so that they trigger once per notch rather than once per event.
|
||||||
|
+ pub scroll_binding_accumulator: (f64, f64),
|
||||||
|
pub clock: Clock<Monotonic>,
|
||||||
|
pub suppressed_keys: HashMap<u32, (KeyPattern, KeyAction)>,
|
||||||
|
// We store both the timer and the keysym used to trigger the key action.
|
||||||
|
@@ -967,6 +970,7 @@
|
||||||
|
seat_state,
|
||||||
|
keyboard,
|
||||||
|
pointer,
|
||||||
|
+ scroll_binding_accumulator: (0.0, 0.0),
|
||||||
|
mapped_layer_surfaces: HashMap::new(),
|
||||||
|
lock_state: LockState::Unlocked,
|
||||||
|
focused_on_demand_layer_shell: None,
|
||||||
|
--- a/src/input/mod.rs
|
||||||
|
+++ b/src/input/mod.rs
|
||||||
|
@@ -569,56 +569,41 @@
|
||||||
|
let mut handled = false;
|
||||||
|
|
||||||
|
// Check vertical axis bindings using discrete amounts
|
||||||
|
- if let Some(discrete) = vertical_amount_discrete {
|
||||||
|
- if discrete > 0.0 {
|
||||||
|
- let mouse_pattern = fht_compositor_config::MousePattern(
|
||||||
|
- modifiers,
|
||||||
|
- fht_compositor_config::MouseInput::Axis(
|
||||||
|
- fht_compositor_config::MouseAxis::WheelUp,
|
||||||
|
- ),
|
||||||
|
- );
|
||||||
|
- if let Some(action) = self.fht.config.mousebinds.get(&mouse_pattern).cloned() {
|
||||||
|
- self.process_mouse_action(0, action, SERIAL_COUNTER.next_serial());
|
||||||
|
- handled = true;
|
||||||
|
- }
|
||||||
|
- } else if discrete < 0.0 {
|
||||||
|
- let mouse_pattern = fht_compositor_config::MousePattern(
|
||||||
|
- modifiers,
|
||||||
|
- fht_compositor_config::MouseInput::Axis(
|
||||||
|
- fht_compositor_config::MouseAxis::WheelDown,
|
||||||
|
- ),
|
||||||
|
- );
|
||||||
|
- if let Some(action) = self.fht.config.mousebinds.get(&mouse_pattern).cloned() {
|
||||||
|
+ if let Some(discrete) = vertical_amount_discrete.filter(|discrete| *discrete != 0.0) {
|
||||||
|
+ let mouse_axis = if discrete > 0.0 {
|
||||||
|
+ fht_compositor_config::MouseAxis::WheelUp
|
||||||
|
+ } else {
|
||||||
|
+ fht_compositor_config::MouseAxis::WheelDown
|
||||||
|
+ };
|
||||||
|
+ let mouse_pattern = fht_compositor_config::MousePattern(
|
||||||
|
+ modifiers,
|
||||||
|
+ fht_compositor_config::MouseInput::Axis(mouse_axis),
|
||||||
|
+ );
|
||||||
|
+ if let Some(action) = self.fht.config.mousebinds.get(&mouse_pattern).cloned() {
|
||||||
|
+ handled = true;
|
||||||
|
+ if accumulate_scroll(&mut self.fht.scroll_binding_accumulator.1, discrete) {
|
||||||
|
self.process_mouse_action(0, action, SERIAL_COUNTER.next_serial());
|
||||||
|
- handled = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check horizontal axis bindings using discrete amounts
|
||||||
|
if !handled {
|
||||||
|
- if let Some(discrete) = horizontal_amount_discrete {
|
||||||
|
- if discrete > 0.0 {
|
||||||
|
- let mouse_pattern = fht_compositor_config::MousePattern(
|
||||||
|
- modifiers,
|
||||||
|
- fht_compositor_config::MouseInput::Axis(
|
||||||
|
- fht_compositor_config::MouseAxis::WheelRight,
|
||||||
|
- ),
|
||||||
|
- );
|
||||||
|
- if let Some(action) = self.fht.config.mousebinds.get(&mouse_pattern).cloned() {
|
||||||
|
- self.process_mouse_action(0, action, SERIAL_COUNTER.next_serial());
|
||||||
|
- handled = true;
|
||||||
|
- }
|
||||||
|
- } else if discrete < 0.0 {
|
||||||
|
- let mouse_pattern = fht_compositor_config::MousePattern(
|
||||||
|
- modifiers,
|
||||||
|
- fht_compositor_config::MouseInput::Axis(
|
||||||
|
- fht_compositor_config::MouseAxis::WheelLeft,
|
||||||
|
- ),
|
||||||
|
- );
|
||||||
|
- if let Some(action) = self.fht.config.mousebinds.get(&mouse_pattern).cloned() {
|
||||||
|
+ if let Some(discrete) = horizontal_amount_discrete.filter(|discrete| *discrete != 0.0)
|
||||||
|
+ {
|
||||||
|
+ let mouse_axis = if discrete > 0.0 {
|
||||||
|
+ fht_compositor_config::MouseAxis::WheelRight
|
||||||
|
+ } else {
|
||||||
|
+ fht_compositor_config::MouseAxis::WheelLeft
|
||||||
|
+ };
|
||||||
|
+ let mouse_pattern = fht_compositor_config::MousePattern(
|
||||||
|
+ modifiers,
|
||||||
|
+ fht_compositor_config::MouseInput::Axis(mouse_axis),
|
||||||
|
+ );
|
||||||
|
+ if let Some(action) = self.fht.config.mousebinds.get(&mouse_pattern).cloned() {
|
||||||
|
+ handled = true;
|
||||||
|
+ if accumulate_scroll(&mut self.fht.scroll_binding_accumulator.0, discrete) {
|
||||||
|
self.process_mouse_action(0, action, SERIAL_COUNTER.next_serial());
|
||||||
|
- handled = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -1080,6 +1065,25 @@
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns `true` if a VT switch key has been handled.
|
||||||
|
+/// Accumulate high-resolution scroll for a scroll binding.
|
||||||
|
+///
|
||||||
|
+/// High-resolution wheels send several events per notch, each with part of the 120 units of a
|
||||||
|
+/// notch, so we accumulate them and only trigger the binding once per full notch. Returns whether
|
||||||
|
+/// the binding should trigger.
|
||||||
|
+fn accumulate_scroll(accumulated: &mut f64, v120: f64) -> bool {
|
||||||
|
+ if accumulated.signum() != v120.signum() {
|
||||||
|
+ // Changed direction, start over
|
||||||
|
+ *accumulated = 0.0;
|
||||||
|
+ }
|
||||||
|
+ *accumulated += v120;
|
||||||
|
+ if accumulated.abs() >= 120.0 {
|
||||||
|
+ *accumulated -= 120.0 * accumulated.signum();
|
||||||
|
+ true
|
||||||
|
+ } else {
|
||||||
|
+ false
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
fn handle_vt_switch(backend: &mut Backend, key_state: KeyState, modified: Keysym) -> bool {
|
||||||
|
if key_state == KeyState::Released {
|
||||||
|
// We only do VT switch on presses.
|
||||||
6
flake.lock
generated
6
flake.lock
generated
|
|
@ -306,11 +306,11 @@
|
||||||
"rust-overlay": []
|
"rust-overlay": []
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1792487869,
|
"lastModified": 1792507568,
|
||||||
"narHash": "sha256-4e5XvmR5lvSr/tSbSM1byipvKpblM5SJjSJWNgGAiSo=",
|
"narHash": "sha256-RGXq8SkxpxU0TaMk3oXbJ5SwkRDY90tvN2zIiofAVMQ=",
|
||||||
"owner": "nferhat",
|
"owner": "nferhat",
|
||||||
"repo": "fht-compositor",
|
"repo": "fht-compositor",
|
||||||
"rev": "a39a9a6e4f13307d034c5976ca5514beda7b21ac",
|
"rev": "458dc48d96aa6d8aa0b834a8052f33c09700ffe8",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue