diff --git a/Cargo.lock b/Cargo.lock index bf3ce1f04..237369d2c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1533,7 +1533,7 @@ dependencies = [ "log", "objc", "pkg-config", - "rdev", + "rdev 0.5.0-2 (git+https://github.com/asur4s/rdev)", "serde 1.0.147", "serde_derive", "tfc", @@ -4248,6 +4248,28 @@ dependencies = [ "x11 2.20.0", ] +[[package]] +name = "rdev" +version = "0.5.0-2" +source = "git+https://github.com/rustdesk/rdev#25c29f61bfdf5d8ec50f0a8a7743bc1d85eb2c04" +dependencies = [ + "cocoa", + "core-foundation 0.9.3", + "core-foundation-sys 0.8.3", + "core-graphics 0.22.3", + "enum-map", + "epoll", + "inotify", + "lazy_static", + "libc", + "mio 0.8.5", + "strum 0.24.1", + "strum_macros 0.24.3", + "widestring 1.0.2", + "winapi 0.3.9", + "x11 2.20.0", +] + [[package]] name = "rdrand" version = "0.4.0" @@ -4518,7 +4540,7 @@ dependencies = [ "num_cpus", "objc", "parity-tokio-ipc", - "rdev", + "rdev 0.5.0-2 (git+https://github.com/rustdesk/rdev)", "repng", "reqwest", "rpassword 7.1.0", diff --git a/Cargo.toml b/Cargo.toml index 2861b3f63..a783b1abe 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -63,7 +63,7 @@ default-net = "0.11.0" wol-rs = "0.9.1" flutter_rust_bridge = { git = "https://github.com/SoLongAndThanksForAllThePizza/flutter_rust_bridge", optional = true } errno = "0.2.8" -rdev = { git = "https://github.com/asur4s/rdev" } +rdev = { git = "https://github.com/rustdesk/rdev" } url = { version = "2.1", features = ["serde"] } reqwest = { version = "0.11", features = ["blocking", "json", "rustls-tls"], default-features=false } @@ -162,4 +162,4 @@ codegen-units = 1 panic = 'abort' strip = true #opt-level = 'z' # only have smaller size after strip -rpath = true \ No newline at end of file +rpath = true diff --git a/flutter/lib/common.dart b/flutter/lib/common.dart index b9077b0cb..0f5502f54 100644 --- a/flutter/lib/common.dart +++ b/flutter/lib/common.dart @@ -1013,7 +1013,7 @@ class LastWindowPosition { return LastWindowPosition(m["width"], m["height"], m["offsetWidth"], m["offsetHeight"], m["isMaximized"]); } catch (e) { - debugPrint(e.toString()); + debugPrintStack(label: e.toString()); return null; } } @@ -1147,7 +1147,7 @@ Future restoreWindowPosition(WindowType type, {int? windowId}) async { final pos = bind.getLocalFlutterConfig(k: kWindowPrefix + type.name); var lpos = LastWindowPosition.loadFromString(pos); if (lpos == null) { - debugPrint("window position saved, but cannot be parsed"); + debugPrint("no window position saved, ignoring position restoration"); return false; } @@ -1212,7 +1212,7 @@ Future initUniLinks() async { } parseRustdeskUri(initialLink); } catch (err) { - debugPrint("$err"); + debugPrintStack(label: "$err"); } } @@ -1422,7 +1422,7 @@ void onActiveWindowChanged() async { rustDeskWinManager.closeAllSubWindows() ]); } catch (err) { - debugPrint("$err"); + debugPrintStack(label: "$err"); } finally { await windowManager.setPreventClose(false); await windowManager.close(); diff --git a/flutter/lib/common/widgets/peer_tab_page.dart b/flutter/lib/common/widgets/peer_tab_page.dart index 5a498a1c4..1711e7b72 100644 --- a/flutter/lib/common/widgets/peer_tab_page.dart +++ b/flutter/lib/common/widgets/peer_tab_page.dart @@ -79,16 +79,19 @@ class _PeerTabPageState extends State .toList() .obs; try { - final json = jsonDecode(bind.getLocalFlutterConfig(k: 'peer-tab-order')); - if (json is List) { - final List list = json.map((e) => e.toString()).toList(); - if (list.length == visibleOrderedTabs.length && - visibleOrderedTabs.every((e) => list.contains(e))) { - visibleOrderedTabs.value = list; + final conf = bind.getLocalFlutterConfig(k: 'peer-tab-order'); + if (conf.isNotEmpty) { + final json = jsonDecode(conf); + if (json is List) { + final List list = json.map((e) => e.toString()).toList(); + if (list.length == visibleOrderedTabs.length && + visibleOrderedTabs.every((e) => list.contains(e))) { + visibleOrderedTabs.value = list; + } } } } catch (e) { - debugPrint('$e'); + debugPrintStack(label: '$e'); } adjustTab(); diff --git a/flutter/lib/desktop/pages/desktop_setting_page.dart b/flutter/lib/desktop/pages/desktop_setting_page.dart index a51b4d035..06cabebe7 100644 --- a/flutter/lib/desktop/pages/desktop_setting_page.dart +++ b/flutter/lib/desktop/pages/desktop_setting_page.dart @@ -63,7 +63,7 @@ class DesktopSettingPage extends StatefulWidget { DesktopTabPage.onAddSetting(initialPage: page); } } catch (e) { - debugPrint('$e'); + debugPrintStack(label: '$e'); } } } diff --git a/flutter/lib/desktop/pages/desktop_tab_page.dart b/flutter/lib/desktop/pages/desktop_tab_page.dart index 794dd1c08..57c7fe4b8 100644 --- a/flutter/lib/desktop/pages/desktop_tab_page.dart +++ b/flutter/lib/desktop/pages/desktop_tab_page.dart @@ -31,7 +31,7 @@ class DesktopTabPage extends StatefulWidget { initialPage: initialPage, ))); } catch (e) { - debugPrint('$e'); + debugPrintStack(label: '$e'); } } } diff --git a/flutter/lib/desktop/widgets/login.dart b/flutter/lib/desktop/widgets/login.dart index 3e58a6de2..053653ab3 100644 --- a/flutter/lib/desktop/widgets/login.dart +++ b/flutter/lib/desktop/widgets/login.dart @@ -460,7 +460,7 @@ Future loginDialog() async { debugPrint('$resp'); completer.complete(true); } catch (err) { - debugPrint(err.toString()); + debugPrintStack(label: err.toString()); cancel(); return; } diff --git a/flutter/lib/mobile/pages/server_page.dart b/flutter/lib/mobile/pages/server_page.dart index 0b2a51d40..38ad18f14 100644 --- a/flutter/lib/mobile/pages/server_page.dart +++ b/flutter/lib/mobile/pages/server_page.dart @@ -564,7 +564,7 @@ void androidChannelInit() { } } } catch (e) { - debugPrint("MethodCallHandler err:$e"); + debugPrintStack(label: "MethodCallHandler err:$e"); } return ""; }); diff --git a/flutter/lib/models/file_model.dart b/flutter/lib/models/file_model.dart index 744a3a502..a7968f701 100644 --- a/flutter/lib/models/file_model.dart +++ b/flutter/lib/models/file_model.dart @@ -363,8 +363,6 @@ class FileModel extends ChangeNotifier { if (_currentRemoteDir.path.isEmpty) { openDirectory(_remoteOption.home, isLocal: false); } - // load last transfer jobs - await bind.sessionLoadLastTransferJobs(id: '${parent.target?.id}'); } Future onClose() async { diff --git a/flutter/lib/models/native_model.dart b/flutter/lib/models/native_model.dart index 0a833583e..cf2de4219 100644 --- a/flutter/lib/models/native_model.dart +++ b/flutter/lib/models/native_model.dart @@ -126,7 +126,7 @@ class PlatformFFI { // no need to set home dir } } catch (e) { - debugPrint('initialize failed: $e'); + debugPrintStack(label: 'initialize failed: $e'); } String id = 'NA'; String name = 'Flutter'; @@ -151,9 +151,8 @@ class PlatformFFI { WindowsDeviceInfo winInfo = await deviceInfo.windowsInfo; name = winInfo.computerName; id = winInfo.computerName; - } catch (e, stacktrace) { - debugPrint("get windows device info failed: $e"); - debugPrintStack(stackTrace: stacktrace); + } catch (e) { + debugPrintStack(label: "get windows device info failed: $e"); name = "unknown"; id = "unknown"; } @@ -174,7 +173,7 @@ class PlatformFFI { await _ffiBind.mainSetHomeDir(home: _homeDir); await _ffiBind.mainInit(appDir: _dir); } catch (e) { - debugPrint('initialize failed: $e'); + debugPrintStack(label: 'initialize failed: $e'); } version = await getVersion(); } diff --git a/libs/hbb_common/src/platform/linux.rs b/libs/hbb_common/src/platform/linux.rs index 1a20ed0e1..4c6375dd7 100644 --- a/libs/hbb_common/src/platform/linux.rs +++ b/libs/hbb_common/src/platform/linux.rs @@ -43,7 +43,8 @@ pub fn get_display_server() -> String { } fn get_display_server_of_session(session: &str) -> String { - if let Ok(output) = run_loginctl(Some(vec!["show-session", "-p", "Type", session])) + let mut display_server = if let Ok(output) = + run_loginctl(Some(vec!["show-session", "-p", "Type", session])) // Check session type of the session { let display_server = String::from_utf8_lossy(&output.stdout) @@ -64,28 +65,23 @@ fn get_display_server_of_session(session: &str) -> String { { if xorg_results.trim_end().to_string() != "" { // If it is, manually return "x11", otherwise return tty - "x11".to_owned() - } else { - display_server + return "x11".to_owned(); } - } else { - // If any of these commands fail just fall back to the display server - display_server } - } else { - display_server } - } else { - // loginctl has not given the expected output. try something else. - if let Ok(sestype) = std::env::var("XDG_SESSION_TYPE") { - return sestype.to_owned(); - } - // If the session is not a tty, then just return the type as usual - display_server } + display_server } else { "".to_owned() + }; + if display_server.is_empty() { + // loginctl has not given the expected output. try something else. + if let Ok(sestype) = std::env::var("XDG_SESSION_TYPE") { + display_server = sestype; + } } + // If the session is not a tty, then just return the type as usual + display_server } pub fn get_values_of_seat0(indices: Vec) -> Vec { @@ -126,8 +122,7 @@ pub fn get_values_of_seat0(indices: Vec) -> Vec { } fn is_active(sid: &str) -> bool { - if let Ok(output) = run_loginctl(Some(vec!["show-session", "-p", "State", sid])) - { + if let Ok(output) = run_loginctl(Some(vec!["show-session", "-p", "State", sid])) { String::from_utf8_lossy(&output.stdout).contains("active") } else { false diff --git a/src/client/io_loop.rs b/src/client/io_loop.rs index efeacb61c..326857d3f 100644 --- a/src/client/io_loop.rs +++ b/src/client/io_loop.rs @@ -936,7 +936,7 @@ impl Remote { self.handle_job_status(d.id, d.file_num, err); } Some(file_response::Union::Error(e)) => { - if let Some(job) = fs::get_job(e.id, &mut self.write_jobs) { + if let Some(_job) = fs::get_job(e.id, &mut self.write_jobs) { fs::remove_job(e.id, &mut self.write_jobs); } self.handle_job_status(e.id, e.file_num, Some(e.error)); diff --git a/src/ipc.rs b/src/ipc.rs index 478094cf2..34711a900 100644 --- a/src/ipc.rs +++ b/src/ipc.rs @@ -78,7 +78,7 @@ pub enum FS { WriteError { id: i32, file_num: i32, - err: String + err: String, }, WriteOffset { id: i32, @@ -544,7 +544,7 @@ async fn check_pid(postfix: &str) { } } } - hbb_common::allow_err!(std::fs::remove_file(&Config::ipc_path(postfix))); + std::fs::remove_file(&Config::ipc_path(postfix)).ok(); } #[inline] diff --git a/src/server/input_service.rs b/src/server/input_service.rs index 4d4389870..695c6f3d5 100644 --- a/src/server/input_service.rs +++ b/src/server/input_service.rs @@ -246,16 +246,18 @@ pub async fn setup_uinput(minx: i32, maxx: i32, miny: i32, maxy: i32) -> ResultT pub async fn update_mouse_resolution(minx: i32, maxx: i32, miny: i32, maxy: i32) -> ResultType<()> { set_uinput_resolution(minx, maxx, miny, maxy).await?; - if let Some(mouse) = ENIGO.lock().unwrap().get_custom_mouse() { - if let Some(mouse) = mouse - .as_mut_any() - .downcast_mut::() - { - allow_err!(mouse.send_refresh()); - } else { - log::error!("failed downcast uinput mouse"); + std::thread::spawn(|| { + if let Some(mouse) = ENIGO.lock().unwrap().get_custom_mouse() { + if let Some(mouse) = mouse + .as_mut_any() + .downcast_mut::() + { + allow_err!(mouse.send_refresh()); + } else { + log::error!("failed downcast uinput mouse"); + } } - } + }); Ok(()) } diff --git a/src/server/uinput.rs b/src/server/uinput.rs index 78b22c562..a2e91e57b 100644 --- a/src/server/uinput.rs +++ b/src/server/uinput.rs @@ -4,7 +4,7 @@ use evdev::{ uinput::{VirtualDevice, VirtualDeviceBuilder}, AttributeSet, EventType, InputEvent, }; -use hbb_common::{allow_err, bail, log, tokio, ResultType}; +use hbb_common::{allow_err, bail, log, tokio::{self, runtime::Runtime}, ResultType}; static IPC_CONN_TIMEOUT: u64 = 1000; static IPC_REQUEST_TIMEOUT: u64 = 1000; @@ -17,24 +17,24 @@ pub mod client { pub struct UInputKeyboard { conn: Connection, + rt: Runtime, } impl UInputKeyboard { pub async fn new() -> ResultType { let conn = ipc::connect(IPC_CONN_TIMEOUT, IPC_POSTFIX_KEYBOARD).await?; - Ok(Self { conn }) + let rt = Runtime::new()?; + Ok(Self { conn, rt }) } - #[tokio::main(flavor = "current_thread")] - async fn send(&mut self, data: Data) -> ResultType<()> { - self.conn.send(&data).await + fn send(&mut self, data: Data) -> ResultType<()> { + self.rt.block_on(self.conn.send(&data)) } - #[tokio::main(flavor = "current_thread")] - async fn send_get_key_state(&mut self, data: Data) -> ResultType { - self.conn.send(&data).await?; + fn send_get_key_state(&mut self, data: Data) -> ResultType { + self.rt.block_on(self.conn.send(&data))?; - match self.conn.next_timeout(IPC_REQUEST_TIMEOUT).await { + match self.rt.block_on(self.conn.next_timeout(IPC_REQUEST_TIMEOUT)) { Ok(Some(Data::KeyboardResponse(ipc::DataKeyboardResponse::GetKeyState(state)))) => { Ok(state) } @@ -101,17 +101,18 @@ pub mod client { pub struct UInputMouse { conn: Connection, + rt: Runtime, } impl UInputMouse { pub async fn new() -> ResultType { let conn = ipc::connect(IPC_CONN_TIMEOUT, IPC_POSTFIX_MOUSE).await?; - Ok(Self { conn }) + let rt = Runtime::new()?; + Ok(Self { conn, rt }) } - #[tokio::main(flavor = "current_thread")] - async fn send(&mut self, data: Data) -> ResultType<()> { - self.conn.send(&data).await + fn send(&mut self, data: Data) -> ResultType<()> { + self.rt.block_on(self.conn.send(&data)) } pub fn send_refresh(&mut self) -> ResultType<()> { @@ -586,6 +587,16 @@ pub mod service { match data { Data::Mouse(data) => { if let DataMouse::Refresh = data { + let resolution = RESOLUTION.lock().unwrap(); + let rng_x = resolution.0.clone(); + let rng_y = resolution.1.clone(); + log::info!( + "Refresh uinput mouce with rng_x: ({}, {}), rng_y: ({}, {})", + rng_x.0, + rng_x.1, + rng_y.0, + rng_y.1 + ); mouse = match mouce::Mouse::new_uinput(rng_x, rng_y) { Ok(mouse) => mouse, Err(e) => { diff --git a/src/server/video_service.rs b/src/server/video_service.rs index 686e28f35..6d1235ed8 100644 --- a/src/server/video_service.rs +++ b/src/server/video_service.rs @@ -21,8 +21,9 @@ use super::{video_qos::VideoQoS, *}; #[cfg(windows)] use crate::portable_service::client::PORTABLE_SERVICE_RUNNING; +#[cfg(windows)] +use hbb_common::get_version_number; use hbb_common::{ - get_version_number, tokio::sync::{ mpsc::{unbounded_channel, UnboundedReceiver, UnboundedSender}, Mutex as TokioMutex,