Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
title: "`WindowPlugin` exit systems moved to `Last`"
pull_requests: [23624]
---

`bevy::window::close_when_requested`, `bevy::window::exit_on_all_closed` and `bevy::window::exit_on_primary_closed` have all been moved into the `Last` schedule to prevent systems that run after `Update` and rely on windows existing from panicking on the last frame of the application.

`exit_on_all_closed` and `exit_on_primary_closed` have also been added to a new `SystemSet`, `ExitSystems`.
17 changes: 9 additions & 8 deletions crates/bevy_window/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ pub mod prelude {

use alloc::sync::Arc;
use bevy_app::prelude::*;
use bevy_ecs::schedule::IntoScheduleConfigs;
use bevy_platform::sync::Mutex;

impl Default for WindowPlugin {
Expand Down Expand Up @@ -87,14 +88,14 @@ pub struct WindowPlugin {
/// surprise your users. It is recommended to leave this setting to
/// either [`ExitCondition::OnAllClosed`] or [`ExitCondition::OnPrimaryClosed`].
///
/// [`ExitCondition::OnAllClosed`] will add [`exit_on_all_closed`] to [`Update`].
/// [`ExitCondition::OnPrimaryClosed`] will add [`exit_on_primary_closed`] to [`Update`].
/// [`ExitCondition::OnAllClosed`] will add [`exit_on_all_closed`] to [`Last`].
/// [`ExitCondition::OnPrimaryClosed`] will add [`exit_on_primary_closed`] to [`Last`].
pub exit_condition: ExitCondition,

/// Whether to close windows when they are requested to be closed (i.e.
/// when the close button is pressed).
///
/// If true, this plugin will add [`close_when_requested`] to [`Update`].
/// If true, this plugin will add [`close_when_requested`] to [`Last`].
/// If this system (or a replacement) is not running, the close button will have no effect.
/// This may surprise your users. It is recommended to leave this setting as `true`.
pub close_when_requested: bool,
Expand Down Expand Up @@ -137,17 +138,17 @@ impl Plugin for WindowPlugin {

match self.exit_condition {
ExitCondition::OnPrimaryClosed => {
app.add_systems(PostUpdate, exit_on_primary_closed);
app.add_systems(Last, exit_on_primary_closed.in_set(ExitSystems));
}
ExitCondition::OnAllClosed => {
app.add_systems(PostUpdate, exit_on_all_closed);
app.add_systems(Last, exit_on_all_closed.in_set(ExitSystems));
}
ExitCondition::DontExit => {}
}

if self.close_when_requested {
// Need to run before `exit_on_*` systems
app.add_systems(Update, close_when_requested);
app.add_systems(Last, close_when_requested.before(ExitSystems));
}
}
}
Expand All @@ -157,11 +158,11 @@ impl Plugin for WindowPlugin {
pub enum ExitCondition {
/// Close application when the primary window is closed
///
/// The plugin will add [`exit_on_primary_closed`] to [`PostUpdate`].
/// The plugin will add [`exit_on_primary_closed`] to [`Last`].
OnPrimaryClosed,
/// Close application when all windows are closed
///
/// The plugin will add [`exit_on_all_closed`] to [`PostUpdate`].
/// The plugin will add [`exit_on_all_closed`] to [`Last`].
OnAllClosed,
/// Keep application running headless even after closing all windows
///
Expand Down
5 changes: 5 additions & 0 deletions crates/bevy_window/src/system.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,11 @@ use crate::{ClosingWindow, PrimaryWindow, Window, WindowCloseRequested};
use bevy_app::AppExit;
use bevy_ecs::prelude::*;

/// A [`SystemSet`] for the system that exits the application.
/// Which can be either [`exit_on_all_closed`] or [`exit_on_primary_closed`].
#[derive(SystemSet, Debug, Clone, PartialEq, Eq, Hash)]
pub struct ExitSystems;

/// Exit the application when there are no open windows.
///
/// This system is added by the [`WindowPlugin`] in the default configuration.
Expand Down
4 changes: 2 additions & 2 deletions crates/bevy_winit/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ extern crate alloc;

use bevy_derive::Deref;
use bevy_reflect::Reflect;
use bevy_window::{RawHandleWrapperHolder, WindowEvent};
use bevy_window::{ExitSystems, RawHandleWrapperHolder, WindowEvent};
use core::cell::RefCell;
use winit::{event_loop::EventLoop, window::WindowId};

Expand Down Expand Up @@ -140,7 +140,7 @@ impl Plugin for WinitPlugin {
// so we don't need to care about its ordering relative to `changed_windows`
changed_windows.ambiguous_with(exit_on_all_closed),
changed_cursor_options,
despawn_windows,
despawn_windows.after(ExitSystems),
check_keyboard_focus_lost,
)
.chain(),
Expand Down