Skip to content

Commit 08daf4b

Browse files
committed
Use removal of window component to signal closing window, some clean up/renaming
1 parent ba8e19a commit 08daf4b

File tree

8 files changed

+44
-42
lines changed

8 files changed

+44
-42
lines changed

crates/bevy_render/src/view/window.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ fn extract_windows(
115115
}
116116

117117
for closed_window in closed.iter() {
118-
extracted_windows.remove(&closed_window.entity);
118+
extracted_windows.remove(&closed_window.window);
119119
}
120120
}
121121

crates/bevy_window/src/event.rs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -46,12 +46,14 @@ pub struct WindowCloseRequested {
4646
pub window: Entity,
4747
}
4848

49-
/// An event that is sent whenever a window is closed. This will be sent by the
50-
/// handler for [`WindowCloseRequested`] or similar.
49+
/// An event that is sent whenever a window is closed. This will be sent by the window
50+
/// backend
5151
#[derive(Debug, Clone)]
5252
pub struct WindowClosed {
5353
/// Window that has been closed.
54-
/// TODO: Does this entity actually exist anymore?
54+
///
55+
/// Note that this entity probably no longer exists
56+
/// by the time this event is received.
5557
pub window: Entity,
5658
}
5759
/// An event reporting that the mouse cursor has moved inside a window.
@@ -124,7 +126,7 @@ pub struct WindowBackendScaleFactorChanged {
124126
/// Events related to files being dragged and dropped on a window.
125127
#[derive(Debug, Clone)]
126128
pub enum FileDragAndDrop {
127-
/// File is being dropped into a window.
129+
/// File is being dropped into a window.
128130
DroppedFile {
129131
/// Window the file was dropped into.
130132
window: Entity,

crates/bevy_window/src/system.rs

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ pub fn exit_on_all_closed(mut app_exit_events: EventWriter<AppExit>, windows: Qu
2222
/// Exit the application when the primary window has been closed
2323
///
2424
/// This system is added by the [`WindowPlugin`]
25-
///
25+
///
2626
/// [`WindowPlugin`]: crate::WindowPlugin
2727
pub fn exit_on_primary_closed(
2828
mut app_exit_events: EventWriter<AppExit>,
@@ -55,32 +55,27 @@ pub fn exit_on_primary_closed(
5555
/// Ensure that you read the caveats documented on that field if doing so.
5656
///
5757
/// [`WindowPlugin`]: crate::WindowPlugin
58-
pub fn close_when_requested(
59-
mut closed: EventReader<WindowCloseRequested>,
60-
mut window_closed: EventWriter<WindowClosed>,
61-
) {
58+
pub fn close_when_requested(mut commands: Commands, mut closed: EventReader<WindowCloseRequested>) {
6259
for event in closed.iter() {
63-
window_closed.send(WindowClosed {
64-
window: event.window,
65-
});
60+
commands.entity(event.window).remove::<Window>();
6661
}
6762
}
6863

6964
/// Close the focused window whenever the escape key (<kbd>Esc</kbd>) is pressed
7065
///
7166
/// This is useful for examples or prototyping.
7267
pub fn close_on_esc(
68+
mut commands: Commands,
7369
focused_windows: Query<(Entity, &WindowFocus)>,
74-
mut window_closed: EventWriter<WindowClosed>,
7570
input: Res<Input<KeyCode>>,
7671
) {
77-
for (entity, focus) in focused_windows.iter() {
72+
for (window, focus) in focused_windows.iter() {
7873
if !focus.focused() {
7974
continue;
8075
}
8176

8277
if input.just_pressed(KeyCode::Escape) {
83-
window_closed.send(WindowClosed { window: entity });
78+
commands.entity(window).remove::<Window>();
8479
}
8580
}
8681
}

crates/bevy_winit/src/lib.rs

Lines changed: 8 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,9 @@ use core::panic;
99

1010
use bevy_ecs::system::{SystemParam, SystemState};
1111
use system::{
12-
create_window_system, update_cursor, update_cursor_position, update_resize_constraints,
13-
update_resolution, update_title, update_window_mode, update_window_position,
14-
update_window_state, window_destroyed,
12+
create_window, despawn_window, update_cursor, update_cursor_position,
13+
update_resize_constraints, update_resolution, update_title, update_window_mode,
14+
update_window_position, update_window_state,
1515
};
1616

1717
pub use winit_config::*;
@@ -67,7 +67,7 @@ impl Plugin for WinitPlugin {
6767
.with_system(update_cursor_position)
6868
.with_system(update_resize_constraints),
6969
)
70-
.add_system_to_stage(CoreStage::Last, window_destroyed);
70+
.add_system_to_stage(CoreStage::PostUpdate, despawn_window.after(ModifiesWindows));
7171

7272
#[cfg(target_arch = "wasm32")]
7373
app.add_plugin(web_resize::CanvasParentResizePlugin);
@@ -86,7 +86,7 @@ impl Plugin for WinitPlugin {
8686
// Here we need to create a winit-window and give it a WindowHandle which the renderer can use.
8787
// It needs to be spawned before the start of the startup-stage, so we cannot use a regular system.
8888
// Instead we need to create the window and spawn it using direct world access
89-
create_window_system(commands, &**event_loop, new_windows, winit_windows);
89+
create_window(commands, &**event_loop, new_windows, winit_windows);
9090
}
9191

9292
system_state.apply(&mut app.world);
@@ -199,18 +199,13 @@ impl Default for WinitPersistentState {
199199
}
200200
}
201201

202-
// TODO: Refactor this to work with new pattern
203202
pub fn winit_runner(mut app: App) {
204-
// TODO: Understand what removing and adding this does
203+
// We remove this so that we have ownership over it.
205204
let mut event_loop = app
206205
.world
207206
.remove_non_send_resource::<EventLoop<()>>()
208207
.unwrap();
209-
// let mut create_window_event_reader = app
210-
// .world
211-
// .remove_resource::<WinitCreateWindowReader>()
212-
// .unwrap()
213-
// .0;
208+
214209
let mut app_exit_event_reader = ManualEventReader::<AppExit>::default();
215210
let mut redraw_event_reader = ManualEventReader::<RequestRedraw>::default();
216211
let mut winit_state = WinitPersistentState::default();
@@ -600,7 +595,7 @@ pub fn winit_runner(mut app: App) {
600595
create_window_system_state.get_mut(&mut app.world);
601596

602597
// Responsible for creating new windows
603-
create_window_system(commands, event_loop, new_windows, winit_windows);
598+
create_window(commands, event_loop, new_windows, winit_windows);
604599

605600
let update = if winit_state.active {
606601
// True if _any_ windows are currently being focused

crates/bevy_winit/src/system.rs

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
use bevy_ecs::{
2-
entity::Entity,
3-
event::EventReader,
2+
entity::{Entities, Entity},
3+
event::EventWriter,
44
prelude::{Added, Changed, With},
5-
system::{Commands, NonSendMut, Query, Res},
5+
system::{Commands, NonSendMut, Query, RemovedComponents, Res},
66
};
77
use bevy_utils::tracing::{error, info};
88
use bevy_window::{
@@ -22,7 +22,7 @@ use crate::{converters, get_best_videomode, get_fitting_videomode, WinitWindows}
2222
/// to an entity.
2323
///
2424
/// This will default any necessary components if they are not already added.
25-
pub fn create_window_system(
25+
pub fn create_window(
2626
mut commands: Commands,
2727
event_loop: &EventLoopWindowTarget<()>,
2828
created_windows: Query<(Entity, WindowComponents), Added<Window>>,
@@ -58,21 +58,28 @@ pub fn create_window_system(
5858
}
5959
}
6060

61-
pub fn window_destroyed(
61+
pub fn despawn_window(
6262
mut commands: Commands,
63+
entities: &Entities,
6364
primary: Option<Res<PrimaryWindow>>,
64-
mut closed: EventReader<WindowClosed>,
65+
closed: RemovedComponents<Window>,
66+
mut close_events: EventWriter<WindowClosed>,
6567
mut winit_windows: NonSendMut<WinitWindows>,
6668
) {
67-
for event in closed.iter() {
68-
winit_windows.remove_window(event.window);
69+
for window in closed.iter() {
70+
winit_windows.remove_window(window);
71+
72+
if entities.contains(window) {
73+
commands.entity(window).despawn();
74+
}
6975

70-
commands.entity(event.window).despawn();
7176
if let Some(ref primary) = primary {
72-
if primary.window == event.window {
77+
if primary.window == window {
7378
commands.remove_resource::<PrimaryWindow>();
7479
}
7580
}
81+
82+
close_events.send(WindowClosed { window });
7683
}
7784
}
7885

crates/bevy_winit/src/winit_windows.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,8 +119,9 @@ impl WinitWindows {
119119

120120
winit_window.set_cursor_visible(components.cursor.visible());
121121

122+
// I don't think we can do this immediately with some platforms.
122123
if components.state.minimized() {
123-
winit_window.set_minimized(true);
124+
//winit_window.set_minimized(true);
124125
}
125126

126127
self.window_id_to_winit.insert(entity, winit_window.id());

examples/window/multiple_windows.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use bevy::{
88

99
fn main() {
1010
App::new()
11-
// Primary window gets spawned as a result of `DefaultPlugins`
11+
// Primary window gets spawned by `DefaultPlugins`
1212
.add_plugins(DefaultPlugins)
1313
// A window bundle inserted as a resource acts as the descriptor
1414
// for a primary window.
@@ -50,6 +50,7 @@ fn setup_extra_windows(mut commands: Commands) {
5050
let second_window_id = commands
5151
.spawn_bundle(WindowBundle {
5252
title: WindowTitle::new("Second window"),
53+
// A window can start minimized.
5354
state: WindowState::Minimized,
5455
..Default::default()
5556
})
@@ -68,6 +69,7 @@ fn setup_extra_windows(mut commands: Commands) {
6869
let third_window_id = commands
6970
.spawn_bundle(WindowBundle {
7071
title: WindowTitle::new("Third window"),
72+
// ... or start maximized.
7173
state: WindowState::Maximized,
7274
..Default::default()
7375
})

examples/window/transparent_window.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ fn main() {
1515
.insert_resource(ClearColor(Color::NONE))
1616
.insert_resource(WindowBundle {
1717
// Setting `transparent` allows the `ClearColor`'s alpha value to take effect
18-
transparency: WindowTransaprency::Transparent,
18+
transparency: WindowTransparency::Transparent,
1919
// Disabling window decorations to make it feel more like a widget than a window
2020
decorations: WindowDecorations::Undecorated,
2121
..default()

0 commit comments

Comments
 (0)