rio_window/
application.rs

1//! End user application handling.
2
3use crate::event::{DeviceEvent, DeviceId, Hook, StartCause, WindowEvent};
4use crate::event_loop::ActiveEventLoop;
5use crate::window::WindowId;
6
7/// The handler of the application events.
8pub trait ApplicationHandler<T: 'static = ()> {
9    /// Emitted when new events arrive from the OS to be processed.
10    ///
11    /// This is a useful place to put code that should be done before you start processing
12    /// events, such as updating frame timing information for benchmarking or checking the
13    /// [`StartCause`] to see if a timer set by
14    /// [`ControlFlow::WaitUntil`][crate::event_loop::ControlFlow::WaitUntil] has elapsed.
15    fn new_events(&mut self, event_loop: &ActiveEventLoop, cause: StartCause) {
16        let _ = (event_loop, cause);
17    }
18
19    /// Emitted when the application has been resumed.
20    ///
21    /// For consistency, all platforms emit a `Resumed` event even if they don't themselves have a
22    /// formal suspend/resume lifecycle. For systems without a formal suspend/resume lifecycle
23    /// the `Resumed` event is always emitted after the
24    /// [`NewEvents(StartCause::Init)`][StartCause::Init] event.
25    ///
26    /// # Portability
27    ///
28    /// It's recommended that applications should only initialize their graphics context and create
29    /// a window after they have received their first `Resumed` event. Some systems
30    /// (specifically Android) won't allow applications to create a render surface until they are
31    /// resumed.
32    ///
33    /// Considering that the implementation of [`Suspended`] and `Resumed` events may be internally
34    /// driven by multiple platform-specific events, and that there may be subtle differences across
35    /// platforms with how these internal events are delivered, it's recommended that applications
36    /// be able to gracefully handle redundant (i.e. back-to-back) [`Suspended`] or `Resumed`
37    /// events.
38    ///
39    /// Also see [`Suspended`] notes.
40    ///
41    /// ## Android
42    ///
43    /// On Android, the `Resumed` event is sent when a new [`SurfaceView`] has been created. This is
44    /// expected to closely correlate with the [`onResume`] lifecycle event but there may
45    /// technically be a discrepancy.
46    ///
47    /// [`onResume`]: https://developer.android.com/reference/android/app/Activity#onResume()
48    ///
49    /// Applications that need to run on Android must wait until they have been `Resumed`
50    /// before they will be able to create a render surface (such as an `EGLSurface`,
51    /// [`VkSurfaceKHR`] or [`wgpu::Surface`]) which depend on having a
52    /// [`SurfaceView`]. Applications must also assume that if they are [`Suspended`], then their
53    /// render surfaces are invalid and should be dropped.
54    ///
55    /// Also see [`Suspended`] notes.
56    ///
57    /// [`SurfaceView`]: https://developer.android.com/reference/android/view/SurfaceView
58    /// [Activity lifecycle]: https://developer.android.com/guide/components/activities/activity-lifecycle
59    /// [`VkSurfaceKHR`]: https://www.khronos.org/registry/vulkan/specs/1.3-extensions/man/html/VkSurfaceKHR.html
60    /// [`wgpu::Surface`]: https://docs.rs/wgpu/latest/wgpu/struct.Surface.html
61    ///
62    /// ## iOS
63    ///
64    /// On iOS, the `Resumed` event is emitted in response to an [`applicationDidBecomeActive`]
65    /// callback which means the application is "active" (according to the
66    /// [iOS application lifecycle]).
67    ///
68    /// [`applicationDidBecomeActive`]: https://developer.apple.com/documentation/uikit/uiapplicationdelegate/1622956-applicationdidbecomeactive
69    /// [iOS application lifecycle]: https://developer.apple.com/documentation/uikit/app_and_environment/managing_your_app_s_life_cycle
70    ///
71    /// ## Web
72    ///
73    /// On Web, the `Resumed` event is emitted in response to a [`pageshow`] event
74    /// with the property [`persisted`] being true, which means that the page is being
75    /// restored from the [`bfcache`] (back/forward cache) - an in-memory cache that
76    /// stores a complete snapshot of a page (including the JavaScript heap) as the
77    /// user is navigating away.
78    ///
79    /// [`pageshow`]: https://developer.mozilla.org/en-US/docs/Web/API/Window/pageshow_event
80    /// [`persisted`]: https://developer.mozilla.org/en-US/docs/Web/API/PageTransitionEvent/persisted
81    /// [`bfcache`]: https://web.dev/bfcache/
82    /// [`Suspended`]: Self::suspended
83    fn resumed(&mut self, event_loop: &ActiveEventLoop);
84
85    /// Emitted when an event is sent from [`EventLoopProxy::send_event`].
86    ///
87    /// [`EventLoopProxy::send_event`]: crate::event_loop::EventLoopProxy::send_event
88    fn user_event(&mut self, event_loop: &ActiveEventLoop, event: T) {
89        let _ = (event_loop, event);
90    }
91
92    /// Emitted when the OS sends an event to a winit window.
93    fn window_event(
94        &mut self,
95        event_loop: &ActiveEventLoop,
96        window_id: WindowId,
97        event: WindowEvent,
98    );
99
100    /// Emitted when the OS sends an event to a device.
101    fn device_event(
102        &mut self,
103        event_loop: &ActiveEventLoop,
104        device_id: DeviceId,
105        event: DeviceEvent,
106    ) {
107        let _ = (event_loop, device_id, event);
108    }
109
110    /// Emitted when the event loop is about to block and wait for new events.
111    ///
112    /// Most applications shouldn't need to hook into this event since there is no real relationship
113    /// between how often the event loop needs to wake up and the dispatching of any specific
114    /// events.
115    ///
116    /// High frequency event sources, such as input devices could potentially lead to lots of wake
117    /// ups and also lots of corresponding `AboutToWait` events.
118    ///
119    /// This is not an ideal event to drive application rendering from and instead applications
120    /// should render in response to [`WindowEvent::RedrawRequested`] events.
121    fn about_to_wait(&mut self, event_loop: &ActiveEventLoop) {
122        let _ = event_loop;
123    }
124
125    /// Emitted when the application has been suspended.
126    ///
127    /// # Portability
128    ///
129    /// Not all platforms support the notion of suspending applications, and there may be no
130    /// technical way to guarantee being able to emit a `Suspended` event if the OS has
131    /// no formal application lifecycle (currently only Android, iOS, and Web do). For this reason,
132    /// Winit does not currently try to emit pseudo `Suspended` events before the application
133    /// quits on platforms without an application lifecycle.
134    ///
135    /// Considering that the implementation of `Suspended` and [`Resumed`] events may be internally
136    /// driven by multiple platform-specific events, and that there may be subtle differences across
137    /// platforms with how these internal events are delivered, it's recommended that applications
138    /// be able to gracefully handle redundant (i.e. back-to-back) `Suspended` or [`Resumed`]
139    /// events.
140    ///
141    /// Also see [`Resumed`] notes.
142    ///
143    /// ## Android
144    ///
145    /// On Android, the `Suspended` event is only sent when the application's associated
146    /// [`SurfaceView`] is destroyed. This is expected to closely correlate with the [`onPause`]
147    /// lifecycle event but there may technically be a discrepancy.
148    ///
149    /// [`onPause`]: https://developer.android.com/reference/android/app/Activity#onPause()
150    ///
151    /// Applications that need to run on Android should assume their [`SurfaceView`] has been
152    /// destroyed, which indirectly invalidates any existing render surfaces that may have been
153    /// created outside of Winit (such as an `EGLSurface`, [`VkSurfaceKHR`] or [`wgpu::Surface`]).
154    ///
155    /// After being `Suspended` on Android applications must drop all render surfaces before
156    /// the event callback completes, which may be re-created when the application is next
157    /// [`Resumed`].
158    ///
159    /// [`SurfaceView`]: https://developer.android.com/reference/android/view/SurfaceView
160    /// [Activity lifecycle]: https://developer.android.com/guide/components/activities/activity-lifecycle
161    /// [`VkSurfaceKHR`]: https://www.khronos.org/registry/vulkan/specs/1.3-extensions/man/html/VkSurfaceKHR.html
162    /// [`wgpu::Surface`]: https://docs.rs/wgpu/latest/wgpu/struct.Surface.html
163    ///
164    /// ## iOS
165    ///
166    /// On iOS, the `Suspended` event is currently emitted in response to an
167    /// [`applicationWillResignActive`] callback which means that the application is
168    /// about to transition from the active to inactive state (according to the
169    /// [iOS application lifecycle]).
170    ///
171    /// [`applicationWillResignActive`]: https://developer.apple.com/documentation/uikit/uiapplicationdelegate/1622950-applicationwillresignactive
172    /// [iOS application lifecycle]: https://developer.apple.com/documentation/uikit/app_and_environment/managing_your_app_s_life_cycle
173    ///
174    /// ## Web
175    ///
176    /// On Web, the `Suspended` event is emitted in response to a [`pagehide`] event
177    /// with the property [`persisted`] being true, which means that the page is being
178    /// put in the [`bfcache`] (back/forward cache) - an in-memory cache that stores a
179    /// complete snapshot of a page (including the JavaScript heap) as the user is
180    /// navigating away.
181    ///
182    /// [`pagehide`]: https://developer.mozilla.org/en-US/docs/Web/API/Window/pagehide_event
183    /// [`persisted`]: https://developer.mozilla.org/en-US/docs/Web/API/PageTransitionEvent/persisted
184    /// [`bfcache`]: https://web.dev/bfcache/
185    /// [`Resumed`]: Self::resumed
186    fn suspended(&mut self, event_loop: &ActiveEventLoop) {
187        let _ = event_loop;
188    }
189
190    /// Emitted when the event loop is being shut down.
191    ///
192    /// This is irreversible - if this method is called, it is guaranteed that the event loop
193    /// will exit right after.
194    fn exiting(&mut self, event_loop: &ActiveEventLoop) {
195        let _ = event_loop;
196    }
197
198    /// Emitted when the application has received a memory warning.
199    ///
200    /// ## Platform-specific
201    ///
202    /// ### Android
203    ///
204    /// On Android, the `MemoryWarning` event is sent when [`onLowMemory`] was called. The
205    /// application must [release memory] or risk being killed.
206    ///
207    /// [`onLowMemory`]: https://developer.android.com/reference/android/app/Application.html#onLowMemory()
208    /// [release memory]: https://developer.android.com/topic/performance/memory#release
209    ///
210    /// ### iOS
211    ///
212    /// On iOS, the `MemoryWarning` event is emitted in response to an
213    /// [`applicationDidReceiveMemoryWarning`] callback. The application must free as much
214    /// memory as possible or risk being terminated, see [how to respond to memory warnings].
215    ///
216    /// [`applicationDidReceiveMemoryWarning`]: https://developer.apple.com/documentation/uikit/uiapplicationdelegate/1623063-applicationdidreceivememorywarni
217    /// [how to respond to memory warnings]: https://developer.apple.com/documentation/uikit/app_and_environment/managing_your_app_s_life_cycle/responding_to_memory_warnings
218    ///
219    /// ### Others
220    ///
221    /// - **macOS / Orbital / Wayland / Web / Windows:** Unsupported.
222    fn memory_warning(&mut self, event_loop: &ActiveEventLoop) {
223        let _ = event_loop;
224    }
225
226    fn open_urls(&mut self, event_loop: &ActiveEventLoop, urls: Vec<String>) {
227        let _ = (event_loop, urls);
228    }
229
230    fn open_config(&mut self, event_loop: &ActiveEventLoop) {
231        let _ = event_loop;
232    }
233
234    fn hook_event(&mut self, event_loop: &ActiveEventLoop, hook: &Hook) {
235        let _ = (event_loop, hook);
236    }
237}