diff --git a/Cargo.lock b/Cargo.lock index 25af86b..a8bb7ac 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -283,6 +283,12 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "cfg_aliases" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd16c4719339c4530435d38e511904438d07cce7950afa3718a84ac36c10e89e" + [[package]] name = "cfg_aliases" version = "0.2.1" @@ -565,6 +571,17 @@ dependencies = [ "powerfmt", ] +[[package]] +name = "derive-new" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d150dea618e920167e5973d70ae6ece4385b7164e0d799fe7c122dd0a5d912ad" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.52", +] + [[package]] name = "derive_builder" version = "0.12.0" @@ -677,6 +694,21 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "dlib" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "330c60081dcc4c72131f8eb70510f1ac07223e5d4163db481a04a0befcffa412" +dependencies = [ + "libloading", +] + +[[package]] +name = "downcast-rs" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75b325c5dbd37f80359721ad39aca5a29fb04c89279657cffdda8736d0c0b9d2" + [[package]] name = "dtoa" version = "1.0.9" @@ -771,6 +803,12 @@ dependencies = [ "zune-inflate", ] +[[package]] +name = "fastrand" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fc0510504f03c51ada170672ac806f1f105a88aa97a5281117e1ddc3368e51a" + [[package]] name = "fdeflate" version = "0.3.4" @@ -780,6 +818,12 @@ dependencies = [ "simd-adler32", ] +[[package]] +name = "fixedbitset" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80" + [[package]] name = "flate2" version = "1.0.28" @@ -965,6 +1009,15 @@ version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" +[[package]] +name = "home" +version = "0.5.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3d1354bf6b7235cb4a0576c2619fd4ed18183f689b12b006a0ee7329eeff9a5" +dependencies = [ + "windows-sys 0.52.0", +] + [[package]] name = "html5ever" version = "0.26.0" @@ -1250,6 +1303,16 @@ dependencies = [ "once_cell", ] +[[package]] +name = "libloading" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c2a198fb6b0eada2a8df47933734e6d35d350665a33a3593d7164fa52c75c19" +dependencies = [ + "cfg-if", + "windows-targets 0.52.4", +] + [[package]] name = "libredox" version = "0.0.1" @@ -1392,6 +1455,18 @@ version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e4a24736216ec316047a1fc4252e27dabb04218aa4a3f37c6e7ddbf1f9782b54" +[[package]] +name = "nix" +version = "0.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab2156c4fce2f8df6c499cc1c763e4394b7482525bf2a9701c9d79d215f519e4" +dependencies = [ + "bitflags 2.4.2", + "cfg-if", + "cfg_aliases 0.1.1", + "libc", +] + [[package]] name = "nix" version = "0.29.0" @@ -1400,7 +1475,7 @@ checksum = "71e2746dc3a24dd78b3cfcb7be93368c6de9963d30f43a6a73998a9cf4b17b46" dependencies = [ "bitflags 2.4.2", "cfg-if", - "cfg_aliases", + "cfg_aliases 0.2.1", "libc", ] @@ -1499,7 +1574,7 @@ dependencies = [ "human_bytes", "image", "indexmap", - "nix", + "nix 0.29.0", "open", "ratatui", "ratatui-image", @@ -1518,6 +1593,7 @@ dependencies = [ "unicode-segmentation", "unicode-width", "urlencoding", + "wl-clipboard-rs", ] [[package]] @@ -1581,6 +1657,16 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" +[[package]] +name = "os_pipe" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29d73ba8daf8fac13b0501d1abeddcfe21ba7401ada61a819144b6c2a4f32209" +dependencies = [ + "libc", + "windows-sys 0.52.0", +] + [[package]] name = "parking_lot" version = "0.12.1" @@ -1622,6 +1708,16 @@ version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" +[[package]] +name = "petgraph" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4c5cc86750666a3ed20bdaf5ca2a0344f9c67674cae0515bec2da16fbaa47db" +dependencies = [ + "fixedbitset", + "indexmap", +] + [[package]] name = "phf" version = "0.10.1" @@ -2167,6 +2263,12 @@ version = "1.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e86697c916019a8588c99b5fac3cead74ec0b4b819707a682fd4d23fa0ce1ba1" +[[package]] +name = "scoped-tls" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1cf6437eb19a8f4a6cc0f7dca544973b0b78843adbfeb3683d1a94a0024a294" + [[package]] name = "scopeguard" version = "1.2.0" @@ -2540,6 +2642,18 @@ version = "0.12.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e1fc403891a21bcfb7c37834ba66a547a8f402146eba7265b5a6d88059c9ff2f" +[[package]] +name = "tempfile" +version = "3.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85b77fafb263dd9d05cbeac119526425676db3784113aa9295c88498cbf8bff1" +dependencies = [ + "cfg-if", + "fastrand", + "rustix", + "windows-sys 0.52.0", +] + [[package]] name = "tendril" version = "0.4.3" @@ -2774,6 +2888,20 @@ dependencies = [ "serde_repr", ] +[[package]] +name = "tree_magic_mini" +version = "3.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "469a727cac55b41448315cc10427c069c618ac59bb6a4480283fcd811749bdc2" +dependencies = [ + "fnv", + "home", + "memchr", + "nom", + "once_cell", + "petgraph", +] + [[package]] name = "try-lock" version = "0.2.5" @@ -2962,6 +3090,79 @@ version = "0.2.91" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4f186bd2dcf04330886ce82d6f33dd75a7bfcf69ecf5763b89fcde53b6ac9838" +[[package]] +name = "wayland-backend" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34e9e6b6d4a2bb4e7e69433e0b35c7923b95d4dc8503a84d25ec917a4bbfdf07" +dependencies = [ + "cc", + "downcast-rs", + "rustix", + "scoped-tls", + "smallvec", + "wayland-sys", +] + +[[package]] +name = "wayland-client" +version = "0.31.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e63801c85358a431f986cffa74ba9599ff571fc5774ac113ed3b490c19a1133" +dependencies = [ + "bitflags 2.4.2", + "rustix", + "wayland-backend", + "wayland-scanner", +] + +[[package]] +name = "wayland-protocols" +version = "0.31.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f81f365b8b4a97f422ac0e8737c438024b5951734506b0e1d775c73030561f4" +dependencies = [ + "bitflags 2.4.2", + "wayland-backend", + "wayland-client", + "wayland-scanner", +] + +[[package]] +name = "wayland-protocols-wlr" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad1f61b76b6c2d8742e10f9ba5c3737f6530b4c243132c2a2ccc8aa96fe25cd6" +dependencies = [ + "bitflags 2.4.2", + "wayland-backend", + "wayland-client", + "wayland-protocols", + "wayland-scanner", +] + +[[package]] +name = "wayland-scanner" +version = "0.31.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67da50b9f80159dec0ea4c11c13e24ef9e7574bd6ce24b01860a175010cea565" +dependencies = [ + "proc-macro2", + "quick-xml 0.31.0", + "quote", +] + +[[package]] +name = "wayland-sys" +version = "0.31.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "105b1842da6554f91526c14a2a2172897b7f745a805d62af4ce698706be79c12" +dependencies = [ + "dlib", + "log", + "pkg-config", +] + [[package]] name = "web-sys" version = "0.3.68" @@ -3166,6 +3367,26 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "wl-clipboard-rs" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "12b41773911497b18ca8553c3daaf8ec9fe9819caf93d451d3055f69de028adb" +dependencies = [ + "derive-new", + "libc", + "log", + "nix 0.28.0", + "os_pipe", + "tempfile", + "thiserror", + "tree_magic_mini", + "wayland-backend", + "wayland-client", + "wayland-protocols", + "wayland-protocols-wlr", +] + [[package]] name = "x11-clipboard" version = "0.3.3" diff --git a/src/clip.rs b/src/clip.rs index 5cd5300..21a10ba 100644 --- a/src/clip.rs +++ b/src/clip.rs @@ -3,22 +3,27 @@ use std::error::Error; use serde::{Deserialize, Serialize}; #[derive(Clone, Serialize, Deserialize, PartialEq, Eq)] -pub enum X11Selection { +pub enum Selection { Primary, Clipboard, + Both, } #[derive(Clone, Serialize, Deserialize)] pub struct ClipboardConfig { pub cmd: Option, pub shell_cmd: Option, - pub x11_selection: Option, + pub selection: Option, + pub wayland: Option, } use clipboard::ClipboardProvider as _; #[cfg(target_os = "linux")] -use clipboard::x11_clipboard::{Clipboard, Primary, X11ClipboardContext}; +use { + clipboard::x11_clipboard::{Clipboard, Primary, X11ClipboardContext}, + wl_clipboard_rs::copy::{ClipboardType, MimeType, Options, Source}, +}; use clipboard::ClipboardContext; @@ -38,13 +43,45 @@ pub fn copy_to_clipboard( #[cfg(target_os = "linux")] { - match conf.and_then(|sel| sel.x11_selection) { - Some(X11Selection::Primary) => X11ClipboardContext::::new() + if conf.as_ref().and_then(|c| c.wayland) == Some(true) { + let clip_type = match conf.and_then(|sel| sel.selection) { + Some(Selection::Primary) => ClipboardType::Primary, + Some(Selection::Both) => ClipboardType::Both, + None | Some(Selection::Clipboard) => ClipboardType::Regular, + }; + let mut opts = Options::new(); + opts.clipboard(clip_type).clone().copy( + Source::Bytes(link.into_bytes().into()), + MimeType::Autodetect, + )?; + return Ok(()); + } + match conf.and_then(|sel| sel.selection) { + Some(Selection::Primary) => X11ClipboardContext::::new() .and_then(|mut s| s.set_contents(link)) .map_err(|e| format!("Failed to copy to x11 \"primary\":\n{}", e).into()), - Some(X11Selection::Clipboard) => X11ClipboardContext::::new() + Some(Selection::Clipboard) => X11ClipboardContext::::new() .and_then(|mut s| s.set_contents(link)) .map_err(|e| format!("Failed to copy to x11 \"clipboard\":\n{}", e).into()), + Some(Selection::Both) => { + let cb = X11ClipboardContext::::new() + .and_then(|mut s| s.set_contents(link.clone())) + .map_err(|e| format!("Failed to copy to x11 \"clipboard\":\n{}", e)); + let pr = X11ClipboardContext::::new() + .and_then(|mut s| s.set_contents(link)) + .map_err(|e| format!("Failed to copy to x11 \"primary\":\n{}", e)); + let mut errors = String::new(); + if let Err(e) = cb { + errors.push_str(&e); + } + if let Err(e) = pr { + errors.push_str(&e); + } + if !errors.is_empty() { + return Err(errors.into()); + } + Ok(()) + } None => ClipboardContext::new() .and_then(|mut s| s.set_contents(link)) .map_err(|e| format!("Failed to copy to clipboard:\n{}", e).into()),