#![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"
)]
extern crate alloc;
use alloc::sync::Arc;
use std::sync::Mutex;
use bevy_a11y::Focus;
mod event;
mod monitor;
mod raw_handle;
mod system;
mod system_cursor;
mod window;
pub use crate::raw_handle::*;
#[cfg(target_os = "android")]
pub use android_activity;
pub use event::*;
pub use monitor::*;
pub use system::*;
pub use system_cursor::*;
pub use window::*;
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,
}
}
}
pub struct WindowPlugin {
pub primary_window: Option<Window>,
pub exit_condition: ExitCondition,
pub close_when_requested: bool,
}
impl Plugin for WindowPlugin {
fn build(&self, app: &mut App) {
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 {
app.add_systems(Update, close_when_requested);
}
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_type::<Monitor>();
app.register_type::<Window>()
.register_type::<PrimaryWindow>();
}
}
#[derive(Clone)]
pub enum ExitCondition {
OnPrimaryClosed,
OnAllClosed,
DontExit,
}
#[cfg(target_os = "android")]
pub static ANDROID_APP: std::sync::OnceLock<android_activity::AndroidApp> =
std::sync::OnceLock::new();