diff --git a/crates/ui-egui/src/canvas.rs b/crates/ui-egui/src/canvas.rs index 1af2a6a4f..38913a943 100644 --- a/crates/ui-egui/src/canvas.rs +++ b/crates/ui-egui/src/canvas.rs @@ -1514,6 +1514,17 @@ impl DocView { self.goto = Some((self.current, 0.0)); } + /// The display shown outside full screen: the one presenting replaced, or the current one. + pub fn normal_display(&self) -> SavedDisplay { + self.presentation.unwrap_or(SavedDisplay { + layout: self.layout, + continuous: self.continuous, + cover: self.cover, + fit: self.fit, + zoom: self.zoom, + }) + } + /// Whether the view is in full screen's one-page-at-a-time display. pub fn presenting(&self) -> bool { self.presentation.is_some() diff --git a/crates/ui-egui/src/last_view.rs b/crates/ui-egui/src/last_view.rs index b575d4a39..691be7107 100644 --- a/crates/ui-egui/src/last_view.rs +++ b/crates/ui-egui/src/last_view.rs @@ -38,17 +38,19 @@ fn absolute(path: &str) -> String { } impl PdfCraftApp { - /// How view `index` shows its document now; `None` for a document without a file. + /// How view `index` shows its document now; `None` for a document without a file. In full + /// screen, the display it will go back to, at the page reached. fn view_to_remember(&self, index: usize) -> Option { let view = self.views.get(index)?; let path = self.session.get(view.id)?.path.as_deref()?; - let zoom = ViewDefaults { fit: view.fit, zoom: view.zoom, ..ViewDefaults::default() }.zoom_name(); + let shown = view.normal_display(); + let zoom = ViewDefaults { fit: shown.fit, zoom: shown.zoom, ..ViewDefaults::default() }.zoom_name(); Some(LastView { path: absolute(path), page: view.current, zoom, - display: canvas::display_token(view.layout, view.continuous).to_string(), - cover: view.cover, + display: canvas::display_token(shown.layout, shown.continuous).to_string(), + cover: shown.cover, }) } diff --git a/crates/ui-egui/src/lib.rs b/crates/ui-egui/src/lib.rs index 386a778cd..33375c5d9 100644 --- a/crates/ui-egui/src/lib.rs +++ b/crates/ui-egui/src/lib.rs @@ -1412,7 +1412,9 @@ impl PdfCraftApp { self.active = Some(self.views.len() - 1); } self.apply_initial_view(self.views.len() - 1, &initial); - // After the document's own initial view, so leaving full screen comes back to it. + // Where the reader left off wins over the file's own initial view (#1767). + self.apply_last_view(self.views.len() - 1); + // After both, so full screen shows one fitted page and leaving it comes back to them. if self.full_screen && let Some(view) = self.views.last_mut() { @@ -1423,8 +1425,6 @@ impl PdfCraftApp { if activate && initial.full_screen { self.pending_full_screen = Some(id); } - // Where the reader left off wins over the file's own initial view (#1767). - self.apply_last_view(self.views.len() - 1); if activate && self.left_open && self.left == LeftPanel::Tool("organize") diff --git a/crates/ui-egui/tests/it/ui.rs b/crates/ui-egui/tests/it/ui.rs index 03db16ce7..5675de66c 100644 --- a/crates/ui-egui/tests/it/ui.rs +++ b/crates/ui-egui/tests/it/ui.rs @@ -1651,3 +1651,40 @@ fn a_file_opened_again_shows_its_last_view() { assert_eq!(app.last_views.len(), 1); assert_eq!((app.last_views[0].page, app.last_views[0].zoom.as_str()), (1, "fit-page")); } + +/// #1767 with full screen: the view remembered while presenting is the one full screen will go +/// back to, and a file reopened in full screen presents one fitted page, then leaves full +/// screen for the remembered view. +#[test] +fn full_screen_neither_is_remembered_nor_hides_the_last_view() { + use pdfcraft_ui_egui::canvas::{Fit, PageLayout}; + let path = std::env::temp_dir().join(format!("pdfcraft-last-view-fs-{}.pdf", std::process::id())).to_string_lossy().into_owned(); + let p = path.clone(); + let mut h = harness(move |app| app.open_bytes("doc.pdf", Some(p), pages_fixture(3)).expect("opens")); + { + let app = h.state_mut(); + app.set_option("zoom", "50").unwrap(); + let view = &mut app.views[0]; + view.set_display(PageLayout::TwoUp, false); + view.go_to_page(2); + view.enter_presentation(); + assert!(view.presenting() && view.fit == Fit::Page); + } + h.run_steps(3); + let saved = h.state().persist(); + h.state_mut().close_tab(0); + let remembered = h.state().last_views[0].clone(); + assert_eq!((remembered.page, remembered.zoom.as_str()), (2, "50%"), "not full screen's fitted page"); + let p = path.clone(); + let mut h = harness(move |app| { + app.restore(&saved); + app.full_screen = true; + app.open_bytes("doc.pdf", Some(p), pages_fixture(3)).expect("opens"); + }); + let v = &h.state().views[0]; + assert!(v.presenting(), "opened in full screen"); + assert_eq!((v.fit, v.continuous, v.current), (Fit::Page, false, 2), "one fitted page, where the reader left off"); + let view = &mut h.state_mut().views[0]; + view.leave_presentation(); + assert_eq!((view.fit, view.zoom, view.layout, view.continuous), (Fit::None, 0.5, PageLayout::TwoUp, false), "the remembered view"); +}