From c39f44e190eb464a60fc76bee63ff8720b72efd7 Mon Sep 17 00:00:00 2001 From: Dahak Builds Date: Sat, 31 Oct 2026 19:04:33 +0000 Subject: [PATCH] Orbit ignores floating input fields passing under the cursor (#10128) (#10206) * claim: #10128 * Orbit ignores floating input fields passing under the cursor (#10128) --------- Co-authored-by: Dahak Builds --- crates/ui-egui/src/viewport.rs | 42 ++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/crates/ui-egui/src/viewport.rs b/crates/ui-egui/src/viewport.rs index 26b6b8c9e1..800638e05f 100644 --- a/crates/ui-egui/src/viewport.rs +++ b/crates/ui-egui/src/viewport.rs @@ -10483,6 +10483,48 @@ mod tests { assert!(h.app.dialog.is_some()); } + /// #10128: a Shift + trackpad orbit must not halt when the spinning model moves a floating + /// value box (Extrude's distance) under the cursor. The box follows the geometry, so mid-orbit + /// it slides under a pointer that never moved; the orbit ignores it and keeps turning, frame + /// after frame, while the pointer is over the box. + #[test] + fn orbit_ignores_floating_field_under_cursor() { + let mut h = crate::scenario::Harness::new(); + h.app.run("sketch.create", json!({"plane": "XY"})).unwrap(); + h.app.run("sketch.rectangle.two_point", json!({"p0": [0, 0], "p1": [40, 30]})).unwrap(); + h.app.run("sketch.finish", json!({})).unwrap(); + let sketch = h.app.session.doc.features[0].id; + h.app.session.selection = vec![Sel::Profile { sketch, index: 0 }]; + h.step(&json!({"start": "solid.extrude"})).unwrap(); + h.frames(6); + let over = + |h: &crate::scenario::Harness| h.ctx.read_response(egui::Id::new("sc_canvas_value")).expect("Extrude's distance box").rect.center(); + let typed = format!("{:?}", h.app.dialog.as_ref().map(|d| &d.kind)); + // The orbit is in progress and the box slides under the cursor: the pointer sits on the + // box every frame, as it does when the spinning model carries the box to the pointer. + let at = over(&h); + h.call("ui.move", json!({"x": at.x, "y": at.y})); + h.frames(2); + assert!(h.ctx.layer_id_at(at).is_some_and(crate::ui_kit::container::is_canvas), "the pointer is on the box"); + let orbit = + |phase| egui::Event::MouseWheel { unit: egui::MouseWheelUnit::Point, delta: vec2(24.0, -16.0), modifiers: egui::Modifiers::SHIFT, phase }; + h.app.synthetic.push(orbit(egui::TouchPhase::Start)); + h.frame(); + let mut last = h.app.cam; + for _ in 0..4 { + h.app.synthetic.push(orbit(egui::TouchPhase::Move)); + h.frame(); + let at = over(&h); + h.call("ui.move", json!({"x": at.x, "y": at.y})); + assert_ne!((h.app.cam.yaw, h.app.cam.pitch), (last.yaw, last.pitch), "the orbit keeps turning while the box is under the cursor"); + last = h.app.cam; + } + h.app.synthetic.push(orbit(egui::TouchPhase::End)); + h.frames(3); + assert_eq!(format!("{:?}", h.app.dialog.as_ref().map(|d| &d.kind)), typed, "the box kept its value"); + assert!(h.app.dialog.is_some()); + } + #[test] fn trackpad_gestures_over_dialogs_do_not_move_the_view() { let ctx = crate::fonts::test_context();