diff --git a/src/client.rs b/src/client.rs index a24c531c1..44d3e0201 100644 --- a/src/client.rs +++ b/src/client.rs @@ -24,6 +24,7 @@ use sha2::{Digest, Sha256}; use uuid::Uuid; pub use file_trait::FileManager; +#[cfg(not(feature = "flutter"))] #[cfg(not(any(target_os = "android", target_os = "ios")))] use hbb_common::tokio::sync::mpsc::UnboundedSender; use hbb_common::{ @@ -58,10 +59,10 @@ use crate::{ }; #[cfg(not(any(target_os = "android", target_os = "ios")))] -use crate::{ - common::{check_clipboard, ClipboardContext, CLIPBOARD_INTERVAL}, - ui_session_interface::SessionPermissionConfig, -}; +use crate::common::{check_clipboard, ClipboardContext, CLIPBOARD_INTERVAL}; +#[cfg(not(feature = "flutter"))] +#[cfg(not(any(target_os = "android", target_os = "ios")))] +use crate::ui_session_interface::SessionPermissionConfig; pub use super::lang::*; @@ -635,7 +636,7 @@ impl Client { } #[cfg(not(any(target_os = "android", target_os = "ios")))] - fn try_start_clipboard(_conf_tx: Option<(SessionPermissionConfig, UnboundedSender)>) { + fn try_start_clipboard(_conf_tx: Option) { let mut clipboard_lock = TEXT_CLIPBOARD_STATE.lock().unwrap(); if clipboard_lock.running { return; @@ -660,11 +661,17 @@ impl Client { if let Some(msg) = check_clipboard(&mut ctx, Some(&OLD_CLIPBOARD_TEXT)) { #[cfg(feature = "flutter")] - crate::flutter::send_text_clipboard_msg(msg); + crate::flutter::send_text_clipboard_msg( + &*OLD_CLIPBOARD_TEXT.lock().unwrap(), + msg, + ); #[cfg(not(feature = "flutter"))] - if let Some((cfg, tx)) = &_conf_tx { - if cfg.is_text_clipboard_required() { - let _ = tx.send(Data::Message(msg)); + if let Some(ctx) = &_ctx { + if ctx.cfg.is_text_clipboard_required() + && *OLD_CLIPBOARD_TEXT.lock().unwrap() + != *ctx.old.lock().unwrap() + { + let _ = ctx.tx.send(Data::Message(msg)); } } } @@ -2423,3 +2430,15 @@ fn decode_id_pk(signed: &[u8], key: &sign::PublicKey) -> ResultType<(String, [u8 bail!("Wrong public length"); } } + +#[cfg(feature = "flutter")] +#[cfg(not(any(target_os = "android", target_os = "ios")))] +pub(crate) struct ClientClipboardContext; + +#[cfg(not(feature = "flutter"))] +#[cfg(not(any(target_os = "android", target_os = "ios")))] +pub(crate) struct ClientClipboardContext { + pub cfg: SessionPermissionConfig, + pub old: Arc>, + pub tx: UnboundedSender, +} diff --git a/src/client/io_loop.rs b/src/client/io_loop.rs index 18a8bfe3d..d5143c0a8 100644 --- a/src/client/io_loop.rs +++ b/src/client/io_loop.rs @@ -1,7 +1,5 @@ use std::collections::HashMap; use std::num::NonZeroI64; -#[cfg(not(any(target_os = "android", target_os = "ios")))] -use std::sync::Mutex; use std::sync::{ atomic::{AtomicUsize, Ordering}, Arc, @@ -51,8 +49,6 @@ pub struct Remote { // Stop sending local audio to remote client. stop_voice_call_sender: Option>, voice_call_request_timestamp: Option, - #[cfg(not(any(target_os = "android", target_os = "ios")))] - old_clipboard: Arc>, read_jobs: Vec, write_jobs: Vec, remove_jobs: HashMap, @@ -87,8 +83,6 @@ impl Remote { audio_sender, receiver, sender, - #[cfg(not(any(target_os = "android", target_os = "ios")))] - old_clipboard: Default::default(), read_jobs: Vec::new(), write_jobs: Vec::new(), remove_jobs: Default::default(), @@ -941,10 +935,11 @@ impl Remote { Client::try_start_clipboard(None); #[cfg(not(feature = "flutter"))] #[cfg(not(any(target_os = "android", target_os = "ios")))] - Client::try_start_clipboard(Some(( - permission_config.clone(), - sender.clone(), - ))); + Client::try_start_clipboard(Some(ClientClipboardContext { + cfg: permission_config.clone(), + old: self.handler.old_clipboard.clone(), + tx: sender.clone(), + })); #[cfg(not(any(target_os = "android", target_os = "ios")))] tokio::spawn(async move { @@ -977,7 +972,7 @@ impl Remote { Some(message::Union::Clipboard(cb)) => { if !self.handler.lc.read().unwrap().disable_clipboard.v { #[cfg(not(any(target_os = "android", target_os = "ios")))] - update_clipboard(cb, Some(&self.old_clipboard)); + update_clipboard(cb, Some(&self.handler.old_clipboard)); #[cfg(any(target_os = "android", target_os = "ios"))] { let content = if cb.compress { diff --git a/src/flutter.rs b/src/flutter.rs index 6c9ff7f37..e49f04043 100644 --- a/src/flutter.rs +++ b/src/flutter.rs @@ -725,9 +725,9 @@ pub fn other_sessions_running(id: &str) -> bool { } #[cfg(not(any(target_os = "android", target_os = "ios")))] -pub fn send_text_clipboard_msg(msg: Message) { +pub fn send_text_clipboard_msg(text: &str, msg: Message) { for (_id, session) in SESSIONS.read().unwrap().iter() { - if session.is_text_clipboard_required() { + if session.is_text_clipboard_required() && text != *session.old_clipboard.lock().unwrap() { session.send(Data::Message(msg.clone())); } } diff --git a/src/ui_session_interface.rs b/src/ui_session_interface.rs index 504982f50..7ae1d5b24 100644 --- a/src/ui_session_interface.rs +++ b/src/ui_session_interface.rs @@ -43,6 +43,8 @@ pub struct Session { pub server_keyboard_enabled: Arc>, pub server_file_transfer_enabled: Arc>, pub server_clipboard_enabled: Arc>, + #[cfg(not(any(target_os = "android", target_os = "ios")))] + pub old_clipboard: Arc>, } #[derive(Clone)]