Fix #4518: a dialog or floating panel over the canvas hides the pointer from it

The document point under the pointer (Object Highlighting, the rulers' marks, the status bar and the Info panel) was taken wherever the pointer was over the canvas's rectangle, even over a dialog, a floating panel or a menu on top of it, so objects under the Print or Export for Screens dialog lit up as the pointer moved over the dialog. It now takes the same check as the tool's hover (the canvas's own layer under the pointer), except during a drag that began on the canvas.
This commit is contained in:
bflatastic
2026-10-29 19:54:33 +07:00
parent 5438ed12d3
commit 2c1713e90b
2 changed files with 26 additions and 2 deletions
+7 -2
View File
@@ -354,9 +354,14 @@ 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));
}
}
+19
View File
@@ -7328,6 +7328,25 @@ 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] {
run(&mut app, vec![], Some(cover));
run(&mut app, vec![], Some(cover));
assert_eq!(app.hover_doc, None, "under it");
run(&mut app, vec![], None);
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 } };