From 50fbf8833b73d7c73752c6ca4f2ad4722f6d62e7 Mon Sep 17 00:00:00 2001 From: 21pages Date: Wed, 27 Mar 2024 13:42:50 +0800 Subject: [PATCH] macos support uni command "rustdesk rustdesk://xxxx" without mainwindow (#7534) Signed-off-by: 21pages --- src/core_main.rs | 36 +++++++++++++++++++++++++----------- src/flutter.rs | 9 ++------- src/platform/macos.rs | 20 +++++++++++++++++++- 3 files changed, 46 insertions(+), 19 deletions(-) diff --git a/src/core_main.rs b/src/core_main.rs index caac2ca99..6d2b0598a 100644 --- a/src/core_main.rs +++ b/src/core_main.rs @@ -31,6 +31,12 @@ fn is_empty_uni_link(arg: &str) -> bool { arg[prefix.len()..].chars().all(|c| c == '/') } +#[inline] +fn is_valid_non_empty_uni_link(arg: &str) -> bool { + let prefix = crate::get_uri_prefix(); + arg.starts_with(&prefix) && arg[prefix.len()..].chars().any(|c| c != '/') +} + /// shared by flutter and sciter main function /// /// [Note] @@ -64,8 +70,9 @@ pub fn core_main() -> Option> { .contains(&arg.as_str()) { _is_flutter_invoke_new_connection = true; - } - if arg == "--elevate" { + } else if i == 1 && is_valid_non_empty_uni_link(&arg) { + return handle_uni_links(arg); + } else if arg == "--elevate" { _is_elevate = true; } else if arg == "--run-as-system" { _is_run_as_system = true; @@ -104,7 +111,7 @@ pub fn core_main() -> Option> { } #[cfg(feature = "flutter")] if _is_flutter_invoke_new_connection { - return core_main_invoke_new_connection(std::env::args()); + return handle_uni_links(cmd_to_uni_link(std::env::args())); } let click_setup = cfg!(windows) && args.is_empty() && crate::common::is_setup(&arg_exe); if click_setup && !config::is_disable_installation() { @@ -511,14 +518,8 @@ fn import_config(path: &str) { } } -/// invoke a new connection -/// -/// [Note] -/// this is for invoke new connection from dbus. -/// If it returns [`None`], then the process will terminate, and flutter gui will not be started. -/// If it returns [`Some`], then the process will continue, and flutter gui will be started. #[cfg(feature = "flutter")] -fn core_main_invoke_new_connection(mut args: std::env::Args) -> Option> { +fn cmd_to_uni_link(mut args: std::env::Args) -> String { let mut authority = None; let mut id = None; let mut param_array = vec![]; @@ -565,6 +566,17 @@ fn core_main_invoke_new_connection(mut args: std::env::Args) -> Option Option> { if uni_links.is_empty() { return None; } @@ -586,7 +598,9 @@ fn core_main_invoke_new_connection(mut args: std::env::Args) -> Option *mut *mut c_char { unsafe { std::ptr::write(args_len, 0) }; - #[cfg(not(any(target_os = "android", target_os = "ios")))] - { - if let Some(args) = crate::core_main::core_main() { - return rust_args_to_c_args(args, args_len); - } - return std::ptr::null_mut() as _; + if let Some(args) = crate::core_main::core_main() { + return rust_args_to_c_args(args, args_len); } - #[cfg(any(target_os = "android", target_os = "ios"))] return std::ptr::null_mut() as _; } diff --git a/src/platform/macos.rs b/src/platform/macos.rs index 1ae35e56b..be4fbbeee 100644 --- a/src/platform/macos.rs +++ b/src/platform/macos.rs @@ -19,7 +19,7 @@ use core_graphics::{ }; use hbb_common::{anyhow::anyhow, bail, log, message_proto::Resolution}; use include_dir::{include_dir, Dir}; -use objc::{class, msg_send, sel, sel_impl}; +use objc::{class, msg_send, runtime::Object, sel, sel_impl}; use scrap::{libc::c_void, quartz::ffi::*}; use std::path::PathBuf; @@ -762,3 +762,21 @@ impl WakeLock { .ok_or(anyhow!("no AwakeHandle"))? } } + +pub fn send_url_to_system(uni_links: &str) -> Result<(), &'static str> { + unsafe { + let ns_string = NSString::alloc(nil); + let url_str = ns_string.init_str(uni_links); + let url: *mut Object = msg_send![class!(NSURL), URLWithString: url_str]; + if url.is_null() { + return Err("Failed to create NSURL"); + } + let workspace: *mut Object = msg_send![class!(NSWorkspace), sharedWorkspace]; + let success: bool = msg_send![workspace, openURL: url]; + if success { + Ok(()) + } else { + Err("Failed to open URL") + } + } +}