From 91e54eeb3794db809b9f05cbe52d05301ee50328 Mon Sep 17 00:00:00 2001 From: Combiler01 Date: Tue, 10 Nov 2026 23:08:08 +0530 Subject: [PATCH] fix(ui): preserve presentation display state when applying preferences --- crates/ui-egui/src/canvas/zoom.rs | 5 ++ crates/ui-egui/src/dialogs/preferences.rs | 69 ++++++++++++++------ crates/ui-egui/tests/it/view.rs | 79 +++++++++++++++++++++++ 3 files changed, 133 insertions(+), 20 deletions(-) diff --git a/crates/ui-egui/src/canvas/zoom.rs b/crates/ui-egui/src/canvas/zoom.rs index 1e0e456073..e9e2eae82b 100644 --- a/crates/ui-egui/src/canvas/zoom.rs +++ b/crates/ui-egui/src/canvas/zoom.rs @@ -62,6 +62,11 @@ impl DocView { }) } + /// The display saved before entering full screen, while presenting. + pub fn saved_display_mut(&mut self) -> Option<&mut SavedDisplay> { + self.presentation.as_mut() + } + /// 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/dialogs/preferences.rs b/crates/ui-egui/src/dialogs/preferences.rs index b40456c987..f2836d6a41 100644 --- a/crates/ui-egui/src/dialogs/preferences.rs +++ b/crates/ui-egui/src/dialogs/preferences.rs @@ -755,33 +755,62 @@ fn card_documents_and_view(ui: &mut egui::Ui, app: &mut PdfCraftApp, t: &Tokens, if app.always_default_view && (always_changed || layout_changed || continuous_changed || gaps_changed || fit_changed || zoom_changed) { let defaults = app.view_defaults; for view in &mut app.views { - view.set_display(defaults.layout, defaults.continuous); view.set_page_gaps(defaults.show_page_gaps); - match defaults.fit { - Fit::None => view.set_zoom(defaults.zoom), - fit if view.fit != fit => view.set_fit(fit), - _ => {} + if let Some(saved) = view.saved_display_mut() { + saved.layout = defaults.layout; + saved.continuous = defaults.continuous; + saved.fit = defaults.fit; + if defaults.fit == Fit::None { + saved.zoom = defaults.zoom; + } + } else { + view.set_display(defaults.layout, defaults.continuous); + match defaults.fit { + Fit::None => view.set_zoom(defaults.zoom), + fit if view.fit != fit => view.set_fit(fit), + _ => {} + } } } } else if let Some(i) = app.active { - if layout_changed { - app.views[i].set_layout(layout_choice); - } - if continuous_changed { - app.views[i].set_continuous(continuous); - } + let view = &mut app.views[i]; if gaps_changed { - app.views[i].set_page_gaps(show_page_gaps); + view.set_page_gaps(show_page_gaps); } - if fit_changed { - match app.view_defaults.fit { - Fit::None => app.views[i].set_zoom(app.view_defaults.zoom), - fit if app.views[i].fit != fit => app.views[i].set_fit(fit), - _ => {} + if let Some(saved) = view.saved_display_mut() { + if layout_changed { + saved.layout = layout_choice; + } + if continuous_changed { + saved.continuous = continuous; + } + if fit_changed { + saved.fit = app.view_defaults.fit; + if app.view_defaults.fit == Fit::None { + saved.zoom = app.view_defaults.zoom; + } + } + if zoom_changed { + saved.fit = Fit::None; + saved.zoom = app.view_defaults.zoom; + } + } else { + if layout_changed { + view.set_layout(layout_choice); + } + if continuous_changed { + view.set_continuous(continuous); + } + if fit_changed { + match app.view_defaults.fit { + Fit::None => view.set_zoom(app.view_defaults.zoom), + fit if view.fit != fit => view.set_fit(fit), + _ => {} + } + } + if zoom_changed { + view.set_zoom(app.view_defaults.zoom); } - } - if zoom_changed { - app.views[i].set_zoom(app.view_defaults.zoom); } } ctx.checkbox(ui, &mut app.text_links, tl!("Open web and email addresses written in the page text"), t); diff --git a/crates/ui-egui/tests/it/view.rs b/crates/ui-egui/tests/it/view.rs index 020397ddcb..aaf6e6cf00 100644 --- a/crates/ui-egui/tests/it/view.rs +++ b/crates/ui-egui/tests/it/view.rs @@ -1296,6 +1296,85 @@ fn preferences_toggle_continuous_scrolling_updates_active_document() { assert!(h.state().views[0].continuous(), "active document view is updated"); } +#[test] +fn preferences_during_full_screen_updates_saved_normal_display_and_restores_on_exit() { + use egui_kittest::kittest::Queryable; + use pdfcraft_ui_egui::canvas::Fit; + + let mut h = harness(&[("continuous", "off"), ("zoom", "50")]); + let v0 = &h.state().views[0]; + assert!(!v0.continuous()); + assert_eq!(v0.fit, Fit::None); + assert_eq!(v0.zoom, 0.5); + + h.state_mut().views[0].enter_presentation(); + assert!(h.state().views[0].presenting()); + assert!(!h.state().views[0].continuous()); + assert_eq!(h.state().views[0].fit, Fit::Page); + + assert!(h.state_mut().execute("app.preferences")); + h.run_steps(3); + h.get_by_label("Always use my default zoom and page layout").scroll_to_me(); + h.run_steps(4); + h.get_by_label("Always use my default zoom and page layout").click(); + h.run_steps(2); + assert!(h.state().always_default_view); + + { + let v = &h.state().views[0]; + assert!(v.presenting(), "presentation display is preserved"); + assert!(!v.continuous(), "presentation display is not continuous"); + assert_eq!(v.fit, Fit::Page, "presentation display stays fitted to page"); + assert!(v.normal_display().continuous, "saved normal display updated to continuous"); + assert_eq!(v.normal_display().fit, Fit::Width, "saved normal display updated to default fit width"); + } + + h.state_mut().views[0].leave_presentation(); + { + let v = &h.state().views[0]; + assert!(!v.presenting()); + assert!(v.continuous(), "continuous scrolling restored from updated preferences"); + assert_eq!(v.fit, Fit::Width, "fit width restored from updated preferences"); + } +} + +#[test] +fn preferences_toggle_continuous_during_full_screen_updates_saved_normal_display() { + use egui_kittest::kittest::Queryable; + use pdfcraft_ui_egui::canvas::Fit; + + let mut h = harness(&[("default-continuous", "off"), ("continuous", "off")]); + assert!(!h.state().views[0].continuous()); + + h.state_mut().views[0].enter_presentation(); + assert!(h.state().views[0].presenting()); + assert!(!h.state().views[0].continuous()); + assert_eq!(h.state().views[0].fit, Fit::Page); + + assert!(h.state_mut().execute("app.preferences")); + h.run_steps(3); + h.get_by_label("Continuous scrolling").scroll_to_me(); + h.run_steps(4); + h.get_by_label("Continuous scrolling").click(); + h.run_steps(2); + + assert!(h.state().view_defaults.continuous); + { + let v = &h.state().views[0]; + assert!(v.presenting(), "presentation display is preserved"); + assert!(!v.continuous(), "presentation display is not continuous"); + assert_eq!(v.fit, Fit::Page, "presentation display stays fitted to page"); + assert!(v.normal_display().continuous, "saved normal display updated to continuous"); + } + + h.state_mut().views[0].leave_presentation(); + { + let v = &h.state().views[0]; + assert!(!v.presenting()); + assert!(v.continuous(), "continuous scrolling restored on exit"); + } +} + #[test] fn preferences_set_the_default_zoom() { use egui_kittest::kittest::Queryable;