diff --git a/.changes/clipboard-feature.md b/.changes/clipboard-feature.md new file mode 100644 index 000000000..7be1cbf66 --- /dev/null +++ b/.changes/clipboard-feature.md @@ -0,0 +1,7 @@ +--- +"tauri": patch +"tauri-runtime": minor +"tauri-runtime-wry": minor +--- + +**Breaking change::* Added the `clipboard` Cargo feature. diff --git a/core/tauri-runtime-wry/Cargo.toml b/core/tauri-runtime-wry/Cargo.toml index 869342cd2..4865778ac 100644 --- a/core/tauri-runtime-wry/Cargo.toml +++ b/core/tauri-runtime-wry/Cargo.toml @@ -42,3 +42,4 @@ objc-exception = [ "wry/objc-exception" ] gtk-tray = [ "wry/gtk-tray" ] ayatana-tray = [ "wry/ayatana-tray" ] global-shortcut = [ "tauri-runtime/global-shortcut" ] +clipboard = [ "tauri-runtime/clipboard" ] diff --git a/core/tauri-runtime-wry/src/clipboard.rs b/core/tauri-runtime-wry/src/clipboard.rs new file mode 100644 index 000000000..e0315c556 --- /dev/null +++ b/core/tauri-runtime-wry/src/clipboard.rs @@ -0,0 +1,62 @@ +// Copyright 2019-2021 Tauri Programme within The Commons Conservancy +// SPDX-License-Identifier: Apache-2.0 +// SPDX-License-Identifier: MIT + +//! Clipboard implementation. + +use crate::{getter, Context, Message}; + +use std::sync::{ + mpsc::{channel, Sender}, + Arc, Mutex, +}; + +use tauri_runtime::{ClipboardManager, Result, UserEvent}; +pub use wry::application::clipboard::Clipboard; + +#[derive(Debug, Clone)] +pub enum ClipboardMessage { + WriteText(String, Sender<()>), + ReadText(Sender>), +} + +#[derive(Debug, Clone)] +pub struct ClipboardManagerWrapper { + pub context: Context, +} + +// SAFETY: this is safe since the `Context` usage is guarded on `send_user_message`. +#[allow(clippy::non_send_fields_in_send_ty)] +unsafe impl Sync for ClipboardManagerWrapper {} + +impl ClipboardManager for ClipboardManagerWrapper { + fn read_text(&self) -> Result> { + let (tx, rx) = channel(); + getter!(self, rx, Message::Clipboard(ClipboardMessage::ReadText(tx))) + } + + fn write_text>(&mut self, text: V) -> Result<()> { + let (tx, rx) = channel(); + getter!( + self, + rx, + Message::Clipboard(ClipboardMessage::WriteText(text.into(), tx)) + )?; + Ok(()) + } +} + +pub fn handle_clipboard_message( + message: ClipboardMessage, + clipboard_manager: &Arc>, +) { + match message { + ClipboardMessage::WriteText(text, tx) => { + clipboard_manager.lock().unwrap().write_text(text); + tx.send(()).unwrap(); + } + ClipboardMessage::ReadText(tx) => tx + .send(clipboard_manager.lock().unwrap().read_text()) + .unwrap(), + } +} diff --git a/core/tauri-runtime-wry/src/lib.rs b/core/tauri-runtime-wry/src/lib.rs index ca1a39bd0..b230a5b84 100644 --- a/core/tauri-runtime-wry/src/lib.rs +++ b/core/tauri-runtime-wry/src/lib.rs @@ -16,8 +16,8 @@ use tauri_runtime::{ dpi::{LogicalPosition, LogicalSize, PhysicalPosition, PhysicalSize, Position, Size}, CursorIcon, DetachedWindow, FileDropEvent, JsEventListenerKey, PendingWindow, WindowEvent, }, - ClipboardManager, Dispatch, Error, EventLoopProxy, ExitRequestedEventAction, Result, RunEvent, - RunIteration, Runtime, RuntimeHandle, UserAttentionType, UserEvent, WindowIcon, + Dispatch, Error, EventLoopProxy, ExitRequestedEventAction, Result, RunEvent, RunIteration, + Runtime, RuntimeHandle, UserAttentionType, UserEvent, WindowIcon, }; use tauri_runtime::window::MenuEvent; @@ -43,7 +43,6 @@ use tauri_utils::{config::WindowConfig, Theme}; use uuid::Uuid; use wry::{ application::{ - clipboard::Clipboard, dpi::{ LogicalPosition as WryLogicalPosition, LogicalSize as WryLogicalSize, PhysicalPosition as WryPhysicalPosition, PhysicalSize as WryPhysicalSize, @@ -111,6 +110,11 @@ mod global_shortcut; #[cfg(feature = "global-shortcut")] use global_shortcut::*; +#[cfg(feature = "clipboard")] +mod clipboard; +#[cfg(feature = "clipboard")] +use clipboard::*; + type WebContextStore = Arc, WebContext>>>; // window type WindowEventHandler = Box; @@ -138,7 +142,7 @@ impl WebviewIdStore { macro_rules! getter { ($self: ident, $rx: expr, $message: expr) => {{ crate::send_user_message(&$self.context, $message)?; - $rx.recv().map_err(|_| Error::FailedToReceiveMessage) + $rx.recv().map_err(|_| crate::Error::FailedToReceiveMessage) }}; } @@ -159,6 +163,7 @@ fn send_user_message(context: &Context, message: Message) -> window_event_listeners: &context.window_event_listeners, #[cfg(feature = "global-shortcut")] global_shortcut_manager: context.main_thread.global_shortcut_manager.clone(), + #[cfg(feature = "clipboard")] clipboard_manager: context.main_thread.clipboard_manager.clone(), menu_event_listeners: &context.menu_event_listeners, windows: context.main_thread.windows.clone(), @@ -240,6 +245,7 @@ struct DispatcherMainThreadContext { web_context: WebContextStore, #[cfg(feature = "global-shortcut")] global_shortcut_manager: Arc>, + #[cfg(feature = "clipboard")] clipboard_manager: Arc>, windows: Arc>>, #[cfg(feature = "system-tray")] @@ -464,32 +470,6 @@ impl From for NativeImageWrapper { } } -#[derive(Debug, Clone)] -pub struct ClipboardManagerWrapper { - context: Context, -} - -// SAFETY: this is safe since the `Context` usage is guarded on `send_user_message`. -#[allow(clippy::non_send_fields_in_send_ty)] -unsafe impl Sync for ClipboardManagerWrapper {} - -impl ClipboardManager for ClipboardManagerWrapper { - fn read_text(&self) -> Result> { - let (tx, rx) = channel(); - getter!(self, rx, Message::Clipboard(ClipboardMessage::ReadText(tx))) - } - - fn write_text>(&mut self, text: V) -> Result<()> { - let (tx, rx) = channel(); - getter!( - self, - rx, - Message::Clipboard(ClipboardMessage::WriteText(text.into(), tx)) - )?; - Ok(()) - } -} - /// Wrapper around a [`wry::application::window::Icon`] that can be created from an [`WindowIcon`]. pub struct WryIcon(WryWindowIcon); @@ -1078,12 +1058,6 @@ pub enum TrayMessage { Close, } -#[derive(Debug, Clone)] -pub enum ClipboardMessage { - WriteText(String, Sender<()>), - ReadText(Sender>), -} - pub type CreateWebviewClosure = Box< dyn FnOnce(&EventLoopWindowTarget>, &WebContextStore) -> Result + Send, >; @@ -1102,6 +1076,7 @@ pub enum Message { ), #[cfg(feature = "global-shortcut")] GlobalShortcut(GlobalShortcutMessage), + #[cfg(feature = "clipboard")] Clipboard(ClipboardMessage), UserEvent(T), } @@ -1115,6 +1090,7 @@ impl Clone for Message { Self::Tray(m) => Self::Tray(m.clone()), #[cfg(feature = "global-shortcut")] Self::GlobalShortcut(m) => Self::GlobalShortcut(m.clone()), + #[cfg(feature = "clipboard")] Self::Clipboard(m) => Self::Clipboard(m.clone()), Self::UserEvent(t) => Self::UserEvent(t.clone()), _ => unimplemented!(), @@ -1590,12 +1566,17 @@ impl EventLoopProxy for EventProxy { /// A Tauri [`Runtime`] wrapper around wry. pub struct Wry { main_thread_id: ThreadId, + #[cfg(feature = "global-shortcut")] global_shortcut_manager: Arc>, #[cfg(feature = "global-shortcut")] global_shortcut_manager_handle: GlobalShortcutManagerHandle, + + #[cfg(feature = "clipboard")] clipboard_manager: Arc>, + #[cfg(feature = "clipboard")] clipboard_manager_handle: ClipboardManagerWrapper, + event_loop: EventLoop>, windows: Arc>>, webview_id_map: WebviewIdStore, @@ -1610,19 +1591,24 @@ impl fmt::Debug for Wry { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { let mut d = f.debug_struct("Wry"); d.field("main_thread_id", &self.main_thread_id) - .field("clipboard_manager", &self.clipboard_manager) - .field("clipboard_manager_handle", &self.clipboard_manager_handle) .field("event_loop", &self.event_loop) .field("windows", &self.windows) .field("web_context", &self.web_context); + #[cfg(feature = "system-tray")] d.field("tray_context", &self.tray_context); + #[cfg(feature = "global-shortcut")] d.field("global_shortcut_manager", &self.global_shortcut_manager) .field( "global_shortcut_manager_handle", &self.global_shortcut_manager_handle, ); + + #[cfg(feature = "clipboard")] + d.field("clipboard_manager", &self.clipboard_manager) + .field("clipboard_manager_handle", &self.clipboard_manager_handle); + d.finish() } } @@ -1703,14 +1689,15 @@ impl RuntimeHandle for WryHandle { impl Wry { fn init(event_loop: EventLoop>) -> Result { - let proxy = event_loop.create_proxy(); let main_thread_id = current_thread().id(); let web_context = WebContextStore::default(); #[cfg(feature = "global-shortcut")] let global_shortcut_manager = Arc::new(Mutex::new(WryShortcutManager::new(&event_loop))); + #[cfg(feature = "clipboard")] let clipboard_manager = Arc::new(Mutex::new(Clipboard::new())); + let windows = Arc::new(Mutex::new(HashMap::default())); let webview_id_map = WebviewIdStore::default(); let window_event_listeners = WindowEventListeners::default(); @@ -1719,10 +1706,11 @@ impl Wry { #[cfg(feature = "system-tray")] let tray_context = TrayContext::default(); + #[allow(unused_variables)] let event_loop_context = Context { webview_id_map: webview_id_map.clone(), main_thread_id, - proxy, + proxy: event_loop.create_proxy(), window_event_listeners: window_event_listeners.clone(), menu_event_listeners: menu_event_listeners.clone(), main_thread: DispatcherMainThreadContext { @@ -1730,6 +1718,7 @@ impl Wry { web_context: web_context.clone(), #[cfg(feature = "global-shortcut")] global_shortcut_manager: global_shortcut_manager.clone(), + #[cfg(feature = "clipboard")] clipboard_manager: clipboard_manager.clone(), windows: windows.clone(), #[cfg(feature = "system-tray")] @@ -1740,6 +1729,7 @@ impl Wry { #[cfg(feature = "global-shortcut")] let global_shortcut_listeners = GlobalShortcutListeners::default(); + #[cfg(feature = "clipboard")] #[allow(clippy::redundant_clone)] let clipboard_manager_handle = ClipboardManagerWrapper { context: event_loop_context.clone(), @@ -1747,6 +1737,7 @@ impl Wry { Ok(Self { main_thread_id, + #[cfg(feature = "global-shortcut")] global_shortcut_manager, #[cfg(feature = "global-shortcut")] @@ -1755,8 +1746,12 @@ impl Wry { shortcuts: Default::default(), listeners: global_shortcut_listeners, }, + + #[cfg(feature = "clipboard")] clipboard_manager, + #[cfg(feature = "clipboard")] clipboard_manager_handle, + event_loop, windows, webview_id_map, @@ -1772,11 +1767,16 @@ impl Wry { impl Runtime for Wry { type Dispatcher = WryDispatcher; type Handle = WryHandle; + #[cfg(feature = "global-shortcut")] type GlobalShortcutManager = GlobalShortcutManagerHandle; + + #[cfg(feature = "clipboard")] type ClipboardManager = ClipboardManagerWrapper; + #[cfg(feature = "system-tray")] type TrayHandler = SystemTrayHandle; + type EventLoopProxy = EventProxy; fn new() -> Result { @@ -1811,6 +1811,7 @@ impl Runtime for Wry { web_context: self.web_context.clone(), #[cfg(feature = "global-shortcut")] global_shortcut_manager: self.global_shortcut_manager.clone(), + #[cfg(feature = "clipboard")] clipboard_manager: self.clipboard_manager.clone(), windows: self.windows.clone(), #[cfg(feature = "system-tray")] @@ -1825,6 +1826,7 @@ impl Runtime for Wry { self.global_shortcut_manager_handle.clone() } + #[cfg(feature = "clipboard")] fn clipboard_manager(&self) -> Self::ClipboardManager { self.clipboard_manager_handle.clone() } @@ -1847,6 +1849,7 @@ impl Runtime for Wry { web_context: self.web_context.clone(), #[cfg(feature = "global-shortcut")] global_shortcut_manager: self.global_shortcut_manager.clone(), + #[cfg(feature = "clipboard")] clipboard_manager: self.clipboard_manager.clone(), windows: self.windows.clone(), #[cfg(feature = "system-tray")] @@ -1953,6 +1956,7 @@ impl Runtime for Wry { #[cfg(feature = "global-shortcut")] let global_shortcut_manager_handle = self.global_shortcut_manager_handle.clone(); + #[cfg(feature = "clipboard")] let clipboard_manager = self.clipboard_manager.clone(); let mut iteration = RunIteration::default(); @@ -1977,6 +1981,7 @@ impl Runtime for Wry { global_shortcut_manager: global_shortcut_manager.clone(), #[cfg(feature = "global-shortcut")] global_shortcut_manager_handle: &global_shortcut_manager_handle, + #[cfg(feature = "clipboard")] clipboard_manager: clipboard_manager.clone(), menu_event_listeners: &menu_event_listeners, #[cfg(feature = "system-tray")] @@ -2004,6 +2009,7 @@ impl Runtime for Wry { #[cfg(feature = "global-shortcut")] let global_shortcut_manager_handle = self.global_shortcut_manager_handle.clone(); + #[cfg(feature = "clipboard")] let clipboard_manager = self.clipboard_manager.clone(); self.event_loop.run(move |event, event_loop, control_flow| { @@ -2020,6 +2026,7 @@ impl Runtime for Wry { global_shortcut_manager: global_shortcut_manager.clone(), #[cfg(feature = "global-shortcut")] global_shortcut_manager_handle: &global_shortcut_manager_handle, + #[cfg(feature = "clipboard")] clipboard_manager: clipboard_manager.clone(), menu_event_listeners: &menu_event_listeners, #[cfg(feature = "system-tray")] @@ -2040,6 +2047,7 @@ pub struct EventLoopIterationContext<'a, T: UserEvent> { global_shortcut_manager: Arc>, #[cfg(feature = "global-shortcut")] global_shortcut_manager_handle: &'a GlobalShortcutManagerHandle, + #[cfg(feature = "clipboard")] clipboard_manager: Arc>, menu_event_listeners: &'a MenuEventListeners, #[cfg(feature = "system-tray")] @@ -2051,6 +2059,7 @@ struct UserMessageContext<'a> { window_event_listeners: &'a WindowEventListeners, #[cfg(feature = "global-shortcut")] global_shortcut_manager: Arc>, + #[cfg(feature = "clipboard")] clipboard_manager: Arc>, menu_event_listeners: &'a MenuEventListeners, windows: Arc>>, @@ -2070,6 +2079,7 @@ fn handle_user_message( menu_event_listeners, #[cfg(feature = "global-shortcut")] global_shortcut_manager, + #[cfg(feature = "clipboard")] clipboard_manager, windows, #[cfg(feature = "system-tray")] @@ -2374,15 +2384,8 @@ fn handle_user_message( Message::GlobalShortcut(message) => { handle_global_shortcut_message(message, &global_shortcut_manager) } - Message::Clipboard(message) => match message { - ClipboardMessage::WriteText(text, tx) => { - clipboard_manager.lock().unwrap().write_text(text); - tx.send(()).unwrap(); - } - ClipboardMessage::ReadText(tx) => tx - .send(clipboard_manager.lock().unwrap().read_text()) - .unwrap(), - }, + #[cfg(feature = "clipboard")] + Message::Clipboard(message) => handle_clipboard_message(message, &clipboard_manager), Message::UserEvent(_) => (), } @@ -2408,6 +2411,7 @@ fn handle_event_loop( global_shortcut_manager, #[cfg(feature = "global-shortcut")] global_shortcut_manager_handle, + #[cfg(feature = "clipboard")] clipboard_manager, menu_event_listeners, #[cfg(feature = "system-tray")] @@ -2615,6 +2619,7 @@ fn handle_event_loop( window_event_listeners, #[cfg(feature = "global-shortcut")] global_shortcut_manager, + #[cfg(feature = "clipboard")] clipboard_manager, menu_event_listeners, windows, diff --git a/core/tauri-runtime/Cargo.toml b/core/tauri-runtime/Cargo.toml index ed75140d9..f2603c028 100644 --- a/core/tauri-runtime/Cargo.toml +++ b/core/tauri-runtime/Cargo.toml @@ -47,3 +47,4 @@ devtools = [ ] system-tray = [ ] macos-private-api = [ ] global-shortcut = [ ] +clipboard = [ ] diff --git a/core/tauri-runtime/src/lib.rs b/core/tauri-runtime/src/lib.rs index ddbc2afe1..bf4948dda 100644 --- a/core/tauri-runtime/src/lib.rs +++ b/core/tauri-runtime/src/lib.rs @@ -311,6 +311,7 @@ pub trait GlobalShortcutManager: Debug + Clone + Send + Sync { } /// Clipboard manager. +#[cfg(feature = "clipboard")] pub trait ClipboardManager: Debug + Clone + Send + Sync { /// Writes the text into the clipboard as plain text. fn write_text>(&mut self, text: T) -> Result<()>; @@ -332,6 +333,7 @@ pub trait Runtime: Debug + Sized + 'static { #[cfg(feature = "global-shortcut")] type GlobalShortcutManager: GlobalShortcutManager; /// The clipboard manager type. + #[cfg(feature = "clipboard")] type ClipboardManager: ClipboardManager; /// The tray handler type. #[cfg(feature = "system-tray")] @@ -358,6 +360,7 @@ pub trait Runtime: Debug + Sized + 'static { fn global_shortcut_manager(&self) -> Self::GlobalShortcutManager; /// Gets the clipboard manager. + #[cfg(feature = "clipboard")] fn clipboard_manager(&self) -> Self::ClipboardManager; /// Create a new webview window. diff --git a/core/tauri/Cargo.toml b/core/tauri/Cargo.toml index 142760022..7bac7e299 100644 --- a/core/tauri/Cargo.toml +++ b/core/tauri/Cargo.toml @@ -142,6 +142,7 @@ fs-extract-api = [ "zip" ] reqwest-client = [ "reqwest", "bytes" ] process-command-api = [ "shared_child", "os_pipe" ] global-shortcut = [ "tauri-runtime/global-shortcut", "tauri-runtime-wry/global-shortcut" ] +clipboard = [ "tauri-runtime/clipboard", "tauri-runtime-wry/clipboard" ] dialog = [ "rfd" ] notification = [ "notify-rust" ] cli = [ "clap" ] @@ -168,8 +169,8 @@ api-all = [ "window-all" ] clipboard-all = [ "clipboard-write-text", "clipboard-read-text" ] -clipboard-read-text = [ ] -clipboard-write-text = [ ] +clipboard-read-text = [ "clipboard" ] +clipboard-write-text = [ "clipboard" ] dialog-all = [ "dialog-open", "dialog-save", "dialog-message", "dialog-ask" ] dialog-ask = [ "dialog" ] dialog-confirm = [ "dialog" ] diff --git a/core/tauri/src/app.rs b/core/tauri/src/app.rs index 090955cd1..f42aad53e 100644 --- a/core/tauri/src/app.rs +++ b/core/tauri/src/app.rs @@ -289,6 +289,7 @@ pub struct AppHandle { manager: WindowManager, #[cfg(feature = "global-shortcut")] global_shortcut_manager: R::GlobalShortcutManager, + #[cfg(feature = "clipboard")] clipboard_manager: R::ClipboardManager, #[cfg(feature = "system-tray")] tray_handle: Option>, @@ -340,6 +341,7 @@ impl Clone for AppHandle { manager: self.manager.clone(), #[cfg(feature = "global-shortcut")] global_shortcut_manager: self.global_shortcut_manager.clone(), + #[cfg(feature = "clipboard")] clipboard_manager: self.clipboard_manager.clone(), #[cfg(feature = "system-tray")] tray_handle: self.tray_handle.clone(), @@ -446,6 +448,7 @@ pub struct App { manager: WindowManager, #[cfg(feature = "global-shortcut")] global_shortcut_manager: R::GlobalShortcutManager, + #[cfg(feature = "clipboard")] clipboard_manager: R::ClipboardManager, #[cfg(feature = "system-tray")] tray_handle: Option>, @@ -520,6 +523,8 @@ macro_rules! shared_app_impl { } /// Gets a copy of the clipboard manager instance. + #[cfg(feature = "clipboard")] + #[cfg_attr(doc_cfg, doc(cfg(feature = "clipboard")))] pub fn clipboard_manager(&self) -> R::ClipboardManager { self.clipboard_manager.clone() } @@ -1242,6 +1247,7 @@ impl Builder { #[cfg(feature = "global-shortcut")] let global_shortcut_manager = runtime.global_shortcut_manager(); + #[cfg(feature = "clipboard")] let clipboard_manager = runtime.clipboard_manager(); let mut app = App { @@ -1249,6 +1255,7 @@ impl Builder { manager: manager.clone(), #[cfg(feature = "global-shortcut")] global_shortcut_manager: global_shortcut_manager.clone(), + #[cfg(feature = "clipboard")] clipboard_manager: clipboard_manager.clone(), #[cfg(feature = "system-tray")] tray_handle: None, @@ -1257,6 +1264,7 @@ impl Builder { manager, #[cfg(feature = "global-shortcut")] global_shortcut_manager, + #[cfg(feature = "clipboard")] clipboard_manager, #[cfg(feature = "system-tray")] tray_handle: None, diff --git a/core/tauri/src/lib.rs b/core/tauri/src/lib.rs index 3fcdf1931..8d8ca25f0 100644 --- a/core/tauri/src/lib.rs +++ b/core/tauri/src/lib.rs @@ -24,6 +24,7 @@ //! - **reqwest-client**: Uses `reqwest` as HTTP client on the `http` APIs. Improves performance, but increases the bundle size. //! - **process-command-api**: Enables the [`api::process::Command`] APIs. //! - **global-shortcut**: Enables the global shortcut APIs. +//! - **clipboard**: Enables the clipboard APIs. //! - **process-relaunch-dangerous-allow-symlink-macos**: Allows the [`api::process::current_binary`] function to allow symlinks on macOS (this is dangerous, see the Security section in the documentation website). //! - **dialog**: Enables the [`api::dialog`] module. //! - **notification**: Enables the [`api::notification`] module. @@ -233,7 +234,7 @@ pub use { dpi::{LogicalPosition, LogicalSize, PhysicalPosition, PhysicalSize, Pixel, Position, Size}, CursorIcon, FileDropEvent, }, - ClipboardManager, RunIteration, TrayIcon, UserAttentionType, + RunIteration, TrayIcon, UserAttentionType, }, self::state::{State, StateManager}, self::utils::{ diff --git a/core/tauri/src/test/mock_runtime.rs b/core/tauri/src/test/mock_runtime.rs index fcb166a67..6088ae4b0 100644 --- a/core/tauri/src/test/mock_runtime.rs +++ b/core/tauri/src/test/mock_runtime.rs @@ -12,8 +12,8 @@ use tauri_runtime::{ dpi::{PhysicalPosition, PhysicalSize, Position, Size}, CursorIcon, DetachedWindow, MenuEvent, PendingWindow, WindowEvent, }, - ClipboardManager, Dispatch, EventLoopProxy, Result, RunEvent, Runtime, RuntimeHandle, - UserAttentionType, UserEvent, WindowIcon, + Dispatch, EventLoopProxy, Result, RunEvent, Runtime, RuntimeHandle, UserAttentionType, UserEvent, + WindowIcon, }; #[cfg(feature = "system-tray")] use tauri_runtime::{ @@ -132,12 +132,14 @@ impl tauri_runtime::GlobalShortcutManager for MockGlobalShortcutManager { } } +#[cfg(feature = "clipboard")] #[derive(Debug, Clone)] pub struct MockClipboardManager { context: RuntimeContext, } -impl ClipboardManager for MockClipboardManager { +#[cfg(feature = "clipboard")] +impl tauri_runtime::ClipboardManager for MockClipboardManager { fn write_text>(&mut self, text: T) -> Result<()> { self.context.clipboard.lock().unwrap().replace(text.into()); Ok(()) @@ -547,6 +549,7 @@ pub struct MockRuntime { pub context: RuntimeContext, #[cfg(feature = "global-shortcut")] global_shortcut_manager: MockGlobalShortcutManager, + #[cfg(feature = "clipboard")] clipboard_manager: MockClipboardManager, #[cfg(feature = "system-tray")] tray_handler: MockTrayHandler, @@ -563,6 +566,7 @@ impl MockRuntime { global_shortcut_manager: MockGlobalShortcutManager { context: context.clone(), }, + #[cfg(feature = "clipboard")] clipboard_manager: MockClipboardManager { context: context.clone(), }, @@ -580,6 +584,7 @@ impl Runtime for MockRuntime { type Handle = MockRuntimeHandle; #[cfg(feature = "global-shortcut")] type GlobalShortcutManager = MockGlobalShortcutManager; + #[cfg(feature = "clipboard")] type ClipboardManager = MockClipboardManager; #[cfg(feature = "system-tray")] type TrayHandler = MockTrayHandler; @@ -609,6 +614,7 @@ impl Runtime for MockRuntime { self.global_shortcut_manager.clone() } + #[cfg(feature = "clipboard")] fn clipboard_manager(&self) -> Self::ClipboardManager { self.clipboard_manager.clone() }