diff --git a/src/platform_impl/macos/app_delegate.rs b/src/platform_impl/macos/app_delegate.rs index eaddcb1d2..c628820c5 100644 --- a/src/platform_impl/macos/app_delegate.rs +++ b/src/platform_impl/macos/app_delegate.rs @@ -39,6 +39,11 @@ lazy_static! { decl.add_class_method(sel!(new), new as extern "C" fn(&Class, Sel) -> id); decl.add_method(sel!(dealloc), dealloc as extern "C" fn(&Object, Sel)); + decl.add_method( + sel!(applicationWillFinishLaunching:), + will_finish_launching as extern "C" fn(&Object, Sel, id), + ); + decl.add_method( sel!(applicationDidFinishLaunching:), did_finish_launching as extern "C" fn(&Object, Sel, id), @@ -85,6 +90,12 @@ extern "C" fn dealloc(this: &Object, _: Sel) { } } +extern "C" fn will_finish_launching(this: &Object, _: Sel, _: id) { + trace!("Triggered `applicationWillFinishLaunching`"); + AppState::will_launch(this); + trace!("Completed `applicationWillFinishLaunching`"); +} + extern "C" fn did_finish_launching(this: &Object, _: Sel, _: id) { trace!("Triggered `applicationDidFinishLaunching`"); AppState::launched(this); diff --git a/src/platform_impl/macos/app_state.rs b/src/platform_impl/macos/app_state.rs index 091c58adf..af55ddb39 100644 --- a/src/platform_impl/macos/app_state.rs +++ b/src/platform_impl/macos/app_state.rs @@ -281,7 +281,16 @@ impl AppState { } } + pub fn will_launch(app_delegate: &Object) { + apply_activation_policy(app_delegate); + } + pub fn launched(app_delegate: &Object) { + // In catalina, if we set the activation policy before the app is launched, + // We get a bug where the menu is not clickable. + // We have solved this problem by setting the activation policy to prohibited + // with `set_policy_to_prohibited` and then running `apply_activation_policy` again. + set_policy_to_prohibited(); apply_activation_policy(app_delegate); unsafe { let ns_app = NSApp(); @@ -443,9 +452,6 @@ fn apply_activation_policy(app_delegate: &Object) { unsafe { use cocoa::appkit::NSApplicationActivationPolicy::*; let ns_app = NSApp(); - // We need to delay setting the activation policy and activating the app - // until `applicationDidFinishLaunching` has been called. Otherwise the - // menu bar won't be interactable. let act_pol = get_aux_state_mut(app_delegate).activation_policy; ns_app.setActivationPolicy_(match act_pol { ActivationPolicy::Regular => NSApplicationActivationPolicyRegular, @@ -454,3 +460,10 @@ fn apply_activation_policy(app_delegate: &Object) { }); } } + +fn set_policy_to_prohibited() { + unsafe { + let ns_app = NSApp(); + ns_app.setActivationPolicy_(cocoa::appkit::NSApplicationActivationPolicyProhibited); + } +}