diff --git a/Cargo.toml b/Cargo.toml index d0fb561..fcd381b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,6 +14,7 @@ categories = ["gui"] [dependencies] raw-window-handle = { version = "0.6", features = ["std"] } thiserror = "1.0" +mime = { path = "./mime" } [target.'cfg(windows)'.dependencies] clipboard-win = { version = "5.0", features = ["std"] } @@ -32,6 +33,7 @@ winit = "0.29" [workspace] members = [ "macos", + "mime", "wayland", "x11", ] diff --git a/mime/Cargo.toml b/mime/Cargo.toml new file mode 100644 index 0000000..74bb6ad --- /dev/null +++ b/mime/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "mime" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[target.'cfg(all(unix, not(any(target_os="macos", target_os="android", target_os="emscripten", target_os="ios", target_os="redox"))))'.dependencies] +smithay-clipboard = { git = "https://github.com/pop-os/smithay-clipboard", tag = "pop-mime-types" } + + diff --git a/src/mime.rs b/mime/src/lib.rs similarity index 98% rename from src/mime.rs rename to mime/src/lib.rs index 97c55aa..78a2303 100644 --- a/src/mime.rs +++ b/mime/src/lib.rs @@ -1,3 +1,5 @@ +pub mod platform; + // need a type that can implement traits for storing custom data use std::{borrow::Cow, error, fmt}; diff --git a/mime/src/platform/linux.rs b/mime/src/platform/linux.rs new file mode 100644 index 0000000..d24dc28 --- /dev/null +++ b/mime/src/platform/linux.rs @@ -0,0 +1,47 @@ +use smithay_clipboard::mime::{AllowedMimeTypes, AsMimeTypes, MimeType}; + +use crate::{ClipboardLoadData, ClipboardStoreData}; + +impl AsMimeTypes for ClipboardStoreData { + fn available(&self) -> std::borrow::Cow<'static, [MimeType]> { + self.data + .available() + .into_iter() + .map(|m| MimeType::Other(m.clone().into())) + .collect() + } + + fn as_bytes( + &self, + mime_type: &MimeType, + ) -> Option> { + self.data.as_bytes(mime_type.as_ref()) + } +} + +impl AllowedMimeTypes for ClipboardLoadData { + // TODO select text variants if string matches... + fn allowed() -> std::borrow::Cow<'static, [MimeType]> { + T::allowed() + .into_iter() + .map(|s| MimeType::Other(s.clone().into())) + .collect() + } +} + +impl TryFrom<(Vec, MimeType)> for ClipboardLoadData +where + T: for<'b> TryFrom<(Vec, String)>, + T: 'static, +{ + type Error = crate::Error; + + fn try_from( + (value, mime): (Vec, MimeType), + ) -> Result { + let mime = mime.to_string(); + Ok(ClipboardLoadData( + T::try_from((value, mime)).map_err(|_| crate::Error)?, + )) + } +} diff --git a/mime/src/platform/mod.rs b/mime/src/platform/mod.rs new file mode 100644 index 0000000..10c3ec9 --- /dev/null +++ b/mime/src/platform/mod.rs @@ -0,0 +1,11 @@ +#[cfg(all( + unix, + not(any( + target_os = "macos", + target_os = "ios", + target_os = "android", + target_os = "emscripten", + target_os = "redox" + )) +))] +pub mod linux; diff --git a/src/lib.rs b/src/lib.rs index f574198..3da6d3e 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,4 +1,4 @@ -pub mod mime; +pub use mime; #[cfg(all( unix, @@ -48,7 +48,7 @@ mod platform; #[path = "platform/dummy.rs"] mod platform; -use mime::{ClipboardLoadData, ClipboardStoreData}; +use mime::ClipboardStoreData; use raw_window_handle::HasDisplayHandle; use std::error::Error; @@ -108,7 +108,7 @@ pub trait ClipboardProvider { fn read_data(&self) -> Option>> where - ClipboardLoadData: platform::InnerAllowedMimeTypes, + T: mime::AllowedMimeTypes, { None } @@ -118,24 +118,38 @@ pub trait ClipboardProvider { _contents: ClipboardStoreData, ) -> Option>> where - ClipboardStoreData: platform::InnerAsMimeTypes, + T: mime::AsMimeTypes, { None } fn read_primary_data(&self) -> Option>> where - ClipboardLoadData: platform::InnerAllowedMimeTypes, + T: mime::AllowedMimeTypes, { None } + fn read_primary_raw( + &self, + _allowed: Vec, + ) -> Option, String), Box>> { + None + } + + fn read_raw( + &self, + _allowed: Vec, + ) -> Option, String), Box>> { + None + } + fn write_primary_data( &mut self, _contents: ClipboardStoreData, ) -> Option>> where - ClipboardStoreData: platform::InnerAsMimeTypes, + T: mime::AsMimeTypes, { None } diff --git a/src/platform/linux.rs b/src/platform/linux.rs index 5001852..bebf78e 100644 --- a/src/platform/linux.rs +++ b/src/platform/linux.rs @@ -5,13 +5,9 @@ use crate::{ use raw_window_handle::{HasDisplayHandle, RawDisplayHandle}; use std::error::Error; -use wayland::MimeType; pub use clipboard_wayland as wayland; pub use clipboard_x11 as x11; -pub use wayland::{ - AllowedMimeTypes as InnerAllowedMimeTypes, AsMimeTypes as InnerAsMimeTypes, -}; pub enum Clipboard { Wayland(wayland::Clipboard), @@ -54,7 +50,7 @@ impl ClipboardProvider for Clipboard { fn read_data(&self) -> Option>> where - ClipboardLoadData: InnerAllowedMimeTypes, + T: mime::AllowedMimeTypes, { match self { Clipboard::Wayland(c) => { @@ -70,7 +66,7 @@ impl ClipboardProvider for Clipboard { contents: ClipboardStoreData, ) -> Option>> where - ClipboardStoreData: InnerAsMimeTypes, + T: mime::AsMimeTypes, { match self { Clipboard::Wayland(c) => { @@ -82,7 +78,7 @@ impl ClipboardProvider for Clipboard { fn read_primary_data(&self) -> Option>> where - ClipboardLoadData: InnerAllowedMimeTypes, + T: mime::AllowedMimeTypes, { match self { Clipboard::Wayland(c) => { @@ -93,12 +89,32 @@ impl ClipboardProvider for Clipboard { } } + fn read_primary_raw( + &self, + allowed: Vec, + ) -> Option, String), Box>> { + match self { + Clipboard::Wayland(c) => Some(c.read_primary_raw(allowed)), + Clipboard::X11(_) => None, + } + } + + fn read_raw( + &self, + allowed: Vec, + ) -> Option, String), Box>> { + match self { + Clipboard::Wayland(c) => Some(c.read_raw(allowed)), + Clipboard::X11(_) => None, + } + } + fn write_primary_data( &mut self, contents: ClipboardStoreData, ) -> Option>> where - ClipboardStoreData: InnerAsMimeTypes, + T: mime::AsMimeTypes, { match self { Clipboard::Wayland(c) => { @@ -121,51 +137,3 @@ pub unsafe fn connect( Ok(clipboard) } - -impl InnerAsMimeTypes for ClipboardLoadData { - fn available(&self) -> std::borrow::Cow<'static, [MimeType]> { - self.0 - .available() - .into_iter() - .map(|m| MimeType::Other(m.clone().into())) - .collect() - } - - fn as_bytes( - &self, - mime_type: &MimeType, - ) -> Option> { - self.0.as_bytes(mime_type.as_ref()) - } -} - -impl InnerAllowedMimeTypes - for ClipboardLoadData -where - ClipboardLoadData: TryFrom<(Vec, MimeType)>, -{ - // TODO select text variants if string matches... - fn allowed() -> std::borrow::Cow<'static, [wayland::MimeType]> { - T::allowed() - .into_iter() - .map(|s| MimeType::Other(s.clone().into())) - .collect() - } -} - -impl TryFrom<(Vec, MimeType)> for ClipboardLoadData -where - T: for<'b> TryFrom<(Vec, String)>, - T: 'static, -{ - type Error = crate::mime::Error; - - fn try_from( - (value, mime): (Vec, MimeType), - ) -> Result { - let mime = mime.to_string(); - Ok(ClipboardLoadData( - T::try_from((value, mime)).map_err(|_| crate::mime::Error)?, - )) - } -} diff --git a/wayland/Cargo.toml b/wayland/Cargo.toml index 2751f2e..3e28518 100644 --- a/wayland/Cargo.toml +++ b/wayland/Cargo.toml @@ -11,4 +11,4 @@ keywords = ["clipboard", "wayland"] [dependencies] smithay-clipboard = { git = "https://github.com/pop-os/smithay-clipboard", tag = "pop-mime-types" } -# smithay-clipboard = { path = "../../smithay-clipboard" } +mime = { path = "../mime" } \ No newline at end of file diff --git a/wayland/src/lib.rs b/wayland/src/lib.rs index fb5bb2e..b14586e 100644 --- a/wayland/src/lib.rs +++ b/wayland/src/lib.rs @@ -13,6 +13,7 @@ // limitations under the License. use std::{ + borrow::Cow, error::Error, ffi::c_void, sync::{Arc, Mutex}, @@ -85,4 +86,38 @@ impl Clipboard { ) -> Result> { Ok(self.context.lock().unwrap().load_primary()?) } + + pub fn read_primary_raw( + &self, + allowed: Vec, + ) -> Result<(Vec, String), Box> { + Ok(self + .context + .lock() + .unwrap() + .load_primary_raw( + allowed + .into_iter() + .map(|s| MimeType::from(Cow::Owned(s))) + .collect::>(), + ) + .map(|(d, m)| (d, m.to_string()))?) + } + + pub fn read_raw( + &self, + allowed: Vec, + ) -> Result<(Vec, String), Box> { + Ok(self + .context + .lock() + .unwrap() + .load_raw( + allowed + .into_iter() + .map(|s| MimeType::from(Cow::Owned(s))) + .collect::>(), + ) + .map(|(d, m)| (d, m.to_string()))?) + } }