1use crate::core::clipboard::Kind;
4use std::sync::Arc;
5use winit::window::{Window, WindowId};
6
7pub struct Clipboard {
10 state: State,
11}
12
13enum State {
14 Connected {
15 clipboard: window_clipboard::Clipboard,
16 #[allow(dead_code)]
21 window: Arc<Window>,
22 },
23 Unavailable,
24}
25
26impl Clipboard {
27 pub fn connect(window: Arc<Window>) -> Clipboard {
29 #[allow(unsafe_code)]
34 let clipboard =
35 unsafe { window_clipboard::Clipboard::connect(&window) };
36
37 let state = match clipboard {
38 Ok(clipboard) => State::Connected { clipboard, window },
39 Err(_) => State::Unavailable,
40 };
41
42 Clipboard { state }
43 }
44
45 pub fn unconnected() -> Clipboard {
48 Clipboard {
49 state: State::Unavailable,
50 }
51 }
52
53 pub fn read(&self, kind: Kind) -> Option<String> {
55 match &self.state {
56 State::Connected { clipboard, .. } => match kind {
57 Kind::Standard => clipboard.read().ok(),
58 Kind::Primary => clipboard.read_primary().and_then(Result::ok),
59 },
60 State::Unavailable => None,
61 }
62 }
63
64 pub fn write(&mut self, kind: Kind, contents: String) {
66 match &mut self.state {
67 State::Connected { clipboard, .. } => {
68 let result = match kind {
69 Kind::Standard => clipboard.write(contents),
70 Kind::Primary => {
71 clipboard.write_primary(contents).unwrap_or(Ok(()))
72 }
73 };
74
75 match result {
76 Ok(()) => {}
77 Err(error) => {
78 log::warn!("error writing to clipboard: {error}");
79 }
80 }
81 }
82 State::Unavailable => {}
83 }
84 }
85
86 pub fn window_id(&self) -> Option<WindowId> {
88 match &self.state {
89 State::Connected { window, .. } => Some(window.id()),
90 State::Unavailable => None,
91 }
92 }
93}
94
95impl crate::core::Clipboard for Clipboard {
96 fn read(&self, kind: Kind) -> Option<String> {
97 self.read(kind)
98 }
99
100 fn write(&mut self, kind: Kind, contents: String) {
101 self.write(kind, contents);
102 }
103}