diff --git a/druid-shell/src/backend/gtk/application.rs b/druid-shell/src/backend/gtk/application.rs index 1678f48e08..d6d615b3be 100644 --- a/druid-shell/src/backend/gtk/application.rs +++ b/druid-shell/src/backend/gtk/application.rs @@ -78,10 +78,20 @@ impl Application { } pub fn clipboard(&self) -> Clipboard { - Clipboard + Clipboard { + selection: gdk::SELECTION_CLIPBOARD, + } } pub fn get_locale() -> String { glib::get_language_names()[0].as_str().into() } } + +impl crate::platform::linux::LinuxApplicationExt for crate::Application { + fn primary_clipboard(&self) -> crate::Clipboard { + crate::Clipboard(Clipboard { + selection: gdk::SELECTION_PRIMARY, + }) + } +} diff --git a/druid-shell/src/backend/gtk/clipboard.rs b/druid-shell/src/backend/gtk/clipboard.rs index e4eaa01e63..3b084d5f8b 100644 --- a/druid-shell/src/backend/gtk/clipboard.rs +++ b/druid-shell/src/backend/gtk/clipboard.rs @@ -28,8 +28,21 @@ const CLIPBOARD_TARGETS: [&str; 5] = [ ]; /// The system clipboard. -#[derive(Debug, Clone)] -pub struct Clipboard; +#[derive(Clone)] +pub struct Clipboard { + pub(crate) selection: Atom, +} + +impl std::fmt::Debug for Clipboard { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + let name = match self.selection { + gdk::SELECTION_PRIMARY => "Primary", + gdk::SELECTION_CLIPBOARD => "Clipboard", + _ => "(other)", + }; + f.debug_tuple("Clipboard").field(&name).finish() + } +} impl Clipboard { /// Put a string onto the system clipboard. @@ -37,7 +50,7 @@ impl Clipboard { let string = string.as_ref().to_string(); let display = gdk::Display::get_default().unwrap(); - let clipboard = gtk::Clipboard::get_default(&display).unwrap(); + let clipboard = gtk::Clipboard::get_for_display(&display, &self.selection); let targets: Vec = CLIPBOARD_TARGETS .iter() @@ -55,7 +68,7 @@ impl Clipboard { pub fn put_formats(&mut self, formats: &[ClipboardFormat]) { let entries = make_entries(formats); let display = gdk::Display::get_default().unwrap(); - let clipboard = gtk::Clipboard::get_default(&display).unwrap(); + let clipboard = gtk::Clipboard::get_for_display(&display, &self.selection); // this is gross: we need to reclone all the data in formats in order // to move it into the closure. :/ let formats = formats.to_owned(); @@ -83,7 +96,7 @@ impl Clipboard { /// Get a string from the system clipboard, if one is available. pub fn get_string(&self) -> Option { let display = gdk::Display::get_default().unwrap(); - let clipboard = gtk::Clipboard::get_default(&display).unwrap(); + let clipboard = gtk::Clipboard::get_for_display(&display, &self.selection); for target in &CLIPBOARD_TARGETS { let atom = Atom::intern(target); @@ -99,7 +112,7 @@ impl Clipboard { /// highest priority on the system clipboard, or `None` if no types are supported. pub fn preferred_format(&self, formats: &[FormatId]) -> Option { let display = gdk::Display::get_default().unwrap(); - let clipboard = gtk::Clipboard::get_default(&display).unwrap(); + let clipboard = gtk::Clipboard::get_for_display(&display, &self.selection); let targets = clipboard.wait_for_targets()?; let format_atoms = formats .iter() @@ -119,7 +132,7 @@ impl Clipboard { /// [`Clipboard::preferred_format`] pub fn get_format(&self, format: FormatId) -> Option> { let display = gdk::Display::get_default().unwrap(); - let clipboard = gtk::Clipboard::get_default(&display).unwrap(); + let clipboard = gtk::Clipboard::get_for_display(&display, &self.selection); let atom = Atom::intern(format); clipboard .wait_for_contents(&atom) @@ -128,7 +141,7 @@ impl Clipboard { pub fn available_type_names(&self) -> Vec { let display = gdk::Display::get_default().unwrap(); - let clipboard = gtk::Clipboard::get_default(&display).unwrap(); + let clipboard = gtk::Clipboard::get_for_display(&display, &self.selection); let targets = clipboard.wait_for_targets().unwrap_or_default(); targets .iter() diff --git a/druid-shell/src/clipboard.rs b/druid-shell/src/clipboard.rs index 486234bcd6..ab992824c4 100644 --- a/druid-shell/src/clipboard.rs +++ b/druid-shell/src/clipboard.rs @@ -126,7 +126,7 @@ pub use crate::backend::clipboard as backend; /// [MIME types]: https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types /// [`ClipboardFormat`]: struct.ClipboardFormat.html #[derive(Debug, Clone)] -pub struct Clipboard(backend::Clipboard); +pub struct Clipboard(pub(crate) backend::Clipboard); impl Clipboard { /// Put a string onto the system clipboard. diff --git a/druid-shell/src/platform/linux.rs b/druid-shell/src/platform/linux.rs index fa8dbd0dcd..5e4071c076 100644 --- a/druid-shell/src/platform/linux.rs +++ b/druid-shell/src/platform/linux.rs @@ -24,3 +24,15 @@ pub trait LinuxApplicationExt { /// This is useful for middle mouse paste. fn primary_clipboard(&self) -> Clipboard; } + +#[cfg(test)] +#[allow(unused_imports)] +mod test { + use crate::Application; + + use super::*; + use static_assertions as sa; + // TODO(shell/x11): implement LinuxApplicationExt + #[cfg(not(feature = "x11"))] + sa::assert_impl_all!(Application: LinuxApplicationExt); +}