From 7b5a422052ee8663308d278181417a8807b00e16 Mon Sep 17 00:00:00 2001 From: Andres Riofrio Date: Mon, 22 Jun 2026 00:27:44 -0400 Subject: [PATCH 1/2] Request app activation on macOS to respect `Window::focused` on startup and window creation --- .../migration-guides/macos_app_activation.md | 10 ++++++++++ crates/bevy_winit/src/lib.rs | 15 +++++++++++++++ crates/bevy_winit/src/system.rs | 8 ++++++++ 3 files changed, 33 insertions(+) create mode 100644 _release-content/migration-guides/macos_app_activation.md diff --git a/_release-content/migration-guides/macos_app_activation.md b/_release-content/migration-guides/macos_app_activation.md new file mode 100644 index 0000000000000..89ab43b7b848a --- /dev/null +++ b/_release-content/migration-guides/macos_app_activation.md @@ -0,0 +1,10 @@ +--- +title: "macOS app activation now follows `Window::focused` on startup and window creation" +pull_requests: [] +--- + +On macOS, apps now request activation (to become the active/frontmost app) on startup only if the `WindowPlugin::primary_window` (or any additional `Window` entities available before `WinitPlugin::build`) has `focused: true`. This allows apps to avoid stealing focus from the user by setting `focused: false`. + +In addition, apps now request activation when a visible `Window` is created after startup with `focused: true`. Set `focused: false` if you'd prefer the app to remain inactive. + +Apps that only use the default `WindowPlugin::primary_window`, which is initially `focused: true` by default, are unchanged. diff --git a/crates/bevy_winit/src/lib.rs b/crates/bevy_winit/src/lib.rs index 2af21099f30df..040d39a3085a3 100644 --- a/crates/bevy_winit/src/lib.rs +++ b/crates/bevy_winit/src/lib.rs @@ -109,6 +109,21 @@ impl Plugin for WinitPlugin { event_loop_builder.with_any_thread(self.run_on_any_thread); } + #[cfg(target_os = "macos")] + { + use bevy_ecs::system::SystemState; + use winit::platform::macos::EventLoopBuilderExtMacOS; + + // Don't request app activation on startup if all its windows should + // start unfocused. Otherwise, app activation would focus one of the + // windows. + let mut initial_windows_state = + SystemState::>::new(app.world_mut()); + let initial_windows = initial_windows_state.get(app.world()).unwrap(); + let initially_focused = initial_windows.iter().any(|(_, window)| window.focused); + event_loop_builder.with_activate_ignoring_other_apps(initially_focused); + } + #[cfg(target_os = "windows")] { use winit::platform::windows::EventLoopBuilderExtWindows; diff --git a/crates/bevy_winit/src/system.rs b/crates/bevy_winit/src/system.rs index 66d8551bf4c4f..f7ca41d41cda6 100644 --- a/crates/bevy_winit/src/system.rs +++ b/crates/bevy_winit/src/system.rs @@ -122,6 +122,14 @@ pub fn create_windows( } } + #[cfg(target_os = "macos")] + { + // Request app activation via `focus_window()` if the window should start focused. + if window.focused { + winit_window.focus_window(); + } + } + window_created_events.write(WindowCreated { window: entity }); } }); From 479d30d687cb65b998942d903e3dac92a5666830 Mon Sep 17 00:00:00 2001 From: Andres Riofrio Date: Mon, 22 Jun 2026 00:33:19 -0400 Subject: [PATCH 2/2] Add PR number to macOS activation migration guide --- _release-content/migration-guides/macos_app_activation.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_release-content/migration-guides/macos_app_activation.md b/_release-content/migration-guides/macos_app_activation.md index 89ab43b7b848a..dac4607f0dfa7 100644 --- a/_release-content/migration-guides/macos_app_activation.md +++ b/_release-content/migration-guides/macos_app_activation.md @@ -1,6 +1,6 @@ --- title: "macOS app activation now follows `Window::focused` on startup and window creation" -pull_requests: [] +pull_requests: [24702] --- On macOS, apps now request activation (to become the active/frontmost app) on startup only if the `WindowPlugin::primary_window` (or any additional `Window` entities available before `WinitPlugin::build`) has `focused: true`. This allows apps to avoid stealing focus from the user by setting `focused: false`.