Skip to content

Commit f68c42a

Browse files
committed
fix: macos maybe
1 parent 8fb818e commit f68c42a

File tree

3 files changed

+83
-0
lines changed

3 files changed

+83
-0
lines changed

apps/plumeimpactor/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ auto-launcher = "0.6.1"
3535

3636
[target.'cfg(target_os = "macos")'.dependencies]
3737
plume_gestalt = { path = "../../crates/plume_gestalt" }
38+
objc2 = "0.6.3"
3839
objc2-app-kit = { version = "0.3.2", features = ["NSResponder", "NSRunningApplication"] }
3940
objc2-foundation = { version = "0.3.2" }
4041

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
#[cfg(target_os = "macos")]
2+
mod platform {
3+
use std::sync::OnceLock;
4+
5+
use objc2::rc::Retained;
6+
use objc2::runtime::{AnyClass, AnyObject, ClassBuilder, Sel};
7+
use objc2::{msg_send, msg_send_id, sel};
8+
use objc2_foundation::MainThreadMarker;
9+
10+
const CORE_EVENT_CLASS: u32 = 0x6165_7674; // 'aevt'
11+
const REOPEN_APPLICATION_EVENT: u32 = 0x7261_7070; // 'rapp'
12+
13+
static HANDLER: OnceLock<Retained<AnyObject>> = OnceLock::new();
14+
15+
extern "C" fn handle_reopen(
16+
_this: &AnyObject,
17+
_cmd: Sel,
18+
_event: Option<&AnyObject>,
19+
_reply: Option<&AnyObject>,
20+
) {
21+
crate::instance::signal_show_request();
22+
}
23+
24+
pub(super) fn install_reopen_handler() {
25+
let Some(_mtm) = MainThreadMarker::new() else {
26+
log::warn!("Cannot install macOS reopen handler: not on the main thread.");
27+
return;
28+
};
29+
30+
HANDLER.get_or_init(|| {
31+
let nsobject = AnyClass::get("NSObject").expect("NSObject class missing");
32+
let handler_class = if let Some(mut builder) =
33+
ClassBuilder::new("ImpactorReopenHandler", nsobject)
34+
{
35+
unsafe {
36+
builder.add_method(
37+
sel!(handleReopen:withReplyEvent:),
38+
handle_reopen
39+
as extern "C" fn(&AnyObject, Sel, Option<&AnyObject>, Option<&AnyObject>),
40+
);
41+
}
42+
builder.register()
43+
} else {
44+
AnyClass::get("ImpactorReopenHandler")
45+
.expect("ImpactorReopenHandler class missing")
46+
};
47+
48+
let handler: Retained<AnyObject> = unsafe { msg_send_id![handler_class, new] };
49+
50+
let Some(manager_class) = AnyClass::get("NSAppleEventManager") else {
51+
log::warn!("NSAppleEventManager class missing");
52+
return handler;
53+
};
54+
55+
let manager: Retained<AnyObject> =
56+
unsafe { msg_send_id![manager_class, sharedAppleEventManager] };
57+
58+
unsafe {
59+
let _: () = msg_send![
60+
&*manager,
61+
setEventHandler: &*handler
62+
andSelector: sel!(handleReopen:withReplyEvent:)
63+
forEventClass: CORE_EVENT_CLASS
64+
andEventID: REOPEN_APPLICATION_EVENT
65+
];
66+
}
67+
68+
handler
69+
});
70+
}
71+
}
72+
73+
#[cfg(not(target_os = "macos"))]
74+
mod platform {
75+
pub(super) fn install_reopen_handler() {}
76+
}
77+
78+
pub(crate) fn install_reopen_handler() {
79+
platform::install_reopen_handler();
80+
}

apps/plumeimpactor/src/main.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ mod appearance;
99
mod defaults;
1010
mod instance;
1111
mod macos_dock;
12+
mod macos_reopen;
1213
mod refresh;
1314
mod screen;
1415
mod startup;
@@ -47,6 +48,7 @@ fn main() -> iced::Result {
4748
{
4849
notify_rust::get_bundle_identifier_or_default("Impactor");
4950
let _ = notify_rust::set_application("dev.khcrysalis.PlumeImpactor");
51+
macos_reopen::install_reopen_handler();
5052
}
5153

5254
let (_daemon_handle, connected_devices) = spawn_refresh_daemon();

0 commit comments

Comments
 (0)