From cc499d7e8ebe11d0738a159f4478968d38e6711d Mon Sep 17 00:00:00 2001 From: Taha-Mahmoodi <85902429+Taha-Mahmoodi@users.noreply.github.com> Date: Thu, 22 Oct 2026 16:24:03 +0430 Subject: [PATCH] Fix #3370: each step stops at the bounds, so a step back in the same frame starts from there Review follow-up (CodeRabbit): step_value clamped once after all of a frame's steps, so at the lower bound a step down then a step up in the same frame left the field at the bound. Each step is now clamped as it is applied. The Stroke panel test steps down and up in one frame at each bound and expects one step above it; it fails without the change. --- crates/ui-egui/src/panels/stroke.rs | 5 +++++ crates/ui-egui/src/widgets.rs | 2 ++ 2 files changed, 7 insertions(+) diff --git a/crates/ui-egui/src/panels/stroke.rs b/crates/ui-egui/src/panels/stroke.rs index 86de5f204..d668e504a 100644 --- a/crates/ui-egui/src/panels/stroke.rs +++ b/crates/ui-egui/src/panels/stroke.rs @@ -642,6 +642,11 @@ mod tests { let texts = frame(&mut app, vec![]); assert_eq!(stroke(&app)[which], low, "{shown}: {:?}", stroke(&app)); assert!(texts.iter().any(|(t, _)| t == after), "{shown} → {after}: {texts:?}"); + // At the bound, a step down and a step up in one frame end one step above it. + let key = |key| Event::Key { key, physical_key: None, pressed: true, repeat: false, modifiers: Modifiers::NONE }; + frame(&mut app, vec![key(egui::Key::ArrowDown), key(egui::Key::ArrowUp)]); + let texts = frame(&mut app, vec![]); + assert!(texts.iter().any(|(t, _)| t == shown), "{after}, down and up → {shown}: {texts:?}"); } } } diff --git a/crates/ui-egui/src/widgets.rs b/crates/ui-egui/src/widgets.rs index a89a84586..00452d98d 100644 --- a/crates/ui-egui/src/widgets.rs +++ b/crates/ui-egui/src/widgets.rs @@ -390,6 +390,8 @@ fn step_value( let mut v = read(buf)?; for (mods, size, n) in steps { v = if mods == egui::Modifiers::SHIFT { v + size * n } else { step_to_multiple(v, size, n) }; + // Each step stops at the bounds, so a step back in the same frame starts from there. + v = within(v, bounds); } // Rounded as fields show it, within the field's bounds. let v = within(round_to(v, STEP_DECIMALS), bounds);