From 857b75b3d094fb51e02f5033b72049d3e89d7d17 Mon Sep 17 00:00:00 2001 From: Lucas Nogueira Date: Tue, 18 Apr 2023 09:10:42 -0300 Subject: [PATCH] feat(desktop): use arboard crate --- Cargo.lock | 137 +++++++++++++++++++++++++++++++ Cargo.toml | 2 +- plugins/clipboard/Cargo.toml | 26 +++--- plugins/clipboard/src/desktop.rs | 33 +++++--- plugins/clipboard/src/error.rs | 11 ++- 5 files changed, 182 insertions(+), 27 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 7ba0bff5..13c496c0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -160,6 +160,26 @@ version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "224afbd727c3d6e4b90103ece64b8d1b67fbb1973b1046c2281eed3f3803f800" +[[package]] +name = "arboard" +version = "3.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6041616acea41d67c4a984709ddab1587fd0b10efe5cc563fee954d2f011854" +dependencies = [ + "clipboard-win", + "core-graphics", + "image", + "log", + "objc", + "objc-foundation", + "objc_id", + "once_cell", + "parking_lot 0.12.1", + "thiserror", + "winapi", + "x11rb", +] + [[package]] name = "arrayref" version = "0.3.6" @@ -656,6 +676,17 @@ version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8a2dd5a6fe8c6e3502f568a6353e5273bbb15193ad9a89e457b9970798efbea1" +[[package]] +name = "clipboard-win" +version = "4.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7191c27c2357d9b7ef96baac1773290d4ca63b24205b82a3fd8a0637afcf0362" +dependencies = [ + "error-code", + "str-buf", + "winapi", +] + [[package]] name = "cocoa" version = "0.24.1" @@ -1256,6 +1287,16 @@ dependencies = [ "libc", ] +[[package]] +name = "error-code" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64f18991e7bf11e7ffee451b5318b5c1a73c52d0d0ada6e5a3017c8c1ced6a21" +dependencies = [ + "libc", + "str-buf", +] + [[package]] name = "event-listener" version = "2.5.3" @@ -1607,6 +1648,16 @@ dependencies = [ "version_check", ] +[[package]] +name = "gethostname" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1ebd34e35c46e00bb73e81363248d627782724609fe1b6396f553f68fe3862e" +dependencies = [ + "libc", + "winapi", +] + [[package]] name = "getrandom" version = "0.1.16" @@ -2070,6 +2121,8 @@ dependencies = [ "color_quant", "num-rational", "num-traits", + "png", + "tiff", ] [[package]] @@ -2266,6 +2319,12 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130" +[[package]] +name = "jpeg-decoder" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc0000e42512c92e31c2252315bda326620a4e034105e900c98ec492fa077b3e" + [[package]] name = "js-sys" version = "0.3.61" @@ -2840,6 +2899,17 @@ dependencies = [ "objc_exception", ] +[[package]] +name = "objc-foundation" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1add1b659e36c9607c7aab864a76c7a4c2760cd0cd2e120f3fb8b952c7e22bf9" +dependencies = [ + "block", + "objc", + "objc_id", +] + [[package]] name = "objc_exception" version = "0.1.2" @@ -4173,6 +4243,12 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" +[[package]] +name = "str-buf" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e08d8363704e6c71fc928674353e6b7c23dcea9d82d7012c8faf2a3a025f8d0" + [[package]] name = "string_cache" version = "0.8.4" @@ -4552,6 +4628,19 @@ dependencies = [ "thiserror", ] +[[package]] +name = "tauri-plugin-clipboard" +version = "0.1.0" +dependencies = [ + "arboard", + "log", + "serde", + "serde_json", + "tauri", + "tauri-build", + "thiserror", +] + [[package]] name = "tauri-plugin-fs-watch" version = "0.1.0" @@ -4871,6 +4960,17 @@ dependencies = [ "once_cell", ] +[[package]] +name = "tiff" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7449334f9ff2baf290d55d73983a7d6fa15e01198faef72af07e2a8db851e471" +dependencies = [ + "flate2", + "jpeg-decoder", + "weezl", +] + [[package]] name = "time" version = "0.1.45" @@ -5543,6 +5643,12 @@ dependencies = [ "windows-metadata", ] +[[package]] +name = "weezl" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9193164d4de03a926d909d3bc7c30543cecb35400c02114792c2cae20d5e2dbb" + [[package]] name = "wepoll-ffi" version = "0.1.2" @@ -5587,6 +5693,15 @@ dependencies = [ "winapi", ] +[[package]] +name = "winapi-wsapoll" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44c17110f57155602a80dca10be03852116403c9ff3cd25b079d666f2aa3df6e" +dependencies = [ + "winapi", +] + [[package]] name = "winapi-x86_64-pc-windows-gnu" version = "0.4.0" @@ -5950,6 +6065,28 @@ dependencies = [ "pkg-config", ] +[[package]] +name = "x11rb" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "592b4883219f345e712b3209c62654ebda0bb50887f330cbd018d0f654bfd507" +dependencies = [ + "gethostname", + "nix 0.24.3", + "winapi", + "winapi-wsapoll", + "x11rb-protocol", +] + +[[package]] +name = "x11rb-protocol" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56b245751c0ac9db0e006dc812031482784e434630205a93c73cfefcaabeac67" +dependencies = [ + "nix 0.24.3", +] + [[package]] name = "x25519-dalek" version = "1.1.1" diff --git a/Cargo.toml b/Cargo.toml index c5337e33..8f02ac2f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [workspace] members = ["plugins/*"] -exclude = ["plugins/fs", "plugins/clipboard"] +exclude = ["plugins/fs"] resolver = "2" [workspace.dependencies] diff --git a/plugins/clipboard/Cargo.toml b/plugins/clipboard/Cargo.toml index b832072d..a0790b60 100644 --- a/plugins/clipboard/Cargo.toml +++ b/plugins/clipboard/Cargo.toml @@ -1,21 +1,19 @@ [package] name = "tauri-plugin-clipboard" version = "0.1.0" -#edition.workspace = true -#authors.workspace = true -#license.workspace = true -edition = "2021" +edition.workspace = true +authors.workspace = true +license.workspace = true [build-dependencies] -#tauri-build.workspace = true -tauri-build = { path = "../../../tauri/core/tauri-build/" } +tauri-build.workspace = true [dependencies] -#serde.workspace = true -#serde_json.workspace = true -#tauri = { workspace = true, features = ["clipboard"] } -#log.workspace = true -#thiserror.workspace = true -serde = "1" -thiserror = "1" -tauri = { path = "../../../tauri/core/tauri", features = ["clipboard"] } \ No newline at end of file +serde.workspace = true +serde_json.workspace = true +tauri = { workspace = true, features = ["clipboard"] } +log.workspace = true +thiserror.workspace = true + +[target."cfg(any(target_os = \"macos\", windows, target_os = \"linux\", target_os = \"dragonfly\", target_os = \"freebsd\", target_os = \"openbsd\", target_os = \"netbsd\"))".dependencies] +arboard = "3" diff --git a/plugins/clipboard/src/desktop.rs b/plugins/clipboard/src/desktop.rs index 2007dc89..8fcc8450 100644 --- a/plugins/clipboard/src/desktop.rs +++ b/plugins/clipboard/src/desktop.rs @@ -3,32 +3,45 @@ // SPDX-License-Identifier: MIT use serde::de::DeserializeOwned; -use tauri::{plugin::PluginApi, runtime::RuntimeHandle, AppHandle, ClipboardManager, Runtime}; +use tauri::{plugin::PluginApi, AppHandle, Runtime}; use crate::models::*; +use std::sync::Mutex; + pub fn init( app: &AppHandle, _api: PluginApi, ) -> crate::Result> { - Ok(Clipboard(app.clone())) + Ok(Clipboard { + app: app.clone(), + clipboard: arboard::Clipboard::new().map(Mutex::new), + }) } /// Access to the clipboard APIs. -pub struct Clipboard(AppHandle); +pub struct Clipboard { + #[allow(dead_code)] + app: AppHandle, + clipboard: Result, arboard::Error>, +} impl Clipboard { pub fn write(&self, kind: ClipKind) -> crate::Result<()> { let ClipKind::PlainText { text, .. } = kind; - self.0 - .runtime_handle() - .clipboard_manager() - .write_text(text) - .map_err(Into::into) + match &self.clipboard { + Ok(clipboard) => clipboard.lock().unwrap().set_text(text).map_err(Into::into), + Err(e) => Err(crate::Error::Clipboard(e.to_string())), + } } pub fn read(&self) -> crate::Result { - let text = self.0.runtime_handle().clipboard_manager().read_text()?; - Ok(ClipboardContents::PlainText(text.unwrap_or_default())) + match &self.clipboard { + Ok(clipboard) => { + let text = clipboard.lock().unwrap().get_text()?; + Ok(ClipboardContents::PlainText(text)) + } + Err(e) => Err(crate::Error::Clipboard(e.to_string())), + } } } diff --git a/plugins/clipboard/src/error.rs b/plugins/clipboard/src/error.rs index a6f58418..7beff881 100644 --- a/plugins/clipboard/src/error.rs +++ b/plugins/clipboard/src/error.rs @@ -12,8 +12,8 @@ pub enum Error { #[error(transparent)] PluginInvoke(#[from] tauri::plugin::mobile::PluginInvokeError), #[cfg(not(target_os = "android"))] - #[error("failed to access clipboard: {0}")] - Clipboard(#[from] tauri::runtime::Error), + #[error("{0}")] + Clipboard(String), } impl Serialize for Error { @@ -24,3 +24,10 @@ impl Serialize for Error { serializer.serialize_str(self.to_string().as_ref()) } } + +#[cfg(not(target_os = "android"))] +impl From for Error { + fn from(error: arboard::Error) -> Self { + Self::Clipboard(error.to_string()) + } +}