diff --git a/crates/ui-egui/src/widgets.rs b/crates/ui-egui/src/widgets.rs index 5fef361fa..5169c9d44 100644 --- a/crates/ui-egui/src/widgets.rs +++ b/crates/ui-egui/src/widgets.rs @@ -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::(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::(wheel_slider_key()); d.remove::(wheel_id); diff --git a/crates/ui-egui/src/widgets/tests_numeric_entry.rs b/crates/ui-egui/src/widgets/tests_numeric_entry.rs index c35dbc78b..730f4333b 100644 --- a/crates/ui-egui/src/widgets/tests_numeric_entry.rs +++ b/crates/ui-egui/src/widgets/tests_numeric_entry.rs @@ -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 {