diff --git a/src-tauri/Cargo.lock b/src-tauri/Cargo.lock index 18915be17e..fd9ebbd5f1 100644 --- a/src-tauri/Cargo.lock +++ b/src-tauri/Cargo.lock @@ -334,6 +334,12 @@ version = "3.12.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3c6ed94e98ecff0c12dd1b04c15ec0d7d9458ca8fe806cea6f12954efe74c63b" +[[package]] +name = "bytecount" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c676a478f63e9fa2dd5368a42f28bba0d6c560b775f38583c8bbaa7fcd67c9c" + [[package]] name = "bytemuck" version = "1.13.1" @@ -757,6 +763,17 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "derive-new" +version = "0.5.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3418329ca0ad70234b9735dc4ceed10af4df60eff9c8e7b06cb5e520d92c3535" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + [[package]] name = "derive_more" version = "0.99.17" @@ -848,6 +865,12 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bd0c93bb4b0c6d9b77f4435b0ae98c24d17f1c45b2ff844c6151a07256ca923b" +[[package]] +name = "downcast-rs" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ea835d29036a4087793836fa931b08837ad5e957da9e23886b29586fb9b6650" + [[package]] name = "dtoa" version = "0.4.8" @@ -1007,6 +1030,12 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "fixedbitset" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80" + [[package]] name = "flate2" version = "1.0.26" @@ -2029,6 +2058,12 @@ version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" +[[package]] +name = "minimal-lexical" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" + [[package]] name = "minisign-verify" version = "0.2.1" @@ -2151,6 +2186,16 @@ version = "0.1.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "72ef4a56884ca558e5ddb05a1d1e7e1bfd9a68d9ed024c21704cc98872dae1bb" +[[package]] +name = "nom" +version = "7.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" +dependencies = [ + "memchr", + "minimal-lexical", +] + [[package]] name = "notify-rust" version = "4.8.0" @@ -2359,6 +2404,16 @@ dependencies = [ "pin-project-lite", ] +[[package]] +name = "os_pipe" +version = "1.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ae859aa07428ca9a929b936690f8b12dc5f11dd8c6992a18ca93919f28bc177" +dependencies = [ + "libc", + "windows-sys 0.48.0", +] + [[package]] name = "overload" version = "0.1.1" @@ -2431,6 +2486,16 @@ version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "478c572c3d73181ff3c2539045f6eb99e5491218eae919370993b890cdbdd98e" +[[package]] +name = "petgraph" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4dd7d28ee937e54fe3080c91faa1c3a46c06de6252988a7f4592ba2310ef22a4" +dependencies = [ + "fixedbitset", + "indexmap", +] + [[package]] name = "phf" version = "0.8.0" @@ -2612,6 +2677,7 @@ dependencies = [ "toml 0.7.3", "window-shadows", "windows 0.44.0", + "wl-clipboard-rs", "x11-clipboard", ] @@ -3967,6 +4033,20 @@ dependencies = [ "tracing-log", ] +[[package]] +name = "tree_magic_mini" +version = "3.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91adfd0607cacf6e4babdb870e9bec4037c1c4b151cfd279ccefc5e0c7feaa6d" +dependencies = [ + "bytecount", + "fnv", + "lazy_static", + "nom", + "once_cell", + "petgraph", +] + [[package]] name = "treediff" version = "4.0.2" @@ -4212,6 +4292,65 @@ version = "0.2.85" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a901d592cafaa4d711bc324edfaff879ac700b19c3dfd60058d2b445be2691eb" +[[package]] +name = "wayland-client" +version = "0.29.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f3b068c05a039c9f755f881dc50f01732214f5685e379829759088967c46715" +dependencies = [ + "bitflags", + "downcast-rs", + "libc", + "nix 0.24.3", + "wayland-commons", + "wayland-scanner", + "wayland-sys", +] + +[[package]] +name = "wayland-commons" +version = "0.29.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8691f134d584a33a6606d9d717b95c4fa20065605f798a3f350d78dced02a902" +dependencies = [ + "nix 0.24.3", + "once_cell", + "smallvec", + "wayland-sys", +] + +[[package]] +name = "wayland-protocols" +version = "0.29.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b950621f9354b322ee817a23474e479b34be96c2e909c14f7bc0100e9a970bc6" +dependencies = [ + "bitflags", + "wayland-client", + "wayland-commons", + "wayland-scanner", +] + +[[package]] +name = "wayland-scanner" +version = "0.29.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f4303d8fa22ab852f789e75a967f0a2cdc430a607751c0499bada3e451cbd53" +dependencies = [ + "proc-macro2", + "quote", + "xml-rs", +] + +[[package]] +name = "wayland-sys" +version = "0.29.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be12ce1a3c39ec7dba25594b97b42cb3195d54953ddb9d3d95a7c3902bc6e9d4" +dependencies = [ + "pkg-config", +] + [[package]] name = "web-sys" version = "0.3.62" @@ -4677,6 +4816,24 @@ dependencies = [ "winapi", ] +[[package]] +name = "wl-clipboard-rs" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "981a303dfbb75d659f6612d05a14b2e363c103d24f676a2d44a00d18507a1ad9" +dependencies = [ + "derive-new", + "libc", + "log", + "nix 0.24.3", + "os_pipe", + "tempfile", + "thiserror", + "tree_magic_mini", + "wayland-client", + "wayland-protocols", +] + [[package]] name = "wry" version = "0.24.3" @@ -4786,6 +4943,12 @@ dependencies = [ "winapi", ] +[[package]] +name = "xml-rs" +version = "0.8.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1690519550bfa95525229b9ca2350c63043a4857b3b0013811b2ccf4a2420b01" + [[package]] name = "zbus" version = "3.12.0" diff --git a/src-tauri/Cargo.toml b/src-tauri/Cargo.toml index 38956b5e01..90f5a21d9a 100644 --- a/src-tauri/Cargo.toml +++ b/src-tauri/Cargo.toml @@ -39,7 +39,7 @@ arboard = "3.2.0" [target.'cfg(target_os = "linux")'.dependencies ] mouse_position = "0.1.3" x11-clipboard = "0.7.1" -# wl-clipboard-rs = "0.7.0" +wl-clipboard-rs = "0.7.0" [features] # by default Tauri runs in production mode diff --git a/src-tauri/src/main.rs b/src-tauri/src/main.rs index 3a0fee87e8..b5981082fc 100644 --- a/src-tauri/src/main.rs +++ b/src-tauri/src/main.rs @@ -30,8 +30,6 @@ pub static APP: OnceCell = OnceCell::new(); pub struct StringWrapper(pub Mutex); fn main() { - #[cfg(target_os = "linux")] - std::env::set_var("GDK_BACKEND", "x11"); tauri::Builder::default() // 单例运行 .plugin(tauri_plugin_single_instance::init(|app, argv, cwd| { @@ -172,7 +170,8 @@ fn main() { write_config, set_proxy, is_macos, - is_linux + is_linux, + is_wayland, ]) //绑定托盘事件 .on_system_tray_event(|app, event| match event { diff --git a/src-tauri/src/selection.rs b/src-tauri/src/selection.rs index dc1700608e..0661fdf761 100644 --- a/src-tauri/src/selection.rs +++ b/src-tauri/src/selection.rs @@ -3,85 +3,86 @@ use crate::StringWrapper; // 获取选择的文本(Linux) #[cfg(target_os = "linux")] pub fn get_selection_text() -> Result { - // use std::env::var; - // if let Ok(session_type) = var("XDG_SESSION_TYPE") { - // match session_type.as_str() { - // "x11" => { - use crate::APP; - use std::time::Duration; - use tauri::Manager; - use x11_clipboard::Clipboard; + use std::env::var; + if let Ok(session_type) = var("XDG_SESSION_TYPE") { + match session_type.as_str() { + "x11" => { + use crate::APP; + use std::time::Duration; + use tauri::Manager; + use x11_clipboard::Clipboard; - if let Ok(clipboard) = Clipboard::new() { - if let Ok(primary) = clipboard.load( - clipboard.getter.atoms.primary, - clipboard.getter.atoms.utf8_string, - clipboard.getter.atoms.property, - Duration::from_millis(100), - ) { - let mut result = String::from_utf8_lossy(&primary) - .trim_matches('\u{0}') - .trim() - .to_string(); + if let Ok(clipboard) = Clipboard::new() { + if let Ok(primary) = clipboard.load( + clipboard.getter.atoms.primary, + clipboard.getter.atoms.utf8_string, + clipboard.getter.atoms.property, + Duration::from_millis(100), + ) { + let mut result = String::from_utf8_lossy(&primary) + .trim_matches('\u{0}') + .trim() + .to_string(); - let app_handle = APP.get().unwrap(); - let last = get_translate_text(app_handle.state()); - // 如果Primary没有变化,就尝试复制一次 - if result.is_empty() || result == last { - copy(); - std::thread::sleep(std::time::Duration::from_millis(200)); - if let Ok(main_clipboard) = clipboard.load( - clipboard.getter.atoms.clipboard, - clipboard.getter.atoms.utf8_string, - clipboard.getter.atoms.property, - Duration::from_millis(100), - ) { - result = String::from_utf8_lossy(&main_clipboard) - .trim_matches('\u{0}') - .trim() - .to_string(); + let app_handle = APP.get().unwrap(); + let last = get_translate_text(app_handle.state()); + // 如果Primary没有变化,就尝试复制一次 + if result.is_empty() || result == last { + copy(); + std::thread::sleep(std::time::Duration::from_millis(200)); + if let Ok(main_clipboard) = clipboard.load( + clipboard.getter.atoms.clipboard, + clipboard.getter.atoms.utf8_string, + clipboard.getter.atoms.property, + Duration::from_millis(100), + ) { + result = String::from_utf8_lossy(&main_clipboard) + .trim_matches('\u{0}') + .trim() + .to_string(); + } + } + Ok(result) + } else { + Err("Clipboard Read Failed".to_string()) + } + } else { + Err("Clipboard Create Failed".to_string()) } } - Ok(result) - } else { - Err("Clipboard Read Failed".to_string()) - } - } else { - Err("Clipboard Create Failed".to_string()) - } - // } - // "wayland" => { - // use std::io::Read; - // use wl_clipboard_rs::paste::{get_contents, ClipboardType, Error, MimeType, Seat}; + "wayland" => { + use std::io::Read; + use wl_clipboard_rs::paste::{get_contents, ClipboardType, Error, MimeType, Seat}; - // let result = - // get_contents(ClipboardType::Primary, Seat::Unspecified, MimeType::Text); + let result = + get_contents(ClipboardType::Primary, Seat::Unspecified, MimeType::Text); - // match result { - // Ok((mut pipe, _)) => { - // let mut contents = vec![]; - // pipe.read_to_end(&mut contents).unwrap(); - // let contents = String::from_utf8_lossy(&contents) - // .trim_matches('\u{0}') - // .trim() - // .to_string(); - // return Ok(contents); - // } + match result { + Ok((mut pipe, _)) => { + let mut contents = vec![]; + pipe.read_to_end(&mut contents).unwrap(); + let contents = String::from_utf8_lossy(&contents) + .trim_matches('\u{0}') + .trim() + .to_string(); + println!("{contents}"); + return Ok(contents); + } - // Err(Error::NoSeats) | Err(Error::ClipboardEmpty) | Err(Error::NoMimeType) => { - // return Ok("".to_string()); - // } + Err(Error::NoSeats) | Err(Error::ClipboardEmpty) | Err(Error::NoMimeType) => { + return Ok("".to_string()); + } - // Err(err) => return Err(err.to_string()), - // } - // } - // _ => { - // return Err(format!("Unknown Session Type: {session_type}").to_string()); - // } - // } - // } else { - // return Err("Get Session Type Failed".to_string()); - // } + Err(err) => return Err(err.to_string()), + } + } + _ => { + return Err(format!("Unknown Session Type: {session_type}").to_string()); + } + } + } else { + return Err("Get Session Type Failed".to_string()); + } } // 获取选择的文本(Windows) diff --git a/src-tauri/src/utils.rs b/src-tauri/src/utils.rs index 46b7415d67..c5f1cb73fb 100644 --- a/src-tauri/src/utils.rs +++ b/src-tauri/src/utils.rs @@ -8,4 +8,18 @@ pub fn is_macos() -> bool { pub fn is_linux() -> bool { let os = std::env::consts::OS; matches!(os, "linux") -} \ No newline at end of file +} + +#[tauri::command] +pub fn is_wayland() -> bool { + use std::env::var; + if let Ok(session_type) = var("XDG_SESSION_TYPE") { + if session_type == "wayland" { + return true; + } else { + return false; + } + } else { + return false; + } +} diff --git a/src/windows/Config/pages/AppConfig/index.jsx b/src/windows/Config/pages/AppConfig/index.jsx index 8be87f16ca..d699b9e5c2 100644 --- a/src/windows/Config/pages/AppConfig/index.jsx +++ b/src/windows/Config/pages/AppConfig/index.jsx @@ -4,7 +4,7 @@ import toast, { Toaster } from 'react-hot-toast'; import { useTheme } from '@mui/material/styles'; import 'flag-icons/css/flag-icons.min.css'; import { useAtom } from 'jotai'; -import React from 'react'; +import React, { useState, useEffect } from 'react'; import ConfigList from '../../components/ConfigList'; import ConfigItem from '../../components/ConfigItem'; import { set } from '../../../../global/config'; @@ -23,9 +23,8 @@ import { } from '../..'; import { invoke } from '@tauri-apps/api/tauri'; -const isLinux = await invoke('is_linux'); - export default function AppConfig() { + const [isLinux, setIsLinux] = useState(false); const [autoStart, setAutoStart] = useAtom(autoStartAtom); const [autoCheck, setAutoCheck] = useAtom(autoCheckAtom); const [defaultPined, setDefaultPined] = useAtom(defaultPinedAtom); @@ -39,6 +38,12 @@ export default function AppConfig() { const [theme, setTheme] = useAtom(themeAtom); const muitheme = useTheme(); + useEffect(() => { + invoke('is_linux').then((v) => { + setIsLinux(v); + }); + }); + return ( <> diff --git a/src/windows/Config/pages/ShortCutConfig/index.jsx b/src/windows/Config/pages/ShortCutConfig/index.jsx index b1b15b920a..439a725520 100644 --- a/src/windows/Config/pages/ShortCutConfig/index.jsx +++ b/src/windows/Config/pages/ShortCutConfig/index.jsx @@ -11,13 +11,17 @@ export default function ShortCutConfig() { const [shortcutTranslate, setShortcutTranslate] = useAtom(shortcutTranslateAtom); const [shortcutPersistent, setShortcutPersistent] = useAtom(shortcutPersistentAtom); const [shortcutOcr, setShortcutOcr] = useAtom(shortcutOcrAtom); - const [ismacos, setIsmacos] = useState(false); + const [isMacos, setIsMacos] = useState(false); + const [isWayland, setIsWayland] = useState(false); const supportKey = ['Control', 'Shift', 'Alt', 'Meta']; useEffect(() => { invoke('is_macos').then((v) => { - setIsmacos(v); + setIsMacos(v); + }); + invoke('is_wayland').then((v) => { + setIsWayland(v); }); }); @@ -32,8 +36,8 @@ export default function ShortCutConfig() { } } else { if (supportKey.includes(e.key)) { - if (e.key == 'Meta' && !ismacos) { - if (ismacos) { + if (e.key == 'Meta' && !isMacos) { + if (isMacos) { e.key = 'Command'; } else { e.key = 'Super'; @@ -49,7 +53,7 @@ export default function ShortCutConfig() { } else { setKey(e.key); } - } else if (e.key.startsWith('F') && !ismacos) { + } else if (e.key.startsWith('F') && !isMacos) { setKey(e.key); } else { if (e.keyCode == 8) { @@ -61,8 +65,12 @@ export default function ShortCutConfig() { return ( - + - + { let currentClipboard = ''; -const isMacos = await invoke('is_macos'); - export default function TopBar() { const [pined, setPined] = useState(get('default_pined') ?? true); const [listenCopy, setListenCopy] = useState(false); + const [isMacos, setIsMacos] = useState(false); const [int, setInt] = useState(); const theme = useTheme(); useEffect(() => { + invoke('is_macos').then((v) => { + setIsMacos(v); + }); if (appWindow.label == 'persistent') { appWindow.setAlwaysOnTop(pined); } else {