mirror of
https://github.com/rustdesk/rustdesk.git
synced 2025-12-12 19:17:58 +00:00
Merge remote-tracking branch 'github/master' into sigma
# Conflicts: # flutter/lib/desktop/widgets/remote_menubar.dart
This commit is contained in:
@@ -1,29 +1,33 @@
|
||||
#[cfg(not(any(target_os = "android", target_os = "ios")))]
|
||||
use std::collections::HashMap;
|
||||
use std::ops::{Deref, DerefMut};
|
||||
use std::str::FromStr;
|
||||
use std::sync::{Arc, Mutex, RwLock};
|
||||
use std::sync::atomic::{AtomicBool, AtomicUsize, Ordering};
|
||||
use std::sync::{
|
||||
atomic::{AtomicBool, AtomicUsize, Ordering},
|
||||
Arc, Mutex, RwLock,
|
||||
};
|
||||
use std::time::{Duration, SystemTime};
|
||||
|
||||
use async_trait::async_trait;
|
||||
use bytes::Bytes;
|
||||
use rdev::{Event, EventType::*};
|
||||
use uuid::Uuid;
|
||||
|
||||
use hbb_common::{allow_err, message_proto::*};
|
||||
use hbb_common::{fs, get_version_number, log, Stream};
|
||||
use hbb_common::config::{Config, LocalConfig, PeerConfig, RS_PUB_KEY};
|
||||
use hbb_common::rendezvous_proto::ConnType;
|
||||
use hbb_common::tokio::{self, sync::mpsc};
|
||||
use hbb_common::{allow_err, message_proto::*};
|
||||
use hbb_common::{fs, get_version_number, log, Stream};
|
||||
|
||||
use crate::{client::Data, client::Interface};
|
||||
use crate::client::{
|
||||
check_if_retry, FileManager, handle_hash, handle_login_error, handle_login_from_ui,
|
||||
handle_test_delay, input_os_password, Key, KEY_MAP, load_config, LoginConfigHandler,
|
||||
QualityStatus, send_mouse, start_video_audio_threads,
|
||||
};
|
||||
use crate::client::io_loop::Remote;
|
||||
use crate::client::{
|
||||
check_if_retry, handle_hash, handle_login_error, handle_login_from_ui, handle_test_delay,
|
||||
input_os_password, load_config, send_mouse, start_video_audio_threads, FileManager, Key,
|
||||
LoginConfigHandler, QualityStatus, KEY_MAP,
|
||||
};
|
||||
use crate::common::{self, GrabState};
|
||||
use crate::keyboard;
|
||||
use crate::{client::Data, client::Interface};
|
||||
|
||||
pub static IS_IN: AtomicBool = AtomicBool::new(false);
|
||||
|
||||
@@ -36,9 +40,37 @@ pub struct Session<T: InvokeUiSession> {
|
||||
pub sender: Arc<RwLock<Option<mpsc::UnboundedSender<Data>>>>,
|
||||
pub thread: Arc<Mutex<Option<std::thread::JoinHandle<()>>>>,
|
||||
pub ui_handler: T,
|
||||
pub server_keyboard_enabled: Arc<RwLock<bool>>,
|
||||
pub server_file_transfer_enabled: Arc<RwLock<bool>>,
|
||||
pub server_clipboard_enabled: Arc<RwLock<bool>>,
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct SessionPermissionConfig {
|
||||
pub lc: Arc<RwLock<LoginConfigHandler>>,
|
||||
pub server_keyboard_enabled: Arc<RwLock<bool>>,
|
||||
pub server_file_transfer_enabled: Arc<RwLock<bool>>,
|
||||
pub server_clipboard_enabled: Arc<RwLock<bool>>,
|
||||
}
|
||||
|
||||
impl SessionPermissionConfig {
|
||||
pub fn is_text_clipboard_required(&self) -> bool {
|
||||
*self.server_clipboard_enabled.read().unwrap()
|
||||
&& *self.server_keyboard_enabled.read().unwrap()
|
||||
&& !self.lc.read().unwrap().disable_clipboard.v
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: InvokeUiSession> Session<T> {
|
||||
pub fn get_permission_config(&self) -> SessionPermissionConfig {
|
||||
SessionPermissionConfig {
|
||||
lc: self.lc.clone(),
|
||||
server_keyboard_enabled: self.server_keyboard_enabled.clone(),
|
||||
server_file_transfer_enabled: self.server_file_transfer_enabled.clone(),
|
||||
server_clipboard_enabled: self.server_clipboard_enabled.clone(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_file_transfer(&self) -> bool {
|
||||
self.lc
|
||||
.read()
|
||||
@@ -127,6 +159,12 @@ impl<T: InvokeUiSession> Session<T> {
|
||||
self.lc.read().unwrap().is_privacy_mode_supported()
|
||||
}
|
||||
|
||||
pub fn is_text_clipboard_required(&self) -> bool {
|
||||
*self.server_clipboard_enabled.read().unwrap()
|
||||
&& *self.server_keyboard_enabled.read().unwrap()
|
||||
&& !self.lc.read().unwrap().disable_clipboard.v
|
||||
}
|
||||
|
||||
pub fn refresh_video(&self) {
|
||||
self.send(Data::Message(LoginConfigHandler::refresh()));
|
||||
}
|
||||
@@ -521,7 +559,7 @@ impl<T: InvokeUiSession> Session<T> {
|
||||
KeyRelease(key)
|
||||
};
|
||||
let event = Event {
|
||||
time: std::time::SystemTime::now(),
|
||||
time: SystemTime::now(),
|
||||
unicode: None,
|
||||
code: keycode as _,
|
||||
scan_code: scancode as _,
|
||||
@@ -608,9 +646,13 @@ impl<T: InvokeUiSession> Session<T> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn reconnect(&self) {
|
||||
pub fn reconnect(&self, force_relay: bool) {
|
||||
self.send(Data::Close);
|
||||
let cloned = self.clone();
|
||||
// override only if true
|
||||
if true == force_relay {
|
||||
cloned.lc.write().unwrap().force_relay = true;
|
||||
}
|
||||
let mut lock = self.thread.lock().unwrap();
|
||||
lock.take().map(|t| t.join());
|
||||
*lock = Some(std::thread::spawn(move || {
|
||||
@@ -748,13 +790,57 @@ impl<T: InvokeUiSession> Session<T> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn change_resolution(&self, width: i32, height: i32) {
|
||||
let mut misc = Misc::new();
|
||||
misc.set_change_resolution(Resolution {
|
||||
width,
|
||||
height,
|
||||
..Default::default()
|
||||
});
|
||||
let mut msg = Message::new();
|
||||
msg.set_misc(misc);
|
||||
self.send(Data::Message(msg));
|
||||
}
|
||||
|
||||
pub fn request_voice_call(&self) {
|
||||
self.send(Data::NewVoiceCall);
|
||||
}
|
||||
|
||||
|
||||
pub fn close_voice_call(&self) {
|
||||
self.send(Data::CloseVoiceCall);
|
||||
}
|
||||
|
||||
pub fn show_relay_hint(
|
||||
&mut self,
|
||||
last_recv_time: tokio::time::Instant,
|
||||
msgtype: &str,
|
||||
title: &str,
|
||||
text: &str,
|
||||
) -> bool {
|
||||
let duration = Duration::from_secs(3);
|
||||
let counter_interval = 3;
|
||||
let lock = self.lc.read().unwrap();
|
||||
let success_time = lock.success_time;
|
||||
let direct = lock.direct.unwrap_or(false);
|
||||
let received = lock.received;
|
||||
drop(lock);
|
||||
if let Some(success_time) = success_time {
|
||||
if direct && last_recv_time.duration_since(success_time) < duration {
|
||||
let retry_for_relay = direct && !received;
|
||||
let retry = check_if_retry(msgtype, title, text, retry_for_relay);
|
||||
if retry && !retry_for_relay {
|
||||
self.lc.write().unwrap().direct_error_counter += 1;
|
||||
if self.lc.read().unwrap().direct_error_counter % counter_interval == 0 {
|
||||
#[cfg(feature = "flutter")]
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
self.lc.write().unwrap().direct_error_counter = 0;
|
||||
}
|
||||
}
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
pub trait InvokeUiSession: Send + Sync + Clone + 'static + Sized + Default {
|
||||
@@ -764,6 +850,7 @@ pub trait InvokeUiSession: Send + Sync + Clone + 'static + Sized + Default {
|
||||
fn set_display(&self, x: i32, y: i32, w: i32, h: i32, cursor_embedded: bool);
|
||||
fn switch_display(&self, display: &SwitchDisplay);
|
||||
fn set_peer_info(&self, peer_info: &PeerInfo); // flutter
|
||||
fn set_displays(&self, displays: &Vec<DisplayInfo>);
|
||||
fn on_connected(&self, conn_type: ConnType);
|
||||
fn update_privacy_mode(&self);
|
||||
fn set_permission(&self, name: &str, value: bool);
|
||||
@@ -789,7 +876,7 @@ pub trait InvokeUiSession: Send + Sync + Clone + 'static + Sized + Default {
|
||||
fn update_block_input_state(&self, on: bool);
|
||||
fn job_progress(&self, id: i32, file_num: i32, speed: f64, finished_size: f64);
|
||||
fn adapt_size(&self);
|
||||
fn on_rgba(&self, data: &[u8]);
|
||||
fn on_rgba(&self, data: &mut Vec<u8>);
|
||||
fn msgbox(&self, msgtype: &str, title: &str, text: &str, link: &str, retry: bool);
|
||||
#[cfg(any(target_os = "android", target_os = "ios"))]
|
||||
fn clipboard(&self, content: String);
|
||||
@@ -799,6 +886,8 @@ pub trait InvokeUiSession: Send + Sync + Clone + 'static + Sized + Default {
|
||||
fn on_voice_call_closed(&self, reason: &str);
|
||||
fn on_voice_call_waiting(&self);
|
||||
fn on_voice_call_incoming(&self);
|
||||
fn get_rgba(&self) -> *const u8;
|
||||
fn next_rgba(&self);
|
||||
}
|
||||
|
||||
impl<T: InvokeUiSession> Deref for Session<T> {
|
||||
@@ -888,6 +977,7 @@ impl<T: InvokeUiSession> Interface for Session<T> {
|
||||
"Connected, waiting for image...",
|
||||
"",
|
||||
);
|
||||
self.lc.write().unwrap().success_time = Some(tokio::time::Instant::now());
|
||||
}
|
||||
self.on_connected(self.lc.read().unwrap().conn_type);
|
||||
#[cfg(windows)]
|
||||
@@ -1049,7 +1139,7 @@ pub async fn io_loop<T: InvokeUiSession>(handler: Session<T>) {
|
||||
let frame_count = Arc::new(AtomicUsize::new(0));
|
||||
let frame_count_cl = frame_count.clone();
|
||||
let ui_handler = handler.ui_handler.clone();
|
||||
let (video_sender, audio_sender) = start_video_audio_threads(move |data: &[u8]| {
|
||||
let (video_sender, audio_sender) = start_video_audio_threads(move |data: &mut Vec<u8>| {
|
||||
frame_count_cl.fetch_add(1, Ordering::Relaxed);
|
||||
ui_handler.on_rgba(data);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user