init sync file clipboard, local to remote

Signed-off-by: dignow <linlong1265@gmail.com>
This commit is contained in:
dignow 2023-07-31 21:40:55 +08:00
parent 433059f8a0
commit 4009fd77e8
4 changed files with 66 additions and 24 deletions

View File

@ -70,6 +70,7 @@ struct MsgChannel {
lazy_static::lazy_static! { lazy_static::lazy_static! {
static ref VEC_MSG_CHANNEL: RwLock<Vec<MsgChannel>> = Default::default(); static ref VEC_MSG_CHANNEL: RwLock<Vec<MsgChannel>> = Default::default();
static ref CLIENT_CONN_ID_COUNTER: Mutex<i32> = Mutex::new(0); static ref CLIENT_CONN_ID_COUNTER: Mutex<i32> = Mutex::new(0);
static ref LAST_FILE_FORMAT_LIST: Arc<Mutex<Option<ClipboardFile>>> = Default::default();
} }
impl ClipboardFile { impl ClipboardFile {
@ -90,6 +91,11 @@ impl ClipboardFile {
} }
} }
#[inline]
pub fn get_last_file_format_list() -> Option<ClipboardFile> {
LAST_FILE_FORMAT_LIST.lock().unwrap().clone()
}
pub fn get_client_conn_id(session_uuid: &SessionID) -> Option<i32> { pub fn get_client_conn_id(session_uuid: &SessionID) -> Option<i32> {
VEC_MSG_CHANNEL VEC_MSG_CHANNEL
.read() .read()
@ -561,6 +567,7 @@ extern "C" fn client_format_list(
} }
log::debug!("client_format_list called, client id: {}, format_list: {:?}", conn_id, &format_list); log::debug!("client_format_list called, client id: {}, format_list: {:?}", conn_id, &format_list);
let data = ClipboardFile::FormatList { format_list }; let data = ClipboardFile::FormatList { format_list };
*LAST_FILE_FORMAT_LIST.lock().unwrap() = Some(data.clone());
// no need to handle result here // no need to handle result here
if conn_id == 0 { if conn_id == 0 {
// msg_channel is used for debug, VEC_MSG_CHANNEL cannot be inspected by the debugger. // msg_channel is used for debug, VEC_MSG_CHANNEL cannot be inspected by the debugger.

View File

@ -6,7 +6,9 @@ use std::sync::{
}; };
#[cfg(windows)] #[cfg(windows)]
use clipboard::{cliprdr::CliprdrClientContext, empty_clipboard, ContextSend}; use clipboard::{
cliprdr::CliprdrClientContext, empty_clipboard, get_last_file_format_list, ContextSend,
};
use crossbeam_queue::ArrayQueue; use crossbeam_queue::ArrayQueue;
use hbb_common::config::{PeerConfig, TransferSerde}; use hbb_common::config::{PeerConfig, TransferSerde};
use hbb_common::fs::{ use hbb_common::fs::{
@ -56,6 +58,7 @@ pub struct Remote<T: InvokeUiSession> {
remove_jobs: HashMap<i32, RemoveJob>, remove_jobs: HashMap<i32, RemoveJob>,
timer: Interval, timer: Interval,
last_update_jobs_status: (Instant, HashMap<i32, u64>), last_update_jobs_status: (Instant, HashMap<i32, u64>),
is_connected: bool,
first_frame: bool, first_frame: bool,
#[cfg(windows)] #[cfg(windows)]
client_conn_id: i32, // used for file clipboard client_conn_id: i32, // used for file clipboard
@ -90,6 +93,7 @@ impl<T: InvokeUiSession> Remote<T> {
remove_jobs: Default::default(), remove_jobs: Default::default(),
timer: time::interval(SEC30), timer: time::interval(SEC30),
last_update_jobs_status: (Instant::now(), Default::default()), last_update_jobs_status: (Instant::now(), Default::default()),
is_connected: false,
first_frame: false, first_frame: false,
#[cfg(windows)] #[cfg(windows)]
client_conn_id: 0, client_conn_id: 0,
@ -195,28 +199,7 @@ impl<T: InvokeUiSession> Remote<T> {
} }
_msg = rx_clip_client.recv() => { _msg = rx_clip_client.recv() => {
#[cfg(windows)] #[cfg(windows)]
match _msg { self.handle_local_clipboard_msg(&mut peer, _msg).await;
Some(clip) => match clip {
clipboard::ClipboardFile::NotifyCallback{r#type, title, text} => {
self.handler.msgbox(&r#type, &title, &text, "");
}
_ => {
let is_stopping_allowed = clip.is_stopping_allowed();
let server_file_transfer_enabled = *self.handler.server_file_transfer_enabled.read().unwrap();
let file_transfer_enabled = self.handler.lc.read().unwrap().enable_file_transfer.v;
let stop = is_stopping_allowed && (!self.first_frame || !(server_file_transfer_enabled && file_transfer_enabled));
log::debug!("Process clipboard message from system, stop: {}, is_stopping_allowed: {}, server_file_transfer_enabled: {}, file_transfer_enabled: {}", stop, is_stopping_allowed, server_file_transfer_enabled, file_transfer_enabled);
if stop {
ContextSend::set_is_stopped();
} else {
allow_err!(peer.send(&crate::clipboard_file::clip_2_msg(clip)).await);
}
}
}
None => {
// unreachable!()
}
}
} }
_ = self.timer.tick() => { _ = self.timer.tick() => {
if last_recv_time.elapsed() >= SEC30 { if last_recv_time.elapsed() >= SEC30 {
@ -277,6 +260,44 @@ impl<T: InvokeUiSession> Remote<T> {
} }
} }
#[cfg(windows)]
async fn handle_local_clipboard_msg(
&self,
peer: &mut crate::client::FramedStream,
msg: Option<clipboard::ClipboardFile>,
) {
match msg {
Some(clip) => match clip {
clipboard::ClipboardFile::NotifyCallback {
r#type,
title,
text,
} => {
self.handler.msgbox(&r#type, &title, &text, "");
}
_ => {
let is_stopping_allowed = clip.is_stopping_allowed();
let server_file_transfer_enabled =
*self.handler.server_file_transfer_enabled.read().unwrap();
let file_transfer_enabled =
self.handler.lc.read().unwrap().enable_file_transfer.v;
let stop = is_stopping_allowed
&& (!self.is_connected
|| !(server_file_transfer_enabled && file_transfer_enabled));
log::debug!("Process clipboard message from system, stop: {}, is_stopping_allowed: {}, server_file_transfer_enabled: {}, file_transfer_enabled: {}", stop, is_stopping_allowed, server_file_transfer_enabled, file_transfer_enabled);
if stop {
ContextSend::set_is_stopped();
} else {
allow_err!(peer.send(&crate::clipboard_file::clip_2_msg(clip)).await);
}
}
},
None => {
// unreachable!()
}
}
}
fn handle_job_status(&mut self, id: i32, file_num: i32, err: Option<String>) { fn handle_job_status(&mut self, id: i32, file_num: i32, err: Option<String>) {
if let Some(job) = self.remove_jobs.get_mut(&id) { if let Some(job) = self.remove_jobs.get_mut(&id) {
if job.no_confirm { if job.no_confirm {
@ -1030,6 +1051,15 @@ impl<T: InvokeUiSession> Remote<T> {
if self.handler.is_file_transfer() { if self.handler.is_file_transfer() {
self.handler.load_last_jobs(); self.handler.load_last_jobs();
} }
self.is_connected = true;
#[cfg(target_os = "windows")]
if self.handler.peer_platform() == crate::platform::PLATFORM_WINDOWS {
if let Some(last_file_format_list) = get_last_file_format_list() {
self.handle_local_clipboard_msg(peer, Some(last_file_format_list))
.await;
}
}
} }
_ => {} _ => {}
}, },

View File

@ -26,6 +26,11 @@ use hbb_common::{message_proto::CursorData, ResultType};
#[cfg(not(any(target_os = "macos", target_os = "android", target_os = "ios")))] #[cfg(not(any(target_os = "macos", target_os = "android", target_os = "ios")))]
const SERVICE_INTERVAL: u64 = 300; const SERVICE_INTERVAL: u64 = 300;
pub const PLATFORM_WINDOWS: &str = "Windows";
pub const PLATFORM_LINUX: &str = "Linux";
pub const PLATFORM_MACOS: &str = "Mac OS";
pub const PLATFORM_ANDROID: &str = "Android";
pub fn is_xfce() -> bool { pub fn is_xfce() -> bool {
#[cfg(target_os = "linux")] #[cfg(target_os = "linux")]
{ {

View File

@ -412,7 +412,7 @@ impl<T: InvokeUiSession> Session<T> {
pub fn get_path_sep(&self, is_remote: bool) -> &'static str { pub fn get_path_sep(&self, is_remote: bool) -> &'static str {
let p = self.get_platform(is_remote); let p = self.get_platform(is_remote);
if &p == "Windows" { if &p == crate::platform::PLATFORM_WINDOWS {
return "\\"; return "\\";
} else { } else {
return "/"; return "/";