From 92fcceba54cb1a8ce76ab5a62a6a4602b185580b Mon Sep 17 00:00:00 2001 From: Tom Grushka Date: Fri, 15 May 2026 15:51:24 -0600 Subject: [PATCH 1/3] fix(magnifier): smooth mouse wheel zoom and respect natural scroll direction - Disable animation for mouse wheel zoom to eliminate the timing race that causes lag and sudden jumps. Each wheel tick now zooms instantly. - Invert zoom direction when natural scrolling is enabled so that forward scroll zooms in, matching macOS/Windows behavior. --- src/input/mod.rs | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/src/input/mod.rs b/src/input/mod.rs index 2a62947c..d2d08e9f 100644 --- a/src/input/mod.rs +++ b/src/input/mod.rs @@ -37,11 +37,12 @@ use cosmic_settings_config::shortcuts; use cosmic_settings_config::shortcuts::action::{Direction, ResizeDirection}; use smithay::{ backend::input::{ - AbsolutePositionEvent, Axis, AxisSource, Device, DeviceCapability, GestureBeginEvent, - GestureEndEvent, GesturePinchUpdateEvent as _, GestureSwipeUpdateEvent as _, InputBackend, - InputEvent, KeyState, KeyboardKeyEvent, PointerAxisEvent, ProximityState, Switch, - SwitchState, SwitchToggleEvent, TabletToolButtonEvent, TabletToolEvent, - TabletToolProximityEvent, TabletToolTipEvent, TabletToolTipState, TouchEvent, + AbsolutePositionEvent, Axis, AxisRelativeDirection, AxisSource, Device, DeviceCapability, + GestureBeginEvent, GestureEndEvent, GesturePinchUpdateEvent as _, + GestureSwipeUpdateEvent as _, InputBackend, InputEvent, KeyState, KeyboardKeyEvent, + PointerAxisEvent, ProximityState, Switch, SwitchState, SwitchToggleEvent, + TabletToolButtonEvent, TabletToolEvent, TabletToolProximityEvent, TabletToolTipEvent, + TabletToolTipState, TouchEvent, }, desktop::{PopupKeyboardGrab, WindowSurfaceType, utils::under_from_surface_tree}, input::{ @@ -914,12 +915,18 @@ impl State { .or_else(|| event.amount(Axis::Vertical)) .map(|val| val * scroll_factor) { + if event.relative_direction(Axis::Vertical) + == AxisRelativeDirection::Inverted + { + percentage *= -1.; + } + if event.source() == AxisSource::Wheel { percentage *= 5.; } let change = -(percentage / 100.); - self.update_zoom(&seat, change, event.source() == AxisSource::Wheel); + self.update_zoom(&seat, change, false); } } else { let mut frame = AxisFrame::new(event.time_msec()).source(event.source()); From 657f0aeddfa92c862873a6d6e75868c52d8caf11 Mon Sep 17 00:00:00 2001 From: Tom Grushka Date: Tue, 19 May 2026 16:30:46 -0600 Subject: [PATCH 2/3] revert self.update_zoom to update with wheel --- src/input/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/input/mod.rs b/src/input/mod.rs index d2d08e9f..69aaccce 100644 --- a/src/input/mod.rs +++ b/src/input/mod.rs @@ -926,7 +926,7 @@ impl State { } let change = -(percentage / 100.); - self.update_zoom(&seat, change, false); + self.update_zoom(&seat, change, event.source() == AxisSource::Wheel); } } else { let mut frame = AxisFrame::new(event.time_msec()).source(event.source()); From c776eeac0314e528398ceb9aed3749785e165bf0 Mon Sep 17 00:00:00 2001 From: Tom Grushka Date: Tue, 19 May 2026 17:46:21 -0600 Subject: [PATCH 3/3] change a11y zoom easing function from EaseInOutCubic to Linear to avoid lagging mouse wheel scroll --- src/shell/zoom.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/shell/zoom.rs b/src/shell/zoom.rs index bb681563..b4ba339f 100644 --- a/src/shell/zoom.rs +++ b/src/shell/zoom.rs @@ -9,7 +9,7 @@ use cosmic::{ }; use cosmic_comp_config::ZoomMovement; use cosmic_config::ConfigSet; -use keyframe::{ease, functions::EaseInOutCubic}; +use keyframe::{ease, functions::Linear}; use smithay::{ backend::renderer::{ImportMem, Renderer, element::AsRenderElements}, desktop::space::SpaceElement, @@ -135,7 +135,7 @@ impl OutputZoomState { let percentage = duration_since.as_millis() as f32 / ANIMATION_DURATION.as_millis() as f32; ease( - EaseInOutCubic, + Linear, EasePoint(*old_point), EasePoint(self.focal_point), percentage, @@ -159,7 +159,7 @@ impl OutputZoomState { let percentage = Instant::now().duration_since(*start).as_millis() as f32 / ANIMATION_DURATION.as_millis() as f32; - ease(EaseInOutCubic, *old_level, self.level, percentage) + ease(Linear, *old_level, self.level, percentage) } else { self.level }