From cfe7eb89541d51e56fe0278373b6f7e3bcc37b81 Mon Sep 17 00:00:00 2001 From: purajit Date: Mon, 16 Sep 2024 06:49:18 -0700 Subject: [PATCH] Prevent winit from overriding LSUIElement in package manifests (#3920) --- src/changelog/unreleased.md | 5 +++++ src/platform/macos.rs | 15 ++++++++------- src/platform_impl/macos/app_state.rs | 15 ++++++++++++--- src/platform_impl/macos/event_loop.rs | 15 ++++++--------- 4 files changed, 31 insertions(+), 19 deletions(-) diff --git a/src/changelog/unreleased.md b/src/changelog/unreleased.md index 1936e13c3..4e9589855 100644 --- a/src/changelog/unreleased.md +++ b/src/changelog/unreleased.md @@ -44,3 +44,8 @@ changelog entry. - On macOS, add `WindowExtMacOS::set_borderless_game` and `WindowAttributesExtMacOS::with_borderless_game` to fully disable the menu bar and dock in Borderless Fullscreen as commonly done in games. + +### Fixed + +- On MacOS, package manifest definitions of `LSUIElement` will no longer be overridden with the + default activation policy, unless explicitly provided during initialization. diff --git a/src/platform/macos.rs b/src/platform/macos.rs index a6c075717..424c9d621 100644 --- a/src/platform/macos.rs +++ b/src/platform/macos.rs @@ -175,14 +175,12 @@ impl WindowExtMacOS for Window { #[inline] fn set_borderless_game(&self, borderless_game: bool) { - let window = self.as_any().downcast_ref::().unwrap(); - window.maybe_wait_on_main(|w| w.set_borderless_game(borderless_game)) + self.window.maybe_wait_on_main(|w| w.set_borderless_game(borderless_game)) } #[inline] fn is_borderless_game(&self) -> bool { - let window = self.as_any().downcast_ref::().unwrap(); - window.maybe_wait_on_main(|w| w.is_borderless_game()) + self.window.maybe_wait_on_main(|w| w.is_borderless_game()) } } @@ -313,9 +311,12 @@ impl WindowAttributesExtMacOS for WindowAttributes { } pub trait EventLoopBuilderExtMacOS { - /// Sets the activation policy for the application. + /// Sets the activation policy for the application. If used, this will override + /// any relevant settings provided in the package manifest. + /// For instance, `with_activation_policy(ActivationPolicy::Regular)` will prevent + /// the application from running as an "agent", even if LSUIElement is set to true. /// - /// It is set to [`ActivationPolicy::Regular`] by default. + /// If unused, the Winit will honor the package manifest. /// /// # Example /// @@ -367,7 +368,7 @@ pub trait EventLoopBuilderExtMacOS { impl EventLoopBuilderExtMacOS for EventLoopBuilder { #[inline] fn with_activation_policy(&mut self, activation_policy: ActivationPolicy) -> &mut Self { - self.platform_specific.activation_policy = activation_policy; + self.platform_specific.activation_policy = Some(activation_policy); self } diff --git a/src/platform_impl/macos/app_state.rs b/src/platform_impl/macos/app_state.rs index ee149384b..71f7c937f 100644 --- a/src/platform_impl/macos/app_state.rs +++ b/src/platform_impl/macos/app_state.rs @@ -18,7 +18,12 @@ use crate::window::WindowId as RootWindowId; #[derive(Debug)] pub(super) struct AppState { - activation_policy: NSApplicationActivationPolicy, + // <<<<<<< HEAD:src/platform_impl/macos/app_state.rs + // activation_policy: NSApplicationActivationPolicy, + // ======= + activation_policy: Option, + // >>>>>>> 7e819bb2 (Prevent winit from overriding LSUIElement in package manifests + // (#3920)):src/platform_impl/apple/appkit/app_state.rs default_menu: bool, activate_ignoring_other_apps: bool, run_loop: RunLoop, @@ -74,7 +79,7 @@ declare_class!( impl ApplicationDelegate { pub(super) fn new( mtm: MainThreadMarker, - activation_policy: NSApplicationActivationPolicy, + activation_policy: Option, default_menu: bool, activate_ignoring_other_apps: bool, ) -> Retained { @@ -111,7 +116,11 @@ impl ApplicationDelegate { // We need to delay setting the activation policy and activating the app // until `applicationDidFinishLaunching` has been called. Otherwise the // menu bar is initially unresponsive on macOS 10.15. - app.setActivationPolicy(self.ivars().activation_policy); + // If no activation policy is explicitly provided, do not set it at all + // to allow the package manifest to define behavior via LSUIElement. + if let Some(activation_policy) = self.ivars().activation_policy { + app.setActivationPolicy(activation_policy); + } window_activation_hack(&app); #[allow(deprecated)] diff --git a/src/platform_impl/macos/event_loop.rs b/src/platform_impl/macos/event_loop.rs index 9b7be282f..cb0620ac9 100644 --- a/src/platform_impl/macos/event_loop.rs +++ b/src/platform_impl/macos/event_loop.rs @@ -202,18 +202,14 @@ pub struct EventLoop { #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] pub(crate) struct PlatformSpecificEventLoopAttributes { - pub(crate) activation_policy: ActivationPolicy, + pub(crate) activation_policy: Option, pub(crate) default_menu: bool, pub(crate) activate_ignoring_other_apps: bool, } impl Default for PlatformSpecificEventLoopAttributes { fn default() -> Self { - Self { - activation_policy: Default::default(), // Regular - default_menu: true, - activate_ignoring_other_apps: true, - } + Self { activation_policy: None, default_menu: true, activate_ignoring_other_apps: true } } } @@ -235,9 +231,10 @@ impl EventLoop { } let activation_policy = match attributes.activation_policy { - ActivationPolicy::Regular => NSApplicationActivationPolicy::Regular, - ActivationPolicy::Accessory => NSApplicationActivationPolicy::Accessory, - ActivationPolicy::Prohibited => NSApplicationActivationPolicy::Prohibited, + None => None, + Some(ActivationPolicy::Regular) => Some(NSApplicationActivationPolicy::Regular), + Some(ActivationPolicy::Accessory) => Some(NSApplicationActivationPolicy::Accessory), + Some(ActivationPolicy::Prohibited) => Some(NSApplicationActivationPolicy::Prohibited), }; let delegate = ApplicationDelegate::new( mtm,