 74ccab947d
			
		
	
	
		74ccab947d
		
			
		
	
	
	
	
		
			
			# Objective - Fixes #12639. - `ReceivedCharacter` was deprecated in #12868 for 0.14, and should be removed for 0.15. ## Solution - Remove all instances of `ReceivedCharacter`, including the relevant `#[allow(deprecated)]` lint attributes. ## Migration Guide `ReceivedCharacter` was deprecated in 0.14 due to `winit` reworking their keyboard system. It has now been fully removed. Switch to using `KeyboardInput` instead. ```rust // 0.14 fn listen_characters(events: EventReader<ReceivedCharacter>) { for event in events.read() { info!("{}", event.char); } } // 0.15 fn listen_characters(events: EventReader<KeyboardInput>) { for event in events.read() { // Only check for characters when the key is pressed. if !event.state.is_pressed() { continue; } // Note that some keys such as `Space` and `Tab` won't be detected as a character. // Instead, check for them as separate enum variants. match &event.logical_key { Key::Character(character) => { info!("{} pressed.", character); }, Key::Space => { info!("Space pressed."); }, _ => {}, } } } ```
		
			
				
	
	
		
			188 lines
		
	
	
		
			6.7 KiB
		
	
	
	
		
			Rust
		
	
	
	
	
	
			
		
		
	
	
			188 lines
		
	
	
		
			6.7 KiB
		
	
	
	
		
			Rust
		
	
	
	
	
	
| #![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 std::sync::{Arc, Mutex};
 | |
| 
 | |
| use bevy_a11y::Focus;
 | |
| 
 | |
| mod event;
 | |
| mod monitor;
 | |
| mod raw_handle;
 | |
| mod system;
 | |
| mod system_cursor;
 | |
| mod window;
 | |
| 
 | |
| pub use crate::raw_handle::*;
 | |
| 
 | |
| pub use event::*;
 | |
| pub use monitor::*;
 | |
| pub use system::*;
 | |
| pub use system_cursor::*;
 | |
| pub use window::*;
 | |
| 
 | |
| /// The windowing prelude.
 | |
| ///
 | |
| /// This includes the most common types in this crate, re-exported for your convenience.
 | |
| pub mod prelude {
 | |
|     #[doc(hidden)]
 | |
|     pub use crate::{
 | |
|         CursorEntered, CursorLeft, CursorMoved, FileDragAndDrop, Ime, MonitorSelection, 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<Window>,
 | |
| 
 | |
|     /// 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::<WindowEvent>()
 | |
|             .add_event::<WindowResized>()
 | |
|             .add_event::<WindowCreated>()
 | |
|             .add_event::<WindowClosing>()
 | |
|             .add_event::<WindowClosed>()
 | |
|             .add_event::<WindowCloseRequested>()
 | |
|             .add_event::<WindowDestroyed>()
 | |
|             .add_event::<RequestRedraw>()
 | |
|             .add_event::<CursorMoved>()
 | |
|             .add_event::<CursorEntered>()
 | |
|             .add_event::<CursorLeft>()
 | |
|             .add_event::<Ime>()
 | |
|             .add_event::<WindowFocused>()
 | |
|             .add_event::<WindowOccluded>()
 | |
|             .add_event::<WindowScaleFactorChanged>()
 | |
|             .add_event::<WindowBackendScaleFactorChanged>()
 | |
|             .add_event::<FileDragAndDrop>()
 | |
|             .add_event::<WindowMoved>()
 | |
|             .add_event::<WindowThemeChanged>()
 | |
|             .add_event::<AppLifecycle>();
 | |
| 
 | |
|         if let Some(primary_window) = &self.primary_window {
 | |
|             let initial_focus = app
 | |
|                 .world_mut()
 | |
|                 .spawn(primary_window.clone())
 | |
|                 .insert((
 | |
|                     PrimaryWindow,
 | |
|                     RawHandleWrapperHolder(Arc::new(Mutex::new(None))),
 | |
|                 ))
 | |
|                 .id();
 | |
|             if let Some(mut focus) = app.world_mut().get_resource_mut::<Focus>() {
 | |
|                 **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::<WindowEvent>()
 | |
|             .register_type::<WindowResized>()
 | |
|             .register_type::<RequestRedraw>()
 | |
|             .register_type::<WindowCreated>()
 | |
|             .register_type::<WindowCloseRequested>()
 | |
|             .register_type::<WindowClosing>()
 | |
|             .register_type::<WindowClosed>()
 | |
|             .register_type::<CursorMoved>()
 | |
|             .register_type::<CursorEntered>()
 | |
|             .register_type::<CursorLeft>()
 | |
|             .register_type::<WindowFocused>()
 | |
|             .register_type::<WindowOccluded>()
 | |
|             .register_type::<WindowScaleFactorChanged>()
 | |
|             .register_type::<WindowBackendScaleFactorChanged>()
 | |
|             .register_type::<FileDragAndDrop>()
 | |
|             .register_type::<WindowMoved>()
 | |
|             .register_type::<WindowThemeChanged>()
 | |
|             .register_type::<AppLifecycle>();
 | |
| 
 | |
|         // Register window descriptor and related types
 | |
|         app.register_type::<Window>()
 | |
|             .register_type::<PrimaryWindow>();
 | |
|     }
 | |
| }
 | |
| 
 | |
| /// 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,
 | |
| }
 |