Skip to content

Commit

Permalink
Implement ApplicationHandler::can_create|destroy_surfaces() (#3765)
Browse files Browse the repository at this point in the history
  • Loading branch information
daxpedda committed Jun 29, 2024
1 parent a0d69c7 commit 75ce71f
Show file tree
Hide file tree
Showing 21 changed files with 180 additions and 116 deletions.
2 changes: 1 addition & 1 deletion examples/child_window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)))
Expand Down
2 changes: 1 addition & 1 deletion examples/control_flow.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.",
);
Expand Down
2 changes: 1 addition & 1 deletion examples/pump_events.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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());
}
Expand Down
2 changes: 1 addition & 1 deletion examples/run_on_demand.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
}
}

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));
Expand Down
4 changes: 2 additions & 2 deletions examples/window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
2 changes: 1 addition & 1 deletion examples/x11_embed.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ fn main() -> Result<(), Box<dyn Error>> {
}

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))
Expand Down
217 changes: 129 additions & 88 deletions src/application.rs

Large diffs are not rendered by default.

8 changes: 8 additions & 0 deletions src/changelog/unreleased.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
5 changes: 5 additions & 0 deletions src/event.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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());
//! }
//!
Expand Down
4 changes: 2 additions & 2 deletions src/platform_impl/android/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
6 changes: 3 additions & 3 deletions src/platform_impl/apple/appkit/app_state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
8 changes: 6 additions & 2 deletions src/platform_impl/apple/uikit/app_state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
1 change: 1 addition & 0 deletions src/platform_impl/apple/uikit/event_loop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,7 @@ fn map_user_event<A: ApplicationHandler>(
},
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),
Expand Down
6 changes: 3 additions & 3 deletions src/platform_impl/linux/wayland/event_loop/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
6 changes: 3 additions & 3 deletions src/platform_impl/linux/x11/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -505,10 +505,10 @@ impl EventLoop {
fn single_iteration<A: ApplicationHandler>(&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
Expand Down
2 changes: 1 addition & 1 deletion src/platform_impl/orbital/event_loop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
1 change: 1 addition & 0 deletions src/platform_impl/web/event_loop/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ fn handle_event<A: ApplicationHandler>(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),
Expand Down
8 changes: 5 additions & 3 deletions src/platform_impl/web/event_loop/runner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 2 additions & 0 deletions src/platform_impl/windows/event_loop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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),
Expand Down Expand Up @@ -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),
Expand Down
6 changes: 3 additions & 3 deletions src/platform_impl/windows/event_loop/runner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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();
}
Expand Down

0 comments on commit 75ce71f

Please sign in to comment.