mirror of
https://github.com/tauri-apps/tauri.git
synced 2026-04-03 10:11:15 +02:00
implement RunEvent::Opened
This commit is contained in:
1
Cargo.lock
generated
1
Cargo.lock
generated
@@ -9032,6 +9032,7 @@ dependencies = [
|
||||
"kuchikiki",
|
||||
"objc2 0.6.3",
|
||||
"objc2-app-kit",
|
||||
"objc2-foundation 0.3.0",
|
||||
"raw-window-handle",
|
||||
"serde",
|
||||
"serde_json",
|
||||
|
||||
@@ -32,6 +32,7 @@ windows = "0.61"
|
||||
[target."cfg(target_os = \"macos\")".dependencies]
|
||||
objc2 = "0.6"
|
||||
objc2-app-kit = { version = "0.3", features = [] }
|
||||
objc2-foundation = { version = "0.3", features = ["NSNotification"] }
|
||||
|
||||
[target."cfg(any(target_os = \"linux\", target_os = \"dragonfly\", target_os = \"freebsd\", target_os = \"openbsd\", target_os = \"netbsd\"))".dependencies]
|
||||
gtk = { version = "0.18", features = ["v3_24"] }
|
||||
|
||||
@@ -40,6 +40,9 @@ use std::{
|
||||
thread::{self, ThreadId},
|
||||
};
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
use crate::application::AppDelegateEvent;
|
||||
|
||||
mod cef_impl;
|
||||
|
||||
#[macro_export]
|
||||
@@ -1837,6 +1840,8 @@ impl<T: UserEvent> CefRuntime<T> {
|
||||
fn init(runtime_args: RuntimeInitArgs<RuntimeInitAttribute>) -> Self {
|
||||
let args = cef::args::Args::new();
|
||||
|
||||
let (event_tx, event_rx) = channel();
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
let (_sandbox, _loader) = {
|
||||
let is_helper = is_cef_helper_process();
|
||||
@@ -1857,7 +1862,17 @@ impl<T: UserEvent> CefRuntime<T> {
|
||||
assert!(loader.load());
|
||||
|
||||
if !is_helper {
|
||||
init_ns_app();
|
||||
let event_tx_ = event_tx.clone();
|
||||
init_ns_app(Box::new(move |event| match event {
|
||||
AppDelegateEvent::ShouldTerminate { tx } => {
|
||||
tx.send(objc2_app_kit::NSApplicationTerminateReply::TerminateCancel)
|
||||
.unwrap();
|
||||
event_tx_.send(RunEvent::Exit).unwrap();
|
||||
}
|
||||
AppDelegateEvent::OpenURLs { urls } => {
|
||||
event_tx_.send(RunEvent::Opened { urls }).unwrap();
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
(sandbox, loader)
|
||||
@@ -1865,8 +1880,6 @@ impl<T: UserEvent> CefRuntime<T> {
|
||||
|
||||
let _ = cef::api_hash(cef::sys::CEF_API_VERSION_LAST, 0);
|
||||
|
||||
let (event_tx, event_rx) = channel();
|
||||
|
||||
let cache_base = dirs::cache_dir().unwrap_or_else(std::env::temp_dir);
|
||||
let cache_path = cache_base.join(&runtime_args.identifier).join("cef");
|
||||
|
||||
@@ -2193,23 +2206,24 @@ impl<T: UserEvent> Runtime<T> for CefRuntime<T> {
|
||||
}
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
fn init_ns_app() {
|
||||
use objc2::{
|
||||
msg_send,
|
||||
rc::Retained,
|
||||
runtime::{AnyObject, NSObjectProtocol},
|
||||
ClassType, MainThreadMarker,
|
||||
};
|
||||
use objc2_app_kit::NSApp;
|
||||
fn init_ns_app(on_event: Box<dyn Fn(AppDelegateEvent)>) {
|
||||
use objc2::{msg_send, rc::Retained, runtime::NSObjectProtocol, ClassType, MainThreadMarker};
|
||||
use objc2_app_kit::{NSApp, NSApplication};
|
||||
|
||||
use application::SimpleApplication;
|
||||
use application::{AppDelegate, SimpleApplication};
|
||||
|
||||
let mtm = MainThreadMarker::new().unwrap();
|
||||
|
||||
unsafe {
|
||||
// Initialize the SimpleApplication instance.
|
||||
// SAFETY: mtm ensures that here is the main thread.
|
||||
let _: Retained<AnyObject> = msg_send![SimpleApplication::class(), sharedApplication];
|
||||
|
||||
use objc2::runtime::ProtocolObject;
|
||||
|
||||
let app: Retained<NSApplication> = msg_send![SimpleApplication::class(), sharedApplication];
|
||||
let delegate = AppDelegate::new(mtm, on_event);
|
||||
let proto_delegate = ProtocolObject::from_ref(&*delegate);
|
||||
app.setDelegate(Some(&proto_delegate));
|
||||
}
|
||||
|
||||
// If there was an invocation to NSApp prior to here,
|
||||
@@ -2220,11 +2234,80 @@ fn init_ns_app() {
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
mod application {
|
||||
use std::cell::Cell;
|
||||
use std::{cell::Cell, sync::mpsc::channel};
|
||||
|
||||
use cef::application_mac::{CefAppProtocol, CrAppControlProtocol, CrAppProtocol};
|
||||
use objc2::{define_class, runtime::Bool, DefinedClass};
|
||||
use objc2_app_kit::NSApplication;
|
||||
use objc2::{
|
||||
define_class, msg_send,
|
||||
rc::Retained,
|
||||
runtime::{Bool, NSObject, NSObjectProtocol},
|
||||
DefinedClass, MainThreadMarker, MainThreadOnly,
|
||||
};
|
||||
use objc2_app_kit::{NSApplication, NSApplicationDelegate, NSApplicationTerminateReply};
|
||||
use objc2_foundation::{NSArray, NSURL};
|
||||
|
||||
pub enum AppDelegateEvent {
|
||||
ShouldTerminate {
|
||||
tx: std::sync::mpsc::Sender<NSApplicationTerminateReply>,
|
||||
},
|
||||
OpenURLs {
|
||||
urls: Vec<url::Url>,
|
||||
},
|
||||
}
|
||||
|
||||
pub struct CefAppDelegateIvars {
|
||||
pub on_event: Box<dyn Fn(AppDelegateEvent)>,
|
||||
}
|
||||
|
||||
define_class!(
|
||||
#[unsafe(super(NSObject))]
|
||||
#[name = "CefAppDelegate"]
|
||||
#[ivars = CefAppDelegateIvars]
|
||||
#[thread_kind = MainThreadOnly]
|
||||
pub struct AppDelegate;
|
||||
|
||||
unsafe impl NSObjectProtocol for AppDelegate {}
|
||||
|
||||
#[allow(non_snake_case)]
|
||||
unsafe impl NSApplicationDelegate for AppDelegate {
|
||||
#[unsafe(method(application:openURLs:))]
|
||||
unsafe fn application_openURLs(&self, _application: &NSApplication, urls: &NSArray<NSURL>) {
|
||||
let converted_urls: Vec<url::Url> = urls
|
||||
.iter()
|
||||
.filter_map(|ns_url| {
|
||||
ns_url
|
||||
.absoluteString()
|
||||
.and_then(|url_string| url_string.to_string().parse().ok())
|
||||
})
|
||||
.collect();
|
||||
|
||||
let handler = &self.ivars().on_event;
|
||||
handler(AppDelegateEvent::OpenURLs {
|
||||
urls: converted_urls,
|
||||
});
|
||||
}
|
||||
|
||||
#[unsafe(method(applicationShouldTerminate:))]
|
||||
unsafe fn applicationShouldTerminate(
|
||||
&self,
|
||||
_sender: &NSApplication,
|
||||
) -> NSApplicationTerminateReply {
|
||||
let (tx, rx) = channel();
|
||||
let handler = &self.ivars().on_event;
|
||||
handler(AppDelegateEvent::ShouldTerminate { tx });
|
||||
rx.try_recv()
|
||||
.unwrap_or(NSApplicationTerminateReply::TerminateNow)
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
impl AppDelegate {
|
||||
pub fn new(mtm: MainThreadMarker, on_event: Box<dyn Fn(AppDelegateEvent)>) -> Retained<Self> {
|
||||
let delegate = Self::alloc(mtm).set_ivars(CefAppDelegateIvars { on_event });
|
||||
let delegate: Retained<Self> = unsafe { msg_send![super(delegate), init] };
|
||||
delegate
|
||||
}
|
||||
}
|
||||
|
||||
/// Instance variables of `SimpleApplication`.
|
||||
pub struct SimpleApplicationIvars {
|
||||
|
||||
Reference in New Issue
Block a user