Merge pull request #1251 from storytold/fix/hover-lines-leave

Canvas: hover distances go when the pointer leaves the canvas
This commit is contained in:
Brandon Thomas
2026-10-25 12:10:32 -04:00
committed by GitHub
3 changed files with 30 additions and 2 deletions
+18
View File
@@ -250,3 +250,21 @@ fn measure_distances_command() {
assert!(s.execute("measure.distances", &json!({"ids": [f]})).is_err(), "top level: pass `to`");
assert!(s.execute("measure.distances", &json!({"ids": [r], "to": 99999})).is_err());
}
#[test]
fn leaving_the_canvas_clears_the_hover_measurement() {
let mut s = Session::new();
let a = rect(&mut s, 0.0, 0.0, 50.0, 50.0, None);
rect(&mut s, 100.0, 0.0, 50.0, 50.0, None);
ex(&mut s, "select.set", json!({"ids": [a]}));
assert!(!hover(&mut s, 125.0, 25.0, true, false, false).is_empty());
assert!(s.tool.overlay.measure_box.is_some());
s.pointer_left();
assert!(s.tool.overlay.guides.is_empty(), "{:?}", s.tool.overlay.guides);
assert_eq!(s.tool.overlay.measure_box, None);
// Dev Mode measures without Alt; leaving clears those too.
s.tool.dev_mode = true;
assert!(!hover(&mut s, 125.0, 25.0, false, false, false).is_empty());
s.pointer_left();
assert!(s.tool.overlay.guides.is_empty());
}
+10
View File
@@ -971,6 +971,16 @@ pub(crate) fn scale_factor(handle: Handle, q: Point, w0: f64, h0: f64, anchor: (
}
impl Session {
/// The pointer left the canvas: what hovering there showed goes (the distances Alt or Dev Mode
/// measured and the box measured to, a vector region's highlight), unless a gesture holds it.
pub fn pointer_left(&mut self) {
if !self.tool.busy() {
self.tool.overlay.guides.clear();
self.tool.overlay.measure_box = None;
}
self.vector_pointer_left();
}
/// What a marquee starting at page point `p` selects inside: the top-level frame it starts in
/// (its children), or the focus view's frame.
pub(crate) fn marquee_within(&self, p: Point) -> Result<Option<NodeId>> {
+2 -2
View File
@@ -556,7 +556,7 @@ fn input(app: &mut FigApp, ui: &mut Ui, resp: &egui::Response) -> bool {
}
// Leaving the canvas: nothing is hovered there any more.
if !app.canvas.dragging && std::mem::take(&mut app.canvas.hovering) {
app.session.vector_pointer_left();
app.session.pointer_left();
}
// A pan whose button was released off the canvas is over.
if !ctx.input(|i| i.pointer.button_down(egui::PointerButton::Middle) || i.pointer.primary_down()) {
@@ -654,7 +654,7 @@ fn input(app: &mut FigApp, ui: &mut Ui, resp: &egui::Response) -> bool {
} else {
// Something over the canvas took the pointer.
if std::mem::take(&mut app.canvas.hovering) {
app.session.vector_pointer_left();
app.session.pointer_left();
}
None
};