Skip to content

Commit 41ef035

Browse files
doonvshunkie
andauthored
Move WindowPlugin exit systems to Last (#23624)
# Objective Fix #11874. ## Solution Old me said that he had problems fixing this, but I just changed the exit systems to `Last` and I have encountered no issues. ## Testing CI passes. I ran several examples including `multiple_windows` and I did the same changes to 0.18.1 and tested it with my library, I found no errors while closing the window in both cases. --------- Co-authored-by: shunkie <shunkie@qq.com>
1 parent 5eed63e commit 41ef035

4 files changed

Lines changed: 24 additions & 10 deletions

File tree

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
---
2+
title: "`WindowPlugin` exit systems moved to `Last`"
3+
pull_requests: [23624]
4+
---
5+
6+
`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.
7+
8+
`exit_on_all_closed` and `exit_on_primary_closed` have also been added to a new `SystemSet`, `ExitSystems`.

crates/bevy_window/src/lib.rs

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ pub mod prelude {
4646

4747
use alloc::sync::Arc;
4848
use bevy_app::prelude::*;
49+
use bevy_ecs::schedule::IntoScheduleConfigs;
4950
use bevy_platform::sync::Mutex;
5051

5152
impl Default for WindowPlugin {
@@ -87,14 +88,14 @@ pub struct WindowPlugin {
8788
/// surprise your users. It is recommended to leave this setting to
8889
/// either [`ExitCondition::OnAllClosed`] or [`ExitCondition::OnPrimaryClosed`].
8990
///
90-
/// [`ExitCondition::OnAllClosed`] will add [`exit_on_all_closed`] to [`Update`].
91-
/// [`ExitCondition::OnPrimaryClosed`] will add [`exit_on_primary_closed`] to [`Update`].
91+
/// [`ExitCondition::OnAllClosed`] will add [`exit_on_all_closed`] to [`Last`].
92+
/// [`ExitCondition::OnPrimaryClosed`] will add [`exit_on_primary_closed`] to [`Last`].
9293
pub exit_condition: ExitCondition,
9394

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

138139
match self.exit_condition {
139140
ExitCondition::OnPrimaryClosed => {
140-
app.add_systems(PostUpdate, exit_on_primary_closed);
141+
app.add_systems(Last, exit_on_primary_closed.in_set(ExitSystems));
141142
}
142143
ExitCondition::OnAllClosed => {
143-
app.add_systems(PostUpdate, exit_on_all_closed);
144+
app.add_systems(Last, exit_on_all_closed.in_set(ExitSystems));
144145
}
145146
ExitCondition::DontExit => {}
146147
}
147148

148149
if self.close_when_requested {
149150
// Need to run before `exit_on_*` systems
150-
app.add_systems(Update, close_when_requested);
151+
app.add_systems(Last, close_when_requested.before(ExitSystems));
151152
}
152153
}
153154
}
@@ -157,11 +158,11 @@ impl Plugin for WindowPlugin {
157158
pub enum ExitCondition {
158159
/// Close application when the primary window is closed
159160
///
160-
/// The plugin will add [`exit_on_primary_closed`] to [`PostUpdate`].
161+
/// The plugin will add [`exit_on_primary_closed`] to [`Last`].
161162
OnPrimaryClosed,
162163
/// Close application when all windows are closed
163164
///
164-
/// The plugin will add [`exit_on_all_closed`] to [`PostUpdate`].
165+
/// The plugin will add [`exit_on_all_closed`] to [`Last`].
165166
OnAllClosed,
166167
/// Keep application running headless even after closing all windows
167168
///

crates/bevy_window/src/system.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,11 @@ use crate::{ClosingWindow, PrimaryWindow, Window, WindowCloseRequested};
33
use bevy_app::AppExit;
44
use bevy_ecs::prelude::*;
55

6+
/// A [`SystemSet`] for the system that exits the application.
7+
/// Which can be either [`exit_on_all_closed`] or [`exit_on_primary_closed`].
8+
#[derive(SystemSet, Debug, Clone, PartialEq, Eq, Hash)]
9+
pub struct ExitSystems;
10+
611
/// Exit the application when there are no open windows.
712
///
813
/// This system is added by the [`WindowPlugin`] in the default configuration.

crates/bevy_winit/src/lib.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ extern crate alloc;
1616

1717
use bevy_derive::Deref;
1818
use bevy_reflect::Reflect;
19-
use bevy_window::{RawHandleWrapperHolder, WindowEvent};
19+
use bevy_window::{ExitSystems, RawHandleWrapperHolder, WindowEvent};
2020
use core::cell::RefCell;
2121
use winit::{event_loop::EventLoop, window::WindowId};
2222

@@ -138,7 +138,7 @@ impl Plugin for WinitPlugin {
138138
(
139139
changed_windows,
140140
changed_cursor_options,
141-
despawn_windows,
141+
despawn_windows.after(ExitSystems),
142142
check_keyboard_focus_lost,
143143
)
144144
.chain(),

0 commit comments

Comments
 (0)