diff --git a/libs/clipboard/src/platform/linux/mod.rs b/libs/clipboard/src/platform/linux/mod.rs index 3a13a5f32..14ae0a164 100644 --- a/libs/clipboard/src/platform/linux/mod.rs +++ b/libs/clipboard/src/platform/linux/mod.rs @@ -64,7 +64,7 @@ trait SysClipboard: Send + Sync { fn stop(&self); fn set_file_list(&self, paths: &[PathBuf]) -> Result<(), CliprdrError>; - fn get_file_list(&self) -> Result, CliprdrError>; + fn get_file_list(&self) -> Vec; } fn get_sys_clipboard(ignore_path: &PathBuf) -> Result, CliprdrError> { @@ -105,6 +105,7 @@ pub struct ClipboardContext { fuse_server: Arc>, clipboard: Arc, + local_files: Mutex>, } impl ClipboardContext { @@ -121,6 +122,7 @@ impl ClipboardContext { let clipboard = get_sys_clipboard(&fuse_mount_point)?; let clipboard = Arc::from(clipboard) as Arc<_>; + let local_files = Mutex::new(vec![]); Ok(Self { fuse_mount_point, @@ -128,6 +130,7 @@ impl ClipboardContext { fuse_tx, fuse_handle: Mutex::new(None), clipboard, + local_files, }) } @@ -186,13 +189,14 @@ impl ClipboardContext { conn_id: i32, request: FileContentsRequest, ) -> Result<(), CliprdrError> { - let file_contents_req = match request { + let file_list = self.local_files.lock(); + + let file_contents_resp = match request { FileContentsRequest::Size { stream_id, file_idx, } => { log::debug!("file contents (size) requested from conn: {}", conn_id); - let file_list = self.clipboard.get_file_list()?; let Some(file) = file_list.get(file_idx) else { log::error!( "invalid file index {} requested from conn: {}", @@ -235,7 +239,6 @@ impl ClipboardContext { length, conn_id ); - let file_list = self.clipboard.get_file_list()?; let Some(file) = file_list.get(file_idx) else { log::error!( "invalid file index {} requested from conn: {}", @@ -307,7 +310,7 @@ impl ClipboardContext { } }; - send_data(conn_id, file_contents_req); + send_data(conn_id, file_contents_resp); log::debug!("file contents sent to conn: {}", conn_id); Ok(()) } @@ -327,6 +330,18 @@ impl ClipboardContext { self.fuse_handle.lock().is_none() } + pub fn sync_local_files(&self) -> Result<(), CliprdrError> { + let mut local_files = self.local_files.lock(); + let clipboard_files = self.clipboard.get_file_list(); + let local_file_list: Vec = local_files.iter().map(|f| f.path.clone()).collect(); + if local_file_list == clipboard_files { + return Ok(()); + } + let new_files = construct_file_list(&clipboard_files)?; + *local_files = new_files; + Ok(()) + } + pub fn serve(&self, conn_id: i32, msg: ClipboardFile) -> Result<(), CliprdrError> { log::debug!("serve clipboard file from conn: {}", conn_id); if self.is_stopped() { @@ -496,9 +511,10 @@ impl ClipboardContext { } fn send_file_list(&self, conn_id: i32) -> Result<(), CliprdrError> { - let file_list = self.clipboard.get_file_list()?; + self.sync_local_files()?; - send_file_list(&file_list, conn_id) + let file_list = self.local_files.lock(); + send_file_list(&*file_list, conn_id) } } diff --git a/libs/clipboard/src/platform/linux/x11.rs b/libs/clipboard/src/platform/linux/x11.rs index bc8e4df72..779b86151 100644 --- a/libs/clipboard/src/platform/linux/x11.rs +++ b/libs/clipboard/src/platform/linux/x11.rs @@ -10,10 +10,7 @@ use parking_lot::Mutex; use x11_clipboard::Clipboard; use x11rb::protocol::xproto::Atom; -use crate::{ - platform::linux::{construct_file_list, send_format_list}, - CliprdrError, -}; +use crate::{platform::linux::send_format_list, CliprdrError}; use super::{encode_path_to_uri, parse_plain_uri_list, SysClipboard}; @@ -159,14 +156,12 @@ impl SysClipboard for X11Clipboard { let mut former = self.former_file_list.lock(); let filtered_st: BTreeSet<_> = filtered.iter().collect(); - let former_st = former.iter().collect(); + let former_st = former.iter().collect::>(); if filtered_st == former_st { std::thread::sleep(std::time::Duration::from_millis(100)); continue; } - // send update to server - log::debug!("clipboard updated: {:?}", filtered); *former = filtered; } @@ -180,8 +175,7 @@ impl SysClipboard for X11Clipboard { log::debug!("stop listening file related atoms on clipboard"); } - fn get_file_list(&self) -> Result, CliprdrError> { - let paths = { self.former_file_list.lock().clone() }; - construct_file_list(&paths) + fn get_file_list(&self) -> Vec { + self.former_file_list.lock().clone() } }