diff --git a/src/common.rs b/src/common.rs index 87e0b98ff..bed64ecaf 100644 --- a/src/common.rs +++ b/src/common.rs @@ -50,6 +50,20 @@ pub fn valid_for_capslock(evt: &KeyEvent) -> bool { } } +pub fn create_clipboard_msg(content: String) -> Message { + let bytes = content.into_bytes(); + let compressed = compress_func(&bytes, COMPRESS_LEVEL); + let compress = compressed.len() < bytes.len(); + let content = if compress { compressed } else { bytes }; + let mut msg = Message::new(); + msg.set_clipboard(Clipboard { + compress, + content, + ..Default::default() + }); + msg +} + pub fn check_clipboard( ctx: &mut ClipboardContext, old: Option<&Arc>>, @@ -61,18 +75,8 @@ pub fn check_clipboard( let changed = content != *old.lock().unwrap(); if changed { log::info!("{} update found on {}", CLIPBOARD_NAME, side); - let bytes = content.clone().into_bytes(); - *old.lock().unwrap() = content; - let compressed = compress_func(&bytes, COMPRESS_LEVEL); - let compress = compressed.len() < bytes.len(); - let content = if compress { compressed } else { bytes }; - let mut msg = Message::new(); - msg.set_clipboard(Clipboard { - compress, - content, - ..Default::default() - }); - return Some(msg); + *old.lock().unwrap() = content.clone(); + return Some(create_clipboard_msg(content)); } } } diff --git a/src/server/clipboard_service.rs b/src/server/clipboard_service.rs index 5393d1f7d..25597d11c 100644 --- a/src/server/clipboard_service.rs +++ b/src/server/clipboard_service.rs @@ -6,7 +6,6 @@ pub use crate::common::{ struct State { ctx: Option, - initialized: bool, } impl Default for State { @@ -18,22 +17,18 @@ impl Default for State { None } }; - Self { - ctx, - initialized: false, - } + Self { ctx } } } impl super::service::Reset for State { fn reset(&mut self) { *CONTENT.lock().unwrap() = Default::default(); - self.initialized = false; } } pub fn new() -> GenericService { - let sp = GenericService::new(NAME, false); + let sp = GenericService::new(NAME, true); sp.repeat::(INTERVAL, run); sp } @@ -41,13 +36,16 @@ pub fn new() -> GenericService { fn run(sp: GenericService, state: &mut State) -> ResultType<()> { if let Some(ctx) = state.ctx.as_mut() { if let Some(msg) = check_clipboard(ctx, None) { - if !state.initialized { - state.initialized = true; - // ignore clipboard update before service start - return Ok(()); - } sp.send(msg); } + sp.snapshot(|sps| { + let txt = crate::CONTENT.lock().unwrap().clone(); + if !txt.is_empty() { + let msg_out = crate::create_clipboard_msg(txt); + sps.send_shared(Arc::new(msg_out)); + } + Ok(()) + })?; } Ok(()) } diff --git a/src/ui/header.tis b/src/ui/header.tis index 951236c89..96b722efb 100644 --- a/src/ui/header.tis +++ b/src/ui/header.tis @@ -36,7 +36,9 @@ function stateChanged() { cur_window_state = view.windowState; adjustBorder(); adaptDisplay(); - if (!is_linux) view.focus = handler; // this cause windows always topmost on linux + if (cur_window_state != View.WINDOW_MINIMIZED) { + view.focus = handler; // to make focus away from restore/maximize button, so that enter key work + } var fs = view.windowState == View.WINDOW_FULL_SCREEN; var el = $(#fullscreen); if (el) el.attributes.toggleClass("active", fs); diff --git a/src/ui/remote.rs b/src/ui/remote.rs index f18600fc9..359f11a4f 100644 --- a/src/ui/remote.rs +++ b/src/ui/remote.rs @@ -9,6 +9,7 @@ use hbb_common::{ fs, log, message_proto::*, protobuf::Message as _, + sleep, tokio::{ self, sync::mpsc, @@ -1145,7 +1146,7 @@ impl Remote { } fn start_clipboard(&mut self) -> Option> { - if self.handler.is_file_transfer() { + if self.handler.is_file_transfer() || self.handler.is_port_forward() { return None; } let (tx, rx) = std::sync::mpsc::channel(); @@ -1430,6 +1431,23 @@ impl Remote { } Some(login_response::Union::peer_info(pi)) => { self.handler.handle_peer_info(pi); + if !(self.handler.is_file_transfer() + || self.handler.is_port_forward() + || !*self.clipboard.read().unwrap() + || !*self.keyboard.read().unwrap() + || self.handler.lc.read().unwrap().disable_clipboard) + { + let txt = self.old_clipboard.lock().unwrap().clone(); + if !txt.is_empty() { + let msg_out = crate::create_clipboard_msg(txt); + let sender = self.sender.clone(); + tokio::spawn(async move { + // due to clipboard service interval time + sleep(common::CLIPBOARD_INTERVAL as f32 / 1_000.).await; + sender.send(Data::Message(msg_out)).ok(); + }); + } + } } _ => {} }, @@ -1587,7 +1605,7 @@ impl Interface for Handler { pi_sciter.set_item("sas_enabled", pi.sas_enabled); if self.is_file_transfer() { if pi.username.is_empty() { - self.on_error("No active user logged on, please connect and logon first."); + self.on_error("No active console user logged on, please connect and logon first."); return; } } else if !self.is_port_forward() {