M3: a page jumped to in single-page view no longer hops into place

The jump scrolls to MARGIN - GAP above the page. A page that fits has
nothing to scroll, and egui clamps the offset only after drawing the
frame, so the page showed 14 pt too high for a frame and then hopped
down. Clamp the jump to the scroll range before handing it to egui.
This commit is contained in:
Verix
2026-10-15 17:28:46 +02:00
parent dc41044ba7
commit bdb943dc3d
2 changed files with 20 additions and 1 deletions
+5 -1
View File
@@ -2467,7 +2467,11 @@ pub fn document_area(app: &mut PdfCraftApp, index: usize, ui: &mut egui::Ui) {
} else if let Some((page, frac)) = view.goto.take() {
let page = page.min(rects.len() - 1);
let r = rects[page];
scroll = scroll.vertical_scroll_offset((r.top() - y_shift - GAP + frac * r.height()).max(0.0));
// Clamped here: egui clamps only after drawing, so a page that fits was drawn MARGIN - GAP
// too high for a frame and then hopped into place. (`avail` is the viewport, as the
// scroll bars float.)
let max_y = (content_h - avail.height()).max(0.0);
scroll = scroll.vertical_scroll_offset((r.top() - y_shift - GAP + frac * r.height()).max(0.0).min(max_y));
}
let ppp = ui.ctx().pixels_per_point();
let scale = view.render_scale(ppp);
+15
View File
@@ -185,6 +185,21 @@ fn single_page_layout_shows_one_page_at_a_time() {
assert!(rect(&h, 0).is_none() && rect(&h, 1).is_some(), "only page 2");
}
#[test]
fn single_page_jump_draws_a_fitting_page_where_it_stays() {
// A page that fits has nothing to scroll, but the jump to it asked for the gap above it:
// drawn that much too high for a frame, it then hopped into place.
let mut h = harness_stepping(1.0 / 60.0, &[("layout", "single")]);
h.key_press_modifiers(Modifiers::COMMAND, Key::Num0); // fit page
h.run_steps(4);
h.state_mut().set_option("page", "2").unwrap();
h.step();
let first = rect(&h, 1).expect("page 2 drawn in the frame after the jump");
h.run_steps(4);
let settled = rect(&h, 1).expect("page 2");
assert!((first.min.y - settled.min.y).abs() < 0.5, "page 2 drawn where it settles: {first:?} then {settled:?}");
}
#[test]
fn single_page_wheel_pans_instead_when_zoomed_in() {
// The zoomed-in guard: with room to pan, the wheel pans and must not turn pages.