macos support uni command "rustdesk rustdesk://xxxx" without mainwindow (#7534)

Signed-off-by: 21pages <pages21@163.com>
This commit is contained in:
21pages 2024-03-27 13:42:50 +08:00 committed by GitHub
parent d7137990b9
commit 50fbf8833b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 46 additions and 19 deletions

View File

@ -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<Vec<String>> {
.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<Vec<String>> {
}
#[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<Vec<String>> {
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<Vec<Strin
);
}
}
return uni_links;
}
/// invoke a new connection
///
/// [Note]
/// this is for invoke new connection.
/// 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 handle_uni_links(uni_links: String) -> Option<Vec<String>> {
if uni_links.is_empty() {
return None;
}
@ -586,7 +598,9 @@ fn core_main_invoke_new_connection(mut args: std::env::Args) -> Option<Vec<Strin
}
#[cfg(target_os = "macos")]
{
return if let Err(_) = crate::ipc::send_url_scheme(uni_links) {
return if let Err(_) = crate::ipc::send_url_scheme(uni_links.clone()) {
let res = crate::platform::send_url_to_system(&uni_links); // if exit, can't invoke this url successfully
println!("open_url result: {res:?}");
Some(Vec::new())
} else {
None

View File

@ -93,14 +93,9 @@ pub extern "C" fn handle_applicationShouldOpenUntitledFile() {
#[no_mangle]
pub extern "C" fn rustdesk_core_main_args(args_len: *mut c_int) -> *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 _;
}

View File

@ -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")
}
}
}