bevy_window/event.rs
1#![allow(deprecated)]
2use std::path::PathBuf;
3
4use bevy_ecs::entity::Entity;
5use bevy_ecs::event::Event;
6use bevy_math::{IVec2, Vec2};
7use bevy_reflect::Reflect;
8use smol_str::SmolStr;
9
10#[cfg(feature = "serialize")]
11use bevy_reflect::{ReflectDeserialize, ReflectSerialize};
12
13use crate::WindowTheme;
14
15/// A window event that is sent whenever a window's logical size has changed.
16#[derive(Event, Debug, Clone, PartialEq, Reflect)]
17#[reflect(Debug, PartialEq)]
18#[cfg_attr(
19 feature = "serialize",
20 derive(serde::Serialize, serde::Deserialize),
21 reflect(Serialize, Deserialize)
22)]
23pub struct WindowResized {
24 /// Window that has changed.
25 pub window: Entity,
26 /// The new logical width of the window.
27 pub width: f32,
28 /// The new logical height of the window.
29 pub height: f32,
30}
31
32/// An event that indicates all of the application's windows should be redrawn,
33/// even if their control flow is set to `Wait` and there have been no window events.
34#[derive(Event, Debug, Clone, PartialEq, Eq, Reflect)]
35#[reflect(Debug, PartialEq)]
36#[cfg_attr(
37 feature = "serialize",
38 derive(serde::Serialize, serde::Deserialize),
39 reflect(Serialize, Deserialize)
40)]
41pub struct RequestRedraw;
42
43/// An event that is sent whenever a new window is created.
44///
45/// To create a new window, spawn an entity with a [`crate::Window`] on it.
46#[derive(Event, Debug, Clone, PartialEq, Eq, Reflect)]
47#[reflect(Debug, PartialEq)]
48#[cfg_attr(
49 feature = "serialize",
50 derive(serde::Serialize, serde::Deserialize),
51 reflect(Serialize, Deserialize)
52)]
53pub struct WindowCreated {
54 /// Window that has been created.
55 pub window: Entity,
56}
57
58/// An event that is sent whenever the operating systems requests that a window
59/// be closed. This will be sent when the close button of the window is pressed.
60///
61/// If the default [`WindowPlugin`] is used, these events are handled
62/// by closing the corresponding [`Window`].
63/// To disable this behavior, set `close_when_requested` on the [`WindowPlugin`]
64/// to `false`.
65///
66/// [`WindowPlugin`]: crate::WindowPlugin
67/// [`Window`]: crate::Window
68#[derive(Event, Debug, Clone, PartialEq, Eq, Reflect)]
69#[reflect(Debug, PartialEq)]
70#[cfg_attr(
71 feature = "serialize",
72 derive(serde::Serialize, serde::Deserialize),
73 reflect(Serialize, Deserialize)
74)]
75pub struct WindowCloseRequested {
76 /// Window to close.
77 pub window: Entity,
78}
79
80/// An event that is sent whenever a window is closed. This will be sent when
81/// the window entity loses its [`Window`](crate::window::Window) component or is despawned.
82#[derive(Event, Debug, Clone, PartialEq, Eq, Reflect)]
83#[reflect(Debug, PartialEq)]
84#[cfg_attr(
85 feature = "serialize",
86 derive(serde::Serialize, serde::Deserialize),
87 reflect(Serialize, Deserialize)
88)]
89pub struct WindowClosed {
90 /// Window that has been closed.
91 ///
92 /// Note that this entity probably no longer exists
93 /// by the time this event is received.
94 pub window: Entity,
95}
96
97/// An event that is sent whenever a window is closing. This will be sent when
98/// after a [`WindowCloseRequested`] event is received and the window is in the process of closing.
99#[derive(Event, Debug, Clone, PartialEq, Eq, Reflect)]
100#[reflect(Debug, PartialEq)]
101#[cfg_attr(
102 feature = "serialize",
103 derive(serde::Serialize, serde::Deserialize),
104 reflect(Serialize, Deserialize)
105)]
106pub struct WindowClosing {
107 /// Window that has been requested to close and is the process of closing.
108 pub window: Entity,
109}
110
111/// An event that is sent whenever a window is destroyed by the underlying window system.
112///
113/// Note that if your application only has a single window, this event may be your last chance to
114/// persist state before the application terminates.
115#[derive(Event, Debug, Clone, PartialEq, Eq, Reflect)]
116#[reflect(Debug, PartialEq)]
117#[cfg_attr(
118 feature = "serialize",
119 derive(serde::Serialize, serde::Deserialize),
120 reflect(Serialize, Deserialize)
121)]
122pub struct WindowDestroyed {
123 /// Window that has been destroyed.
124 ///
125 /// Note that this entity probably no longer exists
126 /// by the time this event is received.
127 pub window: Entity,
128}
129
130/// An event reporting that the mouse cursor has moved inside a window.
131///
132/// The event is sent only if the cursor is over one of the application's windows.
133/// It is the translated version of [`WindowEvent::CursorMoved`] from the `winit` crate with the addition of `delta`.
134///
135/// Not to be confused with the `MouseMotion` event from `bevy_input`.
136///
137/// Because the range of data is limited by the window area and it may have been transformed by the OS to implement certain effects like acceleration,
138/// you should not use it for non-cursor-like behaviour such as 3D camera control. Please see `MouseMotion` instead.
139///
140/// [`WindowEvent::CursorMoved`]: https://docs.rs/winit/latest/winit/event/enum.WindowEvent.html#variant.CursorMoved
141#[derive(Event, Debug, Clone, PartialEq, Reflect)]
142#[reflect(Debug, PartialEq)]
143#[cfg_attr(
144 feature = "serialize",
145 derive(serde::Serialize, serde::Deserialize),
146 reflect(Serialize, Deserialize)
147)]
148pub struct CursorMoved {
149 /// Window that the cursor moved inside.
150 pub window: Entity,
151 /// The cursor position in logical pixels.
152 pub position: Vec2,
153 /// The change in the position of the cursor since the last event was sent.
154 /// This value is `None` if the cursor was outside the window area during the last frame.
155 //
156 // Because the range of this data is limited by the display area and it may have been
157 // transformed by the OS to implement effects such as cursor acceleration, it should
158 // not be used to implement non-cursor-like interactions such as 3D camera control.
159 pub delta: Option<Vec2>,
160}
161
162/// An event that is sent whenever the user's cursor enters a window.
163#[derive(Event, Debug, Clone, PartialEq, Eq, Reflect)]
164#[reflect(Debug, PartialEq)]
165#[cfg_attr(
166 feature = "serialize",
167 derive(serde::Serialize, serde::Deserialize),
168 reflect(Serialize, Deserialize)
169)]
170pub struct CursorEntered {
171 /// Window that the cursor entered.
172 pub window: Entity,
173}
174
175/// An event that is sent whenever the user's cursor leaves a window.
176#[derive(Event, Debug, Clone, PartialEq, Eq, Reflect)]
177#[reflect(Debug, PartialEq)]
178#[cfg_attr(
179 feature = "serialize",
180 derive(serde::Serialize, serde::Deserialize),
181 reflect(Serialize, Deserialize)
182)]
183pub struct CursorLeft {
184 /// Window that the cursor left.
185 pub window: Entity,
186}
187
188/// An event that is sent whenever a window receives a character from the OS or underlying system.
189#[deprecated(since = "0.14.0", note = "Use `KeyboardInput` instead.")]
190#[derive(Event, Debug, Clone, PartialEq, Eq, Reflect)]
191#[reflect(Debug, PartialEq)]
192#[cfg_attr(
193 feature = "serialize",
194 derive(serde::Serialize, serde::Deserialize),
195 reflect(Serialize, Deserialize)
196)]
197pub struct ReceivedCharacter {
198 /// Window that received the character.
199 pub window: Entity,
200 /// Received character.
201 pub char: SmolStr,
202}
203
204/// A Input Method Editor event.
205///
206/// This event is the translated version of the `WindowEvent::Ime` from the `winit` crate.
207///
208/// It is only sent if IME was enabled on the window with [`Window::ime_enabled`](crate::window::Window::ime_enabled).
209#[derive(Event, Debug, Clone, PartialEq, Eq, Reflect)]
210#[reflect(Debug, PartialEq)]
211#[cfg_attr(
212 feature = "serialize",
213 derive(serde::Serialize, serde::Deserialize),
214 reflect(Serialize, Deserialize)
215)]
216pub enum Ime {
217 /// Notifies when a new composing text should be set at the cursor position.
218 Preedit {
219 /// Window that received the event.
220 window: Entity,
221 /// Current value.
222 value: String,
223 /// Cursor begin and end position.
224 ///
225 /// `None` indicated the cursor should be hidden
226 cursor: Option<(usize, usize)>,
227 },
228 /// Notifies when text should be inserted into the editor widget.
229 Commit {
230 /// Window that received the event.
231 window: Entity,
232 /// Input string
233 value: String,
234 },
235 /// Notifies when the IME was enabled.
236 ///
237 /// After this event, you will receive events `Ime::Preedit` and `Ime::Commit`,
238 /// and stop receiving events [`ReceivedCharacter`].
239 Enabled {
240 /// Window that received the event.
241 window: Entity,
242 },
243 /// Notifies when the IME was disabled.
244 Disabled {
245 /// Window that received the event.
246 window: Entity,
247 },
248}
249
250/// An event that indicates a window has received or lost focus.
251#[derive(Event, Debug, Clone, PartialEq, Eq, Reflect)]
252#[reflect(Debug, PartialEq)]
253#[cfg_attr(
254 feature = "serialize",
255 derive(serde::Serialize, serde::Deserialize),
256 reflect(Serialize, Deserialize)
257)]
258pub struct WindowFocused {
259 /// Window that changed focus.
260 pub window: Entity,
261 /// Whether it was focused (true) or lost focused (false).
262 pub focused: bool,
263}
264
265/// The window has been occluded (completely hidden from view).
266///
267/// This is different to window visibility as it depends on
268/// whether the window is closed, minimised, set invisible,
269/// or fully occluded by another window.
270///
271/// It is the translated version of [`WindowEvent::Occluded`] from the `winit` crate.
272///
273/// [`WindowEvent::Occluded`]: https://docs.rs/winit/latest/winit/event/enum.WindowEvent.html#variant.Occluded
274#[derive(Event, Debug, Clone, PartialEq, Eq, Reflect)]
275#[reflect(Debug, PartialEq)]
276#[cfg_attr(
277 feature = "serialize",
278 derive(serde::Serialize, serde::Deserialize),
279 reflect(Serialize, Deserialize)
280)]
281pub struct WindowOccluded {
282 /// Window that changed occluded state.
283 pub window: Entity,
284 /// Whether it was occluded (true) or not occluded (false).
285 pub occluded: bool,
286}
287
288/// An event that indicates a window's scale factor has changed.
289#[derive(Event, Debug, Clone, PartialEq, Reflect)]
290#[reflect(Debug, PartialEq)]
291#[cfg_attr(
292 feature = "serialize",
293 derive(serde::Serialize, serde::Deserialize),
294 reflect(Serialize, Deserialize)
295)]
296pub struct WindowScaleFactorChanged {
297 /// Window that had its scale factor changed.
298 pub window: Entity,
299 /// The new scale factor.
300 pub scale_factor: f64,
301}
302
303/// An event that indicates a window's OS-reported scale factor has changed.
304#[derive(Event, Debug, Clone, PartialEq, Reflect)]
305#[reflect(Debug, PartialEq)]
306#[cfg_attr(
307 feature = "serialize",
308 derive(serde::Serialize, serde::Deserialize),
309 reflect(Serialize, Deserialize)
310)]
311pub struct WindowBackendScaleFactorChanged {
312 /// Window that had its scale factor changed by the backend.
313 pub window: Entity,
314 /// The new scale factor.
315 pub scale_factor: f64,
316}
317
318/// Events related to files being dragged and dropped on a window.
319#[derive(Event, Debug, Clone, PartialEq, Eq, Reflect)]
320#[reflect(Debug, PartialEq)]
321#[cfg_attr(
322 feature = "serialize",
323 derive(serde::Serialize, serde::Deserialize),
324 reflect(Serialize, Deserialize)
325)]
326pub enum FileDragAndDrop {
327 /// File is being dropped into a window.
328 DroppedFile {
329 /// Window the file was dropped into.
330 window: Entity,
331 /// Path to the file that was dropped in.
332 path_buf: PathBuf,
333 },
334
335 /// File is currently being hovered over a window.
336 HoveredFile {
337 /// Window a file is possibly going to be dropped into.
338 window: Entity,
339 /// Path to the file that might be dropped in.
340 path_buf: PathBuf,
341 },
342
343 /// File hovering was canceled.
344 HoveredFileCanceled {
345 /// Window that had a canceled file drop.
346 window: Entity,
347 },
348}
349
350/// An event that is sent when a window is repositioned in physical pixels.
351#[derive(Event, Debug, Clone, PartialEq, Eq, Reflect)]
352#[reflect(Debug, PartialEq)]
353#[cfg_attr(
354 feature = "serialize",
355 derive(serde::Serialize, serde::Deserialize),
356 reflect(Serialize, Deserialize)
357)]
358pub struct WindowMoved {
359 /// Window that moved.
360 pub window: Entity,
361 /// Where the window moved to in physical pixels.
362 pub position: IVec2,
363}
364
365/// An event sent when the system theme changes for a window.
366///
367/// This event is only sent when the window is relying on the system theme to control its appearance.
368/// i.e. It is only sent when [`Window::window_theme`](crate::window::Window::window_theme) is `None` and the system theme changes.
369#[derive(Event, Debug, Clone, PartialEq, Eq, Reflect)]
370#[reflect(Debug, PartialEq)]
371#[cfg_attr(
372 feature = "serialize",
373 derive(serde::Serialize, serde::Deserialize),
374 reflect(Serialize, Deserialize)
375)]
376pub struct WindowThemeChanged {
377 /// Window for which the system theme has changed.
378 pub window: Entity,
379 /// The new system theme.
380 pub theme: WindowTheme,
381}
382
383/// Application lifetime events
384#[derive(Event, Debug, Clone, Copy, PartialEq, Eq, Reflect)]
385#[reflect(Debug, PartialEq)]
386#[cfg_attr(
387 feature = "serialize",
388 derive(serde::Serialize, serde::Deserialize),
389 reflect(Serialize, Deserialize)
390)]
391pub enum AppLifecycle {
392 /// The application is not started yet.
393 Idle,
394 /// The application is running.
395 Running,
396 /// The application is going to be suspended.
397 /// Applications have one frame to react to this event before being paused in the background.
398 WillSuspend,
399 /// The application was suspended.
400 Suspended,
401 /// The application is going to be resumed.
402 /// Applications have one extra frame to react to this event before being fully resumed.
403 WillResume,
404}
405
406impl AppLifecycle {
407 /// Return `true` if the app can be updated.
408 #[inline]
409 pub fn is_active(&self) -> bool {
410 match self {
411 Self::Idle | Self::Suspended => false,
412 Self::Running | Self::WillSuspend | Self::WillResume => true,
413 }
414 }
415}