mirror of
https://github.com/weyne85/rustdesk.git
synced 2025-10-29 17:00:05 +00:00
feat: add url scheme handler for macos
This commit is contained in:
@@ -1,8 +1,4 @@
|
||||
use std::{
|
||||
collections::HashMap,
|
||||
ffi::{CStr, CString},
|
||||
os::raw::c_char,
|
||||
};
|
||||
use std::{collections::HashMap, ffi::{CStr, CString}, os::raw::c_char, thread};
|
||||
use std::str::FromStr;
|
||||
|
||||
use flutter_rust_bridge::{StreamSink, SyncReturn, ZeroCopyBuffer};
|
||||
@@ -1261,6 +1257,23 @@ pub fn main_hide_docker() -> SyncReturn<bool> {
|
||||
SyncReturn(true)
|
||||
}
|
||||
|
||||
/// Start an ipc server for receiving the url scheme.
|
||||
///
|
||||
/// * Should only be called in the main flutter window.
|
||||
/// * macOS only
|
||||
pub fn main_start_ipc_url_server() {
|
||||
#[cfg(target_os = "macos")]
|
||||
thread::spawn(move || crate::server::start_ipc_url_server());
|
||||
}
|
||||
|
||||
/// Send a url scheme throught the ipc.
|
||||
///
|
||||
/// * macOS only
|
||||
pub fn send_url_scheme(url: String) {
|
||||
#[cfg(target_os = "macos")]
|
||||
thread::spawn(move || crate::ui::macos::handle_url_scheme(url));
|
||||
}
|
||||
|
||||
#[cfg(target_os = "android")]
|
||||
pub mod server_side {
|
||||
use hbb_common::log;
|
||||
@@ -1268,7 +1281,7 @@ pub mod server_side {
|
||||
JNIEnv,
|
||||
objects::{JClass, JString},
|
||||
sys::jstring,
|
||||
};
|
||||
};
|
||||
|
||||
use crate::start_server;
|
||||
|
||||
|
||||
11
src/ipc.rs
11
src/ipc.rs
@@ -16,10 +16,10 @@ use hbb_common::{
|
||||
config::{self, Config, Config2},
|
||||
futures::StreamExt as _,
|
||||
futures_util::sink::SinkExt,
|
||||
log, password_security as password, timeout, tokio,
|
||||
log, password_security as password, ResultType, timeout,
|
||||
tokio,
|
||||
tokio::io::{AsyncRead, AsyncWrite},
|
||||
tokio_util::codec::Framed,
|
||||
ResultType,
|
||||
};
|
||||
|
||||
use crate::rendezvous_mediator::RendezvousMediator;
|
||||
@@ -210,6 +210,7 @@ pub enum Data {
|
||||
DataPortableService(DataPortableService),
|
||||
SwitchSidesRequest(String),
|
||||
SwitchSidesBack,
|
||||
UrlLink(String)
|
||||
}
|
||||
|
||||
#[tokio::main(flavor = "current_thread")]
|
||||
@@ -832,3 +833,9 @@ pub async fn test_rendezvous_server() -> ResultType<()> {
|
||||
c.send(&Data::TestRendezvousServer).await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[tokio::main(flavor = "current_thread")]
|
||||
pub async fn send_url_scheme(url: String) -> ResultType<()> {
|
||||
connect(1_000, "_url").await?.send(&Data::UrlLink(url)).await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -1,8 +1,13 @@
|
||||
use crate::ipc::Data;
|
||||
use std::{
|
||||
collections::HashMap,
|
||||
net::SocketAddr,
|
||||
sync::{Arc, Mutex, RwLock, Weak},
|
||||
time::Duration,
|
||||
};
|
||||
|
||||
use bytes::Bytes;
|
||||
|
||||
pub use connection::*;
|
||||
#[cfg(not(any(target_os = "android", target_os = "ios")))]
|
||||
use hbb_common::config::Config2;
|
||||
use hbb_common::{
|
||||
allow_err,
|
||||
anyhow::{anyhow, Context},
|
||||
@@ -12,19 +17,19 @@ use hbb_common::{
|
||||
message_proto::*,
|
||||
protobuf::{Enum, Message as _},
|
||||
rendezvous_proto::*,
|
||||
ResultType,
|
||||
socket_client,
|
||||
sodiumoxide::crypto::{box_, secretbox, sign},
|
||||
timeout, tokio, ResultType, Stream,
|
||||
sodiumoxide::crypto::{box_, secretbox, sign}, Stream, timeout, tokio,
|
||||
};
|
||||
#[cfg(not(any(target_os = "android", target_os = "ios")))]
|
||||
use service::ServiceTmpl;
|
||||
use hbb_common::config::Config2;
|
||||
use hbb_common::tcp::new_listener;
|
||||
use service::{GenericService, Service, Subscriber};
|
||||
use std::{
|
||||
collections::HashMap,
|
||||
net::SocketAddr,
|
||||
sync::{Arc, Mutex, RwLock, Weak},
|
||||
time::Duration,
|
||||
};
|
||||
#[cfg(not(any(target_os = "android", target_os = "ios")))]
|
||||
use service::ServiceTmpl;
|
||||
|
||||
use crate::ipc::{connect, Data};
|
||||
use crate::ui_interface::SENDER;
|
||||
|
||||
pub mod audio_service;
|
||||
cfg_if::cfg_if! {
|
||||
@@ -55,8 +60,6 @@ mod service;
|
||||
mod video_qos;
|
||||
pub mod video_service;
|
||||
|
||||
use hbb_common::tcp::new_listener;
|
||||
|
||||
pub type Childs = Arc<Mutex<Vec<std::process::Child>>>;
|
||||
type ConnMap = HashMap<i32, ConnInner>;
|
||||
|
||||
@@ -425,6 +428,50 @@ pub async fn start_server(is_server: bool) {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
#[tokio::main(flavor = "current_thread")]
|
||||
pub async fn start_ipc_url_server() {
|
||||
log::debug!("Start an ipc server for listening to url schemes");
|
||||
match crate::ipc::new_listener("_url").await {
|
||||
Ok(mut incoming) => {
|
||||
while let Some(Ok(conn)) = incoming.next().await {
|
||||
let mut conn = crate::ipc::Connection::new(conn);
|
||||
match conn.next_timeout(1000).await {
|
||||
Ok(Some(data)) => {
|
||||
match data {
|
||||
Data::UrlLink(url) => {
|
||||
#[cfg(feature = "flutter")]
|
||||
{
|
||||
if let Some(stream) = crate::flutter::GLOBAL_EVENT_STREAM.read().unwrap().get(
|
||||
crate::flutter::APP_TYPE_MAIN
|
||||
) {
|
||||
let mut m = HashMap::new();
|
||||
m.insert("name", "on_url_scheme_received");
|
||||
m.insert("url", url.as_str());
|
||||
stream.add(serde_json::to_string(&m).unwrap());
|
||||
} else {
|
||||
log::warn!("No main window app found!");
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
log::warn!("An unexpected data was sent to the ipc url server.")
|
||||
}
|
||||
}
|
||||
}
|
||||
Err(err) => {
|
||||
log::error!("{}", err);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
Err(err) => {
|
||||
log::error!("{}", err);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
async fn sync_and_watch_config_dir() {
|
||||
if crate::platform::is_root() {
|
||||
|
||||
@@ -17,7 +17,9 @@ use objc::runtime::Class;
|
||||
use objc_id::WeakId;
|
||||
use sciter::{Host, make_args};
|
||||
|
||||
use hbb_common::log;
|
||||
use hbb_common::{log, tokio};
|
||||
|
||||
use crate::ui_cm_interface::start_ipc;
|
||||
|
||||
static APP_HANDLER_IVAR: &str = "GoDeskAppHandler";
|
||||
|
||||
@@ -181,16 +183,22 @@ extern "C" fn handle_menu_item(this: &mut Object, _: Sel, item: id) {
|
||||
}
|
||||
}
|
||||
|
||||
/// The function to handle the url scheme sent by system.
|
||||
/// The function to handle the url scheme sent by the system.
|
||||
///
|
||||
/// 1. Try to send the url scheme from ipc.
|
||||
/// 2. If failed to send the url scheme, we open a new main window to handle this url scheme.
|
||||
pub fn handle_url_scheme(url: String) {
|
||||
unimplemented!();
|
||||
if let Err(err) = crate::ipc::send_url_scheme(url.clone()) {
|
||||
log::debug!("Send the url to the existing flutter process failed, {}. Let's open a new program to handle this.", err);
|
||||
let _ = crate::run_me(vec![url]);
|
||||
}
|
||||
}
|
||||
|
||||
extern fn handle_apple_event(_this: &Object, _cmd: Sel, event: u64, _reply: u64) {
|
||||
let event = event as *mut Object;
|
||||
let url = fruitbasket::parse_url_event(event);
|
||||
log::debug!("event found {}", url);
|
||||
handle_url_scheme(url);
|
||||
log::debug!("an event was received: {}", url);
|
||||
std::thread::spawn(move || handle_url_scheme(url));
|
||||
}
|
||||
|
||||
unsafe fn make_menu_item(title: &str, key: &str, tag: u32) -> *mut Object {
|
||||
|
||||
Reference in New Issue
Block a user