Skip to content

Commit 2b0a9d7

Browse files
committed
simplify code
1 parent 40bb785 commit 2b0a9d7

4 files changed

Lines changed: 23 additions & 189 deletions

File tree

‎src-tauri/Cargo.lock‎

Lines changed: 0 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎src-tauri/Cargo.toml‎

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,6 @@ features = ["native-tls", "socks", "gzip", "deflate"]
4747
winreg = "^0.55.0"
4848

4949
[target.'cfg(target_os = "macos")'.dependencies]
50-
objc2 = "^0.6"
51-
once_cell = "1"
5250

5351
[target.'cfg(not(any(target_os = "android", target_os = "ios")))'.dependencies]
5452
tauri-plugin-cli = "2"

‎src-tauri/src/macos.rs‎

Lines changed: 9 additions & 147 deletions
Original file line numberDiff line numberDiff line change
@@ -18,92 +18,15 @@
1818

1919
use std::{
2020
fs::OpenOptions,
21-
io::{ErrorKind, Result, Write},
22-
sync::Mutex,
21+
io::Write,
2322
};
2423

25-
use objc2::{
26-
class, define_class,
27-
ffi::NSInteger,
28-
msg_send,
29-
rc::Retained,
30-
runtime::{AnyObject, NSObject},
31-
sel, ClassType,
32-
};
33-
use once_cell::sync::OnceCell;
3424
use tauri::{menu::{Menu, MenuItem, PredefinedMenuItem, Submenu}, AppHandle};
3525

36-
type THandler = OnceCell<Mutex<Box<dyn FnMut(Vec<String>) + Send + 'static>>>;
37-
38-
// If the Mutex turns out to be a problem, or FnMut turns out to be useless, we can remove the Mutex and turn FnMut into Fn
39-
static HANDLER: THandler = OnceCell::new();
40-
41-
// keyDirectObject
42-
const KEY_DIRECT_OBJECT: u32 = 0x2d2d2d2d;
43-
44-
// kInternetEventClass
45-
const GURL_EVENT_CLASS: u32 = 0x4755524c;
46-
// kAEGetURL
47-
const EVENT_GET_URL: u32 = 0x4755524c;
48-
49-
// kCoreEventClass
50-
const CORE_EVENT_CLASS: u32 = 0x61657674;
5126
// kAEOpenDocuments
5227
const EVENT_OPEN_DOCUMENTS: u32 = 0x6F646F63;
53-
// kAEReopenApplication
54-
const EVENT_REOPEN_APP: u32 = 0x72617070;
55-
56-
// Adapted from https://github.com/mrmekon/fruitbasket/blob/aad14e400d710d1d46317c0d8c55ff742bfeaadd/src/osx.rs#L848
57-
fn parse_event(event: *mut AnyObject) -> (u32, Vec<String>) {
58-
if event as u64 == 0u64 {
59-
return (0, vec![]);
60-
}
61-
unsafe {
62-
let class: u32 = msg_send![event, eventClass];
63-
let id: u32 = msg_send![event, eventID];
64-
65-
let payload = match (class, id) {
66-
(GURL_EVENT_CLASS, EVENT_GET_URL) => {
67-
let url: *mut AnyObject =
68-
msg_send![event, paramDescriptorForKeyword: KEY_DIRECT_OBJECT];
69-
let nsstring: *mut AnyObject = msg_send![url, stringValue];
70-
let cstr: *const i8 = msg_send![nsstring, UTF8String];
71-
72-
if !cstr.is_null() {
73-
vec![std::ffi::CStr::from_ptr(cstr).to_string_lossy().to_string()]
74-
} else {
75-
vec![]
76-
}
77-
}
78-
(CORE_EVENT_CLASS, EVENT_OPEN_DOCUMENTS) => {
79-
let documents: *mut AnyObject =
80-
msg_send![event, paramDescriptorForKeyword: KEY_DIRECT_OBJECT];
81-
let count: NSInteger = msg_send![documents, numberOfItems];
82-
83-
let mut paths = Vec::<String>::new();
84-
85-
for i in 1..count + 1 {
86-
let path: *mut AnyObject = msg_send![documents, descriptorAtIndex: i];
87-
let nsstring: *mut AnyObject = msg_send![path, stringValue];
88-
let cstr: *const i8 = msg_send![nsstring, UTF8String];
89-
90-
if !cstr.is_null() {
91-
let path_str = std::ffi::CStr::from_ptr(cstr).to_string_lossy().to_string();
92-
paths.push(path_str);
93-
}
94-
}
95-
96-
paths
97-
}
98-
// reopen app event has no useful payload
99-
(_, _) => {
100-
vec![]
101-
}
102-
};
103-
104-
(id, payload)
105-
}
106-
}
28+
// kAEGetURL
29+
const EVENT_GET_URL: u32 = 0x4755524c;
10730

10831
fn log_event(event_id: u32, payload: &[String]) {
10932
let Some(path) = dirs::home_dir().map(|home| home.join("trgui.log")) else {
@@ -116,73 +39,12 @@ fn log_event(event_id: u32, payload: &[String]) {
11639
}
11740

11841
pub fn log_opened_urls(urls: &[String]) {
119-
log_event(EVENT_OPEN_DOCUMENTS, urls);
120-
}
121-
122-
define_class!(
123-
#[unsafe(super(NSObject))]
124-
#[name = "TauriPluginDeepLinkHandler"]
125-
struct Handler;
126-
127-
impl Handler {
128-
#[unsafe(method(handleEvent:withReplyEvent:))]
129-
fn handle_event(&self, event: *mut AnyObject, _replace: *const AnyObject) {
130-
let (event_id, payload) = parse_event(event);
131-
log_event(event_id, &payload);
132-
let mut cb = HANDLER.get().unwrap().lock().unwrap();
133-
cb(payload);
134-
}
135-
}
136-
);
137-
138-
impl Handler {
139-
pub fn new() -> Retained<Self> {
140-
let cls = Self::class();
141-
unsafe { msg_send![msg_send![cls, alloc], init] }
142-
}
143-
}
144-
145-
// Call this once early in app main() or setup hook
146-
pub fn set_handler<F: FnMut(Vec<String>) + Send + 'static>(handler: F) -> Result<()> {
147-
if HANDLER.set(Mutex::new(Box::new(handler))).is_err() {
148-
return Err(std::io::Error::new(
149-
ErrorKind::AlreadyExists,
150-
"Handler was already set",
151-
));
152-
}
153-
154-
Ok(())
155-
}
156-
157-
fn listen_apple_event(event_class: u32, event_id: u32) {
158-
unsafe {
159-
let event_manager: Retained<AnyObject> =
160-
msg_send![class!(NSAppleEventManager), sharedAppleEventManager];
161-
162-
let handler = Handler::new();
163-
let handler_boxed = Box::into_raw(Box::new(handler));
164-
165-
let _: () = msg_send![&event_manager,
166-
setEventHandler: &**handler_boxed,
167-
andSelector: sel!(handleEvent:withReplyEvent:),
168-
forEventClass: event_class,
169-
andEventID: event_id];
170-
}
171-
}
172-
173-
// Call this in app setup hook
174-
pub fn listen_url() {
175-
listen_apple_event(GURL_EVENT_CLASS, EVENT_GET_URL);
176-
}
177-
178-
// Call this in app setup hook
179-
pub fn listen_open_documents() {
180-
listen_apple_event(CORE_EVENT_CLASS, EVENT_OPEN_DOCUMENTS);
181-
}
182-
183-
// Call this in app setup hook
184-
pub fn listen_reopen_app() {
185-
listen_apple_event(CORE_EVENT_CLASS, EVENT_REOPEN_APP);
42+
let event_id = if urls.first().is_some_and(|url| url.starts_with("file:")) {
43+
EVENT_OPEN_DOCUMENTS
44+
} else {
45+
EVENT_GET_URL
46+
};
47+
log_event(event_id, urls);
18648
}
18749

18850
pub fn make_menu<R>(app: &AppHandle<R>) -> tauri::Result<Menu<R>>

‎src-tauri/src/main.rs‎

Lines changed: 14 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
)]
2121

2222
#[cfg(target_os = "macos")]
23-
use std::sync::Mutex;
23+
use std::sync::atomic::{AtomicBool, Ordering};
2424
use std::{sync::Arc, time::Duration};
2525

2626
use createtorrent::CreationRequestsHandle;
@@ -45,12 +45,6 @@ mod tray;
4545

4646
struct ListenerHandle(Arc<RwLock<ipc::Ipc>>);
4747

48-
#[cfg(target_os = "macos")]
49-
#[derive(Default)]
50-
struct MacosEventState {
51-
app_handle: Option<AppHandle>,
52-
}
53-
5448
#[cfg(target_os = "macos")]
5549
fn handle_uris(app: &AppHandle, uris: Vec<String>) {
5650
if uris.is_empty() {
@@ -76,14 +70,11 @@ fn handle_uris(app: &AppHandle, uris: Vec<String>) {
7670

7771
fn setup(
7872
app: &mut App,
79-
#[cfg(target_os = "macos")] macos_events: &Arc<Mutex<MacosEventState>>,
73+
#[cfg(target_os = "macos")] opened_events_ready: &Arc<AtomicBool>,
8074
) -> Result<(), Box<dyn std::error::Error>> {
8175
#[cfg(target_os = "macos")]
8276
{
83-
macos::listen_url();
84-
macos::listen_open_documents();
85-
macos::listen_reopen_app();
86-
macos_events.lock().unwrap().app_handle = Some(app.handle().clone());
77+
opened_events_ready.store(true, Ordering::Release);
8778
}
8879

8980
let mut torrents: Vec<String> = vec![];
@@ -210,7 +201,7 @@ fn main() {
210201
let pending = ipc.pending_queue();
211202

212203
#[cfg(target_os = "macos")]
213-
let macos_events = Arc::new(Mutex::new(MacosEventState::default()));
204+
let opened_events_ready = Arc::new(AtomicBool::new(false));
214205

215206
let app_builder = tauri::Builder::default()
216207
.plugin(tauri_plugin_cli::init())
@@ -245,8 +236,8 @@ fn main() {
245236

246237
#[cfg(target_os = "macos")]
247238
let app_builder = app_builder.setup({
248-
let macos_events = macos_events.clone();
249-
move |app| setup(app, &macos_events)
239+
let opened_events_ready = opened_events_ready.clone();
240+
move |app| setup(app, &opened_events_ready)
250241
});
251242
#[cfg(not(target_os = "macos"))]
252243
let app_builder = app_builder.setup(setup);
@@ -266,26 +257,7 @@ fn main() {
266257
.expect("error while running tauri application");
267258

268259
#[cfg(target_os = "macos")]
269-
{
270-
let event_state = macos_events.clone();
271-
let event_pending = pending.clone();
272-
macos::set_handler(move |uris| {
273-
let events = event_state.lock().unwrap();
274-
if let Some(app_handle) = events.app_handle.clone() {
275-
drop(events);
276-
handle_uris(&app_handle, uris);
277-
} else {
278-
event_pending.lock().unwrap().extend(uris);
279-
}
280-
})
281-
.expect("Unable to set apple event handler");
282-
macos::listen_url();
283-
macos::listen_open_documents();
284-
macos::listen_reopen_app();
285-
}
286-
287-
#[cfg(target_os = "macos")]
288-
let run_events = macos_events.clone();
260+
let run_events_ready = opened_events_ready.clone();
289261
#[cfg(target_os = "macos")]
290262
let run_pending = pending.clone();
291263

@@ -295,13 +267,17 @@ fn main() {
295267
tauri::RunEvent::Opened { urls } => {
296268
let urls: Vec<String> = urls.into_iter().map(|url| url.to_string()).collect();
297269
macos::log_opened_urls(&urls);
298-
let app_handle = run_events.lock().unwrap().app_handle.clone();
299-
if let Some(app_handle) = app_handle {
300-
handle_uris(&app_handle, urls);
270+
if run_events_ready.load(Ordering::Acquire) {
271+
handle_uris(app_handle, urls);
301272
} else {
302273
run_pending.lock().unwrap().extend(urls);
303274
}
304275
}
276+
#[cfg(target_os = "macos")]
277+
tauri::RunEvent::Reopen { has_visible_windows, .. }
278+
if !has_visible_windows => {
279+
tray::toggle_main_window(app_handle, app_handle.get_webview_window("main"));
280+
}
305281
tauri::RunEvent::ExitRequested { api, .. } => {
306282
api.prevent_exit();
307283
tray::set_tray_showhide_text(app_handle, "Show");

0 commit comments

Comments
 (0)