From 9f550e275c353ea92b37c40834cdcfd220ca90ba Mon Sep 17 00:00:00 2001 From: Samuel Onoja Date: Fri, 25 Sep 2026 01:14:07 +0100 Subject: [PATCH] fix: accelerate geometry animations --- crates/ferese-animation/src/lib.rs | 25 +++++++++++++++++++++++-- docs/ferese-window-manager-spec.md | 8 ++++---- 2 files changed, 27 insertions(+), 6 deletions(-) diff --git a/crates/ferese-animation/src/lib.rs b/crates/ferese-animation/src/lib.rs index 94801de..64ae0df 100644 --- a/crates/ferese-animation/src/lib.rs +++ b/crates/ferese-animation/src/lib.rs @@ -19,8 +19,8 @@ impl Default for SpringConfig { fn default() -> Self { Self { mass: 1.0, - stiffness: 320.0, - damping: 36.0, + stiffness: 700.0, + damping: 53.0, position_tolerance: 0.1, velocity_tolerance: 0.1, } @@ -422,6 +422,27 @@ mod tests { assert_eq!(one_forty_four.current, target); } + #[test] + fn default_spring_completes_most_motion_within_two_hundred_milliseconds() { + let start = Rect::new(0.0, 0.0, 100.0, 100.0); + let target = Rect::new(500.0, 300.0, 900.0, 700.0); + let mut animated = AnimatedRect::new(start); + animated.set_target(target); + + for _ in 0..12 { + animated.advance(Duration::from_secs_f64(1.0 / 60.0), SpringConfig::default()); + } + + assert!(animated.current.x >= 475.0); + assert!(animated.current.y >= 285.0); + assert!(animated.current.width >= 860.0); + assert!(animated.current.height >= 670.0); + assert!(animated.current.x <= target.x); + assert!(animated.current.y <= target.y); + assert!(animated.current.width <= target.width); + assert!(animated.current.height <= target.height); + } + #[test] fn disabled_animation_snaps_to_target() { let mut geometry = WindowGeometry::new(Rect::new(0.0, 0.0, 100.0, 100.0), None); diff --git a/docs/ferese-window-manager-spec.md b/docs/ferese-window-manager-spec.md index 09e5e20..af26b5b 100644 --- a/docs/ferese-window-manager-spec.md +++ b/docs/ferese-window-manager-spec.md @@ -574,8 +574,8 @@ to `visual.target`. Geometry uses spring animation; opacity, dimming, blur intensity, and overlays use bounded easing. Updates MUST use presentation or monotonic frame timestamps and MUST NOT assume a fixed refresh rate. -The default geometry spring uses mass `1.0`, stiffness `320.0`, and damping -`36.0`, which is approximately critically damped. Geometry defaults MUST NOT +The default geometry spring uses mass `1.0`, stiffness `700.0`, and damping +`53.0`, which is approximately critically damped. Geometry defaults MUST NOT overshoot shared tile boundaries. User-configured underdamped geometry springs MAY overshoot numerically, but their rendered content remains clipped to the animated allocation and MUST NOT cover adjacent windows. @@ -927,8 +927,8 @@ reduced_motion = false speed = 1.0 [animations.spring] -stiffness = 320.0 -damping = 36.0 +stiffness = 700.0 +damping = 53.0 mass = 1.0 [tiling]