Merge pull request #4579 from storytold/fix/dialogs-hide-canvas-hover

Fix #4518: a dialog or floating panel over the canvas hides the pointer from it
This commit is contained in:
BFlat
2026-10-29 20:20:34 +07:00
committed by GitHub
2 changed files with 27 additions and 2 deletions
+5 -2
View File
@@ -354,9 +354,12 @@ fn canvas_input(app: &mut VectorcraftApp, ui: &Ui, resp: &egui::Response, rect:
handle_input(app, ui, resp, rect);
// `hover_doc` is the document point under the pointer in the view `handle_input` left. The
// wheel, a pan, a Rotate View drag, the Zoom tool and a Presentation Mode click move the view
// there.
// there. A dialog, floating panel or menu over the canvas hides it (Object Highlighting
// showed through them: #4518), unless a drag that began on the canvas goes on there.
let moved = Xf::new(rect, app.view().unwrap_or(&View::default()));
app.hover_doc = ui.input(|i| i.pointer.hover_pos()).filter(|p| rect.contains(*p)).map(|p| moved.to_doc(p));
let dragging = ui.data(|d| d.get_temp::<Drag>(drag_id()).is_some());
app.hover_doc =
ui.input(|i| i.pointer.hover_pos()).filter(|p| rect.contains(*p) && (dragging || drag::on_canvas(ui, resp, *p))).map(|p| moved.to_doc(p));
}
}
+22
View File
@@ -7328,6 +7328,28 @@ fn distance_guides_follow_what_lies_under_a_still_pointer() {
assert_eq!(gap_label(&run(&mut app, vec![])), None, "another document");
}
/// #4518: a floating panel or a modal dialog over the canvas hides the pointer from it, so Object
/// Highlighting, the rulers and the Info panel don't follow a pointer that is over the dialog.
#[test]
fn a_panel_or_dialog_over_the_canvas_hides_the_pointer_from_it() {
let (mut app, ctx, _, over, _) = distance_scene(true);
let run = |app: &mut VectorcraftApp, events, cover| distance_frame_covered(app, &ctx, events, cover);
run(&mut app, vec![egui::Event::PointerMoved(over)], None);
run(&mut app, vec![], None);
assert!(app.hover_doc.is_some(), "over the canvas");
for cover in [Cover::Panel(egui::Rect::from_center_size(over, vec2(120.0, 120.0))), Cover::Dialog] {
// A new window takes a sizing pass before it covers anything, as in the test above.
for _ in 0..3 {
run(&mut app, vec![], Some(cover));
}
assert_eq!(app.hover_doc, None, "under it");
for _ in 0..3 {
run(&mut app, vec![], None);
}
assert!(app.hover_doc.is_some(), "back once it closes");
}
}
/// The 800 × 600 window [`frame`] draws the canvas in.
const WINDOW: egui::Rect = egui::Rect { min: Pos2::ZERO, max: Pos2 { x: 800.0, y: 600.0 } };