diff --git a/crates/ui-egui/src/canvas.rs b/crates/ui-egui/src/canvas.rs index beb88cc87..da2a03737 100644 --- a/crates/ui-egui/src/canvas.rs +++ b/crates/ui-egui/src/canvas.rs @@ -1805,8 +1805,10 @@ pub fn document_area(app: &mut PdfCraftApp, index: usize, ui: &mut egui::Ui) { } } } - // Annotation hover shows the comment, as Acrobat's popups do. - let gesturing = view.comments.gesture.is_some(); + // Annotation hover shows the comment, as Acrobat's popups do; not while drawing + // freehand, where it would cover the next stroke (#429). + let freehand = matches!(tool, QuickTool::Comment(comments::CommentTool::Ink | comments::CommentTool::Eraser)); + let gesturing = view.comments.gesture.is_some() || freehand; for a in info.annotations.iter().filter(|a| a.page == i && a.in_reply_to.is_none() && !gesturing) { let sr = xf.user_rect(info, i, a.rect); if sr.contains(p) && hover_text.is_none() { diff --git a/crates/ui-egui/src/editing.rs b/crates/ui-egui/src/editing.rs index 57c2fef20..fe1736b13 100644 --- a/crates/ui-egui/src/editing.rs +++ b/crates/ui-egui/src/editing.rs @@ -52,6 +52,14 @@ impl PdfCraftApp { } Edit::InsertBlankPage { at, .. } => view.select_pages(&[at.min(info.pages.len() - 1)]), Edit::DeletePages { .. } => view.select_pages(&[]), + // A stroke drawn with the pen stays unselected, so the selection box and + // author popup don't sit over the next stroke (#429). + Edit::AddAnnotation(a) + if matches!(a.shape, pdfcraft_engine::Shape::Ink { .. }) + && self.quick_tool == crate::QuickTool::Comment(crate::comments::CommentTool::Ink) => + { + view.comments.selected = None; + } Edit::AddAnnotation(a) => { // Select the new comment (appended last among the page's comments). let newest = info.annotations.iter().filter(|x| x.page == a.page && x.in_reply_to.is_none()).map(|x| x.index).max(); diff --git a/crates/ui-egui/tests/comments.rs b/crates/ui-egui/tests/comments.rs index cb1dc9a3f..ad36b6f4a 100644 --- a/crates/ui-egui/tests/comments.rs +++ b/crates/ui-egui/tests/comments.rs @@ -171,6 +171,30 @@ fn shapes_and_ink_are_drawn_by_dragging() { assert!((r[0] - 40.0).abs() < 3.0 && (r[1] - 40.0).abs() < 3.0 && (r[2] - 140.0).abs() < 3.0 && (r[3] - 100.0).abs() < 3.0, "{r:?}"); } +#[test] +fn pen_strokes_stay_unselected_so_writing_continues() { + let mut h = harness(|app| app.set_option("quick", "ink").unwrap()); + // No Comments panel: the author's name should only show in a hover popup. + h.state_mut().set_option("panel", "none").unwrap(); + h.run_steps(2); + drag_pt(&mut h, (40.0, 100.0), (140.0, 60.0)); + assert_eq!(h.state().views[0].comments.selected, None, "the first stroke isn't selected"); + // The pointer still rests on the stroke: no author popup covers it. + h.hover_at(at(&h, 140.0, 60.0)); + h.run_steps(3); + assert!(h.query_by_label_contains("Tester").is_none(), "no author popup while drawing"); + drag_pt(&mut h, (60.0, 100.0), (160.0, 60.0)); + let c = comments(&h); + let kinds: Vec<&str> = c.iter().map(|a| a.subtype.as_str()).collect(); + assert_eq!(kinds, ["Ink", "Ink"], "{c:?}"); + assert_eq!(h.state().views[0].comments.selected, None, "nothing is selected after drawing"); + assert_eq!(h.state().quick_tool, QuickTool::Comment(pdfcraft_ui_egui::comments::CommentTool::Ink), "the pen stays on"); + // Other drawn shapes are still selected when made. + h.state_mut().set_option("quick", "square").unwrap(); + drag_pt(&mut h, (180.0, 100.0), (260.0, 40.0)); + assert_eq!(h.state().views[0].comments.selected, Some((0, 2))); +} + #[test] fn sticky_note_composer_posts_and_returns_to_select() { let mut h = harness(|app| app.set_option("quick", "note").unwrap());