Skip to content

Commit 0d0501c

Browse files
authored
refactor(clipboard): use arboard instead of tao closes #8177 (#8394)
* refactor(clipboard): use arboard instead of tao closes #8177 * update api lock * add change file
1 parent 1c582a9 commit 0d0501c

File tree

6 files changed

+151
-94
lines changed

6 files changed

+151
-94
lines changed

.changes/arboard.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"tauri-runtime-wry": patch:bug
3+
---
4+
5+
Use `arboard` instead of `tao` clipboard implementation to prevent a crash.

core/tauri-runtime-wry/Cargo.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ uuid = { version = "1", features = [ "v4" ] }
2020
rand = "0.8"
2121
raw-window-handle = "0.5"
2222
tracing = { version = "0.1", optional = true }
23+
arboard = { version = "3", optional = true }
2324

2425
[target."cfg(windows)".dependencies]
2526
webview2-com = "0.19.1"
@@ -47,6 +48,6 @@ macos-private-api = [
4748
]
4849
objc-exception = [ "wry/objc-exception" ]
4950
global-shortcut = [ "tauri-runtime/global-shortcut" ]
50-
clipboard = [ "tauri-runtime/clipboard" ]
51+
clipboard = [ "tauri-runtime/clipboard", "arboard" ]
5152
linux-headers = [ "wry/linux-headers", "webkit2gtk/v2_36" ]
5253
tracing = [ "dep:tracing", "wry/tracing" ]

core/tauri-runtime-wry/src/clipboard.rs

Lines changed: 20 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -4,59 +4,36 @@
44

55
//! Clipboard implementation.
66
7-
use crate::{getter, Context, Message};
8-
9-
use std::sync::{
10-
mpsc::{channel, Sender},
11-
Arc, Mutex,
7+
use std::{
8+
fmt,
9+
sync::{Arc, Mutex},
1210
};
1311

14-
use tauri_runtime::{ClipboardManager, Result, UserEvent};
15-
pub use wry::application::clipboard::Clipboard;
12+
pub use arboard::Clipboard;
13+
use tauri_runtime::{ClipboardManager, Result};
1614

17-
#[derive(Debug, Clone)]
18-
pub enum ClipboardMessage {
19-
WriteText(String, Sender<()>),
20-
ReadText(Sender<Option<String>>),
15+
#[derive(Clone)]
16+
pub struct ClipboardManagerWrapper {
17+
pub clipboard: Arc<Mutex<Clipboard>>,
2118
}
2219

23-
#[derive(Debug, Clone)]
24-
pub struct ClipboardManagerWrapper<T: UserEvent> {
25-
pub context: Context<T>,
20+
impl fmt::Debug for ClipboardManagerWrapper {
21+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
22+
f.debug_struct("ClipboardManagerWrapper").finish()
23+
}
2624
}
2725

28-
// SAFETY: this is safe since the `Context` usage is guarded on `send_user_message`.
29-
#[allow(clippy::non_send_fields_in_send_ty)]
30-
unsafe impl<T: UserEvent> Sync for ClipboardManagerWrapper<T> {}
31-
32-
impl<T: UserEvent> ClipboardManager for ClipboardManagerWrapper<T> {
26+
impl ClipboardManager for ClipboardManagerWrapper {
3327
fn read_text(&self) -> Result<Option<String>> {
34-
let (tx, rx) = channel();
35-
getter!(self, rx, Message::Clipboard(ClipboardMessage::ReadText(tx)))
28+
Ok(self.clipboard.lock().unwrap().get_text().ok())
3629
}
3730

3831
fn write_text<V: Into<String>>(&mut self, text: V) -> Result<()> {
39-
let (tx, rx) = channel();
40-
getter!(
41-
self,
42-
rx,
43-
Message::Clipboard(ClipboardMessage::WriteText(text.into(), tx))
44-
)?;
45-
Ok(())
46-
}
47-
}
48-
49-
pub fn handle_clipboard_message(
50-
message: ClipboardMessage,
51-
clipboard_manager: &Arc<Mutex<Clipboard>>,
52-
) {
53-
match message {
54-
ClipboardMessage::WriteText(text, tx) => {
55-
clipboard_manager.lock().unwrap().write_text(text);
56-
tx.send(()).unwrap();
57-
}
58-
ClipboardMessage::ReadText(tx) => tx
59-
.send(clipboard_manager.lock().unwrap().read_text())
60-
.unwrap(),
32+
self
33+
.clipboard
34+
.lock()
35+
.unwrap()
36+
.set_text(text.into())
37+
.map_err(|e| crate::Error::Clipboard(Box::new(e)))
6138
}
6239
}

core/tauri-runtime-wry/src/lib.rs

Lines changed: 4 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -175,8 +175,6 @@ pub(crate) fn send_user_message<T: UserEvent>(
175175
webview_id_map: context.webview_id_map.clone(),
176176
#[cfg(all(desktop, feature = "global-shortcut"))]
177177
global_shortcut_manager: context.main_thread.global_shortcut_manager.clone(),
178-
#[cfg(feature = "clipboard")]
179-
clipboard_manager: context.main_thread.clipboard_manager.clone(),
180178
windows: context.main_thread.windows.clone(),
181179
#[cfg(all(desktop, feature = "system-tray"))]
182180
system_tray_manager: context.main_thread.system_tray_manager.clone(),
@@ -276,8 +274,6 @@ pub struct DispatcherMainThreadContext<T: UserEvent> {
276274
pub web_context: WebContextStore,
277275
#[cfg(all(desktop, feature = "global-shortcut"))]
278276
pub global_shortcut_manager: Rc<Mutex<WryShortcutManager>>,
279-
#[cfg(feature = "clipboard")]
280-
pub clipboard_manager: Arc<Mutex<Clipboard>>,
281277
pub windows: Rc<RefCell<HashMap<WebviewId, WindowWrapper>>>,
282278
#[cfg(all(desktop, feature = "system-tray"))]
283279
system_tray_manager: SystemTrayManager,
@@ -1213,8 +1209,6 @@ pub enum Message<T: 'static> {
12131209
),
12141210
#[cfg(all(desktop, feature = "global-shortcut"))]
12151211
GlobalShortcut(GlobalShortcutMessage),
1216-
#[cfg(feature = "clipboard")]
1217-
Clipboard(ClipboardMessage),
12181212
UserEvent(T),
12191213
}
12201214

@@ -1226,8 +1220,6 @@ impl<T: UserEvent> Clone for Message<T> {
12261220
Self::Tray(i, m) => Self::Tray(*i, m.clone()),
12271221
#[cfg(all(desktop, feature = "global-shortcut"))]
12281222
Self::GlobalShortcut(m) => Self::GlobalShortcut(m.clone()),
1229-
#[cfg(feature = "clipboard")]
1230-
Self::Clipboard(m) => Self::Clipboard(m.clone()),
12311223
Self::UserEvent(t) => Self::UserEvent(t.clone()),
12321224
_ => unimplemented!(),
12331225
}
@@ -1829,7 +1821,7 @@ pub struct Wry<T: UserEvent> {
18291821
global_shortcut_manager_handle: GlobalShortcutManagerHandle<T>,
18301822

18311823
#[cfg(feature = "clipboard")]
1832-
clipboard_manager_handle: ClipboardManagerWrapper<T>,
1824+
clipboard_manager_handle: ClipboardManagerWrapper,
18331825

18341826
event_loop: EventLoop<Message<T>>,
18351827
}
@@ -1860,11 +1852,7 @@ impl<T: UserEvent> fmt::Debug for Wry<T> {
18601852
);
18611853

18621854
#[cfg(feature = "clipboard")]
1863-
d.field(
1864-
"clipboard_manager",
1865-
&self.context.main_thread.clipboard_manager,
1866-
)
1867-
.field("clipboard_manager_handle", &self.clipboard_manager_handle);
1855+
d.field("clipboard_manager_handle", &self.clipboard_manager_handle);
18681856

18691857
d.finish()
18701858
}
@@ -1985,9 +1973,6 @@ impl<T: UserEvent> Wry<T> {
19851973
#[cfg(all(desktop, feature = "global-shortcut"))]
19861974
let global_shortcut_manager = Rc::new(Mutex::new(WryShortcutManager::new(&event_loop)));
19871975

1988-
#[cfg(feature = "clipboard")]
1989-
let clipboard_manager = Arc::new(Mutex::new(Clipboard::new()));
1990-
19911976
let windows = Rc::new(RefCell::new(HashMap::default()));
19921977
let webview_id_map = WebviewIdStore::default();
19931978

@@ -2003,8 +1988,6 @@ impl<T: UserEvent> Wry<T> {
20031988
web_context,
20041989
#[cfg(all(desktop, feature = "global-shortcut"))]
20051990
global_shortcut_manager,
2006-
#[cfg(feature = "clipboard")]
2007-
clipboard_manager,
20081991
windows,
20091992
#[cfg(all(desktop, feature = "system-tray"))]
20101993
system_tray_manager,
@@ -2023,7 +2006,7 @@ impl<T: UserEvent> Wry<T> {
20232006
#[cfg(feature = "clipboard")]
20242007
#[allow(clippy::redundant_clone)]
20252008
let clipboard_manager_handle = ClipboardManagerWrapper {
2026-
context: context.clone(),
2009+
clipboard: Arc::new(Mutex::new(Clipboard::new().unwrap())),
20272010
};
20282011

20292012
Ok(Self {
@@ -2056,7 +2039,7 @@ impl<T: UserEvent> Runtime<T> for Wry<T> {
20562039
type GlobalShortcutManager = GlobalShortcutManagerHandle<T>;
20572040

20582041
#[cfg(feature = "clipboard")]
2059-
type ClipboardManager = ClipboardManagerWrapper<T>;
2042+
type ClipboardManager = ClipboardManagerWrapper;
20602043

20612044
#[cfg(all(desktop, feature = "system-tray"))]
20622045
type TrayHandler = SystemTrayHandle<T>;
@@ -2221,8 +2204,6 @@ impl<T: UserEvent> Runtime<T> for Wry<T> {
22212204
#[cfg(all(desktop, feature = "global-shortcut"))]
22222205
let global_shortcut_manager_handle = self.global_shortcut_manager_handle.clone();
22232206

2224-
#[cfg(feature = "clipboard")]
2225-
let clipboard_manager = self.context.main_thread.clipboard_manager.clone();
22262207
let mut iteration = RunIteration::default();
22272208

22282209
let proxy = self.event_loop.create_proxy();
@@ -2249,8 +2230,6 @@ impl<T: UserEvent> Runtime<T> for Wry<T> {
22492230
global_shortcut_manager: global_shortcut_manager.clone(),
22502231
#[cfg(all(desktop, feature = "global-shortcut"))]
22512232
global_shortcut_manager_handle: &global_shortcut_manager_handle,
2252-
#[cfg(feature = "clipboard")]
2253-
clipboard_manager: clipboard_manager.clone(),
22542233
#[cfg(all(desktop, feature = "system-tray"))]
22552234
system_tray_manager: system_tray_manager.clone(),
22562235
#[cfg(feature = "tracing")]
@@ -2275,8 +2254,6 @@ impl<T: UserEvent> Runtime<T> for Wry<T> {
22752254
global_shortcut_manager: global_shortcut_manager.clone(),
22762255
#[cfg(all(desktop, feature = "global-shortcut"))]
22772256
global_shortcut_manager_handle: &global_shortcut_manager_handle,
2278-
#[cfg(feature = "clipboard")]
2279-
clipboard_manager: clipboard_manager.clone(),
22802257
#[cfg(all(desktop, feature = "system-tray"))]
22812258
system_tray_manager: system_tray_manager.clone(),
22822259
#[cfg(feature = "tracing")]
@@ -2306,9 +2283,6 @@ impl<T: UserEvent> Runtime<T> for Wry<T> {
23062283
#[cfg(all(desktop, feature = "global-shortcut"))]
23072284
let global_shortcut_manager_handle = self.global_shortcut_manager_handle.clone();
23082285

2309-
#[cfg(feature = "clipboard")]
2310-
let clipboard_manager = self.context.main_thread.clipboard_manager.clone();
2311-
23122286
let proxy = self.event_loop.create_proxy();
23132287

23142288
self.event_loop.run(move |event, event_loop, control_flow| {
@@ -2326,8 +2300,6 @@ impl<T: UserEvent> Runtime<T> for Wry<T> {
23262300
global_shortcut_manager: global_shortcut_manager.clone(),
23272301
#[cfg(all(desktop, feature = "global-shortcut"))]
23282302
global_shortcut_manager_handle: &global_shortcut_manager_handle,
2329-
#[cfg(feature = "clipboard")]
2330-
clipboard_manager: clipboard_manager.clone(),
23312303
#[cfg(all(desktop, feature = "system-tray"))]
23322304
system_tray_manager: system_tray_manager.clone(),
23332305
#[cfg(feature = "tracing")]
@@ -2351,8 +2323,6 @@ impl<T: UserEvent> Runtime<T> for Wry<T> {
23512323
global_shortcut_manager: global_shortcut_manager.clone(),
23522324
#[cfg(all(desktop, feature = "global-shortcut"))]
23532325
global_shortcut_manager_handle: &global_shortcut_manager_handle,
2354-
#[cfg(feature = "clipboard")]
2355-
clipboard_manager: clipboard_manager.clone(),
23562326
#[cfg(all(desktop, feature = "system-tray"))]
23572327
system_tray_manager: system_tray_manager.clone(),
23582328
#[cfg(feature = "tracing")]
@@ -2372,8 +2342,6 @@ pub struct EventLoopIterationContext<'a, T: UserEvent> {
23722342
pub global_shortcut_manager: Rc<Mutex<WryShortcutManager>>,
23732343
#[cfg(all(desktop, feature = "global-shortcut"))]
23742344
pub global_shortcut_manager_handle: &'a GlobalShortcutManagerHandle<T>,
2375-
#[cfg(feature = "clipboard")]
2376-
pub clipboard_manager: Arc<Mutex<Clipboard>>,
23772345
#[cfg(all(desktop, feature = "system-tray"))]
23782346
pub system_tray_manager: SystemTrayManager,
23792347
#[cfg(feature = "tracing")]
@@ -2385,8 +2353,6 @@ struct UserMessageContext {
23852353
webview_id_map: WebviewIdStore,
23862354
#[cfg(all(desktop, feature = "global-shortcut"))]
23872355
global_shortcut_manager: Rc<Mutex<WryShortcutManager>>,
2388-
#[cfg(feature = "clipboard")]
2389-
clipboard_manager: Arc<Mutex<Clipboard>>,
23902356
#[cfg(all(desktop, feature = "system-tray"))]
23912357
system_tray_manager: SystemTrayManager,
23922358
}
@@ -2401,8 +2367,6 @@ fn handle_user_message<T: UserEvent>(
24012367
webview_id_map,
24022368
#[cfg(all(desktop, feature = "global-shortcut"))]
24032369
global_shortcut_manager,
2404-
#[cfg(feature = "clipboard")]
2405-
clipboard_manager,
24062370
windows,
24072371
#[cfg(all(desktop, feature = "system-tray"))]
24082372
system_tray_manager,
@@ -2805,8 +2769,6 @@ fn handle_user_message<T: UserEvent>(
28052769
Message::GlobalShortcut(message) => {
28062770
handle_global_shortcut_message(message, &global_shortcut_manager)
28072771
}
2808-
#[cfg(feature = "clipboard")]
2809-
Message::Clipboard(message) => handle_clipboard_message(message, &clipboard_manager),
28102772
Message::UserEvent(_) => (),
28112773
}
28122774

@@ -2831,8 +2793,6 @@ fn handle_event_loop<T: UserEvent>(
28312793
global_shortcut_manager,
28322794
#[cfg(all(desktop, feature = "global-shortcut"))]
28332795
global_shortcut_manager_handle,
2834-
#[cfg(feature = "clipboard")]
2835-
clipboard_manager,
28362796
#[cfg(all(desktop, feature = "system-tray"))]
28372797
system_tray_manager,
28382798
#[cfg(feature = "tracing")]
@@ -3079,8 +3039,6 @@ fn handle_event_loop<T: UserEvent>(
30793039
webview_id_map,
30803040
#[cfg(all(desktop, feature = "global-shortcut"))]
30813041
global_shortcut_manager,
3082-
#[cfg(feature = "clipboard")]
3083-
clipboard_manager,
30843042
windows,
30853043
#[cfg(all(desktop, feature = "system-tray"))]
30863044
system_tray_manager,

core/tauri-runtime/src/lib.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -252,6 +252,9 @@ pub enum Error {
252252
#[cfg(all(desktop, feature = "global-shortcut"))]
253253
#[error(transparent)]
254254
GlobalShortcut(Box<dyn std::error::Error + Send + Sync>),
255+
#[cfg(all(desktop, feature = "clipboard"))]
256+
#[error(transparent)]
257+
Clipboard(Box<dyn std::error::Error + Send + Sync>),
255258
#[error("Invalid header name: {0}")]
256259
InvalidHeaderName(#[from] InvalidHeaderName),
257260
#[error("Invalid header value: {0}")]

0 commit comments

Comments
 (0)