bevy_window/
event.rs

1use alloc::string::String;
2use bevy_ecs::{entity::Entity, message::Message};
3use bevy_input::{
4    gestures::*,
5    keyboard::{KeyboardFocusLost, KeyboardInput},
6    mouse::{MouseButtonInput, MouseMotion, MouseWheel},
7    touch::TouchInput,
8};
9use bevy_math::{IVec2, Vec2};
10
11#[cfg(feature = "std")]
12use std::path::PathBuf;
13
14#[cfg(not(feature = "std"))]
15use alloc::string::String as PathBuf;
16
17#[cfg(feature = "bevy_reflect")]
18use bevy_reflect::Reflect;
19
20#[cfg(feature = "serialize")]
21use bevy_reflect::{ReflectDeserialize, ReflectSerialize};
22
23use crate::WindowTheme;
24
25/// A window event that is sent whenever a window's logical size has changed.
26#[derive(Message, Debug, Clone, PartialEq)]
27#[cfg_attr(
28    feature = "bevy_reflect",
29    derive(Reflect),
30    reflect(Debug, PartialEq, Clone)
31)]
32#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
33#[cfg_attr(
34    all(feature = "serialize", feature = "bevy_reflect"),
35    reflect(Serialize, Deserialize)
36)]
37pub struct WindowResized {
38    /// Window that has changed.
39    pub window: Entity,
40    /// The new logical width of the window.
41    pub width: f32,
42    /// The new logical height of the window.
43    pub height: f32,
44}
45
46/// An event that indicates all of the application's windows should be redrawn,
47/// even if their control flow is set to `Wait` and there have been no window events.
48#[derive(Message, Debug, Clone, PartialEq, Eq)]
49#[cfg_attr(
50    feature = "bevy_reflect",
51    derive(Reflect),
52    reflect(Debug, PartialEq, Clone)
53)]
54#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
55#[cfg_attr(
56    all(feature = "serialize", feature = "bevy_reflect"),
57    reflect(Serialize, Deserialize)
58)]
59pub struct RequestRedraw;
60
61/// An event that is sent whenever a new window is created.
62///
63/// To create a new window, spawn an entity with a [`crate::Window`] on it.
64#[derive(Message, Debug, Clone, PartialEq, Eq)]
65#[cfg_attr(
66    feature = "bevy_reflect",
67    derive(Reflect),
68    reflect(Debug, PartialEq, Clone)
69)]
70#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
71#[cfg_attr(
72    all(feature = "serialize", feature = "bevy_reflect"),
73    reflect(Serialize, Deserialize)
74)]
75pub struct WindowCreated {
76    /// Window that has been created.
77    pub window: Entity,
78}
79
80/// An event that is sent whenever the operating systems requests that a window
81/// be closed. This will be sent when the close button of the window is pressed.
82///
83/// If the default [`WindowPlugin`] is used, these events are handled
84/// by closing the corresponding [`Window`].
85/// To disable this behavior, set `close_when_requested` on the [`WindowPlugin`]
86/// to `false`.
87///
88/// [`WindowPlugin`]: crate::WindowPlugin
89/// [`Window`]: crate::Window
90#[derive(Message, Debug, Clone, PartialEq, Eq)]
91#[cfg_attr(
92    feature = "bevy_reflect",
93    derive(Reflect),
94    reflect(Debug, PartialEq, Clone)
95)]
96#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
97#[cfg_attr(
98    all(feature = "serialize", feature = "bevy_reflect"),
99    reflect(Serialize, Deserialize)
100)]
101pub struct WindowCloseRequested {
102    /// Window to close.
103    pub window: Entity,
104}
105
106/// An event that is sent whenever a window is closed. This will be sent when
107/// the window entity loses its [`Window`](crate::window::Window) component or is despawned.
108#[derive(Message, Debug, Clone, PartialEq, Eq)]
109#[cfg_attr(
110    feature = "bevy_reflect",
111    derive(Reflect),
112    reflect(Debug, PartialEq, Clone)
113)]
114#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
115#[cfg_attr(
116    all(feature = "serialize", feature = "bevy_reflect"),
117    reflect(Serialize, Deserialize)
118)]
119pub struct WindowClosed {
120    /// Window that has been closed.
121    ///
122    /// Note that this entity probably no longer exists
123    /// by the time this event is received.
124    pub window: Entity,
125}
126
127/// An event that is sent whenever a window is closing. This will be sent when
128/// after a [`WindowCloseRequested`] event is received and the window is in the process of closing.
129#[derive(Message, Debug, Clone, PartialEq, Eq)]
130#[cfg_attr(
131    feature = "bevy_reflect",
132    derive(Reflect),
133    reflect(Debug, PartialEq, Clone)
134)]
135#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
136#[cfg_attr(
137    all(feature = "serialize", feature = "bevy_reflect"),
138    reflect(Serialize, Deserialize)
139)]
140pub struct WindowClosing {
141    /// Window that has been requested to close and is the process of closing.
142    pub window: Entity,
143}
144
145/// An event that is sent whenever a window is destroyed by the underlying window system.
146///
147/// Note that if your application only has a single window, this event may be your last chance to
148/// persist state before the application terminates.
149#[derive(Message, Debug, Clone, PartialEq, Eq)]
150#[cfg_attr(
151    feature = "bevy_reflect",
152    derive(Reflect),
153    reflect(Debug, PartialEq, Clone)
154)]
155#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
156#[cfg_attr(
157    all(feature = "serialize", feature = "bevy_reflect"),
158    reflect(Serialize, Deserialize)
159)]
160pub struct WindowDestroyed {
161    /// Window that has been destroyed.
162    ///
163    /// Note that this entity probably no longer exists
164    /// by the time this event is received.
165    pub window: Entity,
166}
167
168/// An event reporting that the mouse cursor has moved inside a window.
169///
170/// The event is sent only if the cursor is over one of the application's windows.
171/// It is the translated version of [`WindowEvent::CursorMoved`] from the `winit` crate with the addition of `delta`.
172///
173/// Not to be confused with the `MouseMotion` event from `bevy_input`.
174///
175/// 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,
176/// you should not use it for non-cursor-like behavior such as 3D camera control. Please see `MouseMotion` instead.
177///
178/// [`WindowEvent::CursorMoved`]: https://docs.rs/winit/latest/winit/event/enum.WindowEvent.html#variant.CursorMoved
179#[derive(Message, Debug, Clone, PartialEq)]
180#[cfg_attr(
181    feature = "bevy_reflect",
182    derive(Reflect),
183    reflect(Debug, PartialEq, Clone)
184)]
185#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
186#[cfg_attr(
187    all(feature = "serialize", feature = "bevy_reflect"),
188    reflect(Serialize, Deserialize)
189)]
190pub struct CursorMoved {
191    /// Window that the cursor moved inside.
192    pub window: Entity,
193    /// The cursor position in logical pixels.
194    pub position: Vec2,
195    /// The change in the position of the cursor since the last event was sent.
196    /// This value is `None` if the cursor was outside the window area during the last frame.
197    // Because the range of this data is limited by the display area and it may have been
198    //  transformed by the OS to implement effects such as cursor acceleration, it should
199    // not be used to implement non-cursor-like interactions such as 3D camera control.
200    pub delta: Option<Vec2>,
201}
202
203/// An event that is sent whenever the user's cursor enters a window.
204#[derive(Message, Debug, Clone, PartialEq, Eq)]
205#[cfg_attr(
206    feature = "bevy_reflect",
207    derive(Reflect),
208    reflect(Debug, PartialEq, Clone)
209)]
210#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
211#[cfg_attr(
212    all(feature = "serialize", feature = "bevy_reflect"),
213    reflect(Serialize, Deserialize)
214)]
215pub struct CursorEntered {
216    /// Window that the cursor entered.
217    pub window: Entity,
218}
219
220/// An event that is sent whenever the user's cursor leaves a window.
221#[derive(Message, Debug, Clone, PartialEq, Eq)]
222#[cfg_attr(
223    feature = "bevy_reflect",
224    derive(Reflect),
225    reflect(Debug, PartialEq, Clone)
226)]
227#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
228#[cfg_attr(
229    all(feature = "serialize", feature = "bevy_reflect"),
230    reflect(Serialize, Deserialize)
231)]
232pub struct CursorLeft {
233    /// Window that the cursor left.
234    pub window: Entity,
235}
236
237/// An Input Method Editor event.
238///
239/// This event is the translated version of the `WindowEvent::Ime` from the `winit` crate.
240///
241/// It is only sent if IME was enabled on the window with [`Window::ime_enabled`](crate::window::Window::ime_enabled).
242#[derive(Message, Debug, Clone, PartialEq, Eq)]
243#[cfg_attr(
244    feature = "bevy_reflect",
245    derive(Reflect),
246    reflect(Debug, PartialEq, Clone)
247)]
248#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
249#[cfg_attr(
250    all(feature = "serialize", feature = "bevy_reflect"),
251    reflect(Serialize, Deserialize)
252)]
253pub enum Ime {
254    /// Notifies when a new composing text should be set at the cursor position.
255    Preedit {
256        /// Window that received the event.
257        window: Entity,
258        /// Current value.
259        value: String,
260        /// Cursor begin and end position.
261        ///
262        /// `None` indicated the cursor should be hidden
263        cursor: Option<(usize, usize)>,
264    },
265    /// Notifies when text should be inserted into the editor widget.
266    Commit {
267        /// Window that received the event.
268        window: Entity,
269        /// Input string
270        value: String,
271    },
272    /// Notifies when the IME was enabled.
273    ///
274    /// After this event, you will receive events `Ime::Preedit` and `Ime::Commit`.
275    Enabled {
276        /// Window that received the event.
277        window: Entity,
278    },
279    /// Notifies when the IME was disabled.
280    Disabled {
281        /// Window that received the event.
282        window: Entity,
283    },
284}
285
286/// An event that indicates a window has received or lost focus.
287#[derive(Message, Debug, Clone, PartialEq, Eq)]
288#[cfg_attr(
289    feature = "bevy_reflect",
290    derive(Reflect),
291    reflect(Debug, PartialEq, Clone)
292)]
293#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
294#[cfg_attr(
295    all(feature = "serialize", feature = "bevy_reflect"),
296    reflect(Serialize, Deserialize)
297)]
298pub struct WindowFocused {
299    /// Window that changed focus.
300    pub window: Entity,
301    /// Whether it was focused (true) or lost focused (false).
302    pub focused: bool,
303}
304
305/// The window has been occluded (completely hidden from view).
306///
307/// This is different to window visibility as it depends on
308/// whether the window is closed, minimized, set invisible,
309/// or fully occluded by another window.
310///
311/// It is the translated version of [`WindowEvent::Occluded`] from the `winit` crate.
312///
313/// [`WindowEvent::Occluded`]: https://docs.rs/winit/latest/winit/event/enum.WindowEvent.html#variant.Occluded
314#[derive(Message, Debug, Clone, PartialEq, Eq)]
315#[cfg_attr(
316    feature = "bevy_reflect",
317    derive(Reflect),
318    reflect(Debug, PartialEq, Clone)
319)]
320#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
321#[cfg_attr(
322    all(feature = "serialize", feature = "bevy_reflect"),
323    reflect(Serialize, Deserialize)
324)]
325pub struct WindowOccluded {
326    /// Window that changed occluded state.
327    pub window: Entity,
328    /// Whether it was occluded (true) or not occluded (false).
329    pub occluded: bool,
330}
331
332/// An event that indicates a window's scale factor has changed.
333#[derive(Message, Debug, Clone, PartialEq)]
334#[cfg_attr(
335    feature = "bevy_reflect",
336    derive(Reflect),
337    reflect(Debug, PartialEq, Clone)
338)]
339#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
340#[cfg_attr(
341    all(feature = "serialize", feature = "bevy_reflect"),
342    reflect(Serialize, Deserialize)
343)]
344pub struct WindowScaleFactorChanged {
345    /// Window that had its scale factor changed.
346    pub window: Entity,
347    /// The new scale factor.
348    pub scale_factor: f64,
349}
350
351/// An event that indicates a window's OS-reported scale factor has changed.
352#[derive(Message, Debug, Clone, PartialEq)]
353#[cfg_attr(
354    feature = "bevy_reflect",
355    derive(Reflect),
356    reflect(Debug, PartialEq, Clone)
357)]
358#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
359#[cfg_attr(
360    all(feature = "serialize", feature = "bevy_reflect"),
361    reflect(Serialize, Deserialize)
362)]
363pub struct WindowBackendScaleFactorChanged {
364    /// Window that had its scale factor changed by the backend.
365    pub window: Entity,
366    /// The new scale factor.
367    pub scale_factor: f64,
368}
369
370/// Events related to files being dragged and dropped on a window.
371#[derive(Message, Debug, Clone, PartialEq, Eq)]
372#[cfg_attr(
373    feature = "bevy_reflect",
374    derive(Reflect),
375    reflect(Debug, PartialEq, Clone)
376)]
377#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
378#[cfg_attr(
379    all(feature = "serialize", feature = "bevy_reflect"),
380    reflect(Serialize, Deserialize)
381)]
382pub enum FileDragAndDrop {
383    /// File is being dropped into a window.
384    DroppedFile {
385        /// Window the file was dropped into.
386        window: Entity,
387        /// Path to the file that was dropped in.
388        path_buf: PathBuf,
389    },
390
391    /// File is currently being hovered over a window.
392    HoveredFile {
393        /// Window a file is possibly going to be dropped into.
394        window: Entity,
395        /// Path to the file that might be dropped in.
396        path_buf: PathBuf,
397    },
398
399    /// File hovering was canceled.
400    HoveredFileCanceled {
401        /// Window that had a canceled file drop.
402        window: Entity,
403    },
404}
405
406/// An event that is sent when a window is repositioned in physical pixels.
407#[derive(Message, Debug, Clone, PartialEq, Eq)]
408#[cfg_attr(
409    feature = "bevy_reflect",
410    derive(Reflect),
411    reflect(Debug, PartialEq, Clone)
412)]
413#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
414#[cfg_attr(
415    all(feature = "serialize", feature = "bevy_reflect"),
416    reflect(Serialize, Deserialize)
417)]
418pub struct WindowMoved {
419    /// Window that moved.
420    pub window: Entity,
421    /// Where the window moved to in physical pixels.
422    pub position: IVec2,
423}
424
425/// An event sent when the system theme changes for a window.
426///
427/// This event is only sent when the window is relying on the system theme to control its appearance.
428/// i.e. It is only sent when [`Window::window_theme`](crate::window::Window::window_theme) is `None` and the system theme changes.
429#[derive(Message, Debug, Clone, PartialEq, Eq)]
430#[cfg_attr(
431    feature = "bevy_reflect",
432    derive(Reflect),
433    reflect(Debug, PartialEq, Clone)
434)]
435#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
436#[cfg_attr(
437    all(feature = "serialize", feature = "bevy_reflect"),
438    reflect(Serialize, Deserialize)
439)]
440pub struct WindowThemeChanged {
441    /// Window for which the system theme has changed.
442    pub window: Entity,
443    /// The new system theme.
444    pub theme: WindowTheme,
445}
446
447/// Application lifetime events
448#[derive(Message, Debug, Clone, Copy, PartialEq, Eq)]
449#[cfg_attr(
450    feature = "bevy_reflect",
451    derive(Reflect),
452    reflect(Debug, PartialEq, Clone)
453)]
454#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
455#[cfg_attr(
456    all(feature = "serialize", feature = "bevy_reflect"),
457    reflect(Serialize, Deserialize)
458)]
459pub enum AppLifecycle {
460    /// The application is not started yet.
461    Idle,
462    /// The application is running.
463    Running,
464    /// The application is going to be suspended.
465    /// Applications have one frame to react to this event before being paused in the background.
466    WillSuspend,
467    /// The application was suspended.
468    Suspended,
469    /// The application is going to be resumed.
470    /// Applications have one extra frame to react to this event before being fully resumed.
471    WillResume,
472}
473
474impl AppLifecycle {
475    /// Return `true` if the app can be updated.
476    #[inline]
477    pub fn is_active(&self) -> bool {
478        match self {
479            Self::Idle | Self::Suspended => false,
480            Self::Running | Self::WillSuspend | Self::WillResume => true,
481        }
482    }
483}
484
485/// Wraps all `bevy_window` and `bevy_input` events in a common enum.
486///
487/// Read these events with `MessageReader<WindowEvent>` if you need to
488/// access window events in the order they were received from the
489/// operating system. Otherwise, the event types are individually
490/// readable with `MessageReader<E>` (e.g. `MessageReader<KeyboardInput>`).
491#[derive(Message, Debug, Clone, PartialEq)]
492#[cfg_attr(
493    feature = "bevy_reflect",
494    derive(Reflect),
495    reflect(Debug, PartialEq, Clone)
496)]
497#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
498#[cfg_attr(
499    all(feature = "serialize", feature = "bevy_reflect"),
500    reflect(Serialize, Deserialize)
501)]
502pub enum WindowEvent {
503    /// An application lifecycle event.
504    AppLifecycle(AppLifecycle),
505    /// The user's cursor has entered a window.
506    CursorEntered(CursorEntered),
507    ///The user's cursor has left a window.
508    CursorLeft(CursorLeft),
509    /// The user's cursor has moved inside a window.
510    CursorMoved(CursorMoved),
511    /// A file drag and drop event.
512    FileDragAndDrop(FileDragAndDrop),
513    /// An Input Method Editor event.
514    Ime(Ime),
515    /// A redraw of all of the application's windows has been requested.
516    RequestRedraw(RequestRedraw),
517    /// The window's OS-reported scale factor has changed.
518    WindowBackendScaleFactorChanged(WindowBackendScaleFactorChanged),
519    /// The OS has requested that a window be closed.
520    WindowCloseRequested(WindowCloseRequested),
521    /// A new window has been created.
522    WindowCreated(WindowCreated),
523    /// A window has been destroyed by the underlying windowing system.
524    WindowDestroyed(WindowDestroyed),
525    /// A window has received or lost focus.
526    WindowFocused(WindowFocused),
527    /// A window has been moved.
528    WindowMoved(WindowMoved),
529    /// A window has started or stopped being occluded.
530    WindowOccluded(WindowOccluded),
531    /// A window's logical size has changed.
532    WindowResized(WindowResized),
533    /// A window's scale factor has changed.
534    WindowScaleFactorChanged(WindowScaleFactorChanged),
535    /// Sent for windows that are using the system theme when the system theme changes.
536    WindowThemeChanged(WindowThemeChanged),
537
538    /// The state of a mouse button has changed.
539    MouseButtonInput(MouseButtonInput),
540    /// The physical position of a pointing device has changed.
541    MouseMotion(MouseMotion),
542    /// The mouse wheel has moved.
543    MouseWheel(MouseWheel),
544
545    /// A two finger pinch gesture.
546    PinchGesture(PinchGesture),
547    /// A two finger rotation gesture.
548    RotationGesture(RotationGesture),
549    /// A double tap gesture.
550    DoubleTapGesture(DoubleTapGesture),
551    /// A pan gesture.
552    PanGesture(PanGesture),
553
554    /// A touch input state change.
555    TouchInput(TouchInput),
556
557    /// A keyboard input.
558    KeyboardInput(KeyboardInput),
559    /// Sent when focus has been lost for all Bevy windows.
560    ///
561    /// Used to clear pressed key state.
562    KeyboardFocusLost(KeyboardFocusLost),
563}
564
565impl From<AppLifecycle> for WindowEvent {
566    fn from(e: AppLifecycle) -> Self {
567        Self::AppLifecycle(e)
568    }
569}
570
571impl From<CursorEntered> for WindowEvent {
572    fn from(e: CursorEntered) -> Self {
573        Self::CursorEntered(e)
574    }
575}
576
577impl From<CursorLeft> for WindowEvent {
578    fn from(e: CursorLeft) -> Self {
579        Self::CursorLeft(e)
580    }
581}
582
583impl From<CursorMoved> for WindowEvent {
584    fn from(e: CursorMoved) -> Self {
585        Self::CursorMoved(e)
586    }
587}
588
589impl From<FileDragAndDrop> for WindowEvent {
590    fn from(e: FileDragAndDrop) -> Self {
591        Self::FileDragAndDrop(e)
592    }
593}
594
595impl From<Ime> for WindowEvent {
596    fn from(e: Ime) -> Self {
597        Self::Ime(e)
598    }
599}
600
601impl From<RequestRedraw> for WindowEvent {
602    fn from(e: RequestRedraw) -> Self {
603        Self::RequestRedraw(e)
604    }
605}
606
607impl From<WindowBackendScaleFactorChanged> for WindowEvent {
608    fn from(e: WindowBackendScaleFactorChanged) -> Self {
609        Self::WindowBackendScaleFactorChanged(e)
610    }
611}
612
613impl From<WindowCloseRequested> for WindowEvent {
614    fn from(e: WindowCloseRequested) -> Self {
615        Self::WindowCloseRequested(e)
616    }
617}
618
619impl From<WindowCreated> for WindowEvent {
620    fn from(e: WindowCreated) -> Self {
621        Self::WindowCreated(e)
622    }
623}
624
625impl From<WindowDestroyed> for WindowEvent {
626    fn from(e: WindowDestroyed) -> Self {
627        Self::WindowDestroyed(e)
628    }
629}
630
631impl From<WindowFocused> for WindowEvent {
632    fn from(e: WindowFocused) -> Self {
633        Self::WindowFocused(e)
634    }
635}
636
637impl From<WindowMoved> for WindowEvent {
638    fn from(e: WindowMoved) -> Self {
639        Self::WindowMoved(e)
640    }
641}
642
643impl From<WindowOccluded> for WindowEvent {
644    fn from(e: WindowOccluded) -> Self {
645        Self::WindowOccluded(e)
646    }
647}
648
649impl From<WindowResized> for WindowEvent {
650    fn from(e: WindowResized) -> Self {
651        Self::WindowResized(e)
652    }
653}
654
655impl From<WindowScaleFactorChanged> for WindowEvent {
656    fn from(e: WindowScaleFactorChanged) -> Self {
657        Self::WindowScaleFactorChanged(e)
658    }
659}
660
661impl From<WindowThemeChanged> for WindowEvent {
662    fn from(e: WindowThemeChanged) -> Self {
663        Self::WindowThemeChanged(e)
664    }
665}
666
667impl From<MouseButtonInput> for WindowEvent {
668    fn from(e: MouseButtonInput) -> Self {
669        Self::MouseButtonInput(e)
670    }
671}
672
673impl From<MouseMotion> for WindowEvent {
674    fn from(e: MouseMotion) -> Self {
675        Self::MouseMotion(e)
676    }
677}
678
679impl From<MouseWheel> for WindowEvent {
680    fn from(e: MouseWheel) -> Self {
681        Self::MouseWheel(e)
682    }
683}
684
685impl From<PinchGesture> for WindowEvent {
686    fn from(e: PinchGesture) -> Self {
687        Self::PinchGesture(e)
688    }
689}
690
691impl From<RotationGesture> for WindowEvent {
692    fn from(e: RotationGesture) -> Self {
693        Self::RotationGesture(e)
694    }
695}
696
697impl From<DoubleTapGesture> for WindowEvent {
698    fn from(e: DoubleTapGesture) -> Self {
699        Self::DoubleTapGesture(e)
700    }
701}
702
703impl From<PanGesture> for WindowEvent {
704    fn from(e: PanGesture) -> Self {
705        Self::PanGesture(e)
706    }
707}
708
709impl From<TouchInput> for WindowEvent {
710    fn from(e: TouchInput) -> Self {
711        Self::TouchInput(e)
712    }
713}
714
715impl From<KeyboardInput> for WindowEvent {
716    fn from(e: KeyboardInput) -> Self {
717        Self::KeyboardInput(e)
718    }
719}
720
721impl From<KeyboardFocusLost> for WindowEvent {
722    fn from(e: KeyboardFocusLost) -> Self {
723        Self::KeyboardFocusLost(e)
724    }
725}