From 23a032ef3b2e7a84b8e4fb873c7453faabb046db Mon Sep 17 00:00:00 2001 From: mtlcl410 <2368091+mtlcl410@users.noreply.github.com> Date: Mon, 19 Oct 2026 19:15:58 +0800 Subject: [PATCH] fix(engine): a reload keeps reading colours and hidden comments (#3443) `Session::reload` (the file changed on disk) opens the new bytes with a default render config, so a document shown white on black, or with its comments hidden, went back to the file's own colours and comments until the preference was toggled. The UI re-applies the preference only on open. Reload now carries both display settings over and rebuilds the renderer with them. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01Gv2WwdgjmBz33GWkwgNn3Q --- crates/engine/src/lib.rs | 9 +++++++++ crates/engine/src/tests.rs | 41 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 50 insertions(+) diff --git a/crates/engine/src/lib.rs b/crates/engine/src/lib.rs index 8f39248ab..f1c82dab6 100644 --- a/crates/engine/src/lib.rs +++ b/crates/engine/src/lib.rs @@ -4236,6 +4236,15 @@ impl Session { let at = self.docs.iter().position(|d| d.id == new_id).ok_or_else(|| OpenError::Invalid("the new version was not kept".into()))?; let mut doc = self.docs.remove(at); doc.id = id; + // How the document is shown is the reader's, not the file's: reading colours and hidden + // comments stay as they were (#3443). `open` built the renderer with the defaults. + if let Some(old) = self.docs.get(old) + && (doc.config.reading_colors != old.config.reading_colors || doc.config.hide_comments != old.config.hide_comments) + { + doc.config.reading_colors = old.config.reading_colors; + doc.config.hide_comments = old.config.hide_comments; + doc.renderer = RenderPool::new(doc.display.clone(), render_threads(), doc.config.clone()); + } // Caches keyed by the edit generation (edit lines, images, measurements) must see a new // one; there is nothing new to autosave. doc.generation = generation + 1; diff --git a/crates/engine/src/tests.rs b/crates/engine/src/tests.rs index f125c41da..c4075c602 100644 --- a/crates/engine/src/tests.rs +++ b/crates/engine/src/tests.rs @@ -2709,6 +2709,47 @@ fn reload_reads_the_new_file_into_the_same_document() { assert_eq!(s.docs().len(), 2); } +/// #3443: reloading the file (it changed on disk) keeps how the reader shows it. Reading colours +/// reached the new renderer, not just the setting; hidden comments stay hidden. Each setting is +/// checked alone, so neither one rides on the other being changed. +#[test] +fn reload_keeps_reading_colours_and_hidden_comments() { + let dark_share = |s: &Session, id: DocId| { + let doc = s.get(id).unwrap(); + doc.renderer.set_queue(vec![pdfcraft_render::RenderRequest { + page: 0, + kind: pdfcraft_render::RequestKind::Pixels, + scale: 1.0, + ..Default::default() + }]); + let deadline = std::time::Instant::now() + std::time::Duration::from_secs(30); + let page = loop { + if let Some(page) = doc.renderer.try_recv() { + break page; + } + assert!(std::time::Instant::now() < deadline, "page render did not finish"); + std::thread::yield_now(); + }; + let (px, _) = page.rgba.as_chunks::<4>(); + px.iter().filter(|p| p[0] < 64 && p[1] < 64 && p[2] < 64).count() as f64 / px.len() as f64 + }; + let (mut s, id) = session_with(1); + assert!(dark_share(&s, id) < 0.1, "a white page as the file draws it"); + assert!(s.set_reading_colors(id, ReadingColors::WHITE_ON_BLACK)); + assert!(dark_share(&s, id) > 0.9, "white on black"); + s.reload(id, Arc::new(fixture(2))).unwrap(); + assert_eq!(s.reading_colors(id), Some(ReadingColors::WHITE_ON_BLACK)); + assert!(dark_share(&s, id) > 0.9, "the reloaded page is drawn white on black too"); + assert!(!s.get(id).unwrap().comments_hidden()); + + let (mut s, id) = session_with(1); + assert!(s.set_hide_comments(id, true)); + s.reload(id, Arc::new(fixture(2))).unwrap(); + assert!(s.get(id).unwrap().comments_hidden(), "hidden comments stay hidden"); + assert_eq!(s.reading_colors(id), Some(ReadingColors::default())); + assert!(dark_share(&s, id) < 0.1); +} + #[test] fn revert_goes_back_to_the_saved_version() { let (mut s, id) = session_with(2);