diff --git a/examples/child_window.rs b/examples/child_window.rs index 257859db9f..9b0f305b68 100644 --- a/examples/child_window.rs +++ b/examples/child_window.rs @@ -20,7 +20,7 @@ fn main() -> Result<(), impl std::error::Error> { } impl ApplicationHandler for Application { - fn resumed(&mut self, event_loop: &ActiveEventLoop) { + fn can_create_surfaces(&mut self, event_loop: &ActiveEventLoop) { let attributes = Window::default_attributes() .with_title("parent window") .with_position(Position::Logical(LogicalPosition::new(0.0, 0.0))) diff --git a/examples/control_flow.rs b/examples/control_flow.rs index 13cc94771c..a6076ed050 100644 --- a/examples/control_flow.rs +++ b/examples/control_flow.rs @@ -67,7 +67,7 @@ impl ApplicationHandler for ControlFlowDemo { } } - fn resumed(&mut self, event_loop: &ActiveEventLoop) { + fn can_create_surfaces(&mut self, event_loop: &ActiveEventLoop) { let window_attributes = Window::default_attributes().with_title( "Press 1, 2, 3 to change control flow mode. Press R to toggle redraw requests.", ); diff --git a/examples/pump_events.rs b/examples/pump_events.rs index ad198cfafe..b9f6e78231 100644 --- a/examples/pump_events.rs +++ b/examples/pump_events.rs @@ -22,7 +22,7 @@ fn main() -> std::process::ExitCode { } impl ApplicationHandler for PumpDemo { - fn resumed(&mut self, event_loop: &ActiveEventLoop) { + fn can_create_surfaces(&mut self, event_loop: &ActiveEventLoop) { let window_attributes = Window::default_attributes().with_title("A fantastic window!"); self.window = Some(event_loop.create_window(window_attributes).unwrap()); } diff --git a/examples/run_on_demand.rs b/examples/run_on_demand.rs index 5a277de1b0..6347b0bb90 100644 --- a/examples/run_on_demand.rs +++ b/examples/run_on_demand.rs @@ -28,7 +28,7 @@ fn main() -> Result<(), Box> { } } - fn resumed(&mut self, event_loop: &ActiveEventLoop) { + fn can_create_surfaces(&mut self, event_loop: &ActiveEventLoop) { let window_attributes = Window::default_attributes() .with_title("Fantastic window number one!") .with_inner_size(winit::dpi::LogicalSize::new(128.0, 128.0)); diff --git a/examples/window.rs b/examples/window.rs index 3a2a1f72ab..c92f0ce96b 100644 --- a/examples/window.rs +++ b/examples/window.rs @@ -459,8 +459,8 @@ impl ApplicationHandler for Application { info!("Device {device_id:?} event: {event:?}"); } - fn resumed(&mut self, event_loop: &ActiveEventLoop) { - info!("Resumed the event loop"); + fn can_create_surfaces(&mut self, event_loop: &ActiveEventLoop) { + info!("Ready to create surfaces"); self.dump_monitors(event_loop); // Create initial window. diff --git a/examples/x11_embed.rs b/examples/x11_embed.rs index 9db55e5cd2..b012e5f45b 100644 --- a/examples/x11_embed.rs +++ b/examples/x11_embed.rs @@ -18,7 +18,7 @@ fn main() -> Result<(), Box> { } impl ApplicationHandler for XEmbedDemo { - fn resumed(&mut self, event_loop: &ActiveEventLoop) { + fn can_create_surfaces(&mut self, event_loop: &ActiveEventLoop) { let window_attributes = Window::default_attributes() .with_title("An embedded window!") .with_inner_size(winit::dpi::LogicalSize::new(128.0, 128.0)) diff --git a/src/application.rs b/src/application.rs index dbb9ac1d25..d63a777aa8 100644 --- a/src/application.rs +++ b/src/application.rs @@ -18,69 +18,80 @@ pub trait ApplicationHandler { /// Emitted when the application has been resumed. /// - /// For consistency, all platforms emit a `Resumed` event even if they don't themselves have a - /// formal suspend/resume lifecycle. For systems without a formal suspend/resume lifecycle - /// the `Resumed` event is always emitted after the - /// [`NewEvents(StartCause::Init)`][StartCause::Init] event. - /// - /// # Portability - /// - /// It's recommended that applications should only initialize their graphics context and create - /// a window after they have received their first `Resumed` event. Some systems - /// (specifically Android) won't allow applications to create a render surface until they are - /// resumed. - /// - /// Considering that the implementation of [`Suspended`] and `Resumed` events may be internally - /// driven by multiple platform-specific events, and that there may be subtle differences across - /// platforms with how these internal events are delivered, it's recommended that applications - /// be able to gracefully handle redundant (i.e. back-to-back) [`Suspended`] or `Resumed` - /// events. + /// See [`suspended()`][Self::suspended]. /// - /// Also see [`Suspended`] notes. + /// ## Platform-specific /// - /// ## Android + /// ### iOS /// - /// On Android, the `Resumed` event is sent when a new [`SurfaceView`] has been created. This is - /// expected to closely correlate with the [`onResume`] lifecycle event but there may - /// technically be a discrepancy. + /// On iOS, the [`resumed()`] method is called in response to an [`applicationDidBecomeActive`] + /// callback which means the application is about to transition from the inactive to active + /// state (according to the [iOS application lifecycle]). /// - /// [`onResume`]: https://developer.android.com/reference/android/app/Activity#onResume() + /// [`applicationDidBecomeActive`]: https://developer.apple.com/documentation/uikit/uiapplicationdelegate/1622956-applicationdidbecomeactive + /// [iOS application lifecycle]: https://developer.apple.com/documentation/uikit/app_and_environment/managing_your_app_s_life_cycle /// - /// Applications that need to run on Android must wait until they have been `Resumed` - /// before they will be able to create a render surface (such as an `EGLSurface`, - /// [`VkSurfaceKHR`] or [`wgpu::Surface`]) which depend on having a - /// [`SurfaceView`]. Applications must also assume that if they are [`Suspended`], then their - /// render surfaces are invalid and should be dropped. + /// ### Web /// - /// Also see [`Suspended`] notes. + /// On Web, the [`resumed()`] method is called in response to a [`pageshow`] event if the + /// page is being restored from the [`bfcache`] (back/forward cache) - an in-memory cache + /// that stores a complete snapshot of a page (including the JavaScript heap) as the user is + /// navigating away. /// - /// [`SurfaceView`]: https://developer.android.com/reference/android/view/SurfaceView - /// [Activity lifecycle]: https://developer.android.com/guide/components/activities/activity-lifecycle - /// [`VkSurfaceKHR`]: https://www.khronos.org/registry/vulkan/specs/1.3-extensions/man/html/VkSurfaceKHR.html - /// [`wgpu::Surface`]: https://docs.rs/wgpu/latest/wgpu/struct.Surface.html + /// [`pageshow`]: https://developer.mozilla.org/en-US/docs/Web/API/Window/pageshow_event + /// [`bfcache`]: https://web.dev/bfcache/ /// - /// ## iOS + /// ### Others /// - /// On iOS, the `Resumed` event is emitted in response to an [`applicationDidBecomeActive`] - /// callback which means the application is "active" (according to the - /// [iOS application lifecycle]). + /// **Android / macOS / Orbital / Wayland / Windows / X11:** Unsupported. /// - /// [`applicationDidBecomeActive`]: https://developer.apple.com/documentation/uikit/uiapplicationdelegate/1622956-applicationdidbecomeactive - /// [iOS application lifecycle]: https://developer.apple.com/documentation/uikit/app_and_environment/managing_your_app_s_life_cycle + /// [`resumed()`]: Self::resumed + fn resumed(&mut self, event_loop: &ActiveEventLoop) { + let _ = event_loop; + } + + /// Emitted from the point onwards the application should create render surfaces. /// - /// ## Web + /// See [`destroy_surfaces()`]. /// - /// On Web, the `Resumed` event is emitted in response to a [`pageshow`] event - /// with the property [`persisted`] being true, which means that the page is being - /// restored from the [`bfcache`] (back/forward cache) - an in-memory cache that - /// stores a complete snapshot of a page (including the JavaScript heap) as the - /// user is navigating away. + /// ## Portability /// - /// [`pageshow`]: https://developer.mozilla.org/en-US/docs/Web/API/Window/pageshow_event - /// [`persisted`]: https://developer.mozilla.org/en-US/docs/Web/API/PageTransitionEvent/persisted - /// [`bfcache`]: https://web.dev/bfcache/ - /// [`Suspended`]: Self::suspended - fn resumed(&mut self, event_loop: &ActiveEventLoop); + /// It's recommended that applications should only initialize their render surfaces after the + /// [`can_create_surfaces()`] method is called. Some systems (specifically Android) won't allow + /// applications to create a render surface until that point. + /// + /// For consistency, all platforms call this method even if they don't themselves have a formal + /// surface destroy/create lifecycle. For systems without a surface destroy/create lifecycle the + /// [`can_create_surfaces()`] event is always emitted after the [`StartCause::Init`] event. + /// + /// Applications should be able to gracefully handle back-to-back [`can_create_surfaces()`] and + /// [`destroy_surfaces()`] calls. + /// + /// ## Platform-specific + /// + /// ### Android + /// + /// On Android, the [`can_create_surfaces()`] method is called when a new [`SurfaceView`] has + /// been created. This is expected to closely correlate with the [`onResume`] lifecycle + /// event but there may technically be a discrepancy. + /// + /// [`onResume`]: https://developer.android.com/reference/android/app/Activity#onResume() + /// + /// Applications that need to run on Android must wait until they have been "resumed" before + /// they will be able to create a render surface (such as an `EGLSurface`, [`VkSurfaceKHR`] + /// or [`wgpu::Surface`]) which depend on having a [`SurfaceView`]. Applications must also + /// assume that if they are [suspended], then their render surfaces are invalid and should + /// be dropped. + /// + /// [suspended]: Self::destroy_surfaces + /// [`SurfaceView`]: https://developer.android.com/reference/android/view/SurfaceView + /// [Activity lifecycle]: https://developer.android.com/guide/components/activities/activity-lifecycle + /// [`VkSurfaceKHR`]: https://www.khronos.org/registry/vulkan/specs/1.3-extensions/man/html/VkSurfaceKHR.html + /// [`wgpu::Surface`]: https://docs.rs/wgpu/latest/wgpu/struct.Surface.html + /// + /// [`can_create_surfaces()`]: Self::can_create_surfaces + /// [`destroy_surfaces()`]: Self::destroy_surfaces + fn can_create_surfaces(&mut self, event_loop: &ActiveEventLoop); /// Called after a wake up is requested using [`EventLoopProxy::wake_up()`]. /// @@ -121,7 +132,7 @@ pub trait ApplicationHandler { /// # ) { /// # } /// # - /// # fn resumed(&mut self, _event_loop: &ActiveEventLoop) {} + /// # fn can_create_surfaces(&mut self, _event_loop: &ActiveEventLoop) {} /// # /// fn proxy_wake_up(&mut self, _event_loop: &ActiveEventLoop) { /// // Iterate current events, since wake-ups may have been merged. @@ -208,25 +219,47 @@ pub trait ApplicationHandler { /// Emitted when the application has been suspended. /// - /// # Portability + /// See [`resumed()`][Self::resumed]. /// - /// Not all platforms support the notion of suspending applications, and there may be no - /// technical way to guarantee being able to emit a `Suspended` event if the OS has - /// no formal application lifecycle (currently only Android, iOS, and Web do). For this reason, - /// Winit does not currently try to emit pseudo `Suspended` events before the application - /// quits on platforms without an application lifecycle. + /// ## Platform-specific /// - /// Considering that the implementation of `Suspended` and [`Resumed`] events may be internally - /// driven by multiple platform-specific events, and that there may be subtle differences across - /// platforms with how these internal events are delivered, it's recommended that applications - /// be able to gracefully handle redundant (i.e. back-to-back) `Suspended` or [`Resumed`] - /// events. + /// ### iOS + /// + /// On iOS, the [`suspended()`] method is called in response to an + /// [`applicationWillResignActive`] callback which means that the application is about to + /// transition from the active to inactive state (according to the [iOS application lifecycle]). /// - /// Also see [`Resumed`] notes. + /// [`applicationWillResignActive`]: https://developer.apple.com/documentation/uikit/uiapplicationdelegate/1622950-applicationwillresignactive + /// [iOS application lifecycle]: https://developer.apple.com/documentation/uikit/app_and_environment/managing_your_app_s_life_cycle + /// + /// ### Web /// - /// ## Android + /// On Web, the [`suspended()`] method is called in response to a [`pagehide`] event if the + /// page is being restored from the [`bfcache`] (back/forward cache) - an in-memory cache that + /// stores a complete snapshot of a page (including the JavaScript heap) as the user is + /// navigating away. /// - /// On Android, the `Suspended` event is only sent when the application's associated + /// [`pagehide`]: https://developer.mozilla.org/en-US/docs/Web/API/Window/pagehide_event + /// [`bfcache`]: https://web.dev/bfcache/ + /// + /// ### Others + /// + /// **Android / macOS / Orbital / Wayland / Windows / X11:** Unsupported. + /// + /// [`suspended()`]: Self::suspended + fn suspended(&mut self, event_loop: &ActiveEventLoop) { + let _ = event_loop; + } + + /// Emitted when the application must destroy its render surfaces. + /// + /// See [`can_create_surfaces()`] for more details. + /// + /// ## Platform-specific + /// + /// ### Android + /// + /// On Android, the [`destroy_surfaces()`] method is called when the application's associated /// [`SurfaceView`] is destroyed. This is expected to closely correlate with the [`onPause`] /// lifecycle event but there may technically be a discrepancy. /// @@ -236,38 +269,24 @@ pub trait ApplicationHandler { /// destroyed, which indirectly invalidates any existing render surfaces that may have been /// created outside of Winit (such as an `EGLSurface`, [`VkSurfaceKHR`] or [`wgpu::Surface`]). /// - /// After being `Suspended` on Android applications must drop all render surfaces before + /// After being [suspended] on Android applications must drop all render surfaces before /// the event callback completes, which may be re-created when the application is next - /// [`Resumed`]. + /// [resumed]. /// + /// [suspended]: Self::destroy_surfaces + /// [resumed]: Self::can_create_surfaces /// [`SurfaceView`]: https://developer.android.com/reference/android/view/SurfaceView /// [Activity lifecycle]: https://developer.android.com/guide/components/activities/activity-lifecycle /// [`VkSurfaceKHR`]: https://www.khronos.org/registry/vulkan/specs/1.3-extensions/man/html/VkSurfaceKHR.html /// [`wgpu::Surface`]: https://docs.rs/wgpu/latest/wgpu/struct.Surface.html /// - /// ## iOS - /// - /// On iOS, the `Suspended` event is currently emitted in response to an - /// [`applicationWillResignActive`] callback which means that the application is - /// about to transition from the active to inactive state (according to the - /// [iOS application lifecycle]). - /// - /// [`applicationWillResignActive`]: https://developer.apple.com/documentation/uikit/uiapplicationdelegate/1622950-applicationwillresignactive - /// [iOS application lifecycle]: https://developer.apple.com/documentation/uikit/app_and_environment/managing_your_app_s_life_cycle - /// - /// ## Web + /// ### Others /// - /// On Web, the `Suspended` event is emitted in response to a [`pagehide`] event - /// with the property [`persisted`] being true, which means that the page is being - /// put in the [`bfcache`] (back/forward cache) - an in-memory cache that stores a - /// complete snapshot of a page (including the JavaScript heap) as the user is - /// navigating away. + /// - **iOS / macOS / Orbital / Wayland / Web / Windows / X11:** Unsupported. /// - /// [`pagehide`]: https://developer.mozilla.org/en-US/docs/Web/API/Window/pagehide_event - /// [`persisted`]: https://developer.mozilla.org/en-US/docs/Web/API/PageTransitionEvent/persisted - /// [`bfcache`]: https://web.dev/bfcache/ - /// [`Resumed`]: Self::resumed - fn suspended(&mut self, event_loop: &ActiveEventLoop) { + /// [`can_create_surfaces()`]: Self::can_create_surfaces + /// [`destroy_surfaces()`]: Self::destroy_surfaces + fn destroy_surfaces(&mut self, event_loop: &ActiveEventLoop) { let _ = event_loop; } @@ -308,6 +327,7 @@ pub trait ApplicationHandler { } } +#[deny(clippy::missing_trait_methods)] impl ApplicationHandler for &mut A { #[inline] fn new_events(&mut self, event_loop: &ActiveEventLoop, cause: StartCause) { @@ -319,6 +339,11 @@ impl ApplicationHandler for &mut A { (**self).resumed(event_loop); } + #[inline] + fn can_create_surfaces(&mut self, event_loop: &ActiveEventLoop) { + (**self).can_create_surfaces(event_loop); + } + #[inline] fn proxy_wake_up(&mut self, event_loop: &ActiveEventLoop) { (**self).proxy_wake_up(event_loop); @@ -354,6 +379,11 @@ impl ApplicationHandler for &mut A { (**self).suspended(event_loop); } + #[inline] + fn destroy_surfaces(&mut self, event_loop: &ActiveEventLoop) { + (**self).destroy_surfaces(event_loop); + } + #[inline] fn exiting(&mut self, event_loop: &ActiveEventLoop) { (**self).exiting(event_loop); @@ -365,6 +395,7 @@ impl ApplicationHandler for &mut A { } } +#[deny(clippy::missing_trait_methods)] impl ApplicationHandler for Box { #[inline] fn new_events(&mut self, event_loop: &ActiveEventLoop, cause: StartCause) { @@ -376,6 +407,11 @@ impl ApplicationHandler for Box { (**self).resumed(event_loop); } + #[inline] + fn can_create_surfaces(&mut self, event_loop: &ActiveEventLoop) { + (**self).can_create_surfaces(event_loop); + } + #[inline] fn proxy_wake_up(&mut self, event_loop: &ActiveEventLoop) { (**self).proxy_wake_up(event_loop); @@ -411,6 +447,11 @@ impl ApplicationHandler for Box { (**self).suspended(event_loop); } + #[inline] + fn destroy_surfaces(&mut self, event_loop: &ActiveEventLoop) { + (**self).destroy_surfaces(event_loop); + } + #[inline] fn exiting(&mut self, event_loop: &ActiveEventLoop) { (**self).exiting(event_loop); diff --git a/src/changelog/unreleased.md b/src/changelog/unreleased.md index ebea7a3a6d..09795e9104 100644 --- a/src/changelog/unreleased.md +++ b/src/changelog/unreleased.md @@ -57,6 +57,14 @@ changelog entry. - Changed `EventLoopProxy::send_event` to `EventLoopProxy::wake_up`, it now only wakes up the loop. - On Web, slightly improve accuracy of `DeviceEvent::MouseMotion`. +- `ApplicationHandler::create|destroy_surfaces()` was split off from + `ApplicationHandler::resumed/suspended()`. + + `ApplicationHandler::can_create_surfaces()` should, for portability reasons + to Android, be the only place to create render surfaces. + + `ApplicationHandler::resumed/suspended()` are now only emitted by iOS and Web + and now signify actually resuming/suspending the application. ### Removed diff --git a/src/event.rs b/src/event.rs index 22d31eca48..86a992e2e2 100644 --- a/src/event.rs +++ b/src/event.rs @@ -85,6 +85,11 @@ pub(crate) enum Event { /// [`ApplicationHandler::suspended`]: crate::application::ApplicationHandler::suspended Suspended, + /// See [`ApplicationHandler::can_create_surfaces`] for details. + /// + /// [`ApplicationHandler::can_create_surfaces`]: crate::application::ApplicationHandler::can_create_surfaces + CreateSurfaces, + /// See [`ApplicationHandler::resumed`] for details. /// /// [`ApplicationHandler::resumed`]: crate::application::ApplicationHandler::resumed diff --git a/src/lib.rs b/src/lib.rs index f93eeddc2e..57a3bb62c2 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -52,7 +52,7 @@ //! } //! //! impl ApplicationHandler for App { -//! fn resumed(&mut self, event_loop: &ActiveEventLoop) { +//! fn can_create_surfaces(&mut self, event_loop: &ActiveEventLoop) { //! self.window = Some(event_loop.create_window(Window::default_attributes()).unwrap()); //! } //! diff --git a/src/platform_impl/android/mod.rs b/src/platform_impl/android/mod.rs index 371b11befe..e471a72cdc 100644 --- a/src/platform_impl/android/mod.rs +++ b/src/platform_impl/android/mod.rs @@ -176,10 +176,10 @@ impl EventLoop { match event { MainEvent::InitWindow { .. } => { - app.resumed(self.window_target()); + app.can_create_surfaces(self.window_target()); }, MainEvent::TerminateWindow { .. } => { - app.suspended(self.window_target()); + app.destroy_surfaces(self.window_target()); }, MainEvent::WindowResized { .. } => resized = true, MainEvent::RedrawNeeded { .. } => pending_redraw = true, diff --git a/src/platform_impl/apple/appkit/app_state.rs b/src/platform_impl/apple/appkit/app_state.rs index 0218af4a16..e0ed74c5af 100644 --- a/src/platform_impl/apple/appkit/app_state.rs +++ b/src/platform_impl/apple/appkit/app_state.rs @@ -314,9 +314,9 @@ impl ApplicationDelegate { /// dispatch `NewEvents(Init)` + `Resumed` pub fn dispatch_init_events(&self) { self.with_handler(|app, event_loop| app.new_events(event_loop, StartCause::Init)); - // NB: For consistency all platforms must emit a 'resumed' event even though macOS - // applications don't themselves have a formal suspend/resume lifecycle. - self.with_handler(|app, event_loop| app.resumed(event_loop)); + // NB: For consistency all platforms must call `can_create_surfaces` even though macOS + // applications don't themselves have a formal surface destroy/create lifecycle. + self.with_handler(|app, event_loop| app.can_create_surfaces(event_loop)); } // Called by RunLoopObserver after finishing waiting for new events diff --git a/src/platform_impl/apple/uikit/app_state.rs b/src/platform_impl/apple/uikit/app_state.rs index 0bf0b16b63..0f79962fa0 100644 --- a/src/platform_impl/apple/uikit/app_state.rs +++ b/src/platform_impl/apple/uikit/app_state.rs @@ -496,8 +496,12 @@ pub fn did_finish_launching(mtm: MainThreadMarker) { let (windows, events) = AppState::get_mut(mtm).did_finish_launching_transition(); - let events = std::iter::once(EventWrapper::StaticEvent(Event::NewEvents(StartCause::Init))) - .chain(events); + let events = [ + EventWrapper::StaticEvent(Event::NewEvents(StartCause::Init)), + EventWrapper::StaticEvent(Event::CreateSurfaces), + ] + .into_iter() + .chain(events); handle_nonuser_events(mtm, events); // the above window dance hack, could possibly trigger new windows to be created. diff --git a/src/platform_impl/apple/uikit/event_loop.rs b/src/platform_impl/apple/uikit/event_loop.rs index 69d5bb4585..d628d25581 100644 --- a/src/platform_impl/apple/uikit/event_loop.rs +++ b/src/platform_impl/apple/uikit/event_loop.rs @@ -130,6 +130,7 @@ fn map_user_event( }, Event::Suspended => app.suspended(window_target), Event::Resumed => app.resumed(window_target), + Event::CreateSurfaces => app.can_create_surfaces(window_target), Event::AboutToWait => app.about_to_wait(window_target), Event::LoopExiting => app.exiting(window_target), Event::MemoryWarning => app.memory_warning(window_target), diff --git a/src/platform_impl/linux/wayland/event_loop/mod.rs b/src/platform_impl/linux/wayland/event_loop/mod.rs index 59e03c3316..1135af8b25 100644 --- a/src/platform_impl/linux/wayland/event_loop/mod.rs +++ b/src/platform_impl/linux/wayland/event_loop/mod.rs @@ -301,10 +301,10 @@ impl EventLoop { app.new_events(&self.window_target, cause); - // NB: For consistency all platforms must emit a 'resumed' event even though Wayland - // applications don't themselves have a formal suspend/resume lifecycle. + // NB: For consistency all platforms must call `can_create_surfaces` even though Wayland + // applications don't themselves have a formal surface destroy/create lifecycle. if cause == StartCause::Init { - app.resumed(&self.window_target); + app.can_create_surfaces(&self.window_target); } // Indicate user wake up. diff --git a/src/platform_impl/linux/x11/mod.rs b/src/platform_impl/linux/x11/mod.rs index e057ae2066..a2a7382c88 100644 --- a/src/platform_impl/linux/x11/mod.rs +++ b/src/platform_impl/linux/x11/mod.rs @@ -505,10 +505,10 @@ impl EventLoop { fn single_iteration(&mut self, app: &mut A, cause: StartCause) { app.new_events(&self.event_processor.target, cause); - // NB: For consistency all platforms must emit a 'resumed' event even though X11 - // applications don't themselves have a formal suspend/resume lifecycle. + // NB: For consistency all platforms must call `can_create_surfaces` even though X11 + // applications don't themselves have a formal surface destroy/create lifecycle. if cause == StartCause::Init { - app.resumed(&self.event_processor.target) + app.can_create_surfaces(&self.event_processor.target) } // Process all pending events diff --git a/src/platform_impl/orbital/event_loop.rs b/src/platform_impl/orbital/event_loop.rs index eea7cfd961..06f85b3631 100644 --- a/src/platform_impl/orbital/event_loop.rs +++ b/src/platform_impl/orbital/event_loop.rs @@ -507,7 +507,7 @@ impl EventLoop { app.new_events(&self.window_target, start_cause); if start_cause == StartCause::Init { - app.resumed(&self.window_target); + app.can_create_surfaces(&self.window_target); } // Handle window creates. diff --git a/src/platform_impl/web/event_loop/mod.rs b/src/platform_impl/web/event_loop/mod.rs index 860b97464f..874ab70be0 100644 --- a/src/platform_impl/web/event_loop/mod.rs +++ b/src/platform_impl/web/event_loop/mod.rs @@ -87,6 +87,7 @@ fn handle_event(app: &mut A, target: &RootActiveEventLoop Event::UserWakeUp => app.proxy_wake_up(target), Event::Suspended => app.suspended(target), Event::Resumed => app.resumed(target), + Event::CreateSurfaces => app.can_create_surfaces(target), Event::AboutToWait => app.about_to_wait(target), Event::LoopExiting => app.exiting(target), Event::MemoryWarning => app.memory_warning(target), diff --git a/src/platform_impl/web/event_loop/runner.rs b/src/platform_impl/web/event_loop/runner.rs index b47421abd2..d7a23d5f4e 100644 --- a/src/platform_impl/web/event_loop/runner.rs +++ b/src/platform_impl/web/event_loop/runner.rs @@ -441,9 +441,11 @@ impl Shared { } pub fn init(&self) { - // NB: For consistency all platforms must emit a 'resumed' event even though web - // applications don't themselves have a formal suspend/resume lifecycle. - self.run_until_cleared([Event::NewEvents(StartCause::Init), Event::Resumed].into_iter()); + // NB: For consistency all platforms must call `can_create_surfaces` even though web + // applications don't themselves have a formal surface destroy/create lifecycle. + self.run_until_cleared( + [Event::NewEvents(StartCause::Init), Event::CreateSurfaces].into_iter(), + ); } // Run the polling logic for the Poll ControlFlow, which involves clearing the queue diff --git a/src/platform_impl/windows/event_loop.rs b/src/platform_impl/windows/event_loop.rs index 66cf9ff65c..e2d201ba37 100644 --- a/src/platform_impl/windows/event_loop.rs +++ b/src/platform_impl/windows/event_loop.rs @@ -216,6 +216,7 @@ impl EventLoop { Event::UserWakeUp => app.proxy_wake_up(event_loop_windows_ref), Event::Suspended => app.suspended(event_loop_windows_ref), Event::Resumed => app.resumed(event_loop_windows_ref), + Event::CreateSurfaces => app.can_create_surfaces(event_loop_windows_ref), Event::AboutToWait => app.about_to_wait(event_loop_windows_ref), Event::LoopExiting => app.exiting(event_loop_windows_ref), Event::MemoryWarning => app.memory_warning(event_loop_windows_ref), @@ -281,6 +282,7 @@ impl EventLoop { Event::UserWakeUp => app.proxy_wake_up(event_loop_windows_ref), Event::Suspended => app.suspended(event_loop_windows_ref), Event::Resumed => app.resumed(event_loop_windows_ref), + Event::CreateSurfaces => app.can_create_surfaces(event_loop_windows_ref), Event::AboutToWait => app.about_to_wait(event_loop_windows_ref), Event::LoopExiting => app.exiting(event_loop_windows_ref), Event::MemoryWarning => app.memory_warning(event_loop_windows_ref), diff --git a/src/platform_impl/windows/event_loop/runner.rs b/src/platform_impl/windows/event_loop/runner.rs index d350861538..f6ecabac2c 100644 --- a/src/platform_impl/windows/event_loop/runner.rs +++ b/src/platform_impl/windows/event_loop/runner.rs @@ -345,10 +345,10 @@ impl EventLoopRunner { }, }; self.call_event_handler(Event::NewEvents(start_cause)); - // NB: For consistency all platforms must emit a 'resumed' event even though Windows - // applications don't themselves have a formal suspend/resume lifecycle. + // NB: For consistency all platforms must call `can_create_surfaces` even though Windows + // applications don't themselves have a formal surface destroy/create lifecycle. if init { - self.call_event_handler(Event::Resumed); + self.call_event_handler(Event::CreateSurfaces); } self.dispatch_buffered_events(); }