mirror of
https://github.com/weyne85/rustdesk.git
synced 2025-10-29 17:00:05 +00:00
Merge branch 'feat/x11/clipboard-file/init' into feat/osx/clipboard-file
Signed-off-by: ClSlaid <cailue@bupt.edu.cn>
This commit is contained in:
@@ -24,7 +24,6 @@ use self::url::{encode_path_to_uri, parse_plain_uri_list};
|
||||
|
||||
use super::fuse::FuseServer;
|
||||
|
||||
#[cfg(not(feature = "wayland"))]
|
||||
#[cfg(target_os = "linux")]
|
||||
/// clipboard implementation of x11
|
||||
pub mod x11;
|
||||
@@ -34,6 +33,7 @@ pub mod x11;
|
||||
pub mod ns_clipboard;
|
||||
|
||||
pub mod local_file;
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
pub mod url;
|
||||
|
||||
@@ -68,7 +68,6 @@ fn add_remote_format(local_name: &str, remote_id: i32) {
|
||||
|
||||
trait SysClipboard: Send + Sync {
|
||||
fn start(&self);
|
||||
fn stop(&self);
|
||||
|
||||
fn set_file_list(&self, paths: &[PathBuf]) -> Result<(), CliprdrError>;
|
||||
fn get_file_list(&self) -> Vec<PathBuf>;
|
||||
@@ -531,7 +530,7 @@ impl CliprdrServiceContext for ClipboardContext {
|
||||
if let Some(fuse_handle) = self.fuse_handle.lock().take() {
|
||||
fuse_handle.join();
|
||||
}
|
||||
self.clipboard.stop();
|
||||
// we don't stop the clipboard, keep listening in case of restart
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
||||
@@ -1,8 +1,4 @@
|
||||
use std::{
|
||||
collections::BTreeSet,
|
||||
path::PathBuf,
|
||||
sync::atomic::{AtomicBool, Ordering},
|
||||
};
|
||||
use std::{collections::BTreeSet, path::PathBuf};
|
||||
|
||||
use cacao::pasteboard::{Pasteboard, PasteboardName};
|
||||
use hbb_common::log;
|
||||
@@ -28,7 +24,6 @@ fn set_file_list(file_list: &[PathBuf]) -> Result<(), CliprdrError> {
|
||||
}
|
||||
|
||||
pub struct NsPasteboard {
|
||||
stopped: AtomicBool,
|
||||
ignore_path: PathBuf,
|
||||
|
||||
former_file_list: Mutex<Vec<PathBuf>>,
|
||||
@@ -37,16 +32,10 @@ pub struct NsPasteboard {
|
||||
impl NsPasteboard {
|
||||
pub fn new(ignore_path: &PathBuf) -> Result<Self, CliprdrError> {
|
||||
Ok(Self {
|
||||
stopped: AtomicBool::new(false),
|
||||
ignore_path: ignore_path.to_owned(),
|
||||
former_file_list: Mutex::new(vec![]),
|
||||
})
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn is_stopped(&self) -> bool {
|
||||
self.stopped.load(Ordering::Relaxed)
|
||||
}
|
||||
}
|
||||
|
||||
impl SysClipboard for NsPasteboard {
|
||||
@@ -56,13 +45,11 @@ impl SysClipboard for NsPasteboard {
|
||||
}
|
||||
|
||||
fn start(&self) {
|
||||
self.stopped.store(false, Ordering::Relaxed);
|
||||
{
|
||||
*self.former_file_list.lock() = vec![];
|
||||
}
|
||||
|
||||
loop {
|
||||
if self.is_stopped() {
|
||||
std::thread::sleep(std::time::Duration::from_millis(100));
|
||||
continue;
|
||||
}
|
||||
let file_list = match wait_file_list() {
|
||||
Some(v) => v,
|
||||
None => {
|
||||
@@ -104,10 +91,6 @@ impl SysClipboard for NsPasteboard {
|
||||
log::debug!("stop listening file related atoms on clipboard");
|
||||
}
|
||||
|
||||
fn stop(&self) {
|
||||
self.stopped.store(true, Ordering::Relaxed);
|
||||
}
|
||||
|
||||
fn get_file_list(&self) -> Vec<PathBuf> {
|
||||
self.former_file_list.lock().clone()
|
||||
}
|
||||
|
||||
@@ -1,8 +1,4 @@
|
||||
use std::{
|
||||
collections::BTreeSet,
|
||||
path::PathBuf,
|
||||
sync::atomic::{AtomicBool, Ordering},
|
||||
};
|
||||
use std::{collections::BTreeSet, path::PathBuf};
|
||||
|
||||
use hbb_common::log;
|
||||
use once_cell::sync::OnceCell;
|
||||
@@ -16,15 +12,11 @@ use super::{encode_path_to_uri, parse_plain_uri_list, SysClipboard};
|
||||
|
||||
static X11_CLIPBOARD: OnceCell<Clipboard> = OnceCell::new();
|
||||
|
||||
// this is tested on an Arch Linux with X11
|
||||
const X11_CLIPBOARD_TIMEOUT: std::time::Duration = std::time::Duration::from_millis(70);
|
||||
|
||||
fn get_clip() -> Result<&'static Clipboard, CliprdrError> {
|
||||
X11_CLIPBOARD.get_or_try_init(|| Clipboard::new().map_err(|_| CliprdrError::CliprdrInit))
|
||||
}
|
||||
|
||||
pub struct X11Clipboard {
|
||||
stop: AtomicBool,
|
||||
ignore_path: PathBuf,
|
||||
text_uri_list: Atom,
|
||||
gnome_copied_files: Atom,
|
||||
@@ -50,7 +42,6 @@ impl X11Clipboard {
|
||||
.map_err(|_| CliprdrError::CliprdrInit)?;
|
||||
Ok(Self {
|
||||
ignore_path: ignore_path.to_owned(),
|
||||
stop: AtomicBool::new(false),
|
||||
text_uri_list,
|
||||
gnome_copied_files,
|
||||
nautilus_clipboard,
|
||||
@@ -64,11 +55,18 @@ impl X11Clipboard {
|
||||
// NOTE:
|
||||
// # why not use `load_wait`
|
||||
// load_wait is likely to wait forever, which is not what we want
|
||||
let res = get_clip()?.load(clip, target, prop, X11_CLIPBOARD_TIMEOUT);
|
||||
let res = get_clip()?.load_wait(clip, target, prop);
|
||||
match res {
|
||||
Ok(res) => Ok(res),
|
||||
Err(x11_clipboard::error::Error::UnexpectedType(_)) => Ok(vec![]),
|
||||
Err(_) => Err(CliprdrError::ClipboardInternalError),
|
||||
Err(x11_clipboard::error::Error::Timeout) => {
|
||||
log::debug!("x11 clipboard get content timeout.");
|
||||
Err(CliprdrError::ClipboardInternalError)
|
||||
}
|
||||
Err(e) => {
|
||||
log::debug!("x11 clipboard get content fail: {:?}", e);
|
||||
Err(CliprdrError::ClipboardInternalError)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -81,22 +79,12 @@ impl X11Clipboard {
|
||||
}
|
||||
|
||||
fn wait_file_list(&self) -> Result<Option<Vec<PathBuf>>, CliprdrError> {
|
||||
if self.stop.load(Ordering::Relaxed) {
|
||||
return Ok(None);
|
||||
}
|
||||
let v = self.load(self.text_uri_list)?;
|
||||
let p = parse_plain_uri_list(v)?;
|
||||
Ok(Some(p))
|
||||
}
|
||||
}
|
||||
|
||||
impl X11Clipboard {
|
||||
#[inline]
|
||||
fn is_stopped(&self) -> bool {
|
||||
self.stop.load(Ordering::Relaxed)
|
||||
}
|
||||
}
|
||||
|
||||
impl SysClipboard for X11Clipboard {
|
||||
fn set_file_list(&self, paths: &[PathBuf]) -> Result<(), CliprdrError> {
|
||||
*self.former_file_list.lock() = paths.to_vec();
|
||||
@@ -114,19 +102,12 @@ impl SysClipboard for X11Clipboard {
|
||||
.map_err(|_| CliprdrError::ClipboardInternalError)
|
||||
}
|
||||
|
||||
fn stop(&self) {
|
||||
self.stop.store(true, Ordering::Relaxed);
|
||||
}
|
||||
|
||||
fn start(&self) {
|
||||
self.stop.store(false, Ordering::Relaxed);
|
||||
|
||||
{
|
||||
// clear cached file list
|
||||
*self.former_file_list.lock() = vec![];
|
||||
}
|
||||
loop {
|
||||
if self.is_stopped() {
|
||||
std::thread::sleep(std::time::Duration::from_millis(100));
|
||||
continue;
|
||||
}
|
||||
|
||||
let sth = match self.wait_file_list() {
|
||||
Ok(sth) => sth,
|
||||
Err(e) => {
|
||||
|
||||
Reference in New Issue
Block a user