tawasuyu/llimphi
Sovereign retained-mode GPU UI framework in Rust (wgpu+vello+taffy+parley), Elm loop, 40+ widgets.
⎇ 5b7ac4fd5dcd5bff1aec842610f8e2160f571e2b
widgets/clipboard/src/lib.rs
Historia
Quién tocó qué
crudo
feat: llimphi standalone — framework UI soberano extraído del monorepo
1//! `llimphi-clipboard` — el portapapeles del sistema para apps Llimphi.
2//!
3//! El `text-editor` define el trait [`Clipboard`] pero deja el backend al
4//! caller (no quiere acoplarse a X11/Wayland/macOS/Windows). Este crate
5//! aporta el backend obvio — [`arboard`] — para que cualquier app lo
6//! enchufe en una línea:
7//!
8//! ```ignore
9//! let mut clip = llimphi_clipboard::SystemClipboard::new();
10//! editor.apply_key_with_clipboard(&ev, &mut clip);
11//! ```
12//!
13//! Si no hay display (CI headless, sesión sin servidor gráfico) degrada
14//! a no-op silencioso: `get` devuelve `None`, `set` descarta. Nunca
15//! panica.
16
17#![forbid(unsafe_code)]
18
19use llimphi_widget_text_editor::Clipboard;
20
21/// Portapapeles del sistema vía `arboard`. `None` interno = no se pudo
22/// abrir (sin display); en ese caso opera como [`llimphi_widget_text_editor::NullClipboard`].
23pub struct SystemClipboard {
24 inner: Option<arboard::Clipboard>,
25}
26
27impl SystemClipboard {
28 pub fn new() -> Self {
29 Self {
30 inner: arboard::Clipboard::new().ok(),
31 }
32 }
33
34 /// `true` si el backend del SO está disponible.
35 pub fn is_available(&self) -> bool {
36 self.inner.is_some()
37 }
38}
39
40impl Default for SystemClipboard {
41 fn default() -> Self {
42 Self::new()
43 }
44}
45
46impl Clipboard for SystemClipboard {
47 fn get(&mut self) -> Option<String> {
48 self.inner.as_mut()?.get_text().ok()
49 }
50 fn set(&mut self, s: &str) {
51 if let Some(c) = self.inner.as_mut() {
52 let _ = c.set_text(s.to_owned());
53 }
54 }
55}