Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
69 changes: 54 additions & 15 deletions crates/bevy_window/src/event.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
use alloc::string::String;
#[cfg(feature = "bevy_reflect")]
use bevy_ecs::prelude::ReflectMessage;
use bevy_ecs::{entity::Entity, message::Message};
use bevy_ecs::{
entity::Entity,
event::{EntityEvent, EntityTrigger, Event},
message::Message,
};
use bevy_input::{
gestures::*,
keyboard::{KeyboardFocusLost, KeyboardInput},
Expand All @@ -25,7 +29,7 @@ use bevy_reflect::{ReflectDeserialize, ReflectSerialize};
use crate::WindowTheme;

/// A window event that is sent whenever a window's logical size has changed.
#[derive(Message, Debug, Clone, PartialEq)]
#[derive(Message, EntityEvent, Debug, Clone, Copy, PartialEq)]
#[cfg_attr(
feature = "bevy_reflect",
derive(Reflect),
Expand All @@ -38,6 +42,8 @@ use crate::WindowTheme;
)]
pub struct WindowResized {
/// Window that has changed.
#[event_target]
#[doc(alias = "entity")]
pub window: Entity,
/// The new logical width of the window.
pub width: f32,
Expand All @@ -63,7 +69,7 @@ pub struct RequestRedraw;
/// An event that is sent whenever a new window is created.
///
/// To create a new window, spawn an entity with a [`Window`](`crate::Window`) on it.
#[derive(Message, Debug, Clone, PartialEq, Eq)]
#[derive(Message, EntityEvent, Debug, Clone, Copy, PartialEq, Eq)]
#[cfg_attr(
feature = "bevy_reflect",
derive(Reflect),
Expand All @@ -76,6 +82,8 @@ pub struct RequestRedraw;
)]
pub struct WindowCreated {
/// Window that has been created.
#[event_target]
#[doc(alias = "entity")]
pub window: Entity,
}

Expand All @@ -89,7 +97,7 @@ pub struct WindowCreated {
///
/// [`WindowPlugin`]: crate::WindowPlugin
/// [`Window`]: crate::Window
#[derive(Message, Debug, Clone, PartialEq, Eq)]
#[derive(Message, EntityEvent, Debug, Clone, Copy, PartialEq, Eq)]
#[cfg_attr(
feature = "bevy_reflect",
derive(Reflect),
Expand All @@ -102,12 +110,14 @@ pub struct WindowCreated {
)]
pub struct WindowCloseRequested {
/// Window to close.
#[event_target]
#[doc(alias = "entity")]
pub window: Entity,
}

/// An event that is sent whenever a window is closed. This will be sent when
/// the window entity loses its [`Window`](crate::window::Window) component or is despawned.
#[derive(Message, Debug, Clone, PartialEq, Eq)]
#[derive(Message, EntityEvent, Debug, Clone, Copy, PartialEq, Eq)]
#[cfg_attr(
feature = "bevy_reflect",
derive(Reflect),
Expand All @@ -123,12 +133,14 @@ pub struct WindowClosed {
///
/// Note that this entity probably no longer exists
/// by the time this event is received.
#[event_target]
#[doc(alias = "entity")]
pub window: Entity,
}

/// An event that is sent whenever a window is closing. This will be sent when
/// after a [`WindowCloseRequested`] event is received and the window is in the process of closing.
#[derive(Message, Debug, Clone, PartialEq, Eq)]
#[derive(Message, EntityEvent, Debug, Clone, Copy, PartialEq, Eq)]
#[cfg_attr(
feature = "bevy_reflect",
derive(Reflect),
Expand All @@ -141,14 +153,16 @@ pub struct WindowClosed {
)]
pub struct WindowClosing {
/// Window that has been requested to close and is the process of closing.
#[event_target]
#[doc(alias = "entity")]
pub window: Entity,
}

/// An event that is sent whenever a window is destroyed by the underlying window system.
///
/// Note that if your application only has a single window, this event may be your last chance to
/// persist state before the application terminates.
#[derive(Message, Debug, Clone, PartialEq, Eq)]
#[derive(Message, EntityEvent, Debug, Clone, Copy, PartialEq, Eq)]
#[cfg_attr(
feature = "bevy_reflect",
derive(Reflect),
Expand All @@ -164,6 +178,8 @@ pub struct WindowDestroyed {
///
/// Note that this entity probably no longer exists
/// by the time this event is received.
#[event_target]
#[doc(alias = "entity")]
pub window: Entity,
}

Expand Down Expand Up @@ -286,7 +302,7 @@ pub enum Ime {
}

/// An event that indicates a window has received or lost focus.
#[derive(Message, Debug, Clone, PartialEq, Eq)]
#[derive(Message, EntityEvent, Debug, Clone, Copy, PartialEq, Eq)]
#[cfg_attr(
feature = "bevy_reflect",
derive(Reflect),
Expand All @@ -299,6 +315,8 @@ pub enum Ime {
)]
pub struct WindowFocused {
/// Window that changed focus.
#[event_target]
#[doc(alias = "entity")]
pub window: Entity,
/// Whether it was focused (true) or lost focused (false).
pub focused: bool,
Expand All @@ -313,7 +331,7 @@ pub struct WindowFocused {
/// It is the translated version of [`WindowEvent::Occluded`] from the `winit` crate.
///
/// [`WindowEvent::Occluded`]: https://docs.rs/winit/latest/winit/event/enum.WindowEvent.html#variant.Occluded
#[derive(Message, Debug, Clone, PartialEq, Eq)]
#[derive(Message, EntityEvent, Debug, Clone, Copy, PartialEq, Eq)]
#[cfg_attr(
feature = "bevy_reflect",
derive(Reflect),
Expand All @@ -326,13 +344,15 @@ pub struct WindowFocused {
)]
pub struct WindowOccluded {
/// Window that changed occluded state.
#[event_target]
#[doc(alias = "entity")]
pub window: Entity,
/// Whether it was occluded (true) or not occluded (false).
pub occluded: bool,
}

/// An event that indicates a window's scale factor has changed.
#[derive(Message, Debug, Clone, PartialEq)]
#[derive(Message, EntityEvent, Debug, Clone, Copy, PartialEq)]
#[cfg_attr(
feature = "bevy_reflect",
derive(Reflect),
Expand All @@ -345,13 +365,15 @@ pub struct WindowOccluded {
)]
pub struct WindowScaleFactorChanged {
/// Window that had its scale factor changed.
#[event_target]
#[doc(alias = "entity")]
pub window: Entity,
/// The new scale factor.
pub scale_factor: f64,
}

/// An event that indicates a window's OS-reported scale factor has changed.
#[derive(Message, Debug, Clone, PartialEq)]
#[derive(Message, EntityEvent, Debug, Clone, Copy, PartialEq)]
#[cfg_attr(
feature = "bevy_reflect",
derive(Reflect),
Expand All @@ -364,6 +386,8 @@ pub struct WindowScaleFactorChanged {
)]
pub struct WindowBackendScaleFactorChanged {
/// Window that had its scale factor changed by the backend.
#[event_target]
#[doc(alias = "entity")]
pub window: Entity,
/// The new scale factor.
pub scale_factor: f64,
Expand Down Expand Up @@ -404,9 +428,20 @@ pub enum FileDragAndDrop {
window: Entity,
},
}

impl Event for FileDragAndDrop {
type Trigger<'a> = EntityTrigger;
}
impl EntityEvent for FileDragAndDrop {
fn event_target(&self) -> Entity {
match self {
FileDragAndDrop::HoveredFile { window, .. }
| FileDragAndDrop::DroppedFile { window, .. }
| FileDragAndDrop::HoveredFileCanceled { window } => *window,
}
}
}
/// An event that is sent when a window is repositioned in physical pixels.
#[derive(Message, Debug, Clone, PartialEq, Eq)]
#[derive(Message, EntityEvent, Debug, Clone, Copy, PartialEq, Eq)]
#[cfg_attr(
feature = "bevy_reflect",
derive(Reflect),
Expand All @@ -419,6 +454,8 @@ pub enum FileDragAndDrop {
)]
pub struct WindowMoved {
/// Window that moved.
#[event_target]
#[doc(alias = "entity")]
pub window: Entity,
/// Where the window moved to in physical pixels.
pub position: IVec2,
Expand All @@ -428,7 +465,7 @@ pub struct WindowMoved {
///
/// This event is only sent when the window is relying on the system theme to control its appearance.
/// i.e. It is only sent when [`Window::window_theme`](crate::window::Window::window_theme) is `None` and the system theme changes.
#[derive(Message, Debug, Clone, PartialEq, Eq)]
#[derive(Message, EntityEvent, Debug, Clone, Copy, PartialEq, Eq)]
#[cfg_attr(
feature = "bevy_reflect",
derive(Reflect),
Expand All @@ -441,13 +478,15 @@ pub struct WindowMoved {
)]
pub struct WindowThemeChanged {
/// Window for which the system theme has changed.
#[event_target]
#[doc(alias = "entity")]
pub window: Entity,
/// The new system theme.
pub theme: WindowTheme,
}

/// Application lifetime events
#[derive(Message, Debug, Clone, Copy, PartialEq, Eq)]
#[derive(Message, Event, Debug, Clone, Copy, PartialEq, Eq)]
#[cfg_attr(
feature = "bevy_reflect",
derive(Reflect),
Expand Down
20 changes: 16 additions & 4 deletions crates/bevy_winit/src/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -934,6 +934,7 @@ impl WinitAppRunnerState {
match window_event.clone() {
BevyWindowEvent::AppLifecycle(e) => {
world.write_message(e);
world.trigger(e);
}
BevyWindowEvent::CursorEntered(e) => {
world.write_message(e);
Expand All @@ -945,7 +946,8 @@ impl WinitAppRunnerState {
world.write_message(e);
}
BevyWindowEvent::FileDragAndDrop(e) => {
world.write_message(e);
world.write_message(e.clone());
world.trigger(e);
}
BevyWindowEvent::Ime(e) => {
world.write_message(e);
Expand All @@ -955,33 +957,43 @@ impl WinitAppRunnerState {
}
BevyWindowEvent::WindowBackendScaleFactorChanged(e) => {
world.write_message(e);
world.trigger(e);
}
BevyWindowEvent::WindowCloseRequested(e) => {
world.write_message(e);
world.trigger(e);
}
BevyWindowEvent::WindowCreated(e) => {
world.write_message(e);
world.trigger(e);
}
BevyWindowEvent::WindowDestroyed(e) => {
world.write_message(e);
world.trigger(e);
}
BevyWindowEvent::WindowFocused(e) => {
world.write_message(e);
world.trigger(e);
}
BevyWindowEvent::WindowMoved(e) => {
world.write_message(e);
world.trigger(e);
}
BevyWindowEvent::WindowOccluded(e) => {
world.write_message(e);
world.trigger(e);
}
BevyWindowEvent::WindowResized(e) => {
world.write_message(e);
world.trigger(e);
}
BevyWindowEvent::WindowScaleFactorChanged(e) => {
world.write_message(e);
world.trigger(e);
}
BevyWindowEvent::WindowThemeChanged(e) => {
world.write_message(e);
world.trigger(e);
}
BevyWindowEvent::MouseButtonInput(e) => {
world.write_message(e);
Expand Down Expand Up @@ -1250,12 +1262,12 @@ mod tests {
let (window_backend_scale_factor_changed, window_scale_factor_changed) =
react_to_scale_factor_change(window.0, &mut window.1, changed_scale_factor);
window_backend_scale_factor_changed_writer
.write(window_backend_scale_factor_changed.clone());
.write(window_backend_scale_factor_changed);
window_event.write(BevyWindowEvent::WindowBackendScaleFactorChanged(
window_backend_scale_factor_changed,
));
if let Some(window_scale_factor_changed) = window_scale_factor_changed {
window_scale_factor_changed_writer.write(window_scale_factor_changed.clone());
window_scale_factor_changed_writer.write(window_scale_factor_changed);
window_event.write(BevyWindowEvent::WindowScaleFactorChanged(
window_scale_factor_changed,
));
Expand Down Expand Up @@ -1363,7 +1375,7 @@ mod tests {
mut window_resized_writer: MessageWriter<WindowResized>,
mut window_event: MessageWriter<BevyWindowEvent>| {
let window_resized = react_to_resize(window.0, &mut window.1, changed_size);
window_resized_writer.write(window_resized.clone());
window_resized_writer.write(window_resized);
window_event.write(BevyWindowEvent::WindowResized(window_resized));
},
);
Expand Down
11 changes: 7 additions & 4 deletions crates/bevy_winit/src/system.rs
Original file line number Diff line number Diff line change
Expand Up @@ -129,8 +129,9 @@ pub fn create_windows(
winit_window.focus_window();
}
}

window_created_events.write(WindowCreated { window: entity });
let window_create = WindowCreated { window: entity };
window_created_events.write(window_create);
commands.trigger(window_create);
}
});
});
Expand Down Expand Up @@ -406,7 +407,8 @@ pub(crate) fn changed_windows(
if let Some(new_physical_size) = winit_window.request_inner_size(requested_physical_size) {
let event = react_to_resize(entity, &mut window, new_physical_size);
// Need to send two very similar events because different systems rely on those.
window_resized.write(event.clone());
window_resized.write(event);
commands.trigger(event);
window_event.write(event.into());
}
}
Expand All @@ -418,7 +420,8 @@ pub(crate) fn changed_windows(
// If the scale factor has changed we don't query anything from winit, but send events for camera system to handle.
let event = WindowScaleFactorChanged { scale_factor: requested_scale_factor as f64, window: entity};
// Need to send two very similar events because different systems rely on those.
window_rescaled.write(event.clone());
window_rescaled.write(event);
commands.trigger(event);
window_event.write(event.into());
}
}
Expand Down