diff --git a/crates/bevy_window/src/lib.rs b/crates/bevy_window/src/lib.rs index 22e657cf038c0..c3fc8828be598 100644 --- a/crates/bevy_window/src/lib.rs +++ b/crates/bevy_window/src/lib.rs @@ -19,6 +19,7 @@ extern crate alloc; use alloc::sync::Arc; +use bevy_ecs::system::Commands; use bevy_platform::sync::Mutex; mod event; @@ -56,8 +57,7 @@ use bevy_app::prelude::*; impl Default for WindowPlugin { fn default() -> Self { WindowPlugin { - primary_window: Some(Window::default()), - primary_cursor_options: Some(CursorOptions::default()), + spawn_primary_window: true, exit_condition: ExitCondition::OnAllClosed, close_when_requested: true, } @@ -66,23 +66,28 @@ impl Default for WindowPlugin { /// A [`Plugin`] that defines an interface for windowing support in Bevy. pub struct WindowPlugin { - /// Settings for the primary window. + /// Whether or not to spawn a [`PrimaryWindow`] and its associated required components. + /// If you want to customize the primary window when it spawns, you can use an observer: /// - /// `Some(custom_window)` will spawn an entity with `custom_window` and [`PrimaryWindow`] as components. - /// `None` will not spawn a primary window. + /// ``` + /// # use bevy_window::{CursorOptions, PresentMode, PrimaryWindow, Window, PresentMode}; + /// # use bevy_ecs::prelude::*; + /// fn configure_window( + /// trigger: On, + /// mut window: Query<(&mut CursorOptions, &mut PresentMode)>, + /// ) { + /// // This unwrap is guaranteed to succeed because the queried components are required on any [`Window`] + /// let (mut cursor_options, mut present_mode) = window.get_mut(trigger.target()).unwrap(); + /// cursor_options.visible = false; + /// present_mode = PresentMode::AutoNoVsync; + /// } + /// ``` /// - /// Defaults to `Some(Window::default())`. + /// Defaults to `true`. /// /// Note that if there are no windows the App will exit (by default) due to /// [`exit_on_all_closed`]. - pub primary_window: Option, - - /// Settings for the cursor on the primary window. - /// - /// Defaults to `Some(CursorOptions::default())`. - /// - /// Has no effect if [`WindowPlugin::primary_window`] is `None`. - pub primary_cursor_options: Option, + pub spawn_primary_window: bool, /// Whether to exit the app when there are no open windows. /// @@ -129,15 +134,10 @@ impl Plugin for WindowPlugin { .add_event::() .add_event::(); - if let Some(primary_window) = &self.primary_window { - let mut entity_commands = app.world_mut().spawn(primary_window.clone()); - entity_commands.insert(( - PrimaryWindow, - RawHandleWrapperHolder(Arc::new(Mutex::new(None))), - )); - if let Some(primary_cursor_options) = &self.primary_cursor_options { - entity_commands.insert(primary_cursor_options.clone()); - } + if self.spawn_primary_window { + app.add_systems(PreStartup, |mut commands: Commands| { + commands.spawn(PrimaryWindow); + }); } match self.exit_condition { diff --git a/crates/bevy_window/src/raw_handle.rs b/crates/bevy_window/src/raw_handle.rs index 0943315055fb6..d0e562902dbc7 100644 --- a/crates/bevy_window/src/raw_handle.rs +++ b/crates/bevy_window/src/raw_handle.rs @@ -162,5 +162,5 @@ impl HasDisplayHandle for ThreadLockedRawWindowHandleWrapper { } /// Holder of the [`RawHandleWrapper`] with wrappers, to allow use in asynchronous context -#[derive(Debug, Clone, Component)] +#[derive(Debug, Clone, Component, Default)] pub struct RawHandleWrapperHolder(pub Arc>>); diff --git a/crates/bevy_window/src/window.rs b/crates/bevy_window/src/window.rs index 4fc039d7c7346..2faf397ff4661 100644 --- a/crates/bevy_window/src/window.rs +++ b/crates/bevy_window/src/window.rs @@ -20,7 +20,7 @@ use { #[cfg(all(feature = "serialize", feature = "bevy_reflect"))] use bevy_reflect::{ReflectDeserialize, ReflectSerialize}; -use crate::VideoMode; +use crate::{RawHandleWrapperHolder, VideoMode}; /// Default string used for the window title. /// @@ -53,6 +53,7 @@ static DEFAULT_WINDOW_TITLE: LazyLock = LazyLock::new(|| { derive(Reflect), reflect(Component, Debug, Default, PartialEq, Clone) )] +#[require(Window, RawHandleWrapperHolder)] pub struct PrimaryWindow; /// Reference to a [`Window`], whether it be a direct link to a specific entity or @@ -469,8 +470,8 @@ impl Default for Window { fn default() -> Self { Self { title: DEFAULT_WINDOW_TITLE.to_owned(), + present_mode: PresentMode::default(), name: None, - present_mode: Default::default(), mode: Default::default(), position: Default::default(), resolution: Default::default(), diff --git a/examples/3d/anisotropy.rs b/examples/3d/anisotropy.rs index edb0e92539564..e8134d2ad1306 100644 --- a/examples/3d/anisotropy.rs +++ b/examples/3d/anisotropy.rs @@ -81,13 +81,7 @@ impl Display for Scene { fn main() { App::new() .init_resource::() - .add_plugins(DefaultPlugins.set(WindowPlugin { - primary_window: Some(Window { - title: "Bevy Anisotropy Example".into(), - ..default() - }), - ..default() - })) + .add_plugins(DefaultPlugins) .add_systems(Startup, setup) .add_systems(Update, create_material_variants) .add_systems(Update, animate_light) diff --git a/examples/3d/clustered_decals.rs b/examples/3d/clustered_decals.rs index 60a445b483270..299c74389731a 100644 --- a/examples/3d/clustered_decals.rs +++ b/examples/3d/clustered_decals.rs @@ -122,13 +122,7 @@ impl MaterialExtension for CustomDecalExtension { /// Entry point. fn main() { App::new() - .add_plugins(DefaultPlugins.set(WindowPlugin { - primary_window: Some(Window { - title: "Bevy Clustered Decals Example".into(), - ..default() - }), - ..default() - })) + .add_plugins(DefaultPlugin) .add_plugins(MaterialPlugin::< ExtendedMaterial, >::default()) diff --git a/examples/3d/depth_of_field.rs b/examples/3d/depth_of_field.rs index 7658fdea07303..6a66492bbf0b5 100644 --- a/examples/3d/depth_of_field.rs +++ b/examples/3d/depth_of_field.rs @@ -52,13 +52,7 @@ struct AppSettings { fn main() { App::new() .init_resource::() - .add_plugins(DefaultPlugins.set(WindowPlugin { - primary_window: Some(Window { - title: "Bevy Depth of Field Example".to_string(), - ..default() - }), - ..default() - })) + .add_plugins(DefaultPlugins) .add_systems(Startup, setup) .add_systems(Update, tweak_scene) .add_systems( diff --git a/examples/3d/fog_volumes.rs b/examples/3d/fog_volumes.rs index 63804ee9dea82..bb6d6dc9e7b9d 100644 --- a/examples/3d/fog_volumes.rs +++ b/examples/3d/fog_volumes.rs @@ -15,13 +15,7 @@ use bevy::{ /// Entry point. fn main() { App::new() - .add_plugins(DefaultPlugins.set(WindowPlugin { - primary_window: Some(Window { - title: "Bevy Fog Volumes Example".into(), - ..default() - }), - ..default() - })) + .add_plugins(DefaultPlugins) .insert_resource(AmbientLight::NONE) .add_systems(Startup, setup) .add_systems(Update, rotate_camera) diff --git a/examples/3d/irradiance_volumes.rs b/examples/3d/irradiance_volumes.rs index 80373512db984..da4fd7fd69993 100644 --- a/examples/3d/irradiance_volumes.rs +++ b/examples/3d/irradiance_volumes.rs @@ -147,13 +147,7 @@ struct VoxelVisualizationIrradianceVolumeInfo { fn main() { // Create the example app. App::new() - .add_plugins(DefaultPlugins.set(WindowPlugin { - primary_window: Some(Window { - title: "Bevy Irradiance Volumes Example".into(), - ..default() - }), - ..default() - })) + .add_plugins(DefaultPlugins) .add_plugins(MaterialPlugin::::default()) .init_resource::() .init_resource::() diff --git a/examples/3d/light_textures.rs b/examples/3d/light_textures.rs index babaa9b8a88a3..fa6e89860b46e 100644 --- a/examples/3d/light_textures.rs +++ b/examples/3d/light_textures.rs @@ -105,13 +105,7 @@ struct HelpText; /// Entry point. fn main() { App::new() - .add_plugins(DefaultPlugins.set(WindowPlugin { - primary_window: Some(Window { - title: "Bevy Light Textures Example".into(), - ..default() - }), - ..default() - })) + .add_plugins(DefaultPlugins) .init_resource::() .add_event::>() .add_event::>() diff --git a/examples/3d/mixed_lighting.rs b/examples/3d/mixed_lighting.rs index ffff8652b4110..0a66e1c2b963a 100644 --- a/examples/3d/mixed_lighting.rs +++ b/examples/3d/mixed_lighting.rs @@ -116,13 +116,7 @@ const INITIAL_SPHERE_POSITION: Vec3 = vec3(0.0, 0.5233223, 0.0); fn main() { App::new() - .add_plugins(DefaultPlugins.set(WindowPlugin { - primary_window: Some(Window { - title: "Bevy Mixed Lighting Example".into(), - ..default() - }), - ..default() - })) + .add_plugins(DefaultPlugins) .add_plugins(MeshPickingPlugin) .insert_resource(AmbientLight { color: ClearColor::default().0, diff --git a/examples/3d/occlusion_culling.rs b/examples/3d/occlusion_culling.rs index 0783a28948254..28274ac6e9b9d 100644 --- a/examples/3d/occlusion_culling.rs +++ b/examples/3d/occlusion_culling.rs @@ -182,13 +182,6 @@ fn main() { App::new() .add_plugins( DefaultPlugins - .set(WindowPlugin { - primary_window: Some(Window { - title: "Bevy Occlusion Culling Example".into(), - ..default() - }), - ..default() - }) .set(RenderPlugin { debug_flags: render_debug_flags, ..default() diff --git a/examples/3d/pcss.rs b/examples/3d/pcss.rs index b2715f0b576ad..32d919c7bcc7b 100644 --- a/examples/3d/pcss.rs +++ b/examples/3d/pcss.rs @@ -113,13 +113,7 @@ enum AppSetting { fn main() { App::new() .init_resource::() - .add_plugins(DefaultPlugins.set(WindowPlugin { - primary_window: Some(Window { - title: "Bevy Percentage Closer Soft Shadows Example".into(), - ..default() - }), - ..default() - })) + .add_plugins(DefaultPlugins) .add_event::>() .add_systems(Startup, setup) .add_systems(Update, widgets::handle_ui_interactions::) diff --git a/examples/3d/post_processing.rs b/examples/3d/post_processing.rs index e539d94b3093c..e7e7217e6c82f 100644 --- a/examples/3d/post_processing.rs +++ b/examples/3d/post_processing.rs @@ -27,13 +27,7 @@ struct AppSettings { fn main() { App::new() .init_resource::() - .add_plugins(DefaultPlugins.set(WindowPlugin { - primary_window: Some(Window { - title: "Bevy Chromatic Aberration Example".into(), - ..default() - }), - ..default() - })) + .add_plugins(DefaultPlugins) .add_systems(Startup, setup) .add_systems(Update, handle_keyboard_input) .add_systems( diff --git a/examples/3d/scrolling_fog.rs b/examples/3d/scrolling_fog.rs index 7ec53e1fadc38..73ccf102b47ae 100644 --- a/examples/3d/scrolling_fog.rs +++ b/examples/3d/scrolling_fog.rs @@ -24,13 +24,7 @@ use bevy::{ /// Initializes the example. fn main() { App::new() - .add_plugins(DefaultPlugins.set(WindowPlugin { - primary_window: Some(Window { - title: "Bevy Scrolling Fog".into(), - ..default() - }), - ..default() - })) + .add_plugins(DefaultPlugins) .insert_resource(DirectionalLightShadowMap { size: 4096 }) .add_systems(Startup, setup) .add_systems(Update, scroll_fog) diff --git a/examples/3d/specular_tint.rs b/examples/3d/specular_tint.rs index 148f11ba5caf6..0b657d7ef3fe4 100644 --- a/examples/3d/specular_tint.rs +++ b/examples/3d/specular_tint.rs @@ -50,13 +50,7 @@ enum TintType { /// The entry point. fn main() { App::new() - .add_plugins(DefaultPlugins.set(WindowPlugin { - primary_window: Some(Window { - title: "Bevy Specular Tint Example".into(), - ..default() - }), - ..default() - })) + .add_plugins(DefaultPlugins) .init_resource::() .init_resource::() .insert_resource(AmbientLight { diff --git a/examples/3d/ssr.rs b/examples/3d/ssr.rs index 9deb9ee2c2eed..9716eb837331b 100644 --- a/examples/3d/ssr.rs +++ b/examples/3d/ssr.rs @@ -101,13 +101,7 @@ fn main() { App::new() .insert_resource(DefaultOpaqueRendererMethod::deferred()) .init_resource::() - .add_plugins(DefaultPlugins.set(WindowPlugin { - primary_window: Some(Window { - title: "Bevy Screen Space Reflections Example".into(), - ..default() - }), - ..default() - })) + .add_plugins(DefaultPlugins) .add_plugins(MaterialPlugin::>::default()) .add_systems(Startup, setup) .add_systems(Update, rotate_model) diff --git a/examples/3d/visibility_range.rs b/examples/3d/visibility_range.rs index 18cdcda0f1356..cced92842c10d 100644 --- a/examples/3d/visibility_range.rs +++ b/examples/3d/visibility_range.rs @@ -71,13 +71,7 @@ struct AppStatus { // Sets up the app. fn main() { App::new() - .add_plugins(DefaultPlugins.set(WindowPlugin { - primary_window: Some(Window { - title: "Bevy Visibility Range Example".into(), - ..default() - }), - ..default() - })) + .add_plugins(DefaultPlugins) .init_resource::() .add_systems(Startup, setup) .add_systems( diff --git a/examples/animation/animation_graph.rs b/examples/animation/animation_graph.rs index f33c3850df54a..62b9d54f3d76f 100644 --- a/examples/animation/animation_graph.rs +++ b/examples/animation/animation_graph.rs @@ -74,13 +74,7 @@ fn main() { let args = Args::from_args(&[], &[]).unwrap(); App::new() - .add_plugins(DefaultPlugins.set(WindowPlugin { - primary_window: Some(Window { - title: "Bevy Animation Graph Example".into(), - ..default() - }), - ..default() - })) + .add_plugins(DefaultPlugins) .add_systems(Startup, (setup_assets, setup_scene, setup_ui)) .add_systems(Update, init_animations) .add_systems( diff --git a/examples/animation/animation_masks.rs b/examples/animation/animation_masks.rs index 613e85eb2fce3..a340045d42d0c 100644 --- a/examples/animation/animation_masks.rs +++ b/examples/animation/animation_masks.rs @@ -94,13 +94,7 @@ struct MaskGroupState { // The application entry point. fn main() { App::new() - .add_plugins(DefaultPlugins.set(WindowPlugin { - primary_window: Some(Window { - title: "Bevy Animation Masks Example".into(), - ..default() - }), - ..default() - })) + .add_plugins(DefaultPlugins) .add_systems(Startup, (setup_scene, setup_ui)) .add_systems(Update, setup_animation_graph_once_loaded) .add_systems(Update, handle_button_toggles) diff --git a/examples/animation/morph_targets.rs b/examples/animation/morph_targets.rs index 258059bf55655..6c1268b383d7e 100644 --- a/examples/animation/morph_targets.rs +++ b/examples/animation/morph_targets.rs @@ -12,13 +12,7 @@ use std::f32::consts::PI; fn main() { App::new() - .add_plugins(DefaultPlugins.set(WindowPlugin { - primary_window: Some(Window { - title: "morph targets".to_string(), - ..default() - }), - ..default() - })) + .add_plugins(DefaultPlugins) .insert_resource(AmbientLight { brightness: 150.0, ..default() diff --git a/examples/app/headless_renderer.rs b/examples/app/headless_renderer.rs index 5d027b2115580..9b8460dc613fd 100644 --- a/examples/app/headless_renderer.rs +++ b/examples/app/headless_renderer.rs @@ -89,7 +89,7 @@ fn main() { // Not strictly necessary, as the inclusion of ScheduleRunnerPlugin below // replaces the bevy_winit app runner and so a window is never created. .set(WindowPlugin { - primary_window: None, + spawn_primary_window: false, // Don’t automatically exit due to having no windows. // Instead, the code in `update()` will explicitly produce an `AppExit` event. exit_condition: bevy::window::ExitCondition::DontExit, diff --git a/examples/app/return_after_run.rs b/examples/app/return_after_run.rs index 52d162af16fad..40529c829f6d9 100644 --- a/examples/app/return_after_run.rs +++ b/examples/app/return_after_run.rs @@ -5,23 +5,23 @@ //! - `App::run()` will never return on iOS and Web. //! - It is not possible to recreate a window after the event loop has been terminated. -use bevy::prelude::*; +use bevy::{prelude::*, window::PrimaryWindow}; fn main() { println!("Running Bevy App"); App::new() - .add_plugins(DefaultPlugins.set(WindowPlugin { - primary_window: Some(Window { - title: "Close the window to return to the main function".into(), - ..default() - }), - ..default() - })) + .add_plugins(DefaultPlugins) + .add_observer(configure_window) .add_systems(Update, system) .run(); println!("Bevy App has exited. We are back in our main function."); } +fn configure_window(trigger: On, mut window: Query<&mut Window>) { + let mut window = window.get_mut(trigger.target()).unwrap(); + window.title = "Close the window to return to the main function".into(); +} + fn system() { info!("Logging from Bevy App"); } diff --git a/examples/games/desk_toy.rs b/examples/games/desk_toy.rs index b5c638348eb86..ae860a07d0184 100644 --- a/examples/games/desk_toy.rs +++ b/examples/games/desk_toy.rs @@ -18,19 +18,11 @@ use bevy::window::CompositeAlphaMode; fn main() { App::new() - .add_plugins(DefaultPlugins.set(WindowPlugin { - primary_window: Some(Window { - title: "Bevy Desk Toy".into(), - transparent: true, - #[cfg(target_os = "macos")] - composite_alpha_mode: CompositeAlphaMode::PostMultiplied, - ..default() - }), - ..default() - })) + .add_plugins(DefaultPlugins) .insert_resource(ClearColor(WINDOW_CLEAR_COLOR)) .insert_resource(WindowTransparency(false)) .insert_resource(CursorWorldPos(None)) + .add_observer(configure_window) .add_systems(Startup, setup) .add_systems( Update, @@ -51,6 +43,16 @@ fn main() { .run(); } +fn configure_window(trigger: On, mut window: Query<&mut Window>) { + let mut window = window.get_mut(trigger.target()).unwrap(); + window.title = "Bevy Desk Toy".into(); + window.transparent = true; + #[cfg(target_os = "macos")] + { + window.composite_alpha_mode = CompositeAlphaMode::PostMultiplied; + } +} + /// Whether the window is transparent #[derive(Resource)] struct WindowTransparency(bool); diff --git a/examples/mobile/src/lib.rs b/examples/mobile/src/lib.rs index de831525528d8..8fa419e5d0d2c 100644 --- a/examples/mobile/src/lib.rs +++ b/examples/mobile/src/lib.rs @@ -15,35 +15,16 @@ use bevy::{ /// `main.rs`. pub fn main() { let mut app = App::new(); - app.add_plugins( - DefaultPlugins - .set(LogPlugin { - // This will show some log events from Bevy to the native logger. - level: Level::DEBUG, - filter: "wgpu=error,bevy_render=info,bevy_ecs=trace".to_string(), - ..Default::default() - }) - .set(WindowPlugin { - primary_window: Some(Window { - resizable: false, - mode: WindowMode::BorderlessFullscreen(MonitorSelection::Primary), - // on iOS, gestures must be enabled. - // This doesn't work on Android - recognize_rotation_gesture: true, - // Only has an effect on iOS - prefers_home_indicator_hidden: true, - // Only has an effect on iOS - prefers_status_bar_hidden: true, - // Only has an effect on iOS - preferred_screen_edges_deferring_system_gestures: ScreenEdge::Bottom, - ..default() - }), - ..default() - }), - ) + app.add_plugins(DefaultPlugins.set(LogPlugin { + // This will show some log events from Bevy to the native logger. + level: Level::DEBUG, + filter: "wgpu=error,bevy_render=info,bevy_ecs=trace".to_string(), + ..Default::default() + })) // Make the winit loop wait more aggressively when no user input is received // This can help reduce cpu usage on mobile devices .insert_resource(WinitSettings::mobile()) + .add_observer(configure_window) .add_systems(Startup, (setup_scene, setup_music)) .add_systems( Update, @@ -58,6 +39,22 @@ pub fn main() { .run(); } +fn configure_window(trigger: On, mut window: Query<&mut Window>) { + let mut window = window.get_mut(trigger.target()).unwrap(); + + window.resizable = false; + window.mode = WindowMode::BorderlessFullscreen(MonitorSelection::Primary); + // on iOS, gestures must be enabled. + // This doesn't work on Android + window.recognize_rotation_gesture = true; + // Only has an effect on iOS + window.prefers_home_indicator_hidden = true; + // Only has an effect on iOS + window.prefers_status_bar_hidden = true; + // Only has an effect on iOS + window.preferred_screen_edges_deferring_system_gestures = ScreenEdge::Bottom; +} + fn touch_camera( window: Query<&Window>, mut touches: EventReader, diff --git a/examples/shader/compute_shader_game_of_life.rs b/examples/shader/compute_shader_game_of_life.rs index aa10ccf4bfb6c..65ef532648719 100644 --- a/examples/shader/compute_shader_game_of_life.rs +++ b/examples/shader/compute_shader_game_of_life.rs @@ -14,6 +14,7 @@ use bevy::{ texture::GpuImage, Render, RenderApp, RenderSystems, }, + window::PrimaryWindow, }; use std::borrow::Cow; @@ -28,28 +29,25 @@ fn main() { App::new() .insert_resource(ClearColor(Color::BLACK)) .add_plugins(( - DefaultPlugins - .set(WindowPlugin { - primary_window: Some(Window { - resolution: ( - (SIZE.0 * DISPLAY_FACTOR) as f32, - (SIZE.1 * DISPLAY_FACTOR) as f32, - ) - .into(), - // uncomment for unthrottled FPS - // present_mode: bevy::window::PresentMode::AutoNoVsync, - ..default() - }), - ..default() - }) - .set(ImagePlugin::default_nearest()), + DefaultPlugins.set(ImagePlugin::default_nearest()), GameOfLifeComputePlugin, )) + .add_observer(configure_window) .add_systems(Startup, setup) .add_systems(Update, switch_textures) .run(); } +fn configure_window(trigger: On, mut window: Query<&mut Window>) { + let mut window = window.get_mut(trigger.target()).unwrap(); + window.resolution = ( + (SIZE.0 * DISPLAY_FACTOR) as f32, + (SIZE.1 * DISPLAY_FACTOR) as f32, + ) + .into(); + // Optional: set the present mode to AutoNoVsync for unthrottled FPS +} + fn setup(mut commands: Commands, mut images: ResMut>) { let mut image = Image::new_fill( Extent3d { diff --git a/examples/stress_tests/bevymark.rs b/examples/stress_tests/bevymark.rs index d44fbfa7d28fa..53423434ca83b 100644 --- a/examples/stress_tests/bevymark.rs +++ b/examples/stress_tests/bevymark.rs @@ -15,7 +15,7 @@ use bevy::{ render_resource::{Extent3d, TextureDimension, TextureFormat}, }, sprite::AlphaMode2d, - window::{PresentMode, WindowResolution}, + window::{PresentMode, PrimaryWindow, WindowResolution}, winit::{UpdateMode, WinitSettings}, }; use rand::{seq::SliceRandom, Rng, SeedableRng}; @@ -132,16 +132,7 @@ fn main() { App::new() .add_plugins(( - DefaultPlugins.set(WindowPlugin { - primary_window: Some(Window { - title: "BevyMark".into(), - resolution: WindowResolution::new(1920.0, 1080.0) - .with_scale_factor_override(1.0), - present_mode: PresentMode::AutoNoVsync, - ..default() - }), - ..default() - }), + DefaultPlugins, FrameTimeDiagnosticsPlugin::default(), LogDiagnosticsPlugin::default(), )) @@ -154,6 +145,7 @@ fn main() { count: 0, color: Color::WHITE, }) + .add_observer(configure_window) .add_systems(Startup, setup) .add_systems(FixedUpdate, scheduled_spawner) .add_systems( @@ -171,6 +163,13 @@ fn main() { .run(); } +fn configure_window(trigger: On, mut window: Query<&mut Window>) { + let mut window = window.get_mut(trigger.target()).unwrap(); + window.title = "BevyMark".to_string(); + window.resolution = WindowResolution::new(1920.0, 1080.0).with_scale_factor_override(1.0); + window.present_mode = PresentMode::AutoNoVsync; +} + #[derive(Resource)] struct BirdScheduled { waves: usize, diff --git a/examples/stress_tests/many_animated_sprites.rs b/examples/stress_tests/many_animated_sprites.rs index e34a03195ae27..c2e6bbd93a729 100644 --- a/examples/stress_tests/many_animated_sprites.rs +++ b/examples/stress_tests/many_animated_sprites.rs @@ -8,7 +8,7 @@ use std::time::Duration; use bevy::{ diagnostic::{FrameTimeDiagnosticsPlugin, LogDiagnosticsPlugin}, prelude::*, - window::{PresentMode, WindowResolution}, + window::{PresentMode, PrimaryWindow, WindowResolution}, winit::{UpdateMode, WinitSettings}, }; @@ -22,20 +22,13 @@ fn main() { .add_plugins(( LogDiagnosticsPlugin::default(), FrameTimeDiagnosticsPlugin::default(), - DefaultPlugins.set(WindowPlugin { - primary_window: Some(Window { - present_mode: PresentMode::AutoNoVsync, - resolution: WindowResolution::new(1920.0, 1080.0) - .with_scale_factor_override(1.0), - ..default() - }), - ..default() - }), + DefaultPlugins, )) .insert_resource(WinitSettings { focused_mode: UpdateMode::Continuous, unfocused_mode: UpdateMode::Continuous, }) + .add_observer(configure_window) .add_systems(Startup, setup) .add_systems( Update, @@ -48,6 +41,12 @@ fn main() { .run(); } +fn configure_window(trigger: On, mut window: Query<&mut Window>) { + let mut window = window.get_mut(trigger.target()).unwrap(); + window.resolution = WindowResolution::new(1920.0, 1080.0).with_scale_factor_override(1.0); + window.present_mode = PresentMode::AutoNoVsync; +} + fn setup( mut commands: Commands, assets: Res, diff --git a/examples/stress_tests/many_buttons.rs b/examples/stress_tests/many_buttons.rs index 5dc25ae65100b..4419328af5602 100644 --- a/examples/stress_tests/many_buttons.rs +++ b/examples/stress_tests/many_buttons.rs @@ -6,7 +6,7 @@ use bevy::{ diagnostic::{FrameTimeDiagnosticsPlugin, LogDiagnosticsPlugin}, prelude::*, text::TextColor, - window::{PresentMode, WindowResolution}, + window::{PresentMode, PrimaryWindow, WindowResolution}, winit::{UpdateMode, WinitSettings}, }; @@ -73,14 +73,7 @@ fn main() { let mut app = App::new(); app.add_plugins(( - DefaultPlugins.set(WindowPlugin { - primary_window: Some(Window { - present_mode: PresentMode::AutoNoVsync, - resolution: WindowResolution::new(1920.0, 1080.0).with_scale_factor_override(1.0), - ..default() - }), - ..default() - }), + DefaultPlugins, FrameTimeDiagnosticsPlugin::default(), LogDiagnosticsPlugin::default(), )) @@ -88,6 +81,7 @@ fn main() { focused_mode: UpdateMode::Continuous, unfocused_mode: UpdateMode::Continuous, }) + .add_observer(configure_window) .add_systems(Update, (button_system, set_text_colors_changed)); if !args.no_camera { @@ -129,6 +123,12 @@ fn main() { app.insert_resource(args).run(); } +fn configure_window(trigger: On, mut window: Query<&mut Window>) { + let mut window = window.get_mut(trigger.target()).unwrap(); + window.resolution = WindowResolution::new(1920.0, 1080.0).with_scale_factor_override(1.0); + window.present_mode = PresentMode::AutoNoVsync; +} + fn set_text_colors_changed(mut colors: Query<&mut TextColor>) { for mut text_color in colors.iter_mut() { text_color.set_changed(); diff --git a/examples/stress_tests/many_cameras_lights.rs b/examples/stress_tests/many_cameras_lights.rs index 3f9c4878e0229..1d25edae577d6 100644 --- a/examples/stress_tests/many_cameras_lights.rs +++ b/examples/stress_tests/many_cameras_lights.rs @@ -6,24 +6,24 @@ use bevy::{ math::ops::{cos, sin}, prelude::*, render::camera::Viewport, - window::{PresentMode, WindowResolution}, + window::{PresentMode, PrimaryWindow, WindowResolution}, }; fn main() { App::new() - .add_plugins(DefaultPlugins.set(WindowPlugin { - primary_window: Some(Window { - present_mode: PresentMode::AutoNoVsync, - resolution: WindowResolution::new(1920.0, 1080.0).with_scale_factor_override(1.0), - ..default() - }), - ..default() - })) + .add_plugins(DefaultPlugins) + .add_observer(configure_window) .add_systems(Startup, setup) .add_systems(Update, rotate_cameras) .run(); } +fn configure_window(trigger: On, mut window: Query<&mut Window>) { + let mut window = window.get_mut(trigger.target()).unwrap(); + window.resolution = WindowResolution::new(1920.0, 1080.0).with_scale_factor_override(1.0); + window.present_mode = PresentMode::AutoNoVsync; +} + const CAMERA_ROWS: usize = 4; const CAMERA_COLS: usize = 4; const NUM_LIGHTS: usize = 5; diff --git a/examples/stress_tests/many_cubes.rs b/examples/stress_tests/many_cubes.rs index f18821ee9675f..b4a5bbbeecbd8 100644 --- a/examples/stress_tests/many_cubes.rs +++ b/examples/stress_tests/many_cubes.rs @@ -22,7 +22,7 @@ use bevy::{ render_resource::{Extent3d, TextureDimension, TextureFormat}, view::{NoCpuCulling, NoFrustumCulling, NoIndirectDrawing}, }, - window::{PresentMode, WindowResolution}, + window::{PresentMode, PrimaryWindow, WindowResolution}, winit::{UpdateMode, WinitSettings}, }; use rand::{seq::SliceRandom, Rng, SeedableRng}; @@ -106,14 +106,7 @@ fn main() { let mut app = App::new(); app.add_plugins(( - DefaultPlugins.set(WindowPlugin { - primary_window: Some(Window { - present_mode: PresentMode::AutoNoVsync, - resolution: WindowResolution::new(1920.0, 1080.0).with_scale_factor_override(1.0), - ..default() - }), - ..default() - }), + DefaultPlugins, FrameTimeDiagnosticsPlugin::default(), LogDiagnosticsPlugin::default(), )) @@ -121,6 +114,7 @@ fn main() { focused_mode: UpdateMode::Continuous, unfocused_mode: UpdateMode::Continuous, }) + .add_observer(configure_window) .add_systems(Startup, setup) .add_systems(Update, (move_camera, print_mesh_count)); @@ -131,6 +125,12 @@ fn main() { app.insert_resource(args).run(); } +fn configure_window(trigger: On, mut window: Query<&mut Window>) { + let mut window = window.get_mut(trigger.target()).unwrap(); + window.resolution = WindowResolution::new(1920.0, 1080.0).with_scale_factor_override(1.0); + window.present_mode = PresentMode::AutoNoVsync; +} + const WIDTH: usize = 200; const HEIGHT: usize = 200; diff --git a/examples/stress_tests/many_foxes.rs b/examples/stress_tests/many_foxes.rs index c1284c9bd6c1f..e06390547841e 100644 --- a/examples/stress_tests/many_foxes.rs +++ b/examples/stress_tests/many_foxes.rs @@ -8,7 +8,7 @@ use bevy::{ diagnostic::{FrameTimeDiagnosticsPlugin, LogDiagnosticsPlugin}, pbr::CascadeShadowConfigBuilder, prelude::*, - window::{PresentMode, WindowResolution}, + window::{PresentMode, PrimaryWindow, WindowResolution}, winit::{UpdateMode, WinitSettings}, }; @@ -41,16 +41,7 @@ fn main() { App::new() .add_plugins(( - DefaultPlugins.set(WindowPlugin { - primary_window: Some(Window { - title: "🦊🦊🦊 Many Foxes! 🦊🦊🦊".into(), - present_mode: PresentMode::AutoNoVsync, - resolution: WindowResolution::new(1920.0, 1080.0) - .with_scale_factor_override(1.0), - ..default() - }), - ..default() - }), + DefaultPlugins, FrameTimeDiagnosticsPlugin::default(), LogDiagnosticsPlugin::default(), )) @@ -64,6 +55,7 @@ fn main() { moving: true, sync: args.sync, }) + .add_observer(configure_window) .add_systems(Startup, setup) .add_systems( Update, @@ -76,6 +68,13 @@ fn main() { .run(); } +fn configure_window(trigger: On, mut window: Query<&mut Window>) { + let mut window = window.get_mut(trigger.target()).unwrap(); + window.title = "🦊🦊🦊 Many Foxes! 🦊🦊🦊".to_string(); + window.resolution = WindowResolution::new(1920.0, 1080.0).with_scale_factor_override(1.0); + window.present_mode = PresentMode::AutoNoVsync; +} + #[derive(Resource)] struct Animations { node_indices: Vec, diff --git a/examples/stress_tests/many_gizmos.rs b/examples/stress_tests/many_gizmos.rs index b1ef579b24ea8..5e8cd4a7a5274 100644 --- a/examples/stress_tests/many_gizmos.rs +++ b/examples/stress_tests/many_gizmos.rs @@ -5,7 +5,7 @@ use std::f32::consts::TAU; use bevy::{ diagnostic::{Diagnostic, DiagnosticsStore, FrameTimeDiagnosticsPlugin, LogDiagnosticsPlugin}, prelude::*, - window::{PresentMode, WindowResolution}, + window::{PresentMode, PrimaryWindow, WindowResolution}, winit::{UpdateMode, WinitSettings}, }; @@ -14,15 +14,7 @@ const SYSTEM_COUNT: u32 = 10; fn main() { let mut app = App::new(); app.add_plugins(( - DefaultPlugins.set(WindowPlugin { - primary_window: Some(Window { - title: "Many Debug Lines".to_string(), - present_mode: PresentMode::AutoNoVsync, - resolution: WindowResolution::new(1920.0, 1080.0).with_scale_factor_override(1.0), - ..default() - }), - ..default() - }), + DefaultPlugins, FrameTimeDiagnosticsPlugin::default(), LogDiagnosticsPlugin::default(), )) @@ -34,6 +26,7 @@ fn main() { line_count: 50_000, fancy: false, }) + .add_observer(configure_window) .add_systems(Startup, setup) .add_systems(Update, (input, ui_system)); @@ -44,6 +37,13 @@ fn main() { app.run(); } +fn configure_window(trigger: On, mut window: Query<&mut Window>) { + let mut window = window.get_mut(trigger.target()).unwrap(); + window.title = "Many Debug Lines".to_string(); + window.resolution = WindowResolution::new(1920.0, 1080.0).with_scale_factor_override(1.0); + window.present_mode = PresentMode::AutoNoVsync; +} + #[derive(Resource, Debug)] struct Config { line_count: u32, diff --git a/examples/stress_tests/many_glyphs.rs b/examples/stress_tests/many_glyphs.rs index dc94e65ca8993..2110224912ea0 100644 --- a/examples/stress_tests/many_glyphs.rs +++ b/examples/stress_tests/many_glyphs.rs @@ -11,7 +11,7 @@ use bevy::{ diagnostic::{FrameTimeDiagnosticsPlugin, LogDiagnosticsPlugin}, prelude::*, text::{LineBreak, TextBounds}, - window::{PresentMode, WindowResolution}, + window::{PresentMode, PrimaryWindow, WindowResolution}, winit::{UpdateMode, WinitSettings}, }; @@ -40,14 +40,7 @@ fn main() { let mut app = App::new(); app.add_plugins(( - DefaultPlugins.set(WindowPlugin { - primary_window: Some(Window { - present_mode: PresentMode::AutoNoVsync, - resolution: WindowResolution::new(1920.0, 1080.0).with_scale_factor_override(1.0), - ..default() - }), - ..default() - }), + DefaultPlugins, FrameTimeDiagnosticsPlugin::default(), LogDiagnosticsPlugin::default(), )) @@ -55,6 +48,7 @@ fn main() { focused_mode: UpdateMode::Continuous, unfocused_mode: UpdateMode::Continuous, }) + .add_observer(configure_window) .add_systems(Startup, setup); if args.recompute_text { @@ -64,6 +58,12 @@ fn main() { app.insert_resource(args).run(); } +fn configure_window(trigger: On, mut window: Query<&mut Window>) { + let mut window = window.get_mut(trigger.target()).unwrap(); + window.resolution = WindowResolution::new(1920.0, 1080.0).with_scale_factor_override(1.0); + window.present_mode = PresentMode::AutoNoVsync; +} + fn setup(mut commands: Commands, args: Res) { warn!(include_str!("warning_string.txt")); diff --git a/examples/stress_tests/many_lights.rs b/examples/stress_tests/many_lights.rs index 031897b5e82a1..b9ee0cd549313 100644 --- a/examples/stress_tests/many_lights.rs +++ b/examples/stress_tests/many_lights.rs @@ -10,7 +10,7 @@ use bevy::{ pbr::{ExtractedPointLight, GlobalClusterableObjectMeta}, prelude::*, render::{camera::ScalingMode, Render, RenderApp, RenderSystems}, - window::{PresentMode, WindowResolution}, + window::{PresentMode, PrimaryWindow, WindowResolution}, winit::{UpdateMode, WinitSettings}, }; use rand::{thread_rng, Rng}; @@ -18,16 +18,7 @@ use rand::{thread_rng, Rng}; fn main() { App::new() .add_plugins(( - DefaultPlugins.set(WindowPlugin { - primary_window: Some(Window { - resolution: WindowResolution::new(1920.0, 1080.0) - .with_scale_factor_override(1.0), - title: "many_lights".into(), - present_mode: PresentMode::AutoNoVsync, - ..default() - }), - ..default() - }), + DefaultPlugins, FrameTimeDiagnosticsPlugin::default(), LogDiagnosticsPlugin::default(), LogVisibleLights, @@ -36,11 +27,19 @@ fn main() { focused_mode: UpdateMode::Continuous, unfocused_mode: UpdateMode::Continuous, }) + .add_observer(configure_window) .add_systems(Startup, setup) .add_systems(Update, (move_camera, print_light_count)) .run(); } +fn configure_window(trigger: On, mut window: Query<&mut Window>) { + let mut window = window.get_mut(trigger.target()).unwrap(); + window.title = "many_lights".to_string(); + window.resolution = WindowResolution::new(1920.0, 1080.0).with_scale_factor_override(1.0); + window.present_mode = PresentMode::AutoNoVsync; +} + fn setup( mut commands: Commands, mut meshes: ResMut>, diff --git a/examples/stress_tests/many_materials.rs b/examples/stress_tests/many_materials.rs index f2af7fb3827fc..9a672211515a8 100644 --- a/examples/stress_tests/many_materials.rs +++ b/examples/stress_tests/many_materials.rs @@ -3,7 +3,7 @@ use argh::FromArgs; use bevy::{ diagnostic::{FrameTimeDiagnosticsPlugin, LogDiagnosticsPlugin}, prelude::*, - window::{PresentMode, WindowPlugin, WindowResolution}, + window::{PresentMode, PrimaryWindow, WindowResolution}, }; use std::f32::consts::PI; @@ -24,25 +24,24 @@ fn main() { App::new() .add_plugins(( - DefaultPlugins.set(WindowPlugin { - primary_window: Some(Window { - resolution: WindowResolution::new(1920.0, 1080.0) - .with_scale_factor_override(1.0), - title: "many_materials".into(), - present_mode: PresentMode::AutoNoVsync, - ..default() - }), - ..default() - }), + DefaultPlugins, FrameTimeDiagnosticsPlugin::default(), LogDiagnosticsPlugin::default(), )) .insert_resource(args) + .add_observer(configure_window) .add_systems(Startup, setup) .add_systems(Update, animate_materials) .run(); } +fn configure_window(trigger: On, mut window: Query<&mut Window>) { + let mut window = window.get_mut(trigger.target()).unwrap(); + window.resolution = WindowResolution::new(1920.0, 1080.0).with_scale_factor_override(1.0); + window.title = "many_materials".into(); + window.present_mode = PresentMode::AutoNoVsync; +} + fn setup( mut commands: Commands, args: Res, diff --git a/examples/stress_tests/many_sprites.rs b/examples/stress_tests/many_sprites.rs index 5bf65efb2d357..439829c245536 100644 --- a/examples/stress_tests/many_sprites.rs +++ b/examples/stress_tests/many_sprites.rs @@ -11,7 +11,7 @@ use bevy::{ color::palettes::css::*, diagnostic::{FrameTimeDiagnosticsPlugin, LogDiagnosticsPlugin}, prelude::*, - window::{PresentMode, WindowResolution}, + window::{PresentMode, PrimaryWindow, WindowResolution}, winit::{UpdateMode, WinitSettings}, }; @@ -33,20 +33,13 @@ fn main() { .add_plugins(( LogDiagnosticsPlugin::default(), FrameTimeDiagnosticsPlugin::default(), - DefaultPlugins.set(WindowPlugin { - primary_window: Some(Window { - present_mode: PresentMode::AutoNoVsync, - resolution: WindowResolution::new(1920.0, 1080.0) - .with_scale_factor_override(1.0), - ..default() - }), - ..default() - }), + DefaultPlugins, )) .insert_resource(WinitSettings { focused_mode: UpdateMode::Continuous, unfocused_mode: UpdateMode::Continuous, }) + .add_observer(configure_window) .add_systems(Startup, setup) .add_systems( Update, @@ -55,6 +48,12 @@ fn main() { .run(); } +fn configure_window(trigger: On, mut window: Query<&mut Window>) { + let mut window = window.get_mut(trigger.target()).unwrap(); + window.resolution = WindowResolution::new(1920.0, 1080.0).with_scale_factor_override(1.0); + window.present_mode = PresentMode::AutoNoVsync; +} + fn setup(mut commands: Commands, assets: Res, color_tint: Res) { warn!(include_str!("warning_string.txt")); diff --git a/examples/stress_tests/many_text2d.rs b/examples/stress_tests/many_text2d.rs index cc1247e13ff57..0813b59541d4c 100644 --- a/examples/stress_tests/many_text2d.rs +++ b/examples/stress_tests/many_text2d.rs @@ -7,7 +7,7 @@ use bevy::{ prelude::*, render::view::NoFrustumCulling, text::FontAtlasSets, - window::{PresentMode, WindowResolution}, + window::{PresentMode, PrimaryWindow, WindowResolution}, }; use argh::FromArgs; @@ -72,16 +72,10 @@ fn main() { app.add_plugins(( FrameTimeDiagnosticsPlugin::default(), LogDiagnosticsPlugin::default(), - DefaultPlugins.set(WindowPlugin { - primary_window: Some(Window { - present_mode: PresentMode::AutoNoVsync, - resolution: WindowResolution::new(1920.0, 1080.0).with_scale_factor_override(1.0), - ..default() - }), - ..default() - }), + DefaultPlugins, )) .init_resource::() + .add_observer(configure_window) .add_systems(Startup, setup) .add_systems(Update, (move_camera, print_counts)); @@ -101,6 +95,12 @@ impl Default for PrintingTimer { } } +fn configure_window(trigger: On, mut window: Query<&mut Window>) { + let mut window = window.get_mut(trigger.target()).unwrap(); + window.resolution = WindowResolution::new(1920.0, 1080.0).with_scale_factor_override(1.0); + window.present_mode = PresentMode::AutoNoVsync; +} + fn setup(mut commands: Commands, font: Res, args: Res) { warn!(include_str!("warning_string.txt")); diff --git a/examples/stress_tests/text_pipeline.rs b/examples/stress_tests/text_pipeline.rs index 5f9fdca8e03d1..4382e7698b9a7 100644 --- a/examples/stress_tests/text_pipeline.rs +++ b/examples/stress_tests/text_pipeline.rs @@ -7,22 +7,14 @@ use bevy::{ diagnostic::{FrameTimeDiagnosticsPlugin, LogDiagnosticsPlugin}, prelude::*, text::{LineBreak, TextBounds}, - window::{PresentMode, WindowResolution}, + window::{PresentMode, PrimaryWindow, WindowResolution}, winit::{UpdateMode, WinitSettings}, }; fn main() { App::new() .add_plugins(( - DefaultPlugins.set(WindowPlugin { - primary_window: Some(Window { - present_mode: PresentMode::AutoNoVsync, - resolution: WindowResolution::new(1920.0, 1080.0) - .with_scale_factor_override(1.0), - ..default() - }), - ..default() - }), + DefaultPlugins, FrameTimeDiagnosticsPlugin::default(), LogDiagnosticsPlugin::default(), )) @@ -30,11 +22,18 @@ fn main() { focused_mode: UpdateMode::Continuous, unfocused_mode: UpdateMode::Continuous, }) + .add_observer(configure_window) .add_systems(Startup, spawn) .add_systems(Update, update_text_bounds) .run(); } +fn configure_window(trigger: On, mut window: Query<&mut Window>) { + let mut window = window.get_mut(trigger.target()).unwrap(); + window.resolution = WindowResolution::new(1920.0, 1080.0).with_scale_factor_override(1.0); + window.present_mode = PresentMode::AutoNoVsync; +} + fn spawn(mut commands: Commands, asset_server: Res) { warn!(include_str!("warning_string.txt")); diff --git a/examples/stress_tests/transform_hierarchy.rs b/examples/stress_tests/transform_hierarchy.rs index 49ff27b4ee9e0..7d4885b6116c9 100644 --- a/examples/stress_tests/transform_hierarchy.rs +++ b/examples/stress_tests/transform_hierarchy.rs @@ -189,7 +189,7 @@ fn main() { .insert_resource(cfg) .add_plugins(( DefaultPlugins.set(WindowPlugin { - primary_window: None, + spawn_primary_window: false, exit_condition: ExitCondition::DontExit, ..default() }), diff --git a/examples/tools/scene_viewer/main.rs b/examples/tools/scene_viewer/main.rs index f5ab505d91520..1248243bb21e8 100644 --- a/examples/tools/scene_viewer/main.rs +++ b/examples/tools/scene_viewer/main.rs @@ -18,6 +18,7 @@ use bevy::{ experimental::occlusion_culling::OcclusionCulling, primitives::{Aabb, Sphere}, }, + window::PrimaryWindow, }; #[path = "../../helpers/camera_controller.rs"] @@ -65,25 +66,18 @@ fn main() { let mut app = App::new(); app.add_plugins(( - DefaultPlugins - .set(WindowPlugin { - primary_window: Some(Window { - title: "bevy scene viewer".to_string(), - ..default() - }), - ..default() - }) - .set(AssetPlugin { - file_path: std::env::var("CARGO_MANIFEST_DIR").unwrap_or_else(|_| ".".to_string()), - // Allow scenes to be loaded from anywhere on disk - unapproved_path_mode: UnapprovedPathMode::Allow, - ..default() - }), + DefaultPlugins.set(AssetPlugin { + file_path: std::env::var("CARGO_MANIFEST_DIR").unwrap_or_else(|_| ".".to_string()), + // Allow scenes to be loaded from anywhere on disk + unapproved_path_mode: UnapprovedPathMode::Allow, + ..default() + }), CameraControllerPlugin, SceneViewerPlugin, MorphViewerPlugin, )) .insert_resource(args) + .add_observer(configure_window) .add_systems(Startup, setup) .add_systems(PreUpdate, setup_scene_after_load); @@ -98,6 +92,11 @@ fn main() { app.run(); } +fn configure_window(trigger: On, mut window: Query<&mut Window>) { + let mut window = window.get_mut(trigger.target()).unwrap(); + window.title = "Bevy Scene Viewer".to_string(); +} + fn parse_scene(scene_path: String) -> (String, usize) { if scene_path.contains('#') { let gltf_and_scene = scene_path.split('#').collect::>(); diff --git a/examples/ui/flex_layout.rs b/examples/ui/flex_layout.rs index 2a155eafb1016..dacbbaeec5ce2 100644 --- a/examples/ui/flex_layout.rs +++ b/examples/ui/flex_layout.rs @@ -7,13 +7,7 @@ const MARGIN: Val = Val::Px(12.); fn main() { App::new() - .add_plugins(DefaultPlugins.set(WindowPlugin { - primary_window: Some(Window { - title: "Bevy Flex Layout Example".to_string(), - ..Default::default() - }), - ..Default::default() - })) + .add_plugins(DefaultPlugins) .add_systems(Startup, spawn_layout) .run(); } diff --git a/examples/ui/grid.rs b/examples/ui/grid.rs index 60a95c8e9f75c..a853cc923ad32 100644 --- a/examples/ui/grid.rs +++ b/examples/ui/grid.rs @@ -1,20 +1,20 @@ //! Demonstrates how CSS Grid layout can be used to lay items out in a 2D grid -use bevy::{color::palettes::css::*, prelude::*}; +use bevy::{color::palettes::css::*, prelude::*, window::PrimaryWindow}; fn main() { App::new() - .add_plugins(DefaultPlugins.set(WindowPlugin { - primary_window: Some(Window { - resolution: [800., 600.].into(), - title: "Bevy CSS Grid Layout Example".to_string(), - ..default() - }), - ..default() - })) + .add_plugins(DefaultPlugins) + .add_observer(configure_window) .add_systems(Startup, spawn_layout) .run(); } +fn configure_window(trigger: On, mut window: Query<&mut Window>) { + let mut window = window.get_mut(trigger.target()).unwrap(); + window.title = "Bevy CSS Grid Layout Example".to_string(); + window.resolution = [800., 600.].into(); +} + fn spawn_layout(mut commands: Commands, asset_server: Res) { let font = asset_server.load("fonts/FiraSans-Bold.ttf"); commands.spawn(Camera2d); diff --git a/examples/ui/text_debug.rs b/examples/ui/text_debug.rs index 948cf0a534890..e7ba24b416486 100644 --- a/examples/ui/text_debug.rs +++ b/examples/ui/text_debug.rs @@ -7,26 +7,23 @@ use bevy::{ diagnostic::{DiagnosticsStore, FrameTimeDiagnosticsPlugin}, prelude::*, ui::widget::TextUiWriter, - window::PresentMode, + window::{PresentMode, PrimaryWindow}, }; fn main() { App::new() - .add_plugins(( - DefaultPlugins.set(WindowPlugin { - primary_window: Some(Window { - present_mode: PresentMode::AutoNoVsync, - ..default() - }), - ..default() - }), - FrameTimeDiagnosticsPlugin::default(), - )) + .add_plugins((DefaultPlugins, FrameTimeDiagnosticsPlugin::default())) + .add_observer(configure_window) .add_systems(Startup, infotext_system) .add_systems(Update, change_text_system) .run(); } +fn configure_window(trigger: On, mut window: Query<&mut Window>) { + let mut window = window.get_mut(trigger.target()).unwrap(); + window.present_mode = PresentMode::AutoNoVsync; +} + #[derive(Component)] struct TextChanges; diff --git a/examples/ui/text_wrap_debug.rs b/examples/ui/text_wrap_debug.rs index 986d9c79ff3d8..c250c9182aed5 100644 --- a/examples/ui/text_wrap_debug.rs +++ b/examples/ui/text_wrap_debug.rs @@ -1,7 +1,12 @@ //! This example demonstrates text wrapping and use of the `LineBreakOn` property. use argh::FromArgs; -use bevy::{prelude::*, text::LineBreak, window::WindowResolution, winit::WinitSettings}; +use bevy::{ + prelude::*, + text::LineBreak, + window::{PrimaryWindow, WindowResolution}, + winit::WinitSettings, +}; #[derive(FromArgs, Resource)] /// `text_wrap_debug` demonstrates text wrapping and use of the `LineBreakOn` property @@ -16,30 +21,30 @@ struct Args { } fn main() { + App::new() + .add_plugins(DefaultPlugins) + .insert_resource(WinitSettings::desktop_app()) + .add_observer(configure_window) + .add_systems(Startup, spawn) + .run(); +} + +fn configure_window( + trigger: On, + mut window: Query<&mut Window>, + mut commands: Commands, +) { + let mut window = window.get_mut(trigger.target()).unwrap(); // `from_env` panics on the web #[cfg(not(target_arch = "wasm32"))] let args: Args = argh::from_env(); #[cfg(target_arch = "wasm32")] let args = Args::from_args(&[], &[]).unwrap(); - let window = if let Some(scale_factor) = args.scale_factor { - Window { - resolution: WindowResolution::default().with_scale_factor_override(scale_factor), - ..Default::default() - } - } else { - Window::default() - }; - - App::new() - .add_plugins(DefaultPlugins.set(WindowPlugin { - primary_window: Some(window), - ..Default::default() - })) - .insert_resource(WinitSettings::desktop_app()) - .insert_resource(UiScale(args.ui_scale)) - .add_systems(Startup, spawn) - .run(); + if let Some(scale_factor) = args.scale_factor { + window.resolution = WindowResolution::default().with_scale_factor_override(scale_factor); + } + commands.insert_resource(UiScale(args.ui_scale)); } fn spawn(mut commands: Commands, asset_server: Res) { diff --git a/examples/ui/viewport_debug.rs b/examples/ui/viewport_debug.rs index 58790f938172c..54d8afcba2572 100644 --- a/examples/ui/viewport_debug.rs +++ b/examples/ui/viewport_debug.rs @@ -4,7 +4,7 @@ //! and then switches between them once per second using the `Display` style property. //! If there are no problems both layouts should be identical, except for the color of the margin changing which is used to signal that the displayed UI node tree has changed //! (red for viewport, yellow for pixel). -use bevy::{color::palettes::css::*, prelude::*}; +use bevy::{color::palettes::css::*, prelude::*, window::PrimaryWindow}; const PALETTE: [Srgba; 10] = [ RED, YELLOW, WHITE, BEIGE, AQUA, CRIMSON, NAVY, AZURE, LIME, BLACK, @@ -20,22 +20,20 @@ enum Coords { fn main() { App::new() .insert_resource(UiScale(2.0)) - .add_plugins(DefaultPlugins.set(WindowPlugin { - primary_window: Some(Window { - title: "Viewport Coordinates Debug".to_string(), - // This example relies on these specific viewport dimensions, so let's explicitly - // define them. - resolution: [1280., 720.].into(), - resizable: false, - ..Default::default() - }), - ..Default::default() - })) + .add_plugins(DefaultPlugins) + .add_observer(configure_window) .add_systems(Startup, setup) .add_systems(Update, update) .run(); } +fn configure_window(trigger: On, mut window: Query<&mut Window>) { + let mut window = window.get_mut(trigger.target()).unwrap(); + window.title = "Viewport Coordinates Debug".to_string(); + window.resolution = [1280., 720.].into(); + window.resizable = false; +} + fn update( mut timer: Local, mut visible_tree: Local, diff --git a/examples/ui/window_fallthrough.rs b/examples/ui/window_fallthrough.rs index ee74e2332ec13..9fde4b7011991 100644 --- a/examples/ui/window_fallthrough.rs +++ b/examples/ui/window_fallthrough.rs @@ -2,26 +2,28 @@ //! If you build this, and hit 'P' it should toggle on/off the mouse's passthrough. //! Note: this example will not work on following platforms: iOS / Android / Web / X11. Window fall through is not supported there. -use bevy::{prelude::*, window::CursorOptions}; +use bevy::{ + prelude::*, + window::{CursorOptions, PrimaryWindow, WindowLevel}, +}; fn main() { App::new() .insert_resource(ClearColor(Color::NONE)) // Use a transparent window, to make effects obvious. - .add_plugins(DefaultPlugins.set(WindowPlugin { - primary_window: Some(Window { - // Set the window's parameters, note we're setting the window to always be on top. - transparent: true, - decorations: true, - window_level: bevy::window::WindowLevel::AlwaysOnTop, - ..default() - }), - ..default() - })) + .add_plugins(DefaultPlugins) + .add_observer(configure_window) .add_systems(Startup, setup) .add_systems(Update, toggle_mouse_passthrough) // This allows us to hit 'P' to toggle on/off the mouse's passthrough .run(); } +fn configure_window(trigger: On, mut window: Query<&mut Window>) { + let mut window = window.get_mut(trigger.target()).unwrap(); + window.transparent = true; + window.decorations = true; + window.window_level = WindowLevel::AlwaysOnTop; +} + fn setup(mut commands: Commands, asset_server: Res) { // UI camera commands.spawn(Camera2d); diff --git a/examples/window/low_power.rs b/examples/window/low_power.rs index 5b44442b1b9e6..7771bbde20615 100644 --- a/examples/window/low_power.rs +++ b/examples/window/low_power.rs @@ -5,7 +5,7 @@ use bevy::{ prelude::*, - window::{PresentMode, RequestRedraw, WindowPlugin}, + window::{PresentMode, PrimaryWindow, RequestRedraw}, winit::{EventLoopProxyWrapper, WakeUp, WinitSettings}, }; use core::time::Duration; @@ -22,14 +22,8 @@ fn main() { unfocused_mode: bevy::winit::UpdateMode::reactive_low_power(Duration::from_millis(10)), }) .insert_resource(ExampleMode::Game) - .add_plugins(DefaultPlugins.set(WindowPlugin { - primary_window: Some(Window { - // Turn off vsync to maximize CPU/GPU usage - present_mode: PresentMode::AutoNoVsync, - ..default() - }), - ..default() - })) + .add_plugins(DefaultPlugins) + .add_observer(configure_window) .add_systems(Startup, test_setup::setup) .add_systems( Update, @@ -43,6 +37,12 @@ fn main() { .run(); } +fn configure_window(trigger: On, mut window: Query<&mut Window>) { + let mut window = window.get_mut(trigger.target()).unwrap(); + // Turn off vsync to maximize CPU/GPU usage + window.present_mode = PresentMode::AutoNoVsync; +} + #[derive(Resource, Debug)] enum ExampleMode { Game, diff --git a/examples/window/monitor_info.rs b/examples/window/monitor_info.rs index c4a26982f83bc..a4ec91d1ee814 100644 --- a/examples/window/monitor_info.rs +++ b/examples/window/monitor_info.rs @@ -9,7 +9,7 @@ use bevy::{ fn main() { App::new() .add_plugins(DefaultPlugins.set(WindowPlugin { - primary_window: None, + spawn_primary_window: false, exit_condition: ExitCondition::DontExit, ..default() })) diff --git a/examples/window/scale_factor_override.rs b/examples/window/scale_factor_override.rs index dbe487f07fc90..2b43259171f92 100644 --- a/examples/window/scale_factor_override.rs +++ b/examples/window/scale_factor_override.rs @@ -1,20 +1,18 @@ //! This example illustrates how to override the window scale factor imposed by the //! operating system. -use bevy::{prelude::*, window::WindowResolution}; +use bevy::{ + prelude::*, + window::{PrimaryWindow, WindowResolution}, +}; #[derive(Component)] struct CustomText; fn main() { App::new() - .add_plugins(DefaultPlugins.set(WindowPlugin { - primary_window: Some(Window { - resolution: WindowResolution::new(500., 300.).with_scale_factor_override(1.0), - ..default() - }), - ..default() - })) + .add_plugins(DefaultPlugins) + .add_observer(configure_window) .add_systems(Startup, setup) .add_systems( Update, @@ -23,6 +21,11 @@ fn main() { .run(); } +fn configure_window(trigger: On, mut window: Query<&mut Window>) { + let mut window = window.get_mut(trigger.target()).unwrap(); + window.resolution = WindowResolution::new(1920.0, 1080.0).with_scale_factor_override(1.0); +} + fn setup(mut commands: Commands) { // camera commands.spawn(Camera2d); diff --git a/examples/window/transparent_window.rs b/examples/window/transparent_window.rs index ed5a47297310f..697e9883fc35a 100644 --- a/examples/window/transparent_window.rs +++ b/examples/window/transparent_window.rs @@ -4,32 +4,38 @@ //! [documentation](https://docs.rs/bevy/latest/bevy/prelude/struct.Window.html#structfield.transparent) //! for more details. -use bevy::prelude::*; #[cfg(any(target_os = "macos", target_os = "linux"))] use bevy::window::CompositeAlphaMode; +use bevy::{prelude::*, window::PrimaryWindow}; fn main() { App::new() - .add_plugins(DefaultPlugins.set(WindowPlugin { - primary_window: Some(Window { - // Setting `transparent` allows the `ClearColor`'s alpha value to take effect - transparent: true, - // Disabling window decorations to make it feel more like a widget than a window - decorations: false, - #[cfg(target_os = "macos")] - composite_alpha_mode: CompositeAlphaMode::PostMultiplied, - #[cfg(target_os = "linux")] - composite_alpha_mode: CompositeAlphaMode::PreMultiplied, - ..default() - }), - ..default() - })) + .add_plugins(DefaultPlugins) // ClearColor must have 0 alpha, otherwise some color will bleed through .insert_resource(ClearColor(Color::NONE)) + .add_observer(configure_window) .add_systems(Startup, setup) .run(); } +fn configure_window(trigger: On, mut window: Query<&mut Window>) { + let mut window = window.get_mut(trigger.target()).unwrap(); + + // Setting `transparent` allows the `ClearColor`'s alpha value to take effect + window.transparent = true; + // Disabling window decorations to make it feel more like a widget than a window + window.decorations = false; + + #[cfg(target_os = "macos")] + { + window.composite_alpha_mode = CompositeAlphaMode::PostMultiplied; + } + #[cfg(target_os = "linux")] + { + window.composite_alpha_mode = CompositeAlphaMode::PreMultiplied; + } +} + fn setup(mut commands: Commands, asset_server: Res) { commands.spawn(Camera2d); commands.spawn(Sprite::from_image(asset_server.load("branding/icon.png"))); diff --git a/examples/window/window_drag_move.rs b/examples/window/window_drag_move.rs index 829e315d5fbb0..4ce8f6c7e2632 100644 --- a/examples/window/window_drag_move.rs +++ b/examples/window/window_drag_move.rs @@ -10,7 +10,7 @@ //! //! The `start_drag_resize()` function behaves similarly but permits a window to //! be resized. -use bevy::{math::CompassOctant, prelude::*}; +use bevy::{math::CompassOctant, prelude::*, window::PrimaryWindow}; /// Determine what do on left click. #[derive(Resource, Debug)] @@ -41,20 +41,20 @@ const DIRECTIONS: [CompassOctant; 8] = [ fn main() { App::new() - .add_plugins(DefaultPlugins.set(WindowPlugin { - primary_window: Some(Window { - decorations: false, - ..default() - }), - ..default() - })) + .add_plugins(DefaultPlugins) .insert_resource(ResizeDir(7)) .insert_resource(LeftClickAction::Move) + .add_observer(configure_window) .add_systems(Startup, setup) .add_systems(Update, (handle_input, move_or_resize_windows)) .run(); } +fn configure_window(trigger: On, mut window: Query<&mut Window>) { + let mut window = window.get_mut(trigger.target()).unwrap(); + window.decorations = false; +} + fn setup(mut commands: Commands) { // Camera commands.spawn(Camera3d::default()); diff --git a/examples/window/window_settings.rs b/examples/window/window_settings.rs index 7be899f6e315b..ea7d9b4cd68c4 100644 --- a/examples/window/window_settings.rs +++ b/examples/window/window_settings.rs @@ -7,7 +7,8 @@ use bevy::{ diagnostic::{FrameCount, FrameTimeDiagnosticsPlugin, LogDiagnosticsPlugin}, prelude::*, window::{ - CursorGrabMode, CursorOptions, PresentMode, SystemCursorIcon, WindowLevel, WindowTheme, + CursorGrabMode, CursorOptions, PresentMode, PrimaryWindow, SystemCursorIcon, WindowLevel, + WindowTheme, }, winit::cursor::CursorIcon, }; @@ -15,32 +16,11 @@ use bevy::{ fn main() { App::new() .add_plugins(( - DefaultPlugins.set(WindowPlugin { - primary_window: Some(Window { - title: "I am a window!".into(), - name: Some("bevy.app".into()), - resolution: (500., 300.).into(), - present_mode: PresentMode::AutoVsync, - // Tells Wasm to resize the window according to the available canvas - fit_canvas_to_parent: true, - // Tells Wasm not to override default event handling, like F5, Ctrl+R etc. - prevent_default_event_handling: false, - window_theme: Some(WindowTheme::Dark), - enabled_buttons: bevy::window::EnabledButtons { - maximize: false, - ..Default::default() - }, - // This will spawn an invisible window - // The window will be made visible in the make_visible() system after 3 frames. - // This is useful when you want to avoid the white window that shows up before the GPU is ready to render the app. - visible: false, - ..default() - }), - ..default() - }), + DefaultPlugins, LogDiagnosticsPlugin::default(), FrameTimeDiagnosticsPlugin::default(), )) + .add_observer(configure_window) .add_systems(Startup, init_cursor_icons) .add_systems( Update, @@ -58,6 +38,25 @@ fn main() { .run(); } +fn configure_window(trigger: On, mut window: Query<&mut Window>) { + let mut window = window.get_mut(trigger.target()).unwrap(); + window.title = "I am a window!".into(); + window.name = Some("bevy.app".into()); + window.resolution = (500., 300.).into(); + // Tells Wasm to resize the window according to the available canvas + window.fit_canvas_to_parent = true; + // Tells Wasm not to override default event handling, like F5, Ctrl+R etc. + window.prevent_default_event_handling = false; + window.window_theme = Some(WindowTheme::Dark); + window.enabled_buttons.maximize = false; + // This will spawn an invisible window + // The window will be made visible in the make_visible() system after 3 frames. + // This is useful when you want to avoid the white window that shows up before the GPU is ready to render the app. + window.visible = false; + + window.present_mode = PresentMode::AutoNoVsync; +} + fn make_visible(mut window: Single<&mut Window>, frames: Res) { // The delay may be different for your app or system. if frames.0 == 3 { diff --git a/tests/window/minimizing.rs b/tests/window/minimizing.rs index 8ba5d79fdd75c..d0de08acec89f 100644 --- a/tests/window/minimizing.rs +++ b/tests/window/minimizing.rs @@ -6,13 +6,7 @@ fn main() { // TODO: Combine this with `resizing` once multiple_windows is simpler than // it is currently. App::new() - .add_plugins(DefaultPlugins.set(WindowPlugin { - primary_window: Some(Window { - title: "Minimizing".into(), - ..default() - }), - ..default() - })) + .add_plugins(DefaultPlugins) .add_systems(Startup, (setup_3d, setup_2d)) .add_systems(Update, minimize_automatically) .run(); diff --git a/tests/window/resizing.rs b/tests/window/resizing.rs index 4148a307a063b..b9090dda399ea 100644 --- a/tests/window/resizing.rs +++ b/tests/window/resizing.rs @@ -1,7 +1,10 @@ //! A test to confirm that `bevy` allows setting the window to arbitrary small sizes //! This is run in CI to ensure that this doesn't regress again. -use bevy::{prelude::*, window::WindowResolution}; +use bevy::{ + prelude::*, + window::{PrimaryWindow, WindowResolution}, +}; // The smallest size reached is 1x1, as X11 doesn't support windows with a 0 dimension // TODO: Add a check for platforms other than X11 for 0xk and kx0, despite those currently unsupported on CI. @@ -19,27 +22,25 @@ struct Dimensions { fn main() { App::new() - .add_plugins( - DefaultPlugins.set(WindowPlugin { - primary_window: Some(Window { - resolution: WindowResolution::new(MAX_WIDTH as f32, MAX_HEIGHT as f32) - .with_scale_factor_override(1.0), - title: "Resizing".into(), - ..default() - }), - ..default() - }), - ) + .add_plugins(DefaultPlugins) .insert_resource(Dimensions { width: MAX_WIDTH, height: MAX_HEIGHT, }) .insert_resource(ContractingY) + .add_observer(configure_window) .add_systems(Startup, (setup_3d, setup_2d)) .add_systems(Update, (change_window_size, sync_dimensions)) .run(); } +fn configure_window(trigger: On, mut window: Query<&mut Window>) { + let mut window = window.get_mut(trigger.target()).unwrap(); + + window.resolution = + WindowResolution::new(MAX_WIDTH as f32, MAX_HEIGHT as f32).with_scale_factor_override(1.0); + window.title = "Resizing".into(); +} #[derive(Resource)] enum Phase { ContractingY,