commit 6f71824857fd5d831ee9d8e759f1589b192f0a4c Author: Héctor Ramón Jiménez Date: Wed Dec 18 05:55:32 2019 +0100 Start with an initial draft diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 0000000..8527f0d --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,16 @@ +name: Test +on: [push, pull_request] +jobs: + all: + runs-on: ${{ matrix.os }} + strategy: + matrix: + os: [ubuntu-latest, windows-latest, macOS-latest] + rust: [stable, beta] + steps: + - uses: hecrj/setup-rust-action@v1 + with: + rust-version: ${{ matrix.rust }} + - uses: actions/checkout@master + - name: Run tests + run: cargo test --verbose diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..6936990 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +/target +**/*.rs.bk +Cargo.lock diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..33eec1c --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,22 @@ +[package] +name = "window_clipboard" +version = "0.1.0-alpha" +authors = ["Héctor Ramón Jiménez "] +edition = "2018" +description = "A library to obtain clipboard access from a `raw-window-handle`" +license = "MIT" +repository = "https://github.com/hecrj/iced" +documentation = "https://docs.rs/window_clipboard" +readme = "README.md" +keywords = ["clipboard", "window", "ui", "gui", "raw-window-handle"] +categories = ["gui"] + +[dependencies] +raw-window-handle = "0.3" +clipboard = "0.5" + +[target.'cfg(all(unix, not(any(target_os="macos", target_os="android", target_os="emscripten"))))'.dependencies] +smithay-clipboard = "0.3" + +[dev-dependencies] +winit = "=0.20.0-alpha5" diff --git a/README.md b/README.md new file mode 100644 index 0000000..eac4fb4 --- /dev/null +++ b/README.md @@ -0,0 +1,3 @@ +# window_clipboard + +A library to obtain clipboard access from a `raw-window-handle`. diff --git a/examples/basic.rs b/examples/basic.rs new file mode 100644 index 0000000..fde2e9b --- /dev/null +++ b/examples/basic.rs @@ -0,0 +1,28 @@ +use window_clipboard::Clipboard; +use winit::{ + event::{Event, WindowEvent}, + event_loop::{ControlFlow, EventLoop}, + window::WindowBuilder, +}; + +fn main() { + let event_loop = EventLoop::new(); + + let window = WindowBuilder::new() + .with_title("A fantastic window!") + .build(&event_loop) + .unwrap(); + + let clipboard = Clipboard::new(&window).expect("Create clipboard"); + + event_loop.run(move |event, _, control_flow| match event { + Event::EventsCleared => { + println!("{:?}", clipboard.read()); + } + Event::WindowEvent { + event: WindowEvent::CloseRequested, + window_id, + } if window_id == window.id() => *control_flow = ControlFlow::Exit, + _ => *control_flow = ControlFlow::Wait, + }); +} diff --git a/rustfmt.toml b/rustfmt.toml new file mode 100644 index 0000000..7e5dded --- /dev/null +++ b/rustfmt.toml @@ -0,0 +1,3 @@ +max_width=80 +wrap_comments=true +merge_imports=true diff --git a/src/lib.rs b/src/lib.rs new file mode 100644 index 0000000..2d50654 --- /dev/null +++ b/src/lib.rs @@ -0,0 +1,85 @@ +use raw_window_handle::{HasRawWindowHandle, RawWindowHandle}; +use std::cell::RefCell; +use std::error::Error; + +pub struct Clipboard { + raw: Raw, +} + +enum Raw { + #[cfg(all( + unix, + not(any( + target_os = "macos", + target_os = "android", + target_os = "emscripten" + )) + ))] + Wayland(RefCell), + + NotWayland(RefCell), +} + +impl Clipboard { + pub fn new( + window: &W, + ) -> Result> { + let raw = match window.raw_window_handle() { + #[cfg(all( + unix, + not(any( + target_os = "macos", + target_os = "android", + target_os = "emscripten" + )) + ))] + RawWindowHandle::Wayland(handle) => { + assert!(!handle.display.is_null()); + + Raw::Wayland(RefCell::new(unsafe { + smithay_clipboard::WaylandClipboard::new_from_external( + handle.display as *mut _, + ) + })) + } + _ => { + use clipboard::ClipboardProvider as _; + + Raw::NotWayland(RefCell::new( + clipboard::ClipboardContext::new()? + )) + } + }; + + Ok(Clipboard { raw }) + } + + pub fn read(&self) -> Result> { + // TODO: Think about use of `RefCell` + // Maybe we should make `read` mutable (?) + use clipboard::ClipboardProvider as _; + + match &self.raw { + Raw::Wayland(clipboard) => Ok(clipboard.borrow_mut().load(None)), + Raw::NotWayland(clipboard) => clipboard.borrow_mut().get_contents(), + } + } + + pub fn write( + &mut self, + contents: impl Into, + ) -> Result<(), Box> { + use clipboard::ClipboardProvider as _; + + match &self.raw { + Raw::Wayland(clipboard) => { + clipboard.borrow_mut().store(None, contents); + + Ok(()) + } + Raw::NotWayland(clipboard) => { + clipboard.borrow_mut().set_contents(contents.into()) + } + } + } +}