Skip to content

Commit

Permalink
fix: 修复部分桌面环境Wayland下取词失败的问题
Browse files Browse the repository at this point in the history
  • Loading branch information
Pylogmon committed May 27, 2023
1 parent d280e65 commit 9e5d369
Showing 1 changed file with 90 additions and 70 deletions.
160 changes: 90 additions & 70 deletions src-tauri/src/selection.rs
Original file line number Diff line number Diff line change
@@ -1,81 +1,101 @@
use crate::StringWrapper;

#[cfg(target_os = "linux")]
pub fn get_selection_text_on_x11() -> Result<String, String> {
use crate::APP;
use std::time::Duration;
use tauri::Manager;
use x11_clipboard::Clipboard;

println!("get_selection_text_on_x11");
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();
}
}
Ok(result)
} else {
Err("Clipboard Read Failed".to_string())
}
} else {
Err("Clipboard Create Failed".to_string())
}
}

#[cfg(target_os = "linux")]
pub fn get_selection_text_on_wayland() -> Result<String, String> {
use std::io::Read;
use wl_clipboard_rs::paste::{get_contents, ClipboardType, Error, MimeType, Seat};
use wl_clipboard_rs::utils::is_primary_selection_supported;

println!("get_selection_text_on_wayland");

if let Ok(support) = is_primary_selection_supported() {
if !support {
println!("Primary Selection Not Supported");
std::env::set_var("GDK_BACKEND", "x11");
return get_selection_text_on_x11();
}
} else {
println!("Check Primary Selection Support Failed");
std::env::set_var("GDK_BACKEND", "x11");
return get_selection_text_on_x11();
}

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);
}

Err(Error::NoSeats) | Err(Error::ClipboardEmpty) | Err(Error::NoMimeType) => {
return Ok("".to_string());
}

Err(err) => return Err(err.to_string()),
}
}

// 获取选择的文本(Linux)
#[cfg(target_os = "linux")]
pub fn get_selection_text() -> Result<String, String> {
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();

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())
}
}
"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);

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(err) => return Err(err.to_string()),
}
}
"x11" => get_selection_text_on_x11(),
"wayland" => get_selection_text_on_wayland(),
_ => {
return Err(format!("Unknown Session Type: {session_type}").to_string());
}
Expand Down

0 comments on commit 9e5d369

Please sign in to comment.