2020-05-04 15:14:13 -04:00
|
|
|
use std::any::Any;
|
|
|
|
|
use std::cell::{Cell, RefCell};
|
2023-06-18 11:42:57 +01:00
|
|
|
use std::collections::VecDeque;
|
2025-03-01 12:09:59 +01:00
|
|
|
use std::rc::Rc;
|
2023-07-31 00:39:01 +04:00
|
|
|
use std::sync::{Arc, Mutex};
|
2020-05-04 15:14:13 -04:00
|
|
|
use std::time::Instant;
|
2025-03-03 08:40:04 +01:00
|
|
|
use std::{fmt, mem, panic};
|
2019-08-26 22:05:42 -04:00
|
|
|
|
2023-06-18 11:42:57 +01:00
|
|
|
use windows_sys::Win32::Foundation::HWND;
|
2019-08-26 22:05:42 -04:00
|
|
|
|
2025-03-01 12:09:59 +01:00
|
|
|
use super::{ActiveEventLoop, ControlFlow, EventLoopThreadExecutor};
|
|
|
|
|
use crate::application::ApplicationHandler;
|
2020-01-06 15:28:58 -05:00
|
|
|
use crate::dpi::PhysicalSize;
|
2025-03-01 12:09:59 +01:00
|
|
|
use crate::event::{DeviceEvent, DeviceId, StartCause, SurfaceSizeWriter, WindowEvent};
|
|
|
|
|
use crate::event_loop::ActiveEventLoop as RootActiveEventLoop;
|
2022-08-15 02:36:37 +02:00
|
|
|
use crate::platform_impl::platform::event_loop::{WindowData, GWL_USERDATA};
|
|
|
|
|
use crate::platform_impl::platform::get_window_long;
|
2019-08-26 22:05:42 -04:00
|
|
|
use crate::window::WindowId;
|
|
|
|
|
|
2025-03-01 12:09:59 +01:00
|
|
|
type EventHandler = Cell<Option<&'static mut (dyn ApplicationHandler + 'static)>>;
|
2022-03-24 05:08:04 +11:00
|
|
|
|
2024-06-24 13:04:55 +03:00
|
|
|
pub(crate) struct EventLoopRunner {
|
2025-03-01 12:09:59 +01:00
|
|
|
pub(super) thread_id: u32,
|
|
|
|
|
|
2020-05-04 15:14:13 -04:00
|
|
|
// The event loop's win32 handles
|
2021-07-16 12:40:48 +02:00
|
|
|
pub(super) thread_msg_target: HWND,
|
2023-06-18 11:42:57 +01:00
|
|
|
|
|
|
|
|
// Setting this will ensure pump_events will return to the external
|
|
|
|
|
// loop asap. E.g. set after each RedrawRequested to ensure pump_events
|
|
|
|
|
// can't stall an external loop beyond a frame
|
|
|
|
|
pub(super) interrupt_msg_dispatch: Cell<bool>,
|
2020-05-04 15:14:13 -04:00
|
|
|
|
|
|
|
|
control_flow: Cell<ControlFlow>,
|
2023-09-07 08:25:04 +02:00
|
|
|
exit: Cell<Option<i32>>,
|
2020-05-04 15:14:13 -04:00
|
|
|
runner_state: Cell<RunnerState>,
|
|
|
|
|
last_events_cleared: Cell<Instant>,
|
2025-03-01 12:09:59 +01:00
|
|
|
event_handler: Rc<EventHandler>,
|
|
|
|
|
event_buffer: RefCell<VecDeque<Event>>,
|
2020-05-04 15:14:13 -04:00
|
|
|
|
|
|
|
|
panic_error: Cell<Option<PanicError>>,
|
2019-08-26 22:05:42 -04:00
|
|
|
}
|
2020-03-07 20:04:24 +01:00
|
|
|
|
2025-03-03 08:40:04 +01:00
|
|
|
impl fmt::Debug for EventLoopRunner {
|
|
|
|
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
|
|
|
f.debug_struct("EventLoopRunner")
|
|
|
|
|
.field("thread_msg_target", &self.thread_msg_target)
|
|
|
|
|
.finish_non_exhaustive()
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2019-08-26 22:05:42 -04:00
|
|
|
pub type PanicError = Box<dyn Any + Send + 'static>;
|
|
|
|
|
|
2020-05-04 15:14:13 -04:00
|
|
|
/// See `move_state_to` function for details on how the state loop works.
|
|
|
|
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
2023-06-18 11:42:57 +01:00
|
|
|
pub(crate) enum RunnerState {
|
2020-05-04 15:14:13 -04:00
|
|
|
/// The event loop has just been created, and an `Init` event must be sent.
|
|
|
|
|
Uninitialized,
|
|
|
|
|
/// The event loop is idling.
|
|
|
|
|
Idle,
|
|
|
|
|
/// The event loop is handling the OS's events and sending them to the user's callback.
|
2023-07-28 17:37:56 +01:00
|
|
|
/// `NewEvents` has been sent, and `AboutToWait` hasn't.
|
2020-05-04 15:14:13 -04:00
|
|
|
HandlingMainEvents,
|
2020-07-02 16:53:47 -04:00
|
|
|
/// The event loop has been destroyed. No other events will be emitted.
|
|
|
|
|
Destroyed,
|
2020-05-04 15:14:13 -04:00
|
|
|
}
|
|
|
|
|
|
2025-03-01 12:09:59 +01:00
|
|
|
#[derive(Debug, Clone)]
|
|
|
|
|
pub(crate) enum Event {
|
|
|
|
|
Device { device_id: DeviceId, event: DeviceEvent },
|
|
|
|
|
Window { window_id: WindowId, event: WindowEvent },
|
|
|
|
|
BufferedScaleFactorChanged(HWND, f64, PhysicalSize<u32>),
|
|
|
|
|
// FIXME(madsmtm): Coalesce these into a flag (or similar) instead of handling them as events.
|
|
|
|
|
// https://github.com/rust-windowing/winit/pull/3687
|
|
|
|
|
WakeUp,
|
2020-01-06 15:28:58 -05:00
|
|
|
}
|
|
|
|
|
|
2024-06-24 13:04:55 +03:00
|
|
|
impl EventLoopRunner {
|
2025-03-01 12:09:59 +01:00
|
|
|
pub(crate) fn new(thread_id: u32, thread_msg_target: HWND) -> Self {
|
|
|
|
|
Self {
|
|
|
|
|
thread_id,
|
2020-05-04 15:14:13 -04:00
|
|
|
thread_msg_target,
|
2023-06-18 11:42:57 +01:00
|
|
|
interrupt_msg_dispatch: Cell::new(false),
|
2020-05-04 15:14:13 -04:00
|
|
|
runner_state: Cell::new(RunnerState::Uninitialized),
|
2023-09-07 08:25:04 +02:00
|
|
|
control_flow: Cell::new(ControlFlow::default()),
|
|
|
|
|
exit: Cell::new(None),
|
2020-05-04 15:14:13 -04:00
|
|
|
panic_error: Cell::new(None),
|
|
|
|
|
last_events_cleared: Cell::new(Instant::now()),
|
2025-03-01 12:09:59 +01:00
|
|
|
event_handler: Rc::new(Cell::new(None)),
|
2020-05-04 15:14:13 -04:00
|
|
|
event_buffer: RefCell::new(VecDeque::new()),
|
2020-01-06 15:28:58 -05:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-03-01 12:09:59 +01:00
|
|
|
/// Associate the application's event handler with the runner.
|
2023-06-18 11:42:57 +01:00
|
|
|
///
|
|
|
|
|
/// # Safety
|
|
|
|
|
///
|
2025-03-01 12:09:59 +01:00
|
|
|
/// The returned type must not be leaked (as that would allow the application to be associated
|
|
|
|
|
/// with the runner for too long).
|
|
|
|
|
pub(crate) unsafe fn set_app<'app>(
|
|
|
|
|
&self,
|
|
|
|
|
app: &'app mut (dyn ApplicationHandler + 'app),
|
|
|
|
|
) -> impl Drop + 'app {
|
|
|
|
|
// Erase app lifetime, to allow storing on the event loop runner.
|
|
|
|
|
//
|
|
|
|
|
// SAFETY: Caller upholds that the lifetime of the closure is upheld, by not dropping the
|
|
|
|
|
// return type which resets it.
|
|
|
|
|
let f = unsafe {
|
|
|
|
|
mem::transmute::<
|
|
|
|
|
&'app mut (dyn ApplicationHandler + 'app),
|
|
|
|
|
&'static mut (dyn ApplicationHandler + 'static),
|
|
|
|
|
>(app)
|
|
|
|
|
};
|
|
|
|
|
|
2023-09-29 16:07:44 +02:00
|
|
|
let old_event_handler = self.event_handler.replace(Some(f));
|
2025-03-01 12:09:59 +01:00
|
|
|
|
2020-05-04 15:14:13 -04:00
|
|
|
assert!(old_event_handler.is_none());
|
|
|
|
|
|
2025-03-01 12:09:59 +01:00
|
|
|
struct Resetter(Rc<EventHandler>);
|
|
|
|
|
|
|
|
|
|
impl Drop for Resetter {
|
|
|
|
|
fn drop(&mut self) {
|
|
|
|
|
self.0.set(None);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Resetter(self.event_handler.clone())
|
2023-06-18 11:42:57 +01:00
|
|
|
}
|
|
|
|
|
|
2020-05-04 15:14:13 -04:00
|
|
|
pub(crate) fn reset_runner(&self) {
|
2025-03-01 12:09:59 +01:00
|
|
|
let Self {
|
|
|
|
|
thread_id: _,
|
2020-05-04 15:14:13 -04:00
|
|
|
thread_msg_target: _,
|
2023-06-18 11:42:57 +01:00
|
|
|
interrupt_msg_dispatch,
|
2020-05-04 15:14:13 -04:00
|
|
|
runner_state,
|
|
|
|
|
panic_error,
|
2023-10-10 22:46:08 +02:00
|
|
|
control_flow: _,
|
2023-09-07 08:25:04 +02:00
|
|
|
exit,
|
2020-05-04 15:14:13 -04:00
|
|
|
last_events_cleared: _,
|
|
|
|
|
event_handler,
|
|
|
|
|
event_buffer: _,
|
|
|
|
|
} = self;
|
2023-06-18 11:42:57 +01:00
|
|
|
interrupt_msg_dispatch.set(false);
|
2020-05-04 15:14:13 -04:00
|
|
|
runner_state.set(RunnerState::Uninitialized);
|
|
|
|
|
panic_error.set(None);
|
2023-09-07 08:25:04 +02:00
|
|
|
exit.set(None);
|
2020-05-04 15:14:13 -04:00
|
|
|
event_handler.set(None);
|
2020-01-06 15:28:58 -05:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2020-05-04 15:14:13 -04:00
|
|
|
/// State retrieval functions.
|
2024-06-24 13:04:55 +03:00
|
|
|
impl EventLoopRunner {
|
2023-06-18 11:42:57 +01:00
|
|
|
#[allow(unused)]
|
2020-05-04 15:14:13 -04:00
|
|
|
pub fn thread_msg_target(&self) -> HWND {
|
|
|
|
|
self.thread_msg_target
|
2019-08-26 22:05:42 -04:00
|
|
|
}
|
|
|
|
|
|
2020-05-04 15:14:13 -04:00
|
|
|
pub fn take_panic_error(&self) -> Result<(), PanicError> {
|
|
|
|
|
match self.panic_error.take() {
|
|
|
|
|
Some(err) => Err(err),
|
|
|
|
|
None => Ok(()),
|
2019-08-26 22:05:42 -04:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-09-07 08:25:04 +02:00
|
|
|
pub fn set_control_flow(&self, control_flow: ControlFlow) {
|
|
|
|
|
self.control_flow.set(control_flow)
|
2023-06-18 11:42:57 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub fn control_flow(&self) -> ControlFlow {
|
|
|
|
|
self.control_flow.get()
|
2019-08-26 22:05:42 -04:00
|
|
|
}
|
|
|
|
|
|
2023-09-07 08:25:04 +02:00
|
|
|
pub fn set_exit_code(&self, code: i32) {
|
|
|
|
|
self.exit.set(Some(code))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
pub fn exit_code(&self) -> Option<i32> {
|
|
|
|
|
self.exit.get()
|
|
|
|
|
}
|
|
|
|
|
|
2023-12-22 20:00:20 +04:00
|
|
|
pub fn clear_exit(&self) {
|
|
|
|
|
self.exit.set(None);
|
|
|
|
|
}
|
|
|
|
|
|
2020-05-04 15:14:13 -04:00
|
|
|
pub fn should_buffer(&self) -> bool {
|
|
|
|
|
let handler = self.event_handler.take();
|
|
|
|
|
let should_buffer = handler.is_none();
|
|
|
|
|
self.event_handler.set(handler);
|
|
|
|
|
should_buffer
|
2019-08-26 22:05:42 -04:00
|
|
|
}
|
2020-05-04 15:14:13 -04:00
|
|
|
}
|
2019-08-26 22:05:42 -04:00
|
|
|
|
2020-05-04 15:14:13 -04:00
|
|
|
/// Misc. functions
|
2024-06-24 13:04:55 +03:00
|
|
|
impl EventLoopRunner {
|
2020-05-04 15:14:13 -04:00
|
|
|
pub fn catch_unwind<R>(&self, f: impl FnOnce() -> R) -> Option<R> {
|
|
|
|
|
let panic_error = self.panic_error.take();
|
|
|
|
|
if panic_error.is_none() {
|
|
|
|
|
let result = panic::catch_unwind(panic::AssertUnwindSafe(f));
|
|
|
|
|
|
|
|
|
|
// Check to see if the panic error was set in a re-entrant call to catch_unwind inside
|
|
|
|
|
// of `f`. If it was, that error takes priority. If it wasn't, check if our call to
|
|
|
|
|
// catch_unwind caught any panics and set panic_error appropriately.
|
|
|
|
|
match self.panic_error.take() {
|
|
|
|
|
None => match result {
|
|
|
|
|
Ok(r) => Some(r),
|
|
|
|
|
Err(e) => {
|
|
|
|
|
self.panic_error.set(Some(e));
|
|
|
|
|
None
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
Some(e) => {
|
|
|
|
|
self.panic_error.set(Some(e));
|
|
|
|
|
None
|
|
|
|
|
},
|
2020-03-07 20:04:24 +01:00
|
|
|
}
|
2020-05-04 15:14:13 -04:00
|
|
|
} else {
|
|
|
|
|
self.panic_error.set(panic_error);
|
|
|
|
|
None
|
2020-01-06 15:28:58 -05:00
|
|
|
}
|
|
|
|
|
}
|
2025-03-01 12:09:59 +01:00
|
|
|
|
|
|
|
|
#[inline(always)]
|
|
|
|
|
pub(crate) fn create_thread_executor(&self) -> EventLoopThreadExecutor {
|
|
|
|
|
EventLoopThreadExecutor { thread_id: self.thread_id, target_window: self.thread_msg_target }
|
|
|
|
|
}
|
2020-05-04 15:14:13 -04:00
|
|
|
}
|
2019-08-26 22:05:42 -04:00
|
|
|
|
2020-05-04 15:14:13 -04:00
|
|
|
/// Event dispatch functions.
|
2024-06-24 13:04:55 +03:00
|
|
|
impl EventLoopRunner {
|
2025-03-01 12:09:59 +01:00
|
|
|
pub(crate) fn prepare_wait(self: &Rc<Self>) {
|
2023-06-18 11:42:57 +01:00
|
|
|
self.move_state_to(RunnerState::Idle);
|
|
|
|
|
}
|
|
|
|
|
|
2025-03-01 12:09:59 +01:00
|
|
|
pub(crate) fn wakeup(self: &Rc<Self>) {
|
2020-05-04 15:14:13 -04:00
|
|
|
self.move_state_to(RunnerState::HandlingMainEvents);
|
2019-08-26 22:05:42 -04:00
|
|
|
}
|
|
|
|
|
|
2025-03-01 12:09:59 +01:00
|
|
|
pub(crate) fn send_event(self: &Rc<Self>, event: Event) {
|
|
|
|
|
if let Event::Window { event: WindowEvent::RedrawRequested, .. } = event {
|
|
|
|
|
self.call_event_handler(|app, event_loop| event.dispatch_event(app, event_loop));
|
2023-06-18 11:42:57 +01:00
|
|
|
// As a rule, to ensure that `pump_events` can't block an external event loop
|
|
|
|
|
// for too long, we always guarantee that `pump_events` will return control to
|
|
|
|
|
// the external loop asap after a `RedrawRequested` event is dispatched.
|
|
|
|
|
self.interrupt_msg_dispatch.set(true);
|
2022-03-07 22:58:12 +01:00
|
|
|
} else if self.should_buffer() {
|
|
|
|
|
// If the runner is already borrowed, we're in the middle of an event loop invocation.
|
|
|
|
|
// Add the event to a buffer to be processed later.
|
2025-03-01 12:09:59 +01:00
|
|
|
self.event_buffer.borrow_mut().push_back(event.buffer_scale_factor())
|
2020-05-04 15:14:13 -04:00
|
|
|
} else {
|
2025-03-01 12:09:59 +01:00
|
|
|
self.call_event_handler(|app, event_loop| event.dispatch_event(app, event_loop));
|
2022-03-07 22:58:12 +01:00
|
|
|
self.dispatch_buffered_events();
|
2019-08-26 22:05:42 -04:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-03-01 12:09:59 +01:00
|
|
|
pub(crate) fn loop_destroyed(self: &Rc<Self>) {
|
2020-07-02 16:53:47 -04:00
|
|
|
self.move_state_to(RunnerState::Destroyed);
|
|
|
|
|
}
|
|
|
|
|
|
2025-03-01 12:09:59 +01:00
|
|
|
fn call_event_handler(
|
|
|
|
|
self: &Rc<Self>,
|
|
|
|
|
closure: impl FnOnce(&mut dyn ApplicationHandler, &dyn RootActiveEventLoop),
|
|
|
|
|
) {
|
2020-05-04 15:14:13 -04:00
|
|
|
self.catch_unwind(|| {
|
2025-03-01 12:09:59 +01:00
|
|
|
let event_handler = self.event_handler.take().expect(
|
2020-05-04 15:14:13 -04:00
|
|
|
"either event handler is re-entrant (likely), or no event handler is registered \
|
|
|
|
|
(very unlikely)",
|
|
|
|
|
);
|
2019-08-26 22:05:42 -04:00
|
|
|
|
2025-03-01 12:09:59 +01:00
|
|
|
closure(event_handler, ActiveEventLoop::from_ref(self));
|
2020-05-04 15:14:13 -04:00
|
|
|
|
|
|
|
|
assert!(self.event_handler.replace(Some(event_handler)).is_none());
|
|
|
|
|
});
|
2019-08-26 22:05:42 -04:00
|
|
|
}
|
|
|
|
|
|
2025-03-01 12:09:59 +01:00
|
|
|
fn dispatch_buffered_events(self: &Rc<Self>) {
|
2020-05-04 15:14:13 -04:00
|
|
|
loop {
|
|
|
|
|
// We do this instead of using a `while let` loop because if we use a `while let`
|
|
|
|
|
// loop the reference returned `borrow_mut()` doesn't get dropped until the end
|
|
|
|
|
// of the loop's body and attempts to add events to the event buffer while in
|
|
|
|
|
// `process_event` will fail.
|
|
|
|
|
let buffered_event_opt = self.event_buffer.borrow_mut().pop_front();
|
|
|
|
|
match buffered_event_opt {
|
2025-03-01 12:09:59 +01:00
|
|
|
Some(e) => {
|
|
|
|
|
self.call_event_handler(|app, event_loop| e.dispatch_event(app, event_loop))
|
|
|
|
|
},
|
2020-05-04 15:14:13 -04:00
|
|
|
None => break,
|
|
|
|
|
}
|
2019-08-26 22:05:42 -04:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-07-28 17:37:56 +01:00
|
|
|
/// Dispatch control flow events (`NewEvents`, `AboutToWait`, and
|
|
|
|
|
/// `LoopExiting`) as necessary to bring the internal `RunnerState` to the
|
|
|
|
|
/// new runner state.
|
2020-05-04 15:14:13 -04:00
|
|
|
///
|
|
|
|
|
/// The state transitions are defined as follows:
|
|
|
|
|
///
|
|
|
|
|
/// ```text
|
|
|
|
|
/// Uninitialized
|
|
|
|
|
/// |
|
|
|
|
|
/// V
|
2023-06-18 11:42:57 +01:00
|
|
|
/// Idle
|
|
|
|
|
/// ^ |
|
|
|
|
|
/// | V
|
|
|
|
|
/// HandlingMainEvents
|
|
|
|
|
/// |
|
|
|
|
|
/// V
|
|
|
|
|
/// Destroyed
|
2020-05-04 15:14:13 -04:00
|
|
|
/// ```
|
|
|
|
|
///
|
2020-07-02 16:53:47 -04:00
|
|
|
/// Attempting to transition back to `Uninitialized` will result in a panic. Attempting to
|
2023-06-18 11:42:57 +01:00
|
|
|
/// transition *from* `Destroyed` will also result in a panic. Transitioning to the current
|
2020-07-02 16:53:47 -04:00
|
|
|
/// state is a no-op. Even if the `new_runner_state` isn't the immediate next state in the
|
|
|
|
|
/// runner state machine (e.g. `self.runner_state == HandlingMainEvents` and
|
2020-05-04 15:14:13 -04:00
|
|
|
/// `new_runner_state == Idle`), the intermediate state transitions will still be executed.
|
2025-03-01 12:09:59 +01:00
|
|
|
fn move_state_to(self: &Rc<Self>, new_runner_state: RunnerState) {
|
2023-06-18 11:42:57 +01:00
|
|
|
use RunnerState::{Destroyed, HandlingMainEvents, Idle, Uninitialized};
|
2020-05-04 15:14:13 -04:00
|
|
|
|
|
|
|
|
match (self.runner_state.replace(new_runner_state), new_runner_state) {
|
|
|
|
|
(Uninitialized, Uninitialized)
|
|
|
|
|
| (Idle, Idle)
|
|
|
|
|
| (HandlingMainEvents, HandlingMainEvents)
|
2020-07-02 16:53:47 -04:00
|
|
|
| (Destroyed, Destroyed) => (),
|
2020-05-04 15:14:13 -04:00
|
|
|
|
|
|
|
|
// State transitions that initialize the event loop.
|
|
|
|
|
(Uninitialized, HandlingMainEvents) => {
|
|
|
|
|
self.call_new_events(true);
|
2019-08-26 22:05:42 -04:00
|
|
|
},
|
2020-05-04 15:14:13 -04:00
|
|
|
(Uninitialized, Idle) => {
|
|
|
|
|
self.call_new_events(true);
|
2025-03-01 12:09:59 +01:00
|
|
|
self.call_event_handler(|app, event_loop| app.about_to_wait(event_loop));
|
2023-07-28 17:37:56 +01:00
|
|
|
self.last_events_cleared.set(Instant::now());
|
2019-08-26 22:05:42 -04:00
|
|
|
},
|
2020-07-02 16:53:47 -04:00
|
|
|
(Uninitialized, Destroyed) => {
|
|
|
|
|
self.call_new_events(true);
|
2025-03-01 12:09:59 +01:00
|
|
|
self.call_event_handler(|app, event_loop| app.about_to_wait(event_loop));
|
2023-07-28 17:37:56 +01:00
|
|
|
self.last_events_cleared.set(Instant::now());
|
2020-07-02 16:53:47 -04:00
|
|
|
},
|
2020-05-04 15:14:13 -04:00
|
|
|
(_, Uninitialized) => panic!("cannot move state to Uninitialized"),
|
2019-08-26 22:05:42 -04:00
|
|
|
|
2020-05-04 15:14:13 -04:00
|
|
|
// State transitions that start the event handling process.
|
|
|
|
|
(Idle, HandlingMainEvents) => {
|
|
|
|
|
self.call_new_events(false);
|
|
|
|
|
},
|
2025-03-17 10:56:00 +01:00
|
|
|
(Idle, Destroyed) => {},
|
2019-08-26 22:05:42 -04:00
|
|
|
|
2020-05-04 15:14:13 -04:00
|
|
|
(HandlingMainEvents, Idle) => {
|
2023-07-28 17:37:56 +01:00
|
|
|
// This is always the last event we dispatch before waiting for new events
|
2025-03-01 12:09:59 +01:00
|
|
|
self.call_event_handler(|app, event_loop| app.about_to_wait(event_loop));
|
2023-07-28 17:37:56 +01:00
|
|
|
self.last_events_cleared.set(Instant::now());
|
2020-01-06 15:28:58 -05:00
|
|
|
},
|
2020-07-02 16:53:47 -04:00
|
|
|
(HandlingMainEvents, Destroyed) => {
|
2025-03-01 12:09:59 +01:00
|
|
|
self.call_event_handler(|app, event_loop| app.about_to_wait(event_loop));
|
2023-07-28 17:37:56 +01:00
|
|
|
self.last_events_cleared.set(Instant::now());
|
2020-07-02 16:53:47 -04:00
|
|
|
},
|
2020-05-04 15:14:13 -04:00
|
|
|
|
2020-07-02 16:53:47 -04:00
|
|
|
(Destroyed, _) => panic!("cannot move state from Destroyed"),
|
2019-08-26 22:05:42 -04:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-03-01 12:09:59 +01:00
|
|
|
fn call_new_events(self: &Rc<Self>, init: bool) {
|
2023-09-07 08:25:04 +02:00
|
|
|
let start_cause = match (init, self.control_flow(), self.exit.get()) {
|
|
|
|
|
(true, ..) => StartCause::Init,
|
|
|
|
|
(false, ControlFlow::Poll, None) => StartCause::Poll,
|
|
|
|
|
(false, _, Some(_)) | (false, ControlFlow::Wait, None) => StartCause::WaitCancelled {
|
|
|
|
|
requested_resume: None,
|
|
|
|
|
start: self.last_events_cleared.get(),
|
|
|
|
|
},
|
|
|
|
|
(false, ControlFlow::WaitUntil(requested_resume), None) => {
|
2020-05-04 15:14:13 -04:00
|
|
|
if Instant::now() < requested_resume {
|
|
|
|
|
StartCause::WaitCancelled {
|
|
|
|
|
requested_resume: Some(requested_resume),
|
|
|
|
|
start: self.last_events_cleared.get(),
|
2020-01-06 15:28:58 -05:00
|
|
|
}
|
2020-05-04 15:14:13 -04:00
|
|
|
} else {
|
|
|
|
|
StartCause::ResumeTimeReached {
|
|
|
|
|
requested_resume,
|
|
|
|
|
start: self.last_events_cleared.get(),
|
2020-01-06 15:28:58 -05:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
},
|
2020-05-04 15:14:13 -04:00
|
|
|
};
|
2025-03-01 12:09:59 +01:00
|
|
|
self.call_event_handler(|app, event_loop| app.new_events(event_loop, start_cause));
|
2024-06-30 00:41:57 +02:00
|
|
|
// NB: For consistency all platforms must call `can_create_surfaces` even though Windows
|
|
|
|
|
// applications don't themselves have a formal surface destroy/create lifecycle.
|
2022-07-26 14:03:12 +01:00
|
|
|
if init {
|
2025-03-01 12:09:59 +01:00
|
|
|
self.call_event_handler(|app, event_loop| app.can_create_surfaces(event_loop));
|
2022-07-26 14:03:12 +01:00
|
|
|
}
|
2020-05-04 15:14:13 -04:00
|
|
|
self.dispatch_buffered_events();
|
2020-01-06 15:28:58 -05:00
|
|
|
}
|
2020-05-04 15:14:13 -04:00
|
|
|
}
|
|
|
|
|
|
2025-03-01 12:09:59 +01:00
|
|
|
impl Event {
|
|
|
|
|
/// Mark ScaleFactorChanged as being buffered (which forces us to re-handle when the user set a
|
|
|
|
|
/// new size).
|
|
|
|
|
pub fn buffer_scale_factor(self) -> Self {
|
|
|
|
|
match self {
|
|
|
|
|
Self::Window {
|
2024-09-04 15:04:48 +02:00
|
|
|
event: WindowEvent::ScaleFactorChanged { scale_factor, surface_size_writer },
|
2020-05-04 15:14:13 -04:00
|
|
|
window_id,
|
2025-03-01 12:09:59 +01:00
|
|
|
} => Event::BufferedScaleFactorChanged(
|
2024-10-08 15:29:40 +02:00
|
|
|
window_id.into_raw() as HWND,
|
2023-07-31 00:39:01 +04:00
|
|
|
scale_factor,
|
2025-05-03 20:21:45 +09:00
|
|
|
surface_size_writer.surface_size().unwrap(),
|
2023-07-31 00:39:01 +04:00
|
|
|
),
|
2025-03-01 12:09:59 +01:00
|
|
|
event => event,
|
2019-08-26 22:05:42 -04:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-03-01 12:09:59 +01:00
|
|
|
pub fn dispatch_event(
|
|
|
|
|
self,
|
|
|
|
|
app: &mut dyn ApplicationHandler,
|
|
|
|
|
event_loop: &dyn RootActiveEventLoop,
|
|
|
|
|
) {
|
2020-05-04 15:14:13 -04:00
|
|
|
match self {
|
2025-03-01 12:09:59 +01:00
|
|
|
Self::Window { window_id, event } => app.window_event(event_loop, window_id, event),
|
|
|
|
|
Self::Device { device_id, event } => {
|
|
|
|
|
app.device_event(event_loop, Some(device_id), event)
|
|
|
|
|
},
|
|
|
|
|
Self::BufferedScaleFactorChanged(window, scale_factor, new_surface_size) => {
|
2024-09-04 15:04:48 +02:00
|
|
|
let user_new_surface_size = Arc::new(Mutex::new(new_surface_size));
|
2025-03-01 12:09:59 +01:00
|
|
|
app.window_event(
|
|
|
|
|
event_loop,
|
|
|
|
|
WindowId::from_raw(window as usize),
|
|
|
|
|
WindowEvent::ScaleFactorChanged {
|
2020-05-04 15:14:13 -04:00
|
|
|
scale_factor,
|
2024-09-04 15:04:48 +02:00
|
|
|
surface_size_writer: SurfaceSizeWriter::new(Arc::downgrade(
|
|
|
|
|
&user_new_surface_size,
|
2024-02-06 21:46:30 +02:00
|
|
|
)),
|
2020-05-04 15:14:13 -04:00
|
|
|
},
|
2025-03-01 12:09:59 +01:00
|
|
|
);
|
2024-09-04 15:04:48 +02:00
|
|
|
let surface_size = *user_new_surface_size.lock().unwrap();
|
2024-02-06 21:46:30 +02:00
|
|
|
|
2024-09-04 15:04:48 +02:00
|
|
|
drop(user_new_surface_size);
|
2024-02-06 21:46:30 +02:00
|
|
|
|
2024-09-04 15:04:48 +02:00
|
|
|
if surface_size != new_surface_size {
|
2024-02-06 21:46:30 +02:00
|
|
|
let window_flags = unsafe {
|
2024-10-08 15:29:40 +02:00
|
|
|
let userdata = get_window_long(window, GWL_USERDATA) as *mut WindowData;
|
2024-02-06 21:46:30 +02:00
|
|
|
(*userdata).window_state_lock().window_flags
|
|
|
|
|
};
|
|
|
|
|
|
2024-10-08 15:29:40 +02:00
|
|
|
window_flags.set_size(window, surface_size);
|
2024-02-06 21:46:30 +02:00
|
|
|
}
|
2020-05-04 15:14:13 -04:00
|
|
|
},
|
2025-03-01 12:09:59 +01:00
|
|
|
Self::WakeUp => app.proxy_wake_up(event_loop),
|
2019-08-26 22:05:42 -04:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|