From ca76c52511eadc96b3e9882c4e5c8e436751d46c Mon Sep 17 00:00:00 2001 From: Combiler01 Date: Sat, 17 Oct 2026 22:52:53 +0530 Subject: [PATCH] Restored some code --- .github/workflows/ci.yml | 4 +- apps/pdfcraft/src/main.rs | 2 - crates/ui-egui/src/clipboard.rs | 38 ------------------ crates/ui-egui/src/content_ui.rs | 69 +++++++++----------------------- crates/ui-egui/src/create_ui.rs | 22 ++-------- crates/ui-egui/src/image_pick.rs | 2 +- crates/ui-egui/src/lib.rs | 47 +++------------------- crates/ui-egui/src/zoom_snap.rs | 13 ++---- crates/ui-egui/tests/editing.rs | 26 ++---------- deny.toml | 5 --- 10 files changed, 38 insertions(+), 190 deletions(-) delete mode 100644 crates/ui-egui/src/clipboard.rs diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 388b44f032..7eca1256b0 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -85,11 +85,11 @@ jobs: - name: Test if: runner.os != 'Linux' - run: cargo test --workspace + run: cargo test --workspace -- --test-threads=1 - name: Test (with craft-fonts) if: runner.os == 'Linux' - run: cargo test --workspace + run: cargo test --workspace -- --test-threads=1 - name: Layering if: runner.os == 'Linux' diff --git a/apps/pdfcraft/src/main.rs b/apps/pdfcraft/src/main.rs index 5af9fa3fc0..7a0bb20432 100644 --- a/apps/pdfcraft/src/main.rs +++ b/apps/pdfcraft/src/main.rs @@ -368,8 +368,6 @@ fn app_creator<'a>( Box::new(move |cc| { started.set(true); let mut app = PdfCraftApp::new(); - app.system_clipboard = true; - app.clipboard_override = None; // First start (or settings from before Units existed): the region's unit. app.units = pdfcraft_ui_egui::units::Unit::system(); #[cfg(target_os = "linux")] diff --git a/crates/ui-egui/src/clipboard.rs b/crates/ui-egui/src/clipboard.rs deleted file mode 100644 index a30304fa66..0000000000 --- a/crates/ui-egui/src/clipboard.rs +++ /dev/null @@ -1,38 +0,0 @@ -//! Deterministic in-memory clipboard for headless UI tests and automation. -//! -//! Prevents headless tests running in parallel from competing for the native -//! operating system clipboard, eliminating concurrency races and OS heap corruption. - -use std::path::PathBuf; - -/// A deterministic, in-memory mock clipboard for tests. -#[derive(Clone, Debug, Default, PartialEq, Eq)] -pub struct MockClipboard { - pub text: Option, - pub image: Option<(usize, usize, Vec)>, - pub files: Option>, -} - -impl MockClipboard { - /// Creates an empty mock clipboard. - pub fn new() -> Self { - Self::default() - } - - /// Creates a mock clipboard containing plain text. - pub fn with_text(text: impl Into) -> Self { - Self { text: Some(text.into()), image: None, files: None } - } - - /// Creates a mock clipboard containing an image (width, height, RGBA bytes). - pub fn with_image(width: usize, height: usize, rgba: Vec) -> Self { - Self { text: None, image: Some((width, height, rgba)), files: None } - } - - /// Clears all clipboard contents. - pub fn clear(&mut self) { - self.text = None; - self.image = None; - self.files = None; - } -} diff --git a/crates/ui-egui/src/content_ui.rs b/crates/ui-egui/src/content_ui.rs index c6d914d243..61be108256 100644 --- a/crates/ui-egui/src/content_ui.rs +++ b/crates/ui-egui/src/content_ui.rs @@ -821,19 +821,14 @@ impl crate::PdfCraftApp { return false; }; let copied = pixels.and_then(|(w, h, rgba)| { - if let Some(mock) = &mut self.clipboard_override { - mock.image = Some((w as usize, h as usize, rgba.clone())); - mock.text = None; - } else { - #[cfg(not(target_arch = "wasm32"))] - if self.system_clipboard { - let img = arboard::ImageData { width: w as usize, height: h as usize, bytes: std::borrow::Cow::Borrowed(&rgba) }; - arboard::Clipboard::new().and_then(|mut c| c.set_image(img)).map_err(|e| e.to_string())?; - } - #[cfg(target_arch = "wasm32")] - if self.system_clipboard { - return Err("the web version can't put images on the clipboard yet; use Save Image As".to_string()); - } + #[cfg(not(target_arch = "wasm32"))] + if self.system_clipboard { + let img = arboard::ImageData { width: w as usize, height: h as usize, bytes: std::borrow::Cow::Borrowed(&rgba) }; + arboard::Clipboard::new().and_then(|mut c| c.set_image(img)).map_err(|e| e.to_string())?; + } + #[cfg(target_arch = "wasm32")] + if self.system_clipboard { + return Err("the web version can't put images on the clipboard yet; use Save Image As".to_string()); } self.last_copied_image = Some((w, h, rgba)); Ok((w, h)) @@ -900,25 +895,11 @@ impl crate::PdfCraftApp { /// Whether there is an image in the in-memory clipboard or system clipboard ready to paste. pub fn can_paste_image(&self) -> bool { - if let Some(mock) = &self.clipboard_override { - if mock.text.as_ref().is_some_and(|t| !t.is_empty()) { - return false; - } - if mock.image.is_some() { - return true; - } - return self.last_copied_image.is_some() || self.last_copied_file.is_some(); - } #[cfg(not(target_arch = "wasm32"))] { if self.system_clipboard && let Ok(mut cb) = arboard::Clipboard::new() { - if let Ok(text) = cb.get_text() - && !text.is_empty() - { - return false; - } return cb.get_image().is_ok(); } } @@ -937,33 +918,19 @@ impl crate::PdfCraftApp { return false; } - let (has_system_cb, os_image, system_has_text) = if let Some(mock) = &self.clipboard_override { - let has_text = mock.text.as_ref().is_some_and(|t| !t.is_empty()); - let img = mock.image.clone(); - (true, img, has_text) - } else { - #[cfg(not(target_arch = "wasm32"))] - if self.system_clipboard { - if let Ok(mut cb) = arboard::Clipboard::new() { - let has_text = cb.get_text().map(|t| !t.is_empty()).unwrap_or(false); - let img_opt = cb.get_image().ok().map(|img| (img.width, img.height, img.bytes.to_vec())); - (true, img_opt, has_text) - } else { - (false, None, false) - } + #[cfg(not(target_arch = "wasm32"))] + let (has_system_cb, os_image) = if self.system_clipboard { + if let Ok(mut cb) = arboard::Clipboard::new() { + let img_opt = cb.get_image().ok().map(|img| (img.width, img.height, img.bytes.to_vec())); + (true, img_opt) } else { - (false, None, false) + (false, None) } - #[cfg(target_arch = "wasm32")] - (false, None, false) + } else { + (false, None) }; - - if system_has_text { - self.last_copied_image = None; - self.last_copied_file = None; - self.last_copied_image_rect = None; - return false; - } + #[cfg(target_arch = "wasm32")] + let (has_system_cb, os_image): (bool, Option<(usize, usize, Vec)>) = (false, None); let image_data: Option<(String, Vec)> = if has_system_cb { match os_image { diff --git a/crates/ui-egui/src/create_ui.rs b/crates/ui-egui/src/create_ui.rs index e1ecbbe1f1..fb8f1b2e27 100644 --- a/crates/ui-egui/src/create_ui.rs +++ b/crates/ui-egui/src/create_ui.rs @@ -111,24 +111,10 @@ impl PdfCraftApp { /// Create ▸ Clipboard: a new document from the image (one page, its size) or the text on /// the clipboard, as Acrobat does. pub(crate) fn create_from_clipboard(&mut self) { - let clip = if let Some(mock) = &self.clipboard_override { - if let Some((w, h, rgba)) = &mock.image { - Some(Clip::Image { width: *w, height: *h, rgba: rgba.clone() }) - } else { - mock.text.as_ref().map(|t| Clip::Text(t.clone())) - } - } else if self.system_clipboard { - #[cfg(not(target_arch = "wasm32"))] - { - read_clipboard() - } - #[cfg(target_arch = "wasm32")] - { - None - } - } else { - None - }; + #[cfg(not(target_arch = "wasm32"))] + let clip = read_clipboard(); + #[cfg(target_arch = "wasm32")] + let clip: Option = None; match clip { Some(c) => { if let Err(e) = self.create_from_clip(c) { diff --git a/crates/ui-egui/src/image_pick.rs b/crates/ui-egui/src/image_pick.rs index 9be0a8efc3..9e117395cd 100644 --- a/crates/ui-egui/src/image_pick.rs +++ b/crates/ui-egui/src/image_pick.rs @@ -203,7 +203,7 @@ impl PdfCraftApp { /// previous copy, and puts that file on the system clipboard. #[cfg(not(target_arch = "wasm32"))] fn put_file_on_clipboard(&self, name: &str, bytes: &[u8]) -> Result<(), String> { - if self.clipboard_override.is_some() || !self.system_clipboard { + if !self.system_clipboard { return Ok(()); } let dir = clipboard_dir().ok_or("there is no folder for the copied file")?; diff --git a/crates/ui-egui/src/lib.rs b/crates/ui-egui/src/lib.rs index bc5970aef5..ba8fd6390d 100644 --- a/crates/ui-egui/src/lib.rs +++ b/crates/ui-egui/src/lib.rs @@ -44,8 +44,6 @@ mod combine_ui; pub mod docking; pub use combine_ui::{Columns as CombineColumns, CombineView, Lock as CombineLock, SortKey}; mod camera_ui; -pub mod clipboard; -pub use clipboard::MockClipboard; mod commands; mod comment_props; pub mod comments; @@ -734,9 +732,6 @@ pub struct PdfCraftApp { pub last_copied_file: Option<(String, Vec)>, pub last_copied_image_rect: Option<[f64; 4]>, pub system_clipboard: bool, - /// Deterministic in-memory clipboard for headless UI tests and automation. - /// When `Some`, clipboard operations use this mock instead of the OS clipboard. - pub clipboard_override: Option, /// Attach file: the file to attach instead of asking (tests, automation). pub attach_override: Option<(String, Vec)>, /// Duplicate Field: which field and onto which pages. @@ -1037,8 +1032,7 @@ impl PdfCraftApp { last_copied_image: None, last_copied_file: None, last_copied_image_rect: None, - system_clipboard: false, - clipboard_override: Some(MockClipboard::default()), + system_clipboard: true, attach_override: None, duplicate_draft: None, form_preview: false, @@ -2514,31 +2508,6 @@ impl PdfCraftApp { } } - /// Injects a deterministic mock clipboard for headless tests. - pub fn set_mock_clipboard(&mut self, mock: MockClipboard) { - self.clipboard_override = Some(mock); - } - - /// Sets plain text on the mock clipboard (creating one if absent). - pub fn set_mock_clipboard_text(&mut self, text: impl Into) { - if let Some(mock) = &mut self.clipboard_override { - mock.text = Some(text.into()); - mock.image = None; - } else { - self.clipboard_override = Some(MockClipboard::with_text(text)); - } - } - - /// Sets an image on the mock clipboard (creating one if absent). - pub fn set_mock_clipboard_image(&mut self, width: usize, height: usize, rgba: Vec) { - if let Some(mock) = &mut self.clipboard_override { - mock.image = Some((width, height, rgba)); - mock.text = None; - } else { - self.clipboard_override = Some(MockClipboard::with_image(width, height, rgba)); - } - } - /// `true` while any open document still waits for page renders (used by headless capture). pub fn render_pending(&self) -> bool { self.views.iter().any(|v| v.render_pending()) @@ -2981,18 +2950,14 @@ impl PdfCraftApp { self.cut_page_image(sel.page, sel.index); } if paste { - let system_has_text = if let Some(mock) = &self.clipboard_override { - mock.text.as_ref().is_some_and(|t| !t.is_empty()) + #[cfg(not(target_arch = "wasm32"))] + let system_has_text = if self.system_clipboard { + arboard::Clipboard::new().and_then(|mut cb| cb.get_text()).map(|t| !t.is_empty()).unwrap_or(false) } else { - #[cfg(not(target_arch = "wasm32"))] - if self.system_clipboard { - arboard::Clipboard::new().and_then(|mut cb| cb.get_text()).map(|t| !t.is_empty()).unwrap_or(false) - } else { - false - } - #[cfg(target_arch = "wasm32")] false }; + #[cfg(target_arch = "wasm32")] + let system_has_text = false; if paste_event_text.is_some() || system_has_text { self.last_copied_image = None; diff --git a/crates/ui-egui/src/zoom_snap.rs b/crates/ui-egui/src/zoom_snap.rs index d74627e877..eb2cc86727 100644 --- a/crates/ui-egui/src/zoom_snap.rs +++ b/crates/ui-egui/src/zoom_snap.rs @@ -138,15 +138,10 @@ impl PdfCraftApp { return Err(e); } let (w, h) = (out.width, out.height); - if let Some(mock) = &mut self.clipboard_override { - mock.image = Some((w as usize, h as usize, out.rgba.to_vec())); - mock.text = None; - } else { - #[cfg(not(target_arch = "wasm32"))] - if self.system_clipboard { - let img = arboard::ImageData { width: w as usize, height: h as usize, bytes: std::borrow::Cow::Borrowed(&out.rgba) }; - arboard::Clipboard::new().and_then(|mut c| c.set_image(img)).map_err(|e| e.to_string())?; - } + #[cfg(not(target_arch = "wasm32"))] + if self.system_clipboard { + let img = arboard::ImageData { width: w as usize, height: h as usize, bytes: std::borrow::Cow::Borrowed(&out.rgba) }; + arboard::Clipboard::new().and_then(|mut c| c.set_image(img)).map_err(|e| e.to_string())?; } self.last_snapshot = Some((w, h, out.rgba)); Ok((w, h)) diff --git a/crates/ui-egui/tests/editing.rs b/crates/ui-egui/tests/editing.rs index 02e40bdad3..a9c3dca38a 100644 --- a/crates/ui-egui/tests/editing.rs +++ b/crates/ui-egui/tests/editing.rs @@ -44,7 +44,6 @@ fn harness(pages: usize, setup: impl FnOnce(&mut PdfCraftApp) + 'static) -> Harn let mut h = builder.build_eframe(move |_cc| { let mut app = PdfCraftApp::new(); app.set_option("language", "en").unwrap(); - app.clipboard_override = Some(pdfcraft_ui_egui::MockClipboard::default()); app.open_bytes("doc.pdf", None, fixture(pages)).expect("fixture opens"); setup(&mut app); app @@ -4979,13 +4978,11 @@ fn stale_clipboard_plain_text_does_not_paste_image() { h.state_mut().last_copied_image = Some((10, 10, vec![0; 400])); h.state_mut().last_copied_file = Some(("cached.png".to_string(), vec![1, 2, 3])); h.state_mut().system_clipboard = true; - h.state_mut().clipboard_override = None; - // Set actual system clipboard to plain text, asserting success explicitly + // Set actual system clipboard to plain text #[cfg(not(target_arch = "wasm32"))] - { - let mut cb = arboard::Clipboard::new().expect("acquire OS clipboard"); - cb.set_text("just plain text").expect("set OS clipboard text"); + if let Ok(mut cb) = arboard::Clipboard::new() { + cb.set_text("just plain text").ok(); } // A paste event containing plain text clears internal image cache and does not paste image @@ -5002,23 +4999,6 @@ fn stale_clipboard_plain_text_does_not_paste_image() { assert_eq!(doc.page_images(0).len(), 0, "no image pasted on the page"); } -#[test] -fn deterministic_mock_clipboard_plain_text_does_not_paste_image() { - let mut h = harness(1, |_| {}); - h.run_steps(4); - h.state_mut().last_copied_image = Some((10, 10, vec![0; 400])); - h.state_mut().last_copied_file = Some(("cached.png".to_string(), vec![1, 2, 3])); - - // Inject plain text into the mock clipboard - h.state_mut().set_mock_clipboard_text("just plain text"); - - assert!(!h.state().can_paste_image(), "cannot paste image when mock clipboard has text"); - assert!(!h.state_mut().paste_image(0, None), "must not paste stale cached image"); - - let doc = h.state().session.get(h.state().views[0].id).unwrap(); - assert_eq!(doc.page_images(0).len(), 0, "no image pasted on the page"); -} - #[test] fn rotated_image_selection_and_crop() { let mut png = Vec::new(); diff --git a/deny.toml b/deny.toml index b42a16b547..2362d56822 100644 --- a/deny.toml +++ b/deny.toml @@ -48,11 +48,6 @@ ignore = [ # winprint's fmt-derive (craft-print's Windows spooler), so it runs at compile time on Windows # and is not in the binary. { id = "RUSTSEC-2024-0370", reason = "compile-time proc macro of winprint's fmt-derive (craft-print Windows printing, #1107)" }, - # zbus_names, zvariant, and zvariant_derive are unmaintained (no vulnerability). Reached via - # eframe -> accesskit_unix until upstream migrates to zbus v6. - { id = "RUSTSEC-2026-0370", reason = "unmaintained zbus_names dependency via eframe -> accesskit_unix until upstream migrates to zbus v6" }, - { id = "RUSTSEC-2026-0371", reason = "unmaintained zvariant dependency via eframe -> accesskit_unix until upstream migrates to zbus v6" }, - { id = "RUSTSEC-2026-0372", reason = "unmaintained zvariant_derive dependency via eframe -> accesskit_unix until upstream migrates to zbus v6" }, ] # egui's default UI fonts (Ubuntu-Light, Hack, emoji-icon-font): font licences on the AGENTS.md