Просмотр исходного кода

app: add clipboard.rs and use `x11-clipboard` on x11 instead of miniquad

epiphany 1 месяц назад
Родитель
Сommit
54622a64ca

+ 38 - 0
bin/app/Cargo.lock

@@ -1695,6 +1695,7 @@ dependencies = [
  "tracing-subscriber",
  "tracing-subscriber",
  "unic-langid",
  "unic-langid",
  "url",
  "url",
+ "x11-clipboard",
  "zeno",
  "zeno",
  "zeromq",
  "zeromq",
 ]
 ]
@@ -3022,6 +3023,16 @@ dependencies = [
  "zeroize",
  "zeroize",
 ]
 ]
 
 
+[[package]]
+name = "gethostname"
+version = "1.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1bd49230192a3797a9a4d6abe9b3eed6f7fa4c8a8a4947977c6f80025f92cbd8"
+dependencies = [
+ "rustix",
+ "windows-link",
+]
+
 [[package]]
 [[package]]
 name = "getrandom"
 name = "getrandom"
 version = "0.2.17"
 version = "0.2.17"
@@ -9239,6 +9250,33 @@ dependencies = [
  "tap",
  "tap",
 ]
 ]
 
 
+[[package]]
+name = "x11-clipboard"
+version = "0.9.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "662d74b3d77e396b8e5beb00b9cad6a9eccf40b2ef68cc858784b14c41d535a3"
+dependencies = [
+ "libc",
+ "x11rb",
+]
+
+[[package]]
+name = "x11rb"
+version = "0.13.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9993aa5be5a26815fe2c3eacfc1fde061fc1a1f094bf1ad2a18bf9c495dd7414"
+dependencies = [
+ "gethostname",
+ "rustix",
+ "x11rb-protocol",
+]
+
+[[package]]
+name = "x11rb-protocol"
+version = "0.13.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ea6fc2961e4ef194dcbfe56bb845534d0dc8098940c7e5c012a258bfec6701bd"
+
 [[package]]
 [[package]]
 name = "x25519-dalek"
 name = "x25519-dalek"
 version = "2.0.1"
 version = "2.0.1"

+ 3 - 0
bin/app/Cargo.toml

@@ -93,6 +93,9 @@ dirs = "5.0.1"
 # Enable ASM routines for non-Android platforms.
 # Enable ASM routines for non-Android platforms.
 rav1d = { git = "https://github.com/leo030303/rav1d", branch = "add-rust-api", features = ["bitdepth_8"] }
 rav1d = { git = "https://github.com/leo030303/rav1d", branch = "add-rust-api", features = ["bitdepth_8"] }
 
 
+[target.'cfg(target_os = "linux")'.dependencies]
+x11-clipboard = "0.9.3"
+
 [target.'cfg(target_os = "android")'.dependencies]
 [target.'cfg(target_os = "android")'.dependencies]
 tracing-android = "0.2.0"
 tracing-android = "0.2.0"
 # Required by Arti: tor-dirmgr
 # Required by Arti: tor-dirmgr

+ 2 - 1
bin/app/src/app/schema/wallet/receive.rs

@@ -22,6 +22,7 @@ use crate::{
         node::{create_button, create_layer, create_text, create_vector_art},
         node::{create_button, create_layer, create_text, create_vector_art},
         schema::COLOR_SCHEME,
         schema::COLOR_SCHEME,
     },
     },
+    clipboard,
     expr,
     expr,
     gfx::gfxtag,
     gfx::gfxtag,
     mesh::COLOR_CYAN,
     mesh::COLOR_CYAN,
@@ -172,7 +173,7 @@ pub async fn make(
     let listen_click = app.ex.spawn(async move {
     let listen_click = app.ex.spawn(async move {
         while let Ok(_) = recvr.recv().await {
         while let Ok(_) = recvr.recv().await {
             let addr = receive_address_text2.get();
             let addr = receive_address_text2.get();
-            miniquad::window::clipboard_set(&addr);
+            clipboard::set(&addr);
         }
         }
     });
     });
     app.tasks.lock().unwrap().push(listen_click);
     app.tasks.lock().unwrap().push(listen_click);

+ 2 - 1
bin/app/src/app/schema/wallet/send_step2.rs

@@ -26,6 +26,7 @@ use crate::{
         node::{create_button, create_layer, create_singleline_edit, create_text, create_vector_art},
         node::{create_button, create_layer, create_singleline_edit, create_text, create_vector_art},
         schema::COLOR_SCHEME,
         schema::COLOR_SCHEME,
     },
     },
+    clipboard,
     expr,
     expr,
     gfx::gfxtag,
     gfx::gfxtag,
     mesh::COLOR_CYAN,
     mesh::COLOR_CYAN,
@@ -332,7 +333,7 @@ pub async fn make(
     let renderer_clone = app.renderer.clone();
     let renderer_clone = app.renderer.clone();
     let listen_click = app.ex.spawn(async move {
     let listen_click = app.ex.spawn(async move {
         while let Ok(_) = recvr.recv().await {
         while let Ok(_) = recvr.recv().await {
-            if let Some(clipboard_text) = miniquad::window::clipboard_get() {
+            if let Some(clipboard_text) = clipboard::get() {
                 let text_prop = recipient_input2.get_property("text").unwrap();
                 let text_prop = recipient_input2.get_property("text").unwrap();
                 let atom = &mut renderer_clone.make_guard(gfxtag!("step2 recipient paste"));
                 let atom = &mut renderer_clone.make_guard(gfxtag!("step2 recipient paste"));
                 text_prop.set_str(atom, Role::App, 0, &clipboard_text).unwrap();
                 text_prop.set_str(atom, Role::App, 0, &clipboard_text).unwrap();

+ 67 - 0
bin/app/src/clipboard.rs

@@ -0,0 +1,67 @@
+/* This file is part of DarkFi (https://dark.fi)
+ *
+ * Copyright (C) 2020-2026 Dyne.org foundation
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#[cfg(target_os = "linux")]
+use std::sync::{Arc, Mutex};
+#[cfg(target_os = "linux")]
+use std::time::Duration;
+
+#[cfg(target_os = "linux")]
+static X11_CLIPBOARD: Mutex<Option<Arc<x11_clipboard::Clipboard>>> = Mutex::new(None);
+
+#[cfg(target_os = "linux")]
+fn get_clipboard() -> Option<Arc<x11_clipboard::Clipboard>> {
+    let mut clipboard = X11_CLIPBOARD.lock().unwrap();
+    if clipboard.is_none() {
+        *clipboard = x11_clipboard::Clipboard::new().ok().map(Arc::new);
+    }
+    clipboard.clone()
+}
+
+pub fn get() -> Option<String> {
+    #[cfg(target_os = "linux")]
+    if let Some(clipboard) = get_clipboard() {
+        if let Ok(bytes) = clipboard.load(
+            clipboard.getter.atoms.clipboard,
+            clipboard.getter.atoms.utf8_string,
+            clipboard.getter.atoms.property,
+            Duration::from_secs(2),
+        ) {
+            if let Ok(text) = String::from_utf8(bytes) {
+                return Some(text)
+            }
+        }
+    }
+
+    miniquad::window::clipboard_get()
+}
+
+pub fn set(text: &str) {
+    #[cfg(target_os = "linux")]
+    if let Some(clipboard) = get_clipboard() {
+        if clipboard.store(
+            clipboard.setter.atoms.clipboard,
+            clipboard.setter.atoms.utf8_string,
+            text,
+        ).is_ok() {
+            return
+        }
+    }
+
+    miniquad::window::clipboard_set(text);
+}

+ 1 - 0
bin/app/src/main.rs

@@ -35,6 +35,7 @@ extern crate tracing;
 mod android;
 mod android;
 mod app;
 mod app;
 mod build_info;
 mod build_info;
+mod clipboard;
 mod error;
 mod error;
 mod expr;
 mod expr;
 mod gfx;
 mod gfx;

+ 7 - 6
bin/app/src/ui/edit/mod.rs

@@ -37,6 +37,7 @@ use tracing::instrument;
 #[cfg(target_os = "android")]
 #[cfg(target_os = "android")]
 use crate::android::textinput::AndroidTextInputState;
 use crate::android::textinput::AndroidTextInputState;
 use crate::{
 use crate::{
+    clipboard,
     gfx::{
     gfx::{
         anim::Frame as AnimFrame, gfxtag, DrawCall, DrawInstruction, DrawMesh, ManagedSeqAnimPtr,
         anim::Frame as AnimFrame, gfxtag, DrawCall, DrawInstruction, DrawMesh, ManagedSeqAnimPtr,
         Point, Rectangle, RenderApi, Renderer, RendererSync, Vertex,
         Point, Rectangle, RenderApi, Renderer, RendererSync, Vertex,
@@ -528,13 +529,13 @@ impl BaseEdit {
                 if action_mod {
                 if action_mod {
                     let editor = self.editor.lock();
                     let editor = self.editor.lock();
                     if let Some(txt) = editor.selected_text() {
                     if let Some(txt) = editor.selected_text() {
-                        miniquad::window::clipboard_set(&txt);
+                        clipboard::set(&txt);
                     }
                     }
                 }
                 }
             }
             }
             'v' => {
             'v' => {
                 if action_mod {
                 if action_mod {
-                    if let Some(txt) = miniquad::window::clipboard_get() {
+                    if let Some(txt) = clipboard::get() {
                         self.editor.lock().insert(&txt, atom);
                         self.editor.lock().insert(&txt, atom);
                         // Maybe insert should call this?
                         // Maybe insert should call this?
                         self.behave.apply_cursor_scroll();
                         self.behave.apply_cursor_scroll();
@@ -703,11 +704,11 @@ impl BaseEdit {
             match action_id {
             match action_id {
                 ACTION_COPY => {
                 ACTION_COPY => {
                     if let Some(txt) = self.editor.lock().selected_text() {
                     if let Some(txt) = self.editor.lock().selected_text() {
-                        miniquad::window::clipboard_set(&txt);
+                        clipboard::set(&txt);
                     }
                     }
                 }
                 }
                 ACTION_PASTE => {
                 ACTION_PASTE => {
-                    if let Some(txt) = miniquad::window::clipboard_get() {
+                    if let Some(txt) = clipboard::get() {
                         self.editor.lock().insert(&txt, atom);
                         self.editor.lock().insert(&txt, atom);
                         self.behave.apply_cursor_scroll();
                         self.behave.apply_cursor_scroll();
                         self.finish_select(atom);
                         self.finish_select(atom);
@@ -1851,11 +1852,11 @@ impl UIObject for BaseEdit {
             match action_id {
             match action_id {
                 ACTION_COPY => {
                 ACTION_COPY => {
                     if let Some(txt) = self.editor.lock().selected_text() {
                     if let Some(txt) = self.editor.lock().selected_text() {
-                        miniquad::window::clipboard_set(&txt);
+                        clipboard::set(&txt);
                     }
                     }
                 }
                 }
                 ACTION_PASTE => {
                 ACTION_PASTE => {
-                    if let Some(txt) = miniquad::window::clipboard_get() {
+                    if let Some(txt) = clipboard::get() {
                         self.editor.lock().insert(&txt, atom);
                         self.editor.lock().insert(&txt, atom);
                         self.behave.apply_cursor_scroll();
                         self.behave.apply_cursor_scroll();
                         self.finish_select(atom);
                         self.finish_select(atom);