ailloli_ui_openxr/clipboard.rs
1//! Clipboard adapter used by XR/runtime integrations.
2//!
3//! Desktop runtimes usually rely on `arboard` through `ailloli_ui_winit`.
4//! For XR hosts this crate keeps a conservative default: a memory-backed clipboard
5//! that remains consistent inside the process and never blocks the render loop.
6
7use std::cell::RefCell;
8
9use ailloli_ui_runtime::app::ClipboardProvider;
10
11#[derive(Default)]
12/// Process-local clipboard storage for hosts without a system clipboard.
13///
14/// The initial and explicitly cleared state reads as `None`; writing an empty
15/// string also restores that state. Reads return an owned clone.
16///
17/// # Examples
18///
19/// ```
20/// use ailloli_ui_openxr::VrClipboard;
21/// use ailloli_ui_runtime::app::ClipboardProvider;
22///
23/// let clipboard = VrClipboard::new();
24/// assert_eq!(clipboard.read_text(), None);
25/// clipboard.write_text("XR note")?;
26/// assert_eq!(clipboard.read_text().as_deref(), Some("XR note"));
27/// # Ok::<(), String>(())
28/// ```
29pub struct VrClipboard {
30 /// UI-local UTF-8 clipboard contents retained for the VR session.
31 text: RefCell<String>,
32}
33
34impl VrClipboard {
35 /// Creates an empty process-local clipboard.
36 ///
37 /// # Examples
38 ///
39 /// ```
40 /// use ailloli_ui_openxr::VrClipboard;
41 /// use ailloli_ui_runtime::app::ClipboardProvider;
42 ///
43 /// let clipboard = VrClipboard::new();
44 /// assert_eq!(clipboard.read_text(), None);
45 /// ```
46 pub fn new() -> Self {
47 Self::default()
48 }
49}
50
51impl ClipboardProvider for VrClipboard {
52 fn read_text(&self) -> Option<String> {
53 let text = self.text.borrow();
54 if text.is_empty() {
55 None
56 } else {
57 Some(text.clone())
58 }
59 }
60
61 fn write_text(&self, text: &str) -> Result<(), String> {
62 let mut slot = self.text.borrow_mut();
63 *slot = text.to_string();
64 Ok(())
65 }
66}