Trait winit::application::ApplicationHandler

source ·
pub trait ApplicationHandler {
    // Required methods
    fn can_create_surfaces(&mut self, event_loop: &dyn ActiveEventLoop);
    fn window_event(
        &mut self,
        event_loop: &dyn ActiveEventLoop,
        window_id: WindowId,
        event: WindowEvent,
    );

    // Provided methods
    fn new_events(
        &mut self,
        event_loop: &dyn ActiveEventLoop,
        cause: StartCause,
    ) { ... }
    fn resumed(&mut self, event_loop: &dyn ActiveEventLoop) { ... }
    fn proxy_wake_up(&mut self, event_loop: &dyn ActiveEventLoop) { ... }
    fn device_event(
        &mut self,
        event_loop: &dyn ActiveEventLoop,
        device_id: DeviceId,
        event: DeviceEvent,
    ) { ... }
    fn about_to_wait(&mut self, event_loop: &dyn ActiveEventLoop) { ... }
    fn suspended(&mut self, event_loop: &dyn ActiveEventLoop) { ... }
    fn destroy_surfaces(&mut self, event_loop: &dyn ActiveEventLoop) { ... }
    fn exiting(&mut self, event_loop: &dyn ActiveEventLoop) { ... }
    fn memory_warning(&mut self, event_loop: &dyn ActiveEventLoop) { ... }
}
Expand description

The handler of the application events.

Required Methods§

source

fn can_create_surfaces(&mut self, event_loop: &dyn ActiveEventLoop)

Emitted from the point onwards the application should create render surfaces.

See destroy_surfaces().

§Portability

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.

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.

source

fn window_event( &mut self, event_loop: &dyn ActiveEventLoop, window_id: WindowId, event: WindowEvent, )

Emitted when the OS sends an event to a winit window.

Provided Methods§

source

fn new_events(&mut self, event_loop: &dyn ActiveEventLoop, cause: StartCause)

Emitted when new events arrive from the OS to be processed.

This is a useful place to put code that should be done before you start processing events, such as updating frame timing information for benchmarking or checking the StartCause to see if a timer set by ControlFlow::WaitUntil has elapsed.

source

fn resumed(&mut self, event_loop: &dyn ActiveEventLoop)

Emitted when the application has been resumed.

See suspended().

§Platform-specific
§iOS

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).

§Web

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.

§Others

Android / macOS / Orbital / Wayland / Windows / X11: Unsupported.

source

fn proxy_wake_up(&mut self, event_loop: &dyn ActiveEventLoop)

Called after a wake up is requested using EventLoopProxy::wake_up().

Multiple calls to the aforementioned method will be merged, and will only wake the event loop once; however, due to the nature of multi-threading some wake ups may appear spuriously. For these reasons, you should not rely on the number of times that this was called.

The order in which this is emitted in relation to other events is not guaranteed. The time at which this will be emitted is not guaranteed, only that it will happen “soon”. That is, there may be several executions of the event loop, including multiple redraws to windows, between EventLoopProxy::wake_up() being called and the event being delivered.

§Example

Use a std::sync::mpsc channel to handle events from a different thread.

use std::sync::mpsc;
use std::thread;
use std::time::Duration;

use winit::application::ApplicationHandler;
use winit::event_loop::{ActiveEventLoop, EventLoop};

struct MyApp {
    receiver: mpsc::Receiver<u64>,
}

impl ApplicationHandler for MyApp {
    fn proxy_wake_up(&mut self, _event_loop: &dyn ActiveEventLoop) {
        // Iterate current events, since wake-ups may have been merged.
        //
        // Note: We take care not to use `recv` or `iter` here, as those are blocking,
        // and that would be bad for performance and might lead to a deadlock.
        for i in self.receiver.try_iter() {
            println!("received: {i}");
        }
    }

    // Rest of `ApplicationHandler`
}

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let event_loop = EventLoop::new()?;

    let (sender, receiver) = mpsc::channel();

    let mut app = MyApp { receiver };

    // Send an event in a loop
    let proxy = event_loop.create_proxy();
    let background_thread = thread::spawn(move || {
        let mut i = 0;
        loop {
            println!("sending: {i}");
            if sender.send(i).is_err() {
                // Stop sending once `MyApp` is dropped
                break;
            }
            // Trigger the wake-up _after_ we placed the event in the channel.
            // Otherwise, `proxy_wake_up` might be triggered prematurely.
            proxy.wake_up();
            i += 1;
            thread::sleep(Duration::from_secs(1));
        }
    });

    event_loop.run_app(&mut app)?;

    drop(app);
    background_thread.join().unwrap();

    Ok(())
}
source

fn device_event( &mut self, event_loop: &dyn ActiveEventLoop, device_id: DeviceId, event: DeviceEvent, )

Emitted when the OS sends an event to a device.

source

fn about_to_wait(&mut self, event_loop: &dyn ActiveEventLoop)

Emitted when the event loop is about to block and wait for new events.

Most applications shouldn’t need to hook into this event since there is no real relationship between how often the event loop needs to wake up and the dispatching of any specific events.

High frequency event sources, such as input devices could potentially lead to lots of wake ups and also lots of corresponding AboutToWait events.

This is not an ideal event to drive application rendering from and instead applications should render in response to WindowEvent::RedrawRequested events.

source

fn suspended(&mut self, event_loop: &dyn ActiveEventLoop)

Emitted when the application has been suspended.

See resumed().

§Platform-specific
§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).

§Web

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.

§Others

Android / macOS / Orbital / Wayland / Windows / X11: Unsupported.

source

fn destroy_surfaces(&mut self, event_loop: &dyn ActiveEventLoop)

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.

Applications that need to run on Android should assume their SurfaceView has been 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 the event callback completes, which may be re-created when the application is next resumed.

§Others
  • iOS / macOS / Orbital / Wayland / Web / Windows / X11: Unsupported.
source

fn exiting(&mut self, event_loop: &dyn ActiveEventLoop)

Emitted when the event loop is being shut down.

This is irreversible - if this method is called, it is guaranteed that the event loop will exit right after.

source

fn memory_warning(&mut self, event_loop: &dyn ActiveEventLoop)

Emitted when the application has received a memory warning.

§Platform-specific
§Android

On Android, the MemoryWarning event is sent when onLowMemory was called. The application must release memory or risk being killed.

§iOS

On iOS, the MemoryWarning event is emitted in response to an applicationDidReceiveMemoryWarning callback. The application must free as much memory as possible or risk being terminated, see how to respond to memory warnings.

§Others
  • macOS / Orbital / Wayland / Web / Windows: Unsupported.

Implementations on Foreign Types§

source§

impl<A: ?Sized + ApplicationHandler> ApplicationHandler for &mut A

source§

fn new_events(&mut self, event_loop: &dyn ActiveEventLoop, cause: StartCause)

source§

fn resumed(&mut self, event_loop: &dyn ActiveEventLoop)

source§

fn can_create_surfaces(&mut self, event_loop: &dyn ActiveEventLoop)

source§

fn proxy_wake_up(&mut self, event_loop: &dyn ActiveEventLoop)

source§

fn window_event( &mut self, event_loop: &dyn ActiveEventLoop, window_id: WindowId, event: WindowEvent, )

source§

fn device_event( &mut self, event_loop: &dyn ActiveEventLoop, device_id: DeviceId, event: DeviceEvent, )

source§

fn about_to_wait(&mut self, event_loop: &dyn ActiveEventLoop)

source§

fn suspended(&mut self, event_loop: &dyn ActiveEventLoop)

source§

fn destroy_surfaces(&mut self, event_loop: &dyn ActiveEventLoop)

source§

fn exiting(&mut self, event_loop: &dyn ActiveEventLoop)

source§

fn memory_warning(&mut self, event_loop: &dyn ActiveEventLoop)

source§

impl<A: ?Sized + ApplicationHandler> ApplicationHandler for Box<A>

source§

fn new_events(&mut self, event_loop: &dyn ActiveEventLoop, cause: StartCause)

source§

fn resumed(&mut self, event_loop: &dyn ActiveEventLoop)

source§

fn can_create_surfaces(&mut self, event_loop: &dyn ActiveEventLoop)

source§

fn proxy_wake_up(&mut self, event_loop: &dyn ActiveEventLoop)

source§

fn window_event( &mut self, event_loop: &dyn ActiveEventLoop, window_id: WindowId, event: WindowEvent, )

source§

fn device_event( &mut self, event_loop: &dyn ActiveEventLoop, device_id: DeviceId, event: DeviceEvent, )

source§

fn about_to_wait(&mut self, event_loop: &dyn ActiveEventLoop)

source§

fn suspended(&mut self, event_loop: &dyn ActiveEventLoop)

source§

fn destroy_surfaces(&mut self, event_loop: &dyn ActiveEventLoop)

source§

fn exiting(&mut self, event_loop: &dyn ActiveEventLoop)

source§

fn memory_warning(&mut self, event_loop: &dyn ActiveEventLoop)

Implementors§