diff --git a/Cargo.lock b/Cargo.lock index 10cc343cfdf6..284b8c3ea06c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1119,6 +1119,7 @@ dependencies = [ "instant", "puffin", "serde", + "smithay-clipboard", "tracing", "tts", "webbrowser", @@ -3118,6 +3119,16 @@ dependencies = [ "wayland-protocols", ] +[[package]] +name = "smithay-clipboard" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "610b551bd25378bfd2b8e7a0fcbd83d427e8f2f6a40c47ae0f70688e9949dd55" +dependencies = [ + "smithay-client-toolkit", + "wayland-client", +] + [[package]] name = "socket2" version = "0.4.4" @@ -3506,7 +3517,7 @@ version = "1.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4ee73e6e4924fe940354b8d4d98cad5231175d615cd855b758adc658c0aac6a0" dependencies = [ - "cfg-if 0.1.10", + "cfg-if 1.0.0", "static_assertions", ] @@ -3856,7 +3867,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fc6a3cffdb686fbb24d9fb8f03a213803277ed2300f11026a3afe1f108dc021b" dependencies = [ "jni", - "ndk-glue 0.5.2", + "ndk-glue 0.6.2", "url", "web-sys", "widestring", diff --git a/egui-winit/Cargo.toml b/egui-winit/Cargo.toml index b999ef19ee59..6f88dc453617 100644 --- a/egui-winit/Cargo.toml +++ b/egui-winit/Cargo.toml @@ -25,7 +25,7 @@ bytemuck = ["egui/bytemuck"] # enable cut/copy/paste to OS clipboard. # if disabled a clipboard will be simulated so you can still copy/paste within the egui app. -clipboard = ["arboard"] +clipboard = ["arboard", "smithay-clipboard"] # enable opening links in a browser when an egui hyperlink is clicked. links = ["webbrowser"] @@ -49,6 +49,7 @@ tracing = "0.1" winit = "0.26.1" arboard = { version = "2.1", optional = true, default-features = false } +smithay-clipboard = { version = "0.6.3", optional = true } puffin = { version = "0.13", optional = true } serde = { version = "1.0", optional = true, features = ["derive"] } webbrowser = { version = "0.7", optional = true } diff --git a/egui-winit/src/clipboard.rs b/egui-winit/src/clipboard.rs index 8737bfd9f968..46e92c9d2842 100644 --- a/egui-winit/src/clipboard.rs +++ b/egui-winit/src/clipboard.rs @@ -1,3 +1,5 @@ +use std::os::raw::c_void; + /// Handles interfacing with the OS clipboard. /// /// If the "clipboard" feature is off, or we cannot connect to the OS clipboard, @@ -6,23 +8,37 @@ pub struct Clipboard { #[cfg(feature = "arboard")] arboard: Option, + #[cfg(feature = "smithay-clipboard")] + smithay: Option, + /// Fallback manual clipboard. clipboard: String, } -impl Default for Clipboard { - fn default() -> Self { +impl Clipboard { + #[allow(unused_variables)] + pub fn new(#[allow(unused_variables)] wayland_display: Option<*mut c_void>) -> Self { Self { #[cfg(feature = "arboard")] arboard: init_arboard(), - - clipboard: String::default(), + #[cfg(feature = "smithay-clipboard")] + smithay: init_smithay_clipboard(wayland_display), + clipboard: Default::default(), } } -} -impl Clipboard { pub fn get(&mut self) -> Option { + #[cfg(feature = "smithay-clipboard")] + if let Some(clipboard) = &mut self.smithay { + return match clipboard.load() { + Ok(text) => Some(text), + Err(err) => { + tracing::error!("Paste error: {}", err); + None + } + }; + } + #[cfg(feature = "arboard")] if let Some(clipboard) = &mut self.arboard { return match clipboard.get_text() { @@ -38,6 +54,12 @@ impl Clipboard { } pub fn set(&mut self, text: String) { + #[cfg(feature = "smithay-clipboard")] + if let Some(clipboard) = &mut self.smithay { + clipboard.store(text); + return; + } + #[cfg(feature = "arboard")] if let Some(clipboard) = &mut self.arboard { if let Err(err) = clipboard.set_text(text) { @@ -60,3 +82,16 @@ fn init_arboard() -> Option { } } } + +#[cfg(feature = "smithay-clipboard")] +fn init_smithay_clipboard( + wayland_display: Option<*mut c_void>, +) -> Option { + if let Some(display) = wayland_display { + #[allow(unsafe_code)] + Some(unsafe { smithay_clipboard::Clipboard::new(display) }) + } else { + tracing::error!("Cannot initialize smithay clipboard without a display handle!"); + None + } +} diff --git a/egui-winit/src/lib.rs b/egui-winit/src/lib.rs index 47129ac2fe48..056fcbf198d4 100644 --- a/egui-winit/src/lib.rs +++ b/egui-winit/src/lib.rs @@ -5,6 +5,8 @@ #![allow(clippy::manual_range_contains)] +use std::os::raw::c_void; + pub use egui; pub use winit; @@ -14,6 +16,9 @@ mod window_settings; pub use window_settings::WindowSettings; +#[cfg(unix)] +use winit::platform::unix::WindowExtUnix; + pub fn native_pixels_per_point(window: &winit::window::Window) -> f32 { window.scale_factor() as f32 } @@ -53,13 +58,21 @@ impl State { /// * `max_texture_side`: e.g. `GL_MAX_TEXTURE_SIZE` /// * the native `pixels_per_point` (dpi scaling). pub fn new(max_texture_side: usize, window: &winit::window::Window) -> Self { - Self::from_pixels_per_point(max_texture_side, native_pixels_per_point(window)) + Self::from_pixels_per_point( + max_texture_side, + native_pixels_per_point(window), + window.wayland_display(), + ) } /// Initialize with: /// * `max_texture_side`: e.g. `GL_MAX_TEXTURE_SIZE` /// * the given `pixels_per_point` (dpi scaling). - pub fn from_pixels_per_point(max_texture_side: usize, pixels_per_point: f32) -> Self { + pub fn from_pixels_per_point( + max_texture_side: usize, + pixels_per_point: f32, + wayland_display: Option<*mut c_void>, + ) -> Self { Self { start_time: instant::Instant::now(), egui_input: egui::RawInput { @@ -72,7 +85,7 @@ impl State { current_cursor_icon: egui::CursorIcon::Default, current_pixels_per_point: pixels_per_point, - clipboard: Default::default(), + clipboard: clipboard::Clipboard::new(wayland_display), screen_reader: screen_reader::ScreenReader::default(), simulate_touch_screen: false,