#![cfg_attr(docsrs, feature(doc_auto_cfg))] #![doc( html_logo_url = "https://bevyengine.org/assets/icon.png", html_favicon_url = "https://bevyengine.org/assets/icon.png" )] //! `bevy_window` provides a platform-agnostic interface for windowing in Bevy. //! //! This crate contains types for window management and events, //! used by windowing implementors such as `bevy_winit`. //! The [`WindowPlugin`] sets up some global window-related parameters and //! is part of the [`DefaultPlugins`](https://docs.rs/bevy/latest/bevy/struct.DefaultPlugins.html). use bevy_a11y::Focus; mod cursor; mod event; mod raw_handle; mod system; mod window; pub use crate::raw_handle::*; pub use cursor::*; pub use event::*; pub use system::*; pub use window::*; #[allow(missing_docs)] pub mod prelude { #[doc(hidden)] pub use crate::{ CursorEntered, CursorIcon, CursorLeft, CursorMoved, FileDragAndDrop, Ime, MonitorSelection, ReceivedCharacter, Window, WindowMoved, WindowPlugin, WindowPosition, WindowResizeConstraints, }; } use bevy_app::prelude::*; impl Default for WindowPlugin { fn default() -> Self { WindowPlugin { primary_window: Some(Window::default()), exit_condition: ExitCondition::OnAllClosed, close_when_requested: true, } } } /// A [`Plugin`] that defines an interface for windowing support in Bevy. pub struct WindowPlugin { /// Settings for the primary window. /// /// `Some(custom_window)` will spawn an entity with `custom_window` and [`PrimaryWindow`] as components. /// `None` will not spawn a primary window. /// /// Defaults to `Some(Window::default())`. /// /// Note that if there are no windows the App will exit (by default) due to /// [`exit_on_all_closed`]. pub primary_window: Option, /// Whether to exit the app when there are no open windows. /// /// If disabling this, ensure that you send the [`bevy_app::AppExit`] /// event when the app should exit. If this does not occur, you will /// create 'headless' processes (processes without windows), which may /// surprise your users. It is recommended to leave this setting to /// either [`ExitCondition::OnAllClosed`] or [`ExitCondition::OnPrimaryClosed`]. /// /// [`ExitCondition::OnAllClosed`] will add [`exit_on_all_closed`] to [`Update`]. /// [`ExitCondition::OnPrimaryClosed`] will add [`exit_on_primary_closed`] to [`Update`]. pub exit_condition: ExitCondition, /// Whether to close windows when they are requested to be closed (i.e. /// when the close button is pressed). /// /// If true, this plugin will add [`close_when_requested`] to [`Update`]. /// If this system (or a replacement) is not running, the close button will have no effect. /// This may surprise your users. It is recommended to leave this setting as `true`. pub close_when_requested: bool, } impl Plugin for WindowPlugin { fn build(&self, app: &mut App) { // User convenience events app.add_event::() .add_event::() .add_event::() .add_event::() .add_event::() .add_event::() .add_event::() .add_event::() .add_event::() .add_event::() .add_event::() .add_event::() .add_event::() .add_event::() .add_event::() .add_event::() .add_event::() .add_event::() .add_event::(); if let Some(primary_window) = &self.primary_window { let initial_focus = app .world_mut() .spawn(primary_window.clone()) .insert(PrimaryWindow) .id(); if let Some(mut focus) = app.world_mut().get_resource_mut::() { **focus = Some(initial_focus); } } match self.exit_condition { ExitCondition::OnPrimaryClosed => { app.add_systems(PostUpdate, exit_on_primary_closed); } ExitCondition::OnAllClosed => { app.add_systems(PostUpdate, exit_on_all_closed); } ExitCondition::DontExit => {} } if self.close_when_requested { // Need to run before `exit_on_*` systems app.add_systems(Update, close_when_requested); } // Register event types app.register_type::() .register_type::() .register_type::() .register_type::() .register_type::() .register_type::() .register_type::() .register_type::() .register_type::() .register_type::() .register_type::() .register_type::() .register_type::() .register_type::() .register_type::() .register_type::() .register_type::(); // Register window descriptor and related types app.register_type::() .register_type::(); } } /// Defines the specific conditions the application should exit on #[derive(Clone)] pub enum ExitCondition { /// Close application when the primary window is closed /// /// The plugin will add [`exit_on_primary_closed`] to [`Update`]. OnPrimaryClosed, /// Close application when all windows are closed /// /// The plugin will add [`exit_on_all_closed`] to [`Update`]. OnAllClosed, /// Keep application running headless even after closing all windows /// /// If selecting this, ensure that you send the [`bevy_app::AppExit`] /// event when the app should exit. If this does not occur, you will /// create 'headless' processes (processes without windows), which may /// surprise your users. DontExit, }