diff --git a/Cargo.lock b/Cargo.lock index 61e6767a3..8270aa2ca 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3065,7 +3065,7 @@ checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" [[package]] name = "hwcodec" version = "0.7.1" -source = "git+https://github.com/rustdesk-org/hwcodec#7ee119a58b6ee6ca255a438af69ad0785ba44797" +source = "git+https://github.com/rustdesk-org/hwcodec#6376b41da010b87ae984e843cedca2b52c79b1cd" dependencies = [ "bindgen 0.59.2", "cc", diff --git a/src/client.rs b/src/client.rs index a201336ac..83b6de43a 100644 --- a/src/client.rs +++ b/src/client.rs @@ -1384,7 +1384,8 @@ pub struct LoginConfigHandler { password_source: PasswordSource, // where the sent password comes from shared_password: Option, // Store the shared password pub enable_trusted_devices: bool, - pub record: bool, + pub record_state: bool, + pub record_permission: bool, } impl Deref for LoginConfigHandler { @@ -1489,7 +1490,8 @@ impl LoginConfigHandler { self.adapter_luid = adapter_luid; self.selected_windows_session_id = None; self.shared_password = shared_password; - self.record = LocalConfig::get_bool_option(OPTION_ALLOW_AUTO_RECORD_OUTGOING); + self.record_state = false; + self.record_permission = true; } /// Check if the client should auto login. @@ -2354,10 +2356,11 @@ pub fn start_video_thread( let format = CodecFormat::from(&vf); if video_handler.is_none() { let mut handler = VideoHandler::new(format, display); - let record = session.lc.read().unwrap().record; + let record_state = session.lc.read().unwrap().record_state; + let record_permission = session.lc.read().unwrap().record_permission; let id = session.lc.read().unwrap().id.clone(); - if record { - handler.record_screen(record, id, display); + if record_state && record_permission { + handler.record_screen(true, id, display); } video_handler = Some(handler); } @@ -2436,8 +2439,6 @@ pub fn start_video_thread( } } MediaData::RecordScreen(start) => { - log::info!("record screen command: start: {start}"); - session.update_record_status(start); let id = session.lc.read().unwrap().id.clone(); if let Some(handler) = video_handler.as_mut() { handler.record_screen(start, id, display); diff --git a/src/client/io_loop.rs b/src/client/io_loop.rs index df07331cf..cbef0d914 100644 --- a/src/client/io_loop.rs +++ b/src/client/io_loop.rs @@ -27,7 +27,7 @@ use crossbeam_queue::ArrayQueue; use hbb_common::tokio::sync::mpsc::error::TryRecvError; use hbb_common::{ allow_err, - config::{self, PeerConfig, TransferSerde}, + config::{self, LocalConfig, PeerConfig, TransferSerde}, fs::{ self, can_enable_overwrite_detection, get_job, get_string, new_send_confirm, DigestCheckResult, RemoveJobMeta, @@ -71,6 +71,7 @@ pub struct Remote { peer_info: ParsedPeerInfo, video_threads: HashMap, chroma: Arc>>, + last_record_state: bool, } #[derive(Default)] @@ -116,6 +117,7 @@ impl Remote { peer_info: Default::default(), video_threads: Default::default(), chroma: Default::default(), + last_record_state: false, } } @@ -846,10 +848,8 @@ impl Remote { } } Data::RecordScreen(start) => { - self.handler.lc.write().unwrap().record = start; - for (_, v) in self.video_threads.iter_mut() { - v.video_sender.send(MediaData::RecordScreen(start)).ok(); - } + self.handler.lc.write().unwrap().record_state = start; + self.update_record_state(); } Data::ElevateDirect => { let mut request = ElevationRequest::new(); @@ -1484,6 +1484,8 @@ impl Remote { self.handler.set_permission("restart", p.enabled); } Ok(Permission::Recording) => { + self.handler.lc.write().unwrap().record_permission = p.enabled; + self.update_record_state(); self.handler.set_permission("recording", p.enabled); } Ok(Permission::BlockInput) => { @@ -1983,15 +1985,39 @@ impl Remote { }, ); self.video_threads.insert(display, video_thread); - let auto_record = self.handler.lc.read().unwrap().record; - if auto_record && self.video_threads.len() == 1 { - let mut misc = Misc::new(); - misc.set_client_record_status(true); - let mut msg = Message::new(); - msg.set_misc(misc); - self.sender.send(Data::Message(msg)).ok(); + if self.video_threads.len() == 1 { + let auto_record = + LocalConfig::get_bool_option(config::keys::OPTION_ALLOW_AUTO_RECORD_OUTGOING); + self.handler.lc.write().unwrap().record_state = auto_record; + self.update_record_state(); } } + + fn update_record_state(&mut self) { + // state + let permission = self.handler.lc.read().unwrap().record_permission; + if !permission { + self.handler.lc.write().unwrap().record_state = false; + } + let state = self.handler.lc.read().unwrap().record_state; + let start = state && permission; + if self.last_record_state == start { + return; + } + self.last_record_state = start; + log::info!("record screen start: {start}"); + // update local + for (_, v) in self.video_threads.iter_mut() { + v.video_sender.send(MediaData::RecordScreen(start)).ok(); + } + self.handler.update_record_status(start); + // update remote + let mut misc = Misc::new(); + misc.set_client_record_status(start); + let mut msg = Message::new(); + msg.set_misc(misc); + self.sender.send(Data::Message(msg)).ok(); + } } struct RemoveJob { @@ -2040,3 +2066,10 @@ struct VideoThread { discard_queue: Arc>, fps_control: FpsControl, } + +impl Drop for VideoThread { + fn drop(&mut self) { + // since channels are buffered, messages sent before the disconnect will still be properly received. + *self.discard_queue.write().unwrap() = true; + } +} diff --git a/src/flutter_ffi.rs b/src/flutter_ffi.rs index 0bb17c903..9e23b7b02 100644 --- a/src/flutter_ffi.rs +++ b/src/flutter_ffi.rs @@ -1,3 +1,5 @@ +#[cfg(not(any(target_os = "android", target_os = "ios")))] +use crate::keyboard::input_source::{change_input_source, get_cur_session_input_source}; use crate::{ client::file_trait::FileManager, common::{make_fd_to_json, make_vec_fd_to_json}, @@ -7,11 +9,6 @@ use crate::{ input::*, ui_interface::{self, *}, }; -#[cfg(not(any(target_os = "android", target_os = "ios")))] -use crate::{ - common::get_default_sound_input, - keyboard::input_source::{change_input_source, get_cur_session_input_source}, -}; use flutter_rust_bridge::{StreamSink, SyncReturn}; #[cfg(feature = "plugin_framework")] #[cfg(not(any(target_os = "android", target_os = "ios")))] diff --git a/src/ui_session_interface.rs b/src/ui_session_interface.rs index 176426464..14baa6946 100644 --- a/src/ui_session_interface.rs +++ b/src/ui_session_interface.rs @@ -390,16 +390,11 @@ impl Session { } pub fn record_screen(&self, start: bool) { - let mut misc = Misc::new(); - misc.set_client_record_status(start); - let mut msg = Message::new(); - msg.set_misc(misc); - self.send(Data::Message(msg)); self.send(Data::RecordScreen(start)); } pub fn is_recording(&self) -> bool { - self.lc.read().unwrap().record + self.lc.read().unwrap().record_state } pub fn save_custom_image_quality(&self, custom_image_quality: i32) {