diff --git a/espanso-mac-utils/src/ffi.rs b/espanso-mac-utils/src/ffi.rs index 190a673..407abb6 100644 --- a/espanso-mac-utils/src/ffi.rs +++ b/espanso-mac-utils/src/ffi.rs @@ -29,4 +29,6 @@ extern "C" { pub fn mac_utils_prompt_accessibility() -> i32; pub fn mac_utils_transition_to_foreground_app(); pub fn mac_utils_transition_to_background_app(); + pub fn mac_utils_start_headless_eventloop(); + pub fn mac_utils_exit_headless_eventloop(); } diff --git a/espanso-mac-utils/src/lib.rs b/espanso-mac-utils/src/lib.rs index de6c3b3..a338ae3 100644 --- a/espanso-mac-utils/src/lib.rs +++ b/espanso-mac-utils/src/lib.rs @@ -113,6 +113,20 @@ pub fn convert_to_background_app() { } } +#[cfg(target_os = "macos")] +pub fn start_headless_eventloop() { + unsafe { + ffi::mac_utils_start_headless_eventloop(); + } +} + +#[cfg(target_os = "macos")] +pub fn exit_headless_eventloop() { + unsafe { + ffi::mac_utils_exit_headless_eventloop(); + } +} + #[cfg(test)] #[cfg(target_os = "macos")] mod tests { diff --git a/espanso-mac-utils/src/native.h b/espanso-mac-utils/src/native.h index 984b540..b44ee48 100644 --- a/espanso-mac-utils/src/native.h +++ b/espanso-mac-utils/src/native.h @@ -40,4 +40,8 @@ extern "C" void mac_utils_transition_to_foreground_app(); // When called, convert the current process to a background app (hide the dock icon). extern "C" void mac_utils_transition_to_background_app(); +// Start and stop a "headless" eventloop to receive NSApplication events. +extern "C" void mac_utils_start_headless_eventloop(); +extern "C" void mac_utils_exit_headless_eventloop(); + #endif //ESPANSO_MAC_UTILS_H \ No newline at end of file diff --git a/espanso-mac-utils/src/native.mm b/espanso-mac-utils/src/native.mm index 75ff286..b17f034 100644 --- a/espanso-mac-utils/src/native.mm +++ b/espanso-mac-utils/src/native.mm @@ -88,4 +88,16 @@ void mac_utils_transition_to_foreground_app() { void mac_utils_transition_to_background_app() { ProcessSerialNumber psn = { 0, kCurrentProcess }; TransformProcessType(&psn, kProcessTransformToUIElementApplication); +} + +void mac_utils_start_headless_eventloop() { + NSApplication * application = [NSApplication sharedApplication]; + [NSApp run]; +} + +void mac_utils_exit_headless_eventloop() { + dispatch_async(dispatch_get_main_queue(), ^(void) { + [NSApp stop:nil]; + [NSApp abortModal]; + }); } \ No newline at end of file