KEY-SLIDER-NUDGE: a drag that leaves the row disarms wheel edits

The disarm waited for the button to be released outside the row, so a
drag that went out and came back kept the wheel armed. Leaving disarms
now even mid-drag, and a drag that starts outside the row does not arm.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Haocheng Fang
2026-10-21 13:40:04 -05:00
co-authored by Claude Opus 5.5
parent 868de3a9fe
commit 977bbebcdc
2 changed files with 32 additions and 3 deletions
+8 -3
View File
@@ -259,15 +259,20 @@ pub fn slider(ui: &mut Ui, spec: &ControlSpec, value: f64, enabled: bool, label_
if enabled && resp.gained_focus() {
ui.data_mut(|d| d.insert_temp(focused_slider_key(), id));
}
if enabled && (resp.clicked() || resp.drag_started()) {
let selected = enabled && (resp.clicked() || resp.drag_started());
if selected {
resp.request_focus();
ui.data_mut(|d| d.insert_temp(focused_slider_key(), id));
}
// A drag that leaves the row disarms too (it keeps dragging: that needs no wheel selection),
// and one that only starts once the pointer is outside doesn't arm it again.
if selected && pointer_in_row && !left_row {
ui.data_mut(|d| {
d.insert_temp(focused_slider_key(), id);
d.insert_temp(wheel_slider_key(), id);
d.remove::<f32>(wheel_id);
});
wheel_armed = true;
} else if wheel_armed && (!enabled || !resp.has_focus() || ((!pointer_in_row || left_row) && !resp.is_pointer_button_down_on())) {
} else if wheel_armed && (!enabled || !resp.has_focus() || !pointer_in_row || left_row) {
ui.data_mut(|d| {
d.remove::<egui::Id>(wheel_slider_key());
d.remove::<f32>(wheel_id);
@@ -259,6 +259,30 @@ fn leaving_the_row_during_a_drag_keeps_dragging_but_release_disarms_the_wheel()
assert_eq!(h.value, released, "releasing outside disarms subsequent wheel edits");
}
#[test]
fn a_drag_that_leaves_and_ends_back_in_the_row_disarms_the_wheel() {
let mut h = Harness::new();
let inside = h.track.center();
let outside = egui::pos2(h.track.right() - 20.0, 80.0);
let button = |pos, pressed| Event::PointerButton { pos, button: PointerButton::Primary, pressed, modifiers: Modifiers::NONE };
h.frame(vec![Event::PointerMoved(inside)]);
h.frame(vec![button(inside, true)]);
h.frame(vec![Event::PointerMoved(outside)]);
h.frame(vec![Event::PointerMoved(inside)]);
h.frame(vec![button(inside, false)]);
let released = h.value;
h.frame(vec![Event::MouseWheel {
unit: egui::MouseWheelUnit::Point,
delta: vec2(0.0, 120.0),
phase: egui::TouchPhase::Move,
modifiers: Modifiers::NONE,
}]);
for _ in 0..40 {
h.frame(vec![]);
}
assert_eq!(h.value, released, "the drag left the row, so the wheel needs a fresh selection");
}
#[test]
fn leaving_and_returning_within_one_frame_still_disarms_the_wheel() {
let wheel = || Event::MouseWheel {