diff --git a/crates/ui-egui/src/canvas.rs b/crates/ui-egui/src/canvas.rs index 95767e2c06..97e867a090 100644 --- a/crates/ui-egui/src/canvas.rs +++ b/crates/ui-egui/src/canvas.rs @@ -1645,6 +1645,9 @@ fn draw_pages( if resp.secondary_clicked() { // Set again below when the right-click lands on a link. view.links.context = None; + // Set again below by the page right-clicked: a right-click off the pages (between them, + // beside one) anchors no page's menu, which then acts on the current page. + view.comments.context_at = None; let mut over_image = false; if tool == QuickTool::EditText { let pointer_pos = ptr.pos; diff --git a/crates/ui-egui/src/canvas/page_input.rs b/crates/ui-egui/src/canvas/page_input.rs index 2f74110d7c..49cf70067b 100644 --- a/crates/ui-egui/src/canvas/page_input.rs +++ b/crates/ui-egui/src/canvas/page_input.rs @@ -105,9 +105,9 @@ pub(super) fn page_tool_input(ui: &mut egui::Ui, view: &mut DocView, frame: &mut _ => false, }; // A right-click while the primary button is held (a comment moved, a box drawn) leaves the - // selections that press acts on alone; egui ends the press's own interaction when another button - // goes down, so the button is what tells. A touch's long press, which egui reports as a - // right-click with the finger still down, opens its menu. + // selections that press acts on alone. egui ends the press's own interaction when any button is + // released, the right-click's own frame included, so the button is what tells. A touch's long + // press, which egui reports as a right-click with the finger still down, opens its menu. let press_held = ptr.primary_down && !resp.long_touched(); let context = frame.right_click_on(xf.rect).and_then(|p| right_click(&hits, &under, view, p, press_held)); // A mark already placed takes its own press (comments, below), as does one being moved on this diff --git a/crates/ui-egui/src/canvas/page_pointer/tests.rs b/crates/ui-egui/src/canvas/page_pointer/tests.rs index f9280e9045..40548a998a 100644 --- a/crates/ui-egui/src/canvas/page_pointer/tests.rs +++ b/crates/ui-egui/src/canvas/page_pointer/tests.rs @@ -191,10 +191,10 @@ const PAGE_MODULES: [&str; 37] = [ ]; /// What a file that acts on the pages uses: the pointer, a tool's or the comments' page context, -/// what a press is to a page, or the router's hits and owners. Such a file is a page module. One -/// that acts on the pages through the page view's response and a bare point alone uses none of -/// them (`canvas/image_pick.rs`): PAGE_MODULES lists it by hand. -const PAGE_MODULE_MARKS: [&str; 5] = ["PagePointer", "PageToolContext", "PageCx", "PagePress", "page_router::"]; +/// what a press is to a page, the router's hits and owners, or the router itself. Such a file is a +/// page module. One that acts on the pages through the page view's response and a bare point alone +/// uses none of them (`canvas/image_pick.rs`): PAGE_MODULES lists it by hand. +const PAGE_MODULE_MARKS: [&str; 6] = ["PagePointer", "PageToolContext", "PageCx", "PagePress", "page_router::", ".router."]; /// The router's own files, which define what page modules use. const ROUTER_FILES: [&str; 3] = ["canvas/page_pointer.rs", "canvas/page_router.rs", "canvas/page_cursor.rs"]; diff --git a/crates/ui-egui/src/tools/link_ui.rs b/crates/ui-egui/src/tools/link_ui.rs index 041edaf1c7..63db81b9f3 100644 --- a/crates/ui-egui/src/tools/link_ui.rs +++ b/crates/ui-egui/src/tools/link_ui.rs @@ -70,12 +70,14 @@ pub(crate) fn hit(xf: &PageXform, info: &DocInfo, page: usize, links: &[LinkItem if !xf.rect.contains(p) { return None; } - let index = if tool == QuickTool::Link { - links.iter().rfind(|l| l.page == page && screen_rect(xf, info, page, l.rect).expand(LINK_TOOL_MARGIN).contains(p))?.index + let (index, link) = if tool == QuickTool::Link { + let index = links.iter().rfind(|l| l.page == page && screen_rect(xf, info, page, l.rect).expand(LINK_TOOL_MARGIN).contains(p))?.index; + (index, info.links.iter().find(|l| l.page == page && l.index == index)) } else { - info.links.iter().rfind(|l| l.page == page && xf.user_rect(info, page, l.rect).contains(p))?.index + let link = info.links.iter().rfind(|l| l.page == page && xf.user_rect(info, page, l.rect).contains(p))?; + (link.index, Some(link)) }; - let tip = info.links.iter().find(|l| l.page == page && l.index == index).map(|l| target_label(info, &l.target)); + let tip = link.map(|l| target_label(info, &l.target)); let declines_drag = tool == QuickTool::Link; Some(Hit { tip, declines_drag, ..Hit::new(Owner::Link { index }, Layer::Link, egui::CursorIcon::PointingHand) }) } diff --git a/crates/ui-egui/tests/it/pointer.rs b/crates/ui-egui/tests/it/pointer.rs index 51444f4517..8364f3a635 100644 --- a/crates/ui-egui/tests/it/pointer.rs +++ b/crates/ui-egui/tests/it/pointer.rs @@ -1708,3 +1708,20 @@ fn a_fill_and_sign_click_places_nothing_while_a_mark_is_moved() { mouse_click(&mut h, blank); assert_eq!(marks(&h), before, "no mark is placed"); } + +/// A right-click between the pages anchors no page's menu, so Delete page and Paste act on the +/// current page. The menu used to keep the anchor of the last right-click on a page. +#[test] +fn a_right_click_between_the_pages_anchors_no_pages_menu() { + let mut h = open(two_pages_pdf(), "100", false); + h.run_steps(2); + h.state_mut().views[0].comments.context_at = Some((0, [10.0, 10.0])); + let (one, two) = { + let v = &h.state().views[0]; + (v.page_screen_rect(0).expect("page 1 on screen"), v.page_screen_rect(1).expect("page 2 on screen")) + }; + let gap = egui::pos2(one.center().x, (one.max.y + two.min.y) / 2.0); + assert!(!one.contains(gap) && !two.contains(gap), "between the pages: {one:?} {two:?}"); + right_click(&mut h, gap); + assert_eq!(h.state().views[0].comments.context_at, None); +}