From 2ae6ab7e774742e8fd7ba00cb29c2cc82f036fe2 Mon Sep 17 00:00:00 2001 From: atlas dostal Date: Mon, 22 Jan 2024 18:56:30 -0800 Subject: [PATCH 01/14] Rename WindowMoved.entity to window --- crates/bevy_window/src/event.rs | 2 +- crates/bevy_winit/src/lib.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/bevy_window/src/event.rs b/crates/bevy_window/src/event.rs index 28e8e19cda3f3..30402b84db261 100644 --- a/crates/bevy_window/src/event.rs +++ b/crates/bevy_window/src/event.rs @@ -332,7 +332,7 @@ pub enum FileDragAndDrop { )] pub struct WindowMoved { /// Window that moved. - pub entity: Entity, + pub window: Entity, /// Where the window moved to in physical pixels. pub position: IVec2, } diff --git a/crates/bevy_winit/src/lib.rs b/crates/bevy_winit/src/lib.rs index dc1861a38f99a..232b667075a1c 100644 --- a/crates/bevy_winit/src/lib.rs +++ b/crates/bevy_winit/src/lib.rs @@ -662,7 +662,7 @@ pub fn winit_runner(mut app: App) { let position = ivec2(position.x, position.y); window.position.set(position); event_writers.window_moved.send(WindowMoved { - entity: window_entity, + window: window_entity, position, }); } From 70f33dd53ee27ed2c3095d0b520b0d8b2b0bceb8 Mon Sep 17 00:00:00 2001 From: atlas dostal Date: Mon, 22 Jan 2024 19:47:39 -0800 Subject: [PATCH 02/14] Refactor create_window SystemState --- crates/bevy_winit/src/lib.rs | 115 +++++--------------------------- crates/bevy_winit/src/system.rs | 28 ++++---- 2 files changed, 34 insertions(+), 109 deletions(-) diff --git a/crates/bevy_winit/src/lib.rs b/crates/bevy_winit/src/lib.rs index 232b667075a1c..917545533afba 100644 --- a/crates/bevy_winit/src/lib.rs +++ b/crates/bevy_winit/src/lib.rs @@ -154,62 +154,9 @@ impl Plugin for WinitPlugin { // Otherwise, we want to create a window before `bevy_render` initializes the renderer // so that we have a surface to use as a hint. This improves compatibility with `wgpu` // backends, especially WASM/WebGL2. - #[cfg(not(target_arch = "wasm32"))] - let mut create_window_system_state: SystemState<( - Commands, - Query<(Entity, &mut Window)>, - EventWriter, - NonSendMut, - NonSendMut, - ResMut, - ResMut, - )> = SystemState::from_world(&mut app.world); - - #[cfg(target_arch = "wasm32")] - let mut create_window_system_state: SystemState<( - Commands, - Query<(Entity, &mut Window)>, - EventWriter, - NonSendMut, - NonSendMut, - ResMut, - ResMut, - )> = SystemState::from_world(&mut app.world); - - #[cfg(not(target_arch = "wasm32"))] - let ( - commands, - mut windows, - event_writer, - winit_windows, - adapters, - handlers, - accessibility_requested, - ) = create_window_system_state.get_mut(&mut app.world); - - #[cfg(target_arch = "wasm32")] - let ( - commands, - mut windows, - event_writer, - winit_windows, - adapters, - handlers, - accessibility_requested, - ) = create_window_system_state.get_mut(&mut app.world); - - create_windows( - &event_loop, - commands, - windows.iter_mut(), - event_writer, - winit_windows, - adapters, - handlers, - accessibility_requested, - ); - - create_window_system_state.apply(&mut app.world); + let mut create_window = SystemState::::from_world(&mut app.world); + create_windows(&event_loop, create_window.get_mut(&mut app.world)); + create_window.apply(&mut app.world); } // `winit`'s windows are bound to the event loop that created them, so the event loop must @@ -311,6 +258,16 @@ impl Default for WinitAppRunnerState { } } +type CreateWindowParams<'w, 's, F = ()> = ( + Commands<'w, 's>, + Query<'w, 's, (Entity, &'static mut Window), F>, + EventWriter<'w, WindowCreated>, + NonSendMut<'w, WinitWindows>, + NonSendMut<'w, AccessKitAdapters>, + ResMut<'w, WinitActionHandlers>, + Res<'w, AccessibilityRequested>, +); + /// The default [`App::runner`] for the [`WinitPlugin`] plugin. /// /// Overriding the app's [runner](bevy_app::App::runner) while using `WinitPlugin` will bypass the @@ -345,16 +302,8 @@ pub fn winit_runner(mut app: App) { NonSend, )> = SystemState::new(&mut app.world); - let mut create_window_system_state: SystemState<( - Commands, - Query<(Entity, &mut Window), Added>, - EventWriter, - NonSendMut, - NonSendMut, - ResMut, - ResMut, - )> = SystemState::from_world(&mut app.world); - + let mut create_window_system_state = + SystemState::>>::from_world(&mut app.world); // setup up the event loop let event_handler = move |event: Event<()>, event_loop: &EventLoopWindowTarget<()>| { #[cfg(feature = "trace")] @@ -845,15 +794,7 @@ fn run_app_update_if_should( app: &mut App, focused_windows_state: &mut SystemState<(Res, Query<&Window>)>, event_loop: &EventLoopWindowTarget<()>, - create_window_system_state: &mut SystemState<( - Commands, - Query<(Entity, &mut Window), Added>, - EventWriter, - NonSendMut, - NonSendMut, - ResMut, - ResMut, - )>, + create_window: &mut SystemState>>, app_exit_event_reader: &mut ManualEventReader, redraw_event_reader: &mut ManualEventReader, ) { @@ -918,28 +859,8 @@ fn run_app_update_if_should( // create any new windows // (even if app did not update, some may have been created by plugin setup) - let ( - commands, - mut windows, - event_writer, - winit_windows, - adapters, - handlers, - accessibility_requested, - ) = create_window_system_state.get_mut(&mut app.world); - - create_windows( - event_loop, - commands, - windows.iter_mut(), - event_writer, - winit_windows, - adapters, - handlers, - accessibility_requested, - ); - - create_window_system_state.apply(&mut app.world); + create_windows(event_loop, create_window.get_mut(&mut app.world)); + create_window.apply(&mut app.world); } fn react_to_resize( diff --git a/crates/bevy_winit/src/system.rs b/crates/bevy_winit/src/system.rs index 45557b3639a4b..2a7c11ea878bb 100644 --- a/crates/bevy_winit/src/system.rs +++ b/crates/bevy_winit/src/system.rs @@ -3,8 +3,9 @@ use bevy_ecs::{ entity::Entity, event::EventWriter, prelude::{Changed, Component, Resource}, + query::QueryFilter, removal_detection::RemovedComponents, - system::{Commands, NonSendMut, Query, ResMut}, + system::{Commands, NonSendMut, Query, ResMut, SystemParamItem}, world::Mut, }; use bevy_utils::{ @@ -25,7 +26,8 @@ use crate::{ self, convert_enabled_buttons, convert_window_level, convert_window_theme, convert_winit_theme, }, - get_best_videomode, get_fitting_videomode, WindowAndInputEventWriters, WinitWindows, + get_best_videomode, get_fitting_videomode, CreateWindowParams, WindowAndInputEventWriters, + WinitWindows, }; /// Creates new windows on the [`winit`] backend for each entity with a newly-added @@ -34,17 +36,19 @@ use crate::{ /// If any of these entities are missing required components, those will be added with their /// default values. #[allow(clippy::too_many_arguments)] -pub(crate) fn create_windows<'a>( +pub(crate) fn create_windows( event_loop: &EventLoopWindowTarget<()>, - mut commands: Commands, - created_windows: impl Iterator)>, - mut event_writer: EventWriter, - mut winit_windows: NonSendMut, - mut adapters: NonSendMut, - mut handlers: ResMut, - accessibility_requested: ResMut, + ( + mut commands, + mut created_windows, + mut window_created_events, + mut winit_windows, + mut adapters, + mut handlers, + accessibility_requested, + ): SystemParamItem>, ) { - for (entity, mut window) in created_windows { + for (entity, mut window) in &mut created_windows { if winit_windows.get_window(entity).is_some() { continue; } @@ -81,7 +85,7 @@ pub(crate) fn create_windows<'a>( window: window.clone(), }); - event_writer.send(WindowCreated { window: entity }); + window_created_events.send(WindowCreated { window: entity }); } } From 149fe2da650276ead8b204e2870d1f6112dd94af Mon Sep 17 00:00:00 2001 From: atlas dostal Date: Mon, 22 Jan 2024 19:51:59 -0800 Subject: [PATCH 03/14] Remove unused imports --- crates/bevy_winit/src/system.rs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/crates/bevy_winit/src/system.rs b/crates/bevy_winit/src/system.rs index 2a7c11ea878bb..93bf098fc3048 100644 --- a/crates/bevy_winit/src/system.rs +++ b/crates/bevy_winit/src/system.rs @@ -1,12 +1,10 @@ -use bevy_a11y::AccessibilityRequested; use bevy_ecs::{ entity::Entity, event::EventWriter, prelude::{Changed, Component, Resource}, query::QueryFilter, removal_detection::RemovedComponents, - system::{Commands, NonSendMut, Query, ResMut, SystemParamItem}, - world::Mut, + system::{NonSendMut, Query, SystemParamItem}, }; use bevy_utils::{ tracing::{error, info, warn}, @@ -21,7 +19,6 @@ use winit::{ }; use crate::{ - accessibility::{AccessKitAdapters, WinitActionHandlers}, converters::{ self, convert_enabled_buttons, convert_window_level, convert_window_theme, convert_winit_theme, From 351bdfe080c0d84333d59cca19c021bbd3b7f8b6 Mon Sep 17 00:00:00 2001 From: atlas dostal Date: Mon, 22 Jan 2024 19:55:48 -0800 Subject: [PATCH 04/14] Combine nested conditions --- crates/bevy_winit/src/lib.rs | 29 +++++++++++++---------------- 1 file changed, 13 insertions(+), 16 deletions(-) diff --git a/crates/bevy_winit/src/lib.rs b/crates/bevy_winit/src/lib.rs index 917545533afba..47026a3e8c2f1 100644 --- a/crates/bevy_winit/src/lib.rs +++ b/crates/bevy_winit/src/lib.rs @@ -86,24 +86,21 @@ impl Plugin for WinitPlugin { // This is needed because the features checked in the inner // block might be enabled on other platforms than linux. - #[cfg(target_os = "linux")] + #[cfg(all(target_os = "linux", feature = "x11"))] { - #[cfg(feature = "x11")] - { - use winit::platform::x11::EventLoopBuilderExtX11; - - // This allows a Bevy app to be started and ran outside of the main thread. - // A use case for this is to allow external applications to spawn a thread - // which runs a Bevy app without requiring the Bevy app to need to reside on - // the main thread, which can be problematic. - event_loop_builder.with_any_thread(self.run_on_any_thread); - } + use winit::platform::x11::EventLoopBuilderExtX11; - #[cfg(feature = "wayland")] - { - use winit::platform::wayland::EventLoopBuilderExtWayland; - event_loop_builder.with_any_thread(self.run_on_any_thread); - } + // This allows a Bevy app to be started and ran outside of the main thread. + // A use case for this is to allow external applications to spawn a thread + // which runs a Bevy app without requiring the Bevy app to need to reside on + // the main thread, which can be problematic. + event_loop_builder.with_any_thread(self.run_on_any_thread); + } + + #[cfg(all(target_os = "linux", feature = "wayland"))] + { + use winit::platform::wayland::EventLoopBuilderExtWayland; + event_loop_builder.with_any_thread(self.run_on_any_thread); } #[cfg(target_os = "windows")] From 5a65d696bcb8ea473035c5688c16f9e4db10b60a Mon Sep 17 00:00:00 2001 From: atlas dostal Date: Mon, 22 Jan 2024 19:56:16 -0800 Subject: [PATCH 05/14] Extract message to variable to collapse method chain --- crates/bevy_winit/src/lib.rs | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/crates/bevy_winit/src/lib.rs b/crates/bevy_winit/src/lib.rs index 47026a3e8c2f1..09d7f77196160 100644 --- a/crates/bevy_winit/src/lib.rs +++ b/crates/bevy_winit/src/lib.rs @@ -112,12 +112,8 @@ impl Plugin for WinitPlugin { #[cfg(target_os = "android")] { use winit::platform::android::EventLoopBuilderExtAndroid; - event_loop_builder.with_android_app( - ANDROID_APP - .get() - .expect("Bevy must be setup with the #[bevy_main] macro on Android") - .clone(), - ); + let msg = "Bevy must be setup with the #[bevy_main] macro on Android"; + event_loop_builder.with_android_app(ANDROID_APP.get().expect(msg).clone()); } app.init_non_send_resource::() From 468959d222e76829c8717bbf4c1bdceb2eb54c6b Mon Sep 17 00:00:00 2001 From: atlas dostal Date: Mon, 22 Jan 2024 20:06:02 -0800 Subject: [PATCH 06/14] Refactor create_window SystemState android --- crates/bevy_winit/src/lib.rs | 34 ++-------------------------------- 1 file changed, 2 insertions(+), 32 deletions(-) diff --git a/crates/bevy_winit/src/lib.rs b/crates/bevy_winit/src/lib.rs index 09d7f77196160..a0d3d91f1b5f3 100644 --- a/crates/bevy_winit/src/lib.rs +++ b/crates/bevy_winit/src/lib.rs @@ -685,38 +685,8 @@ pub fn winit_runner(mut app: App) { #[cfg(any(target_os = "android", target_os = "ios", target_os = "macos"))] { if runner_state.active == ActiveState::NotYetStarted { - let mut create_window_system_state: SystemState<( - Commands, - Query<(Entity, &mut Window)>, - EventWriter, - NonSendMut, - NonSendMut, - ResMut, - ResMut, - )> = SystemState::from_world(&mut app.world); - - let ( - commands, - mut windows, - event_writer, - winit_windows, - adapters, - handlers, - accessibility_requested, - ) = create_window_system_state.get_mut(&mut app.world); - - create_windows( - event_loop, - commands, - windows.iter_mut(), - event_writer, - winit_windows, - adapters, - handlers, - accessibility_requested, - ); - - create_window_system_state.apply(&mut app.world); + create_windows(event_loop, create_window.get_mut(&mut app.world)); + create_window.apply(&mut app.world); } } From 3031ac8c227ba0575e67051ab7e57a2a675f07ea Mon Sep 17 00:00:00 2001 From: atlas dostal Date: Mon, 22 Jan 2024 20:06:29 -0800 Subject: [PATCH 07/14] Fix comments --- crates/bevy_winit/src/lib.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/crates/bevy_winit/src/lib.rs b/crates/bevy_winit/src/lib.rs index a0d3d91f1b5f3..7d1ff9f57b449 100644 --- a/crates/bevy_winit/src/lib.rs +++ b/crates/bevy_winit/src/lib.rs @@ -84,8 +84,7 @@ impl Plugin for WinitPlugin { fn build(&self, app: &mut App) { let mut event_loop_builder = EventLoopBuilder::<()>::with_user_event(); - // This is needed because the features checked in the inner - // block might be enabled on other platforms than linux. + // linux check is needed because x11 might be enabled on other platforms. #[cfg(all(target_os = "linux", feature = "x11"))] { use winit::platform::x11::EventLoopBuilderExtX11; @@ -97,6 +96,7 @@ impl Plugin for WinitPlugin { event_loop_builder.with_any_thread(self.run_on_any_thread); } + // linux check is needed because wayland might be enabled on other platforms. #[cfg(all(target_os = "linux", feature = "wayland"))] { use winit::platform::wayland::EventLoopBuilderExtWayland; @@ -297,7 +297,7 @@ pub fn winit_runner(mut app: App) { let mut create_window_system_state = SystemState::>>::from_world(&mut app.world); - // setup up the event loop + // set up the event loop let event_handler = move |event: Event<()>, event_loop: &EventLoopWindowTarget<()>| { #[cfg(feature = "trace")] let _span = bevy_utils::tracing::info_span!("winit event_handler").entered(); From e58144ba6161a5c59883d322dde6389fab622510 Mon Sep 17 00:00:00 2001 From: atlas dostal Date: Mon, 22 Jan 2024 21:03:00 -0800 Subject: [PATCH 08/14] Refactor event loop --- crates/bevy_winit/src/lib.rs | 829 +++++++++++++++----------------- crates/bevy_winit/src/system.rs | 9 +- 2 files changed, 388 insertions(+), 450 deletions(-) diff --git a/crates/bevy_winit/src/lib.rs b/crates/bevy_winit/src/lib.rs index 7d1ff9f57b449..e8d9d2842b35f 100644 --- a/crates/bevy_winit/src/lib.rs +++ b/crates/bevy_winit/src/lib.rs @@ -12,20 +12,20 @@ mod system; mod winit_config; mod winit_windows; +use approx::relative_eq; use bevy_a11y::AccessibilityRequested; use bevy_utils::{Duration, Instant}; use system::{changed_windows, create_windows, despawn_windows, CachedWindow}; +use winit::dpi::{LogicalSize, PhysicalSize}; pub use winit_config::*; pub use winit_windows::*; use bevy_app::{App, AppExit, Last, Plugin, PluginsState}; use bevy_ecs::event::{Events, ManualEventReader}; use bevy_ecs::prelude::*; -use bevy_ecs::system::{SystemParam, SystemState}; +use bevy_ecs::system::SystemState; use bevy_input::{ - keyboard::KeyboardInput, mouse::{MouseButtonInput, MouseMotion, MouseScrollUnit, MouseWheel}, - touch::TouchInput, touchpad::{TouchpadMagnify, TouchpadRotate}, }; use bevy_math::{ivec2, DVec2, Vec2}; @@ -158,33 +158,13 @@ impl Plugin for WinitPlugin { } } -#[derive(SystemParam)] -struct WindowAndInputEventWriters<'w> { - // `winit` `WindowEvent`s - window_resized: EventWriter<'w, WindowResized>, - window_close_requested: EventWriter<'w, WindowCloseRequested>, - window_scale_factor_changed: EventWriter<'w, WindowScaleFactorChanged>, - window_backend_scale_factor_changed: EventWriter<'w, WindowBackendScaleFactorChanged>, - window_focused: EventWriter<'w, WindowFocused>, - window_occluded: EventWriter<'w, WindowOccluded>, - window_moved: EventWriter<'w, WindowMoved>, - window_theme_changed: EventWriter<'w, WindowThemeChanged>, - window_destroyed: EventWriter<'w, WindowDestroyed>, - lifetime: EventWriter<'w, ApplicationLifetime>, - keyboard_input: EventWriter<'w, KeyboardInput>, - character_input: EventWriter<'w, ReceivedCharacter>, - mouse_button_input: EventWriter<'w, MouseButtonInput>, - touchpad_magnify_input: EventWriter<'w, TouchpadMagnify>, - touchpad_rotate_input: EventWriter<'w, TouchpadRotate>, - mouse_wheel_input: EventWriter<'w, MouseWheel>, - touch_input: EventWriter<'w, TouchInput>, - ime_input: EventWriter<'w, Ime>, - file_drag_and_drop: EventWriter<'w, FileDragAndDrop>, - cursor_moved: EventWriter<'w, CursorMoved>, - cursor_entered: EventWriter<'w, CursorEntered>, - cursor_left: EventWriter<'w, CursorLeft>, - // `winit` `DeviceEvent`s - mouse_motion: EventWriter<'w, MouseMotion>, +trait AppSendEvent { + fn send_event(&mut self, event: E); +} +impl AppSendEvent for App { + fn send_event(&mut self, event: E) { + self.world.send_event(event); + } } /// Persistent state that is used to run the [`App`] according to the current @@ -289,466 +269,426 @@ pub fn winit_runner(mut app: App) { SystemState::new(&mut app.world); let mut event_writer_system_state: SystemState<( - WindowAndInputEventWriters, + EventWriter, NonSend, Query<(&mut Window, &mut CachedWindow)>, NonSend, )> = SystemState::new(&mut app.world); - let mut create_window_system_state = + let mut create_window = SystemState::>>::from_world(&mut app.world); // set up the event loop - let event_handler = move |event: Event<()>, event_loop: &EventLoopWindowTarget<()>| { - #[cfg(feature = "trace")] - let _span = bevy_utils::tracing::info_span!("winit event_handler").entered(); - - if app.plugins_state() != PluginsState::Cleaned { - if app.plugins_state() != PluginsState::Ready { - #[cfg(not(target_arch = "wasm32"))] - tick_global_task_pools_on_main_thread(); - } else { - app.finish(); - app.cleanup(); - } - runner_state.redraw_requested = true; + let event_handler = move |event, event_loop: &EventLoopWindowTarget<()>| { + handle_winit_event( + &mut app, + &mut app_exit_event_reader, + &mut runner_state, + &mut create_window, + &mut event_writer_system_state, + &mut focused_windows_state, + &mut redraw_event_reader, + event, + event_loop, + ); + }; - if let Some(app_exit_events) = app.world.get_resource::>() { - if app_exit_event_reader.read(app_exit_events).last().is_some() { - event_loop.exit(); - return; - } - } + trace!("starting winit event loop"); + // TODO(clean): the winit docs mention using `spawn` instead of `run` on WASM. + if let Err(err) = event_loop.run(event_handler) { + error!("winit event loop returned an error: {err}"); + } +} + +#[allow(clippy::too_many_arguments /* TODO: probs can reduce # of args */)] +fn handle_winit_event( + app: &mut App, + app_exit_event_reader: &mut ManualEventReader, + runner_state: &mut WinitAppRunnerState, + create_window: &mut SystemState>>, + event_writer_system_state: &mut SystemState<( + EventWriter, + NonSend, + Query<(&mut Window, &mut CachedWindow)>, + NonSend, + )>, + focused_windows_state: &mut SystemState<(Res, Query<&Window>)>, + redraw_event_reader: &mut ManualEventReader, + event: Event<()>, + event_loop: &EventLoopWindowTarget<()>, +) { + #[cfg(feature = "trace")] + let _span = bevy_utils::tracing::info_span!("winit event_handler").entered(); + + if app.plugins_state() != PluginsState::Cleaned { + if app.plugins_state() != PluginsState::Ready { + #[cfg(not(target_arch = "wasm32"))] + tick_global_task_pools_on_main_thread(); + } else { + app.finish(); + app.cleanup(); } + runner_state.redraw_requested = true; - match event { - Event::AboutToWait => { - let (config, windows) = focused_windows_state.get(&app.world); - let focused = windows.iter().any(|window| window.focused); - let mut should_update = match config.update_mode(focused) { - UpdateMode::Continuous => { - runner_state.redraw_requested - || runner_state.window_event_received - || runner_state.device_event_received - } - UpdateMode::Reactive { .. } => { - runner_state.wait_elapsed - || runner_state.redraw_requested - || runner_state.window_event_received - || runner_state.device_event_received - } - UpdateMode::ReactiveLowPower { .. } => { - runner_state.wait_elapsed - || runner_state.redraw_requested - || runner_state.window_event_received - } - }; + if let Some(app_exit_events) = app.world.get_resource::>() { + if app_exit_event_reader.read(app_exit_events).last().is_some() { + event_loop.exit(); + return; + } + } + } - // Ensure that an update is triggered on the first iterations for app initialization - if runner_state.startup_forced_updates > 0 { - runner_state.startup_forced_updates -= 1; - should_update = true; + match event { + Event::AboutToWait => { + let (config, windows) = focused_windows_state.get(&app.world); + let focused = windows.iter().any(|window| window.focused); + let mut should_update = match config.update_mode(focused) { + UpdateMode::Continuous => { + runner_state.redraw_requested + || runner_state.window_event_received + || runner_state.device_event_received } - - // Trigger one last update to enter suspended state - if runner_state.active == ActiveState::WillSuspend { - should_update = true; + UpdateMode::Reactive { .. } => { + runner_state.wait_elapsed + || runner_state.redraw_requested + || runner_state.window_event_received + || runner_state.device_event_received } - - if should_update { - let visible = windows.iter().any(|window| window.visible); - let (_, winit_windows, _, _) = - event_writer_system_state.get_mut(&mut app.world); - if visible && runner_state.active != ActiveState::WillSuspend { - for window in winit_windows.windows.values() { - window.request_redraw(); - } - } else { - // there are no windows, or they are not visible. - // Winit won't send events on some platforms, so trigger an update manually. - run_app_update_if_should( - &mut runner_state, - &mut app, - &mut focused_windows_state, - event_loop, - &mut create_window_system_state, - &mut app_exit_event_reader, - &mut redraw_event_reader, - ); - if runner_state.active != ActiveState::Suspended { - event_loop.set_control_flow(ControlFlow::Poll); - } - } + UpdateMode::ReactiveLowPower { .. } => { + runner_state.wait_elapsed + || runner_state.redraw_requested + || runner_state.window_event_received } + }; + + // Ensure that an update is triggered on the first iterations for app initialization + if runner_state.startup_forced_updates > 0 { + runner_state.startup_forced_updates -= 1; + should_update = true; } - Event::NewEvents(_) => { - if let Some(t) = runner_state.scheduled_update { - let now = Instant::now(); - let remaining = t.checked_duration_since(now).unwrap_or(Duration::ZERO); - runner_state.wait_elapsed = remaining.is_zero(); - } + + // Trigger one last update to enter suspended state + if runner_state.active == ActiveState::WillSuspend { + should_update = true; } - Event::WindowEvent { - event, window_id, .. - } => { - let (mut event_writers, winit_windows, mut windows, access_kit_adapters) = - event_writer_system_state.get_mut(&mut app.world); - - let Some(window_entity) = winit_windows.get_window_entity(window_id) else { - warn!( - "Skipped event {:?} for unknown winit Window Id {:?}", - event, window_id - ); - return; - }; - let Ok((mut window, _)) = windows.get_mut(window_entity) else { - warn!( - "Window {:?} is missing `Window` component, skipping event {:?}", - window_entity, event + if should_update { + let visible = windows.iter().any(|window| window.visible); + let (_, winit_windows, _, _) = event_writer_system_state.get_mut(&mut app.world); + if visible && runner_state.active != ActiveState::WillSuspend { + for window in winit_windows.windows.values() { + window.request_redraw(); + } + } else { + // there are no windows, or they are not visible. + // Winit won't send events on some platforms, so trigger an update manually. + run_app_update_if_should( + runner_state, + app, + focused_windows_state, + event_loop, + create_window, + app_exit_event_reader, + redraw_event_reader, ); - return; - }; - - // Allow AccessKit to respond to `WindowEvent`s before they reach - // the engine. - if let Some(adapter) = access_kit_adapters.get(&window_entity) { - if let Some(window) = winit_windows.get_window(window_entity) { - adapter.process_event(window, &event); + if runner_state.active != ActiveState::Suspended { + event_loop.set_control_flow(ControlFlow::Poll); } } + } + } + Event::NewEvents(_) => { + if let Some(t) = runner_state.scheduled_update { + let now = Instant::now(); + let remaining = t.checked_duration_since(now).unwrap_or(Duration::ZERO); + runner_state.wait_elapsed = remaining.is_zero(); + } + } + Event::WindowEvent { + event, window_id, .. + } => { + let (mut window_resized, winit_windows, mut windows, access_kit_adapters) = + event_writer_system_state.get_mut(&mut app.world); + + let Some(window) = winit_windows.get_window_entity(window_id) else { + warn!("Skipped event {event:?} for unknown winit Window Id {window_id:?}"); + return; + }; + + let Ok((mut win, _)) = windows.get_mut(window) else { + warn!("Window {window:?} is missing `Window` component, skipping event {event:?}"); + return; + }; + + // Allow AccessKit to respond to `WindowEvent`s before they reach + // the engine. + if let Some(adapter) = access_kit_adapters.get(&window) { + if let Some(winit_window) = winit_windows.get_window(window) { + adapter.process_event(winit_window, &event); + } + } - runner_state.window_event_received = true; + runner_state.window_event_received = true; - match event { - WindowEvent::Resized(size) => { - react_to_resize(&mut window, size, &mut event_writers, window_entity); - } - WindowEvent::CloseRequested => { - event_writers - .window_close_requested - .send(WindowCloseRequested { - window: window_entity, - }); - } - WindowEvent::KeyboardInput { ref event, .. } => { - if event.state.is_pressed() { - if let Some(char) = &event.text { - event_writers.character_input.send(ReceivedCharacter { - window: window_entity, - char: char.clone(), - }); - } + match event { + WindowEvent::Resized(size) => { + react_to_resize(&mut win, size, &mut window_resized, window); + } + WindowEvent::CloseRequested => app.send_event(WindowCloseRequested { window }), + WindowEvent::KeyboardInput { ref event, .. } => { + if event.state.is_pressed() { + if let Some(char) = &event.text { + let char = char.clone(); + app.send_event(ReceivedCharacter { window, char }); } - let keyboard_event = - converters::convert_keyboard_input(event, window_entity); - event_writers.keyboard_input.send(keyboard_event); } - WindowEvent::CursorMoved { position, .. } => { - let physical_position = DVec2::new(position.x, position.y); - window.set_physical_cursor_position(Some(physical_position)); - event_writers.cursor_moved.send(CursorMoved { - window: window_entity, - position: (physical_position / window.resolution.scale_factor() as f64) - .as_vec2(), - }); - } - WindowEvent::CursorEntered { .. } => { - event_writers.cursor_entered.send(CursorEntered { - window: window_entity, - }); - } - WindowEvent::CursorLeft { .. } => { - window.set_physical_cursor_position(None); - event_writers.cursor_left.send(CursorLeft { - window: window_entity, + app.send_event(converters::convert_keyboard_input(event, window)); + } + WindowEvent::CursorMoved { position, .. } => { + let physical_position = DVec2::new(position.x, position.y); + win.set_physical_cursor_position(Some(physical_position)); + let position = + (physical_position / win.resolution.scale_factor() as f64).as_vec2(); + app.send_event(CursorMoved { window, position }); + } + WindowEvent::CursorEntered { .. } => { + app.send_event(CursorEntered { window }); + } + WindowEvent::CursorLeft { .. } => { + win.set_physical_cursor_position(None); + app.send_event(CursorLeft { window }); + } + WindowEvent::MouseInput { state, button, .. } => { + app.send_event(MouseButtonInput { + button: converters::convert_mouse_button(button), + state: converters::convert_element_state(state), + window, + }); + } + WindowEvent::TouchpadMagnify { delta, .. } => { + app.send_event(TouchpadMagnify(delta as f32)); + } + WindowEvent::TouchpadRotate { delta, .. } => { + app.send_event(TouchpadRotate(delta)); + } + WindowEvent::MouseWheel { delta, .. } => match delta { + event::MouseScrollDelta::LineDelta(x, y) => { + app.send_event(MouseWheel { + unit: MouseScrollUnit::Line, + x, + y, + window, }); } - WindowEvent::MouseInput { state, button, .. } => { - event_writers.mouse_button_input.send(MouseButtonInput { - button: converters::convert_mouse_button(button), - state: converters::convert_element_state(state), - window: window_entity, + event::MouseScrollDelta::PixelDelta(p) => { + app.send_event(MouseWheel { + unit: MouseScrollUnit::Pixel, + x: p.x as f32, + y: p.y as f32, + window, }); } - WindowEvent::TouchpadMagnify { delta, .. } => { - event_writers - .touchpad_magnify_input - .send(TouchpadMagnify(delta as f32)); - } - WindowEvent::TouchpadRotate { delta, .. } => { - event_writers - .touchpad_rotate_input - .send(TouchpadRotate(delta)); - } - WindowEvent::MouseWheel { delta, .. } => match delta { - event::MouseScrollDelta::LineDelta(x, y) => { - event_writers.mouse_wheel_input.send(MouseWheel { - unit: MouseScrollUnit::Line, - x, - y, - window: window_entity, - }); - } - event::MouseScrollDelta::PixelDelta(p) => { - event_writers.mouse_wheel_input.send(MouseWheel { - unit: MouseScrollUnit::Pixel, - x: p.x as f32, - y: p.y as f32, - window: window_entity, - }); + }, + WindowEvent::Touch(touch) => { + let location = touch + .location + .to_logical(win.resolution.scale_factor() as f64); + app.send_event(converters::convert_touch_input(touch, location, window)); + } + WindowEvent::ScaleFactorChanged { + scale_factor, + mut inner_size_writer, + } => { + let prior_factor = win.resolution.scale_factor(); + win.resolution.set_scale_factor(scale_factor as f32); + // Note: this may be different from new_scale_factor if + // `scale_factor_override` is set to Some(thing) + let new_factor = win.resolution.scale_factor(); + + let mut new_inner_size = + PhysicalSize::new(win.physical_width(), win.physical_height()); + let scale_factor_override = win.resolution.scale_factor_override(); + if let Some(forced_factor) = scale_factor_override { + // This window is overriding the OS-suggested DPI, so its physical size + // should be set based on the overriding value. Its logical size already + // incorporates any resize constraints. + let maybe_new_inner_size = LogicalSize::new(win.width(), win.height()) + .to_physical::(forced_factor as f64); + if let Err(err) = inner_size_writer.request_inner_size(new_inner_size) { + warn!("Winit Failed to resize the window: {err}"); + } else { + new_inner_size = maybe_new_inner_size; } - }, - WindowEvent::Touch(touch) => { - let location = touch - .location - .to_logical(window.resolution.scale_factor() as f64); - event_writers - .touch_input - .send(converters::convert_touch_input( - touch, - location, - window_entity, - )); } - WindowEvent::ScaleFactorChanged { + let new_logical_width = new_inner_size.width as f32 / new_factor; + let new_logical_height = new_inner_size.height as f32 / new_factor; + + let width_equal = relative_eq!(win.width(), new_logical_width); + let height_equal = relative_eq!(win.height(), new_logical_height); + win.resolution + .set_physical_resolution(new_inner_size.width, new_inner_size.height); + + app.send_event(WindowBackendScaleFactorChanged { + window, scale_factor, - mut inner_size_writer, - } => { - event_writers.window_backend_scale_factor_changed.send( - WindowBackendScaleFactorChanged { - window: window_entity, - scale_factor, - }, - ); - - let prior_factor = window.resolution.scale_factor(); - window.resolution.set_scale_factor(scale_factor as f32); - let new_factor = window.resolution.scale_factor(); - - let mut new_inner_size = winit::dpi::PhysicalSize::new( - window.physical_width(), - window.physical_height(), - ); - if let Some(forced_factor) = window.resolution.scale_factor_override() { - // This window is overriding the OS-suggested DPI, so its physical size - // should be set based on the overriding value. Its logical size already - // incorporates any resize constraints. - let maybe_new_inner_size = - winit::dpi::LogicalSize::new(window.width(), window.height()) - .to_physical::(forced_factor as f64); - if let Err(err) = inner_size_writer.request_inner_size(new_inner_size) { - warn!("Winit Failed to resize the window: {err}"); - } else { - new_inner_size = maybe_new_inner_size; - } - } else if approx::relative_ne!(new_factor, prior_factor) { - event_writers.window_scale_factor_changed.send( - WindowScaleFactorChanged { - window: window_entity, - scale_factor, - }, - ); - } - let new_logical_width = new_inner_size.width as f32 / new_factor; - let new_logical_height = new_inner_size.height as f32 / new_factor; - if approx::relative_ne!(window.width(), new_logical_width) - || approx::relative_ne!(window.height(), new_logical_height) - { - event_writers.window_resized.send(WindowResized { - window: window_entity, - width: new_logical_width, - height: new_logical_height, - }); - } - window - .resolution - .set_physical_resolution(new_inner_size.width, new_inner_size.height); - } - WindowEvent::Focused(focused) => { - window.focused = focused; - event_writers.window_focused.send(WindowFocused { - window: window_entity, - focused, + }); + if scale_factor_override.is_none() && !relative_eq!(new_factor, prior_factor) { + app.send_event(WindowScaleFactorChanged { + window, + scale_factor, }); } - WindowEvent::Occluded(occluded) => { - event_writers.window_occluded.send(WindowOccluded { - window: window_entity, - occluded, + + if !width_equal || !height_equal { + app.send_event(WindowResized { + window, + width: new_logical_width, + height: new_logical_height, }); } - WindowEvent::DroppedFile(path_buf) => { - event_writers - .file_drag_and_drop - .send(FileDragAndDrop::DroppedFile { - window: window_entity, - path_buf, - }); - } - WindowEvent::HoveredFile(path_buf) => { - event_writers - .file_drag_and_drop - .send(FileDragAndDrop::HoveredFile { - window: window_entity, - path_buf, - }); - } - WindowEvent::HoveredFileCancelled => { - event_writers.file_drag_and_drop.send( - FileDragAndDrop::HoveredFileCanceled { - window: window_entity, - }, - ); - } - WindowEvent::Moved(position) => { - let position = ivec2(position.x, position.y); - window.position.set(position); - event_writers.window_moved.send(WindowMoved { - window: window_entity, - position, + } + WindowEvent::Focused(focused) => { + win.focused = focused; + app.send_event(WindowFocused { window, focused }); + } + WindowEvent::Occluded(occluded) => { + app.send_event(WindowOccluded { window, occluded }); + } + WindowEvent::DroppedFile(path_buf) => { + app.send_event(FileDragAndDrop::DroppedFile { window, path_buf }); + } + WindowEvent::HoveredFile(path_buf) => { + app.send_event(FileDragAndDrop::HoveredFile { window, path_buf }); + } + WindowEvent::HoveredFileCancelled => { + app.send_event(FileDragAndDrop::HoveredFileCanceled { window }); + } + WindowEvent::Moved(position) => { + let position = ivec2(position.x, position.y); + win.position.set(position); + app.send_event(WindowMoved { window, position }); + } + WindowEvent::Ime(event) => match event { + event::Ime::Preedit(value, cursor) => { + app.send_event(Ime::Preedit { + window, + value, + cursor, }); } - WindowEvent::Ime(event) => match event { - event::Ime::Preedit(value, cursor) => { - event_writers.ime_input.send(Ime::Preedit { - window: window_entity, - value, - cursor, - }); - } - event::Ime::Commit(value) => { - event_writers.ime_input.send(Ime::Commit { - window: window_entity, - value, - }); - } - event::Ime::Enabled => { - event_writers.ime_input.send(Ime::Enabled { - window: window_entity, - }); - } - event::Ime::Disabled => { - event_writers.ime_input.send(Ime::Disabled { - window: window_entity, - }); - } - }, - WindowEvent::ThemeChanged(theme) => { - event_writers.window_theme_changed.send(WindowThemeChanged { - window: window_entity, - theme: convert_winit_theme(theme), - }); + event::Ime::Commit(value) => { + app.send_event(Ime::Commit { window, value }); } - WindowEvent::Destroyed => { - event_writers.window_destroyed.send(WindowDestroyed { - window: window_entity, - }); + event::Ime::Enabled => { + app.send_event(Ime::Enabled { window }); } - WindowEvent::RedrawRequested => { - run_app_update_if_should( - &mut runner_state, - &mut app, - &mut focused_windows_state, - event_loop, - &mut create_window_system_state, - &mut app_exit_event_reader, - &mut redraw_event_reader, - ); + event::Ime::Disabled => { + app.send_event(Ime::Disabled { window }); } - _ => {} + }, + WindowEvent::ThemeChanged(theme) => { + app.send_event(WindowThemeChanged { + window, + theme: convert_winit_theme(theme), + }); } - - let mut windows = app.world.query::<(&mut Window, &mut CachedWindow)>(); - if let Ok((window, mut cache)) = windows.get_mut(&mut app.world, window_entity) { - if window.is_changed() { - cache.window = window.clone(); - } + WindowEvent::Destroyed => { + app.send_event(WindowDestroyed { window }); } + WindowEvent::RedrawRequested => { + run_app_update_if_should( + runner_state, + app, + focused_windows_state, + event_loop, + create_window, + app_exit_event_reader, + redraw_event_reader, + ); + } + _ => {} } - Event::DeviceEvent { event, .. } => { - runner_state.device_event_received = true; - if let DeviceEvent::MouseMotion { delta: (x, y) } = event { - let (mut event_writers, ..) = event_writer_system_state.get_mut(&mut app.world); - event_writers.mouse_motion.send(MouseMotion { - delta: Vec2::new(x as f32, y as f32), - }); + + let mut windows = app.world.query::<(&mut Window, &mut CachedWindow)>(); + if let Ok((window, mut cache)) = windows.get_mut(&mut app.world, window) { + if window.is_changed() { + cache.window = window.clone(); } } - Event::Suspended => { - let (mut event_writers, ..) = event_writer_system_state.get_mut(&mut app.world); - event_writers.lifetime.send(ApplicationLifetime::Suspended); - // Mark the state as `WillSuspend`. This will let the schedule run one last time - // before actually suspending to let the application react - runner_state.active = ActiveState::WillSuspend; + } + Event::DeviceEvent { event, .. } => { + runner_state.device_event_received = true; + if let DeviceEvent::MouseMotion { delta: (x, y) } = event { + app.send_event(MouseMotion { + delta: Vec2::new(x as f32, y as f32), + }); } - Event::Resumed => { - #[cfg(any(target_os = "android", target_os = "ios", target_os = "macos"))] - { - if runner_state.active == ActiveState::NotYetStarted { - create_windows(event_loop, create_window.get_mut(&mut app.world)); - create_window.apply(&mut app.world); - } + } + Event::Suspended => { + app.send_event(ApplicationLifetime::Suspended); + // Mark the state as `WillSuspend`. This will let the schedule run one last time + // before actually suspending to let the application react + runner_state.active = ActiveState::WillSuspend; + } + Event::Resumed => { + #[cfg(any(target_os = "android", target_os = "ios", target_os = "macos"))] + { + if runner_state.active == ActiveState::NotYetStarted { + create_windows(event_loop, create_window.get_mut(&mut app.world)); + create_window.apply(&mut app.world); } + } - let (mut event_writers, ..) = event_writer_system_state.get_mut(&mut app.world); - match runner_state.active { - ActiveState::NotYetStarted => { - event_writers.lifetime.send(ApplicationLifetime::Started); - } - _ => { - event_writers.lifetime.send(ApplicationLifetime::Resumed); - } + match runner_state.active { + ActiveState::NotYetStarted => { + app.send_event(ApplicationLifetime::Started); } - runner_state.active = ActiveState::Active; - runner_state.redraw_requested = true; - #[cfg(target_os = "android")] - { - // Get windows that are cached but without raw handles. Those window were already created, but got their - // handle wrapper removed when the app was suspended. - let mut query = app + _ => { + app.send_event(ApplicationLifetime::Resumed); + } + } + runner_state.active = ActiveState::Active; + runner_state.redraw_requested = true; + #[cfg(target_os = "android")] + { + // Get windows that are cached but without raw handles. Those window were already created, but got their + // handle wrapper removed when the app was suspended. + let mut query = app .world .query_filtered::<(Entity, &Window), (With, Without)>(); - if let Ok((entity, window)) = query.get_single(&app.world) { - use raw_window_handle::{HasRawDisplayHandle, HasRawWindowHandle}; - let window = window.clone(); - - let ( - _, - _, - _, - mut winit_windows, - mut adapters, - mut handlers, - accessibility_requested, - ) = create_window_system_state.get_mut(&mut app.world); - - let winit_window = winit_windows.create_window( - event_loop, - entity, - &window, - &mut adapters, - &mut handlers, - &accessibility_requested, - ); - - let wrapper = RawHandleWrapper { - window_handle: winit_window.raw_window_handle(), - display_handle: winit_window.raw_display_handle(), - }; - - app.world.entity_mut(entity).insert(wrapper); - } - event_loop.set_control_flow(ControlFlow::Wait); + if let Ok((entity, window)) = query.get_single(&app.world) { + use raw_window_handle::{HasRawDisplayHandle, HasRawWindowHandle}; + let window = window.clone(); + + let ( + _, + _, + _, + mut winit_windows, + mut adapters, + mut handlers, + accessibility_requested, + ) = create_window.get_mut(&mut app.world); + + let winit_window = winit_windows.create_window( + event_loop, + entity, + &window, + &mut adapters, + &mut handlers, + &accessibility_requested, + ); + + let wrapper = RawHandleWrapper { + window_handle: winit_window.raw_window_handle(), + display_handle: winit_window.raw_display_handle(), + }; + + app.world.entity_mut(entity).insert(wrapper); } + event_loop.set_control_flow(ControlFlow::Wait); } - _ => (), } - }; - - trace!("starting winit event loop"); - // TODO(clean): the winit docs mention using `spawn` instead of `run` on WASM. - if let Err(err) = event_loop.run(event_handler) { - error!("winit event loop returned an error: {err}"); + _ => (), } } @@ -827,18 +767,17 @@ fn run_app_update_if_should( } fn react_to_resize( - window: &mut Mut<'_, Window>, + win: &mut Mut<'_, Window>, size: winit::dpi::PhysicalSize, - event_writers: &mut WindowAndInputEventWriters<'_>, - window_entity: Entity, + window_resized: &mut EventWriter, + window: Entity, ) { - window - .resolution + win.resolution .set_physical_resolution(size.width, size.height); - event_writers.window_resized.send(WindowResized { - window: window_entity, - width: window.width(), - height: window.height(), + window_resized.send(WindowResized { + window, + width: win.width(), + height: win.height(), }); } diff --git a/crates/bevy_winit/src/system.rs b/crates/bevy_winit/src/system.rs index 93bf098fc3048..ff6ed5422b4f8 100644 --- a/crates/bevy_winit/src/system.rs +++ b/crates/bevy_winit/src/system.rs @@ -10,7 +10,7 @@ use bevy_utils::{ tracing::{error, info, warn}, EntityHashMap, }; -use bevy_window::{RawHandleWrapper, Window, WindowClosed, WindowCreated}; +use bevy_window::{RawHandleWrapper, Window, WindowClosed, WindowCreated, WindowResized}; use raw_window_handle::{HasRawDisplayHandle, HasRawWindowHandle}; use winit::{ @@ -23,8 +23,7 @@ use crate::{ self, convert_enabled_buttons, convert_window_level, convert_window_theme, convert_winit_theme, }, - get_best_videomode, get_fitting_videomode, CreateWindowParams, WindowAndInputEventWriters, - WinitWindows, + get_best_videomode, get_fitting_videomode, CreateWindowParams, WinitWindows, }; /// Creates new windows on the [`winit`] backend for each entity with a newly-added @@ -124,7 +123,7 @@ pub struct CachedWindow { pub(crate) fn changed_windows( mut changed_windows: Query<(Entity, &mut Window, &mut CachedWindow), Changed>, winit_windows: NonSendMut, - mut event_writers: WindowAndInputEventWriters<'_>, + mut window_resized: EventWriter, ) { for (entity, mut window, mut cache) in &mut changed_windows { if let Some(winit_window) = winit_windows.get_window(entity) { @@ -162,7 +161,7 @@ pub(crate) fn changed_windows( window.resolution.physical_height(), ); if let Some(size_now) = winit_window.request_inner_size(physical_size) { - crate::react_to_resize(&mut window, size_now, &mut event_writers, entity); + crate::react_to_resize(&mut window, size_now, &mut window_resized, entity); } } From 5f98852daee450c15cd1b1b3aa07896ea26ab544 Mon Sep 17 00:00:00 2001 From: atlas dostal Date: Mon, 22 Jan 2024 21:17:54 -0800 Subject: [PATCH 09/14] Fix dead code warning --- crates/bevy_winit/src/system.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/bevy_winit/src/system.rs b/crates/bevy_winit/src/system.rs index ff6ed5422b4f8..7027e712ad89e 100644 --- a/crates/bevy_winit/src/system.rs +++ b/crates/bevy_winit/src/system.rs @@ -87,7 +87,7 @@ pub(crate) fn create_windows( /// Cache for closing windows so we can get better debug information. #[derive(Debug, Clone, Resource)] -pub struct WindowTitleCache(EntityHashMap); +pub struct WindowTitleCache(#[allow(dead_code)] EntityHashMap); pub(crate) fn despawn_windows( mut closed: RemovedComponents, From a891dd332af811c3f292fe748c25afeae755ff2d Mon Sep 17 00:00:00 2001 From: atlas dostal Date: Mon, 22 Jan 2024 23:50:53 -0800 Subject: [PATCH 10/14] Use ellipsis to discard --- crates/bevy_winit/src/lib.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/crates/bevy_winit/src/lib.rs b/crates/bevy_winit/src/lib.rs index e8d9d2842b35f..3fa8d62670777 100644 --- a/crates/bevy_winit/src/lib.rs +++ b/crates/bevy_winit/src/lib.rs @@ -660,9 +660,7 @@ fn handle_winit_event( let window = window.clone(); let ( - _, - _, - _, + .., mut winit_windows, mut adapters, mut handlers, From 44811880fdac5daac5352f4bf627b51f53833122 Mon Sep 17 00:00:00 2001 From: atlas dostal Date: Mon, 22 Jan 2024 23:51:15 -0800 Subject: [PATCH 11/14] Collapse match --- crates/bevy_winit/src/lib.rs | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/crates/bevy_winit/src/lib.rs b/crates/bevy_winit/src/lib.rs index 3fa8d62670777..f72c5b607c273 100644 --- a/crates/bevy_winit/src/lib.rs +++ b/crates/bevy_winit/src/lib.rs @@ -639,12 +639,8 @@ fn handle_winit_event( } match runner_state.active { - ActiveState::NotYetStarted => { - app.send_event(ApplicationLifetime::Started); - } - _ => { - app.send_event(ApplicationLifetime::Resumed); - } + ActiveState::NotYetStarted => app.send_event(ApplicationLifetime::Started), + _ => app.send_event(ApplicationLifetime::Resumed), } runner_state.active = ActiveState::Active; runner_state.redraw_requested = true; From 2a07690d79bbd9ad3dd53ee5a2595f062af9f199 Mon Sep 17 00:00:00 2001 From: atlas dostal Date: Mon, 22 Jan 2024 23:52:26 -0800 Subject: [PATCH 12/14] Extract var to collapse --- crates/bevy_winit/src/lib.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/crates/bevy_winit/src/lib.rs b/crates/bevy_winit/src/lib.rs index f72c5b607c273..b6904f275187e 100644 --- a/crates/bevy_winit/src/lib.rs +++ b/crates/bevy_winit/src/lib.rs @@ -618,9 +618,8 @@ fn handle_winit_event( Event::DeviceEvent { event, .. } => { runner_state.device_event_received = true; if let DeviceEvent::MouseMotion { delta: (x, y) } = event { - app.send_event(MouseMotion { - delta: Vec2::new(x as f32, y as f32), - }); + let delta = Vec2::new(x as f32, y as f32); + app.send_event(MouseMotion { delta }); } } Event::Suspended => { From 0765bb19a7774104ebb1889febe0632fbd3179ed Mon Sep 17 00:00:00 2001 From: atlas dostal Date: Mon, 22 Jan 2024 23:53:57 -0800 Subject: [PATCH 13/14] Rename to window_component --- crates/bevy_winit/src/lib.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/crates/bevy_winit/src/lib.rs b/crates/bevy_winit/src/lib.rs index b6904f275187e..be28715f2bd62 100644 --- a/crates/bevy_winit/src/lib.rs +++ b/crates/bevy_winit/src/lib.rs @@ -609,9 +609,9 @@ fn handle_winit_event( } let mut windows = app.world.query::<(&mut Window, &mut CachedWindow)>(); - if let Ok((window, mut cache)) = windows.get_mut(&mut app.world, window) { - if window.is_changed() { - cache.window = window.clone(); + if let Ok((window_component, mut cache)) = windows.get_mut(&mut app.world, window) { + if window_component.is_changed() { + cache.window = window_component.clone(); } } } From 3b15c21780734d95e776b890e68f51c947603f2d Mon Sep 17 00:00:00 2001 From: atlas dostal Date: Tue, 23 Jan 2024 00:20:55 -0800 Subject: [PATCH 14/14] Remove unused WindowTitleCache --- crates/bevy_winit/src/system.rs | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/crates/bevy_winit/src/system.rs b/crates/bevy_winit/src/system.rs index 7027e712ad89e..69d2153b8c0ef 100644 --- a/crates/bevy_winit/src/system.rs +++ b/crates/bevy_winit/src/system.rs @@ -1,15 +1,12 @@ use bevy_ecs::{ entity::Entity, event::EventWriter, - prelude::{Changed, Component, Resource}, + prelude::{Changed, Component}, query::QueryFilter, removal_detection::RemovedComponents, system::{NonSendMut, Query, SystemParamItem}, }; -use bevy_utils::{ - tracing::{error, info, warn}, - EntityHashMap, -}; +use bevy_utils::tracing::{error, info, warn}; use bevy_window::{RawHandleWrapper, Window, WindowClosed, WindowCreated, WindowResized}; use raw_window_handle::{HasRawDisplayHandle, HasRawWindowHandle}; @@ -85,10 +82,6 @@ pub(crate) fn create_windows( } } -/// Cache for closing windows so we can get better debug information. -#[derive(Debug, Clone, Resource)] -pub struct WindowTitleCache(#[allow(dead_code)] EntityHashMap); - pub(crate) fn despawn_windows( mut closed: RemovedComponents, window_entities: Query<&Window>,