chore: implement EventLoopProvider in each winit-* crate

This commit is contained in:
Kirill Chibisov
2026-07-27 21:50:29 +09:00
parent d74e5c51d1
commit 42366231b0
10 changed files with 326 additions and 40 deletions

View File

@@ -17,7 +17,7 @@ use winit_core::error::{EventLoopError, NotSupportedError, RequestError};
use winit_core::event::{self, DeviceId, FingerId, Force, StartCause, SurfaceSizeWriter}; use winit_core::event::{self, DeviceId, FingerId, Force, StartCause, SurfaceSizeWriter};
use winit_core::event_loop::pump_events::PumpStatus; use winit_core::event_loop::pump_events::PumpStatus;
use winit_core::event_loop::{ use winit_core::event_loop::{
ActiveEventLoop as RootActiveEventLoop, ControlFlow, DeviceEvents, ActiveEventLoop as RootActiveEventLoop, ControlFlow, DeviceEvents, EventLoopProvider,
EventLoopProxy as CoreEventLoopProxy, EventLoopProxyProvider, EventLoopProxy as CoreEventLoopProxy, EventLoopProxyProvider,
OwnedDisplayHandle as CoreOwnedDisplayHandle, OwnedDisplayHandle as CoreOwnedDisplayHandle,
}; };
@@ -644,6 +644,41 @@ impl EventLoop {
} }
} }
impl EventLoopProvider for EventLoop {
fn run_app<A: ApplicationHandler + 'static>(
mut self,
mut app: A,
) -> Result<(), EventLoopError> {
let result = self.run_app_on_demand(&mut app);
// SAFETY: unsure that the state is dropped before the exit from the event loop.
drop(app);
result
}
fn create_proxy(&self) -> CoreEventLoopProxy {
self.window_target().create_proxy()
}
fn owned_display_handle(&self) -> CoreOwnedDisplayHandle {
self.window_target().owned_display_handle()
}
fn listen_device_events(&self, allowed: DeviceEvents) {
self.window_target().listen_device_events(allowed);
}
fn set_control_flow(&self, control_flow: ControlFlow) {
self.window_target().set_control_flow(control_flow);
}
fn create_custom_cursor(
&self,
custom_cursor: CustomCursorSource,
) -> Result<CustomCursor, RequestError> {
self.window_target().create_custom_cursor(custom_cursor)
}
}
pub struct EventLoopProxy { pub struct EventLoopProxy {
wake_up: AtomicBool, wake_up: AtomicBool,
waker: AndroidAppWaker, waker: AndroidAppWaker,

View File

@@ -28,7 +28,7 @@ use winit_core::event::WindowEvent;
use winit_core::event_loop::pump_events::PumpStatus; use winit_core::event_loop::pump_events::PumpStatus;
use winit_core::event_loop::{ use winit_core::event_loop::{
ActiveEventLoop as RootActiveEventLoop, AsyncRequestSerial, ControlFlow, DeviceEvents, ActiveEventLoop as RootActiveEventLoop, AsyncRequestSerial, ControlFlow, DeviceEvents,
DndAction, DragIcon, EventLoopProxy as CoreEventLoopProxy, DndAction, DragIcon, EventLoopProvider, EventLoopProxy as CoreEventLoopProxy,
OwnedDisplayHandle as CoreOwnedDisplayHandle, OwnedDisplayHandle as CoreOwnedDisplayHandle,
}; };
use winit_core::monitor::MonitorHandle as CoreMonitorHandle; use winit_core::monitor::MonitorHandle as CoreMonitorHandle;
@@ -552,6 +552,41 @@ impl EventLoop {
} }
} }
impl EventLoopProvider for EventLoop {
fn run_app<A: ApplicationHandler + 'static>(
mut self,
mut app: A,
) -> Result<(), EventLoopError> {
let result = self.run_app_on_demand(&mut app);
// SAFETY: unsure that the state is dropped before the exit from the event loop.
drop(app);
result
}
fn create_proxy(&self) -> CoreEventLoopProxy {
self.window_target().create_proxy()
}
fn owned_display_handle(&self) -> CoreOwnedDisplayHandle {
self.window_target().owned_display_handle()
}
fn listen_device_events(&self, allowed: DeviceEvents) {
self.window_target().listen_device_events(allowed);
}
fn set_control_flow(&self, control_flow: ControlFlow) {
self.window_target().set_control_flow(control_flow);
}
fn create_custom_cursor(
&self,
custom_cursor: CustomCursorSource,
) -> Result<CoreCustomCursor, RequestError> {
self.window_target().create_custom_cursor(custom_cursor)
}
}
pub(crate) struct OwnedDisplayHandle; pub(crate) struct OwnedDisplayHandle;
impl HasDisplayHandle for OwnedDisplayHandle { impl HasDisplayHandle for OwnedDisplayHandle {

View File

@@ -20,7 +20,7 @@ use winit_core::error::{EventLoopError, NotSupportedError, RequestError};
use winit_core::event::{self, Ime, Modifiers, StartCause}; use winit_core::event::{self, Ime, Modifiers, StartCause};
use winit_core::event_loop::pump_events::PumpStatus; use winit_core::event_loop::pump_events::PumpStatus;
use winit_core::event_loop::{ use winit_core::event_loop::{
ActiveEventLoop as RootActiveEventLoop, ControlFlow, DeviceEvents, ActiveEventLoop as RootActiveEventLoop, ControlFlow, DeviceEvents, EventLoopProvider,
EventLoopProxy as CoreEventLoopProxy, EventLoopProxyProvider, EventLoopProxy as CoreEventLoopProxy, EventLoopProxyProvider,
OwnedDisplayHandle as CoreOwnedDisplayHandle, OwnedDisplayHandle as CoreOwnedDisplayHandle,
}; };
@@ -734,6 +734,41 @@ impl EventLoop {
} }
} }
impl EventLoopProvider for EventLoop {
fn run_app<A: ApplicationHandler + 'static>(
mut self,
mut app: A,
) -> Result<(), EventLoopError> {
let result = self.run_app_on_demand(&mut app);
// SAFETY: unsure that the state is dropped before the exit from the event loop.
drop(app);
result
}
fn create_proxy(&self) -> CoreEventLoopProxy {
self.window_target().create_proxy()
}
fn owned_display_handle(&self) -> CoreOwnedDisplayHandle {
self.window_target().owned_display_handle()
}
fn listen_device_events(&self, allowed: DeviceEvents) {
self.window_target().listen_device_events(allowed);
}
fn set_control_flow(&self, control_flow: ControlFlow) {
self.window_target().set_control_flow(control_flow);
}
fn create_custom_cursor(
&self,
custom_cursor: CustomCursorSource,
) -> Result<CustomCursor, RequestError> {
self.window_target().create_custom_cursor(custom_cursor)
}
}
#[derive(Debug)] #[derive(Debug)]
pub struct EventLoopProxy { pub struct EventLoopProxy {
user_events_sender: mpsc::SyncSender<()>, user_events_sender: mpsc::SyncSender<()>,

View File

@@ -19,7 +19,7 @@ use winit_core::application::ApplicationHandler;
use winit_core::cursor::{CustomCursor, CustomCursorSource}; use winit_core::cursor::{CustomCursor, CustomCursorSource};
use winit_core::error::{EventLoopError, NotSupportedError, RequestError}; use winit_core::error::{EventLoopError, NotSupportedError, RequestError};
use winit_core::event_loop::{ use winit_core::event_loop::{
ActiveEventLoop as RootActiveEventLoop, ControlFlow, DeviceEvents, ActiveEventLoop as RootActiveEventLoop, ControlFlow, DeviceEvents, EventLoopProvider,
EventLoopProxy as CoreEventLoopProxy, OwnedDisplayHandle as CoreOwnedDisplayHandle, EventLoopProxy as CoreEventLoopProxy, OwnedDisplayHandle as CoreOwnedDisplayHandle,
}; };
use winit_core::monitor::MonitorHandle as CoreMonitorHandle; use winit_core::monitor::MonitorHandle as CoreMonitorHandle;
@@ -333,3 +333,32 @@ impl EventLoop {
&self.window_target &self.window_target
} }
} }
impl EventLoopProvider for EventLoop {
fn run_app<A: ApplicationHandler + 'static>(self, app: A) -> Result<(), EventLoopError> {
self.run_app_never_return(app)
}
fn create_proxy(&self) -> CoreEventLoopProxy {
self.window_target().create_proxy()
}
fn owned_display_handle(&self) -> CoreOwnedDisplayHandle {
self.window_target().owned_display_handle()
}
fn listen_device_events(&self, allowed: DeviceEvents) {
self.window_target().listen_device_events(allowed);
}
fn set_control_flow(&self, control_flow: ControlFlow) {
self.window_target().set_control_flow(control_flow);
}
fn create_custom_cursor(
&self,
custom_cursor: CustomCursorSource,
) -> Result<CustomCursor, RequestError> {
self.window_target().create_custom_cursor(custom_cursor)
}
}

View File

@@ -32,7 +32,7 @@ use winit_core::event::{DeviceEvent, StartCause, SurfaceSizeWriter, WindowEvent}
use winit_core::event_loop::pump_events::PumpStatus; use winit_core::event_loop::pump_events::PumpStatus;
use winit_core::event_loop::{ use winit_core::event_loop::{
ActiveEventLoop as RootActiveEventLoop, AsyncRequestSerial, ControlFlow, DeviceEvents, ActiveEventLoop as RootActiveEventLoop, AsyncRequestSerial, ControlFlow, DeviceEvents,
DndAction, DragIcon, OwnedDisplayHandle as CoreOwnedDisplayHandle, DndAction, DragIcon, EventLoopProvider, OwnedDisplayHandle as CoreOwnedDisplayHandle,
}; };
use winit_core::icon::RgbaIcon; use winit_core::icon::RgbaIcon;
use winit_core::monitor::MonitorHandle as CoreMonitorHandle; use winit_core::monitor::MonitorHandle as CoreMonitorHandle;
@@ -624,6 +624,41 @@ impl EventLoop {
} }
} }
impl EventLoopProvider for EventLoop {
fn run_app<A: ApplicationHandler + 'static>(
mut self,
mut app: A,
) -> Result<(), EventLoopError> {
let result = self.run_app_on_demand(&mut app);
// SAFETY: unsure that the state is dropped before the exit from the event loop.
drop(app);
result
}
fn create_proxy(&self) -> CoreEventLoopProxy {
self.active_event_loop.create_proxy()
}
fn owned_display_handle(&self) -> CoreOwnedDisplayHandle {
self.active_event_loop.owned_display_handle()
}
fn listen_device_events(&self, allowed: DeviceEvents) {
self.active_event_loop.listen_device_events(allowed);
}
fn set_control_flow(&self, control_flow: ControlFlow) {
self.active_event_loop.set_control_flow(control_flow);
}
fn create_custom_cursor(
&self,
custom_cursor: CustomCursorSource,
) -> Result<CoreCustomCursor, RequestError> {
self.active_event_loop.create_custom_cursor(custom_cursor)
}
}
impl AsFd for EventLoop { impl AsFd for EventLoop {
fn as_fd(&self) -> BorrowedFd<'_> { fn as_fd(&self) -> BorrowedFd<'_> {
self.event_loop.as_fd() self.event_loop.as_fd()

View File

@@ -1,8 +1,12 @@
use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::atomic::{AtomicBool, Ordering};
use winit_core::application::ApplicationHandler; use winit_core::application::ApplicationHandler;
use winit_core::error::{EventLoopError, NotSupportedError}; use winit_core::cursor::{CustomCursor as CoreCustomCursor, CustomCursorSource};
use winit_core::event_loop::ActiveEventLoop as RootActiveEventLoop; use winit_core::error::{EventLoopError, NotSupportedError, RequestError};
use winit_core::event_loop::{
ActiveEventLoop as RootActiveEventLoop, ControlFlow, DeviceEvents, EventLoopProvider,
EventLoopProxy, OwnedDisplayHandle,
};
use crate::{ use crate::{
HasMonitorPermissionFuture, MonitorPermissionFuture, PollStrategy, WaitUntilStrategy, backend, HasMonitorPermissionFuture, MonitorPermissionFuture, PollStrategy, WaitUntilStrategy, backend,
@@ -77,3 +81,33 @@ impl EventLoop {
) )
} }
} }
impl EventLoopProvider for EventLoop {
fn run_app<A: ApplicationHandler + 'static>(self, app: A) -> Result<(), EventLoopError> {
self.register_app(app);
Ok(())
}
fn create_proxy(&self) -> EventLoopProxy {
self.window_target().create_proxy()
}
fn owned_display_handle(&self) -> OwnedDisplayHandle {
self.window_target().owned_display_handle()
}
fn listen_device_events(&self, allowed: DeviceEvents) {
self.window_target().listen_device_events(allowed);
}
fn set_control_flow(&self, control_flow: ControlFlow) {
self.window_target().set_control_flow(control_flow);
}
fn create_custom_cursor(
&self,
custom_cursor: CustomCursorSource,
) -> Result<CoreCustomCursor, RequestError> {
self.window_target().create_custom_cursor(custom_cursor)
}
}

View File

@@ -74,8 +74,8 @@ use winit_core::event::{
use winit_core::event_loop::pump_events::PumpStatus; use winit_core::event_loop::pump_events::PumpStatus;
use winit_core::event_loop::{ use winit_core::event_loop::{
ActiveEventLoop as RootActiveEventLoop, AsyncRequestSerial, ControlFlow, DeviceEvents, ActiveEventLoop as RootActiveEventLoop, AsyncRequestSerial, ControlFlow, DeviceEvents,
DndAction, DragIcon, EventLoopProxy as RootEventLoopProxy, EventLoopProxyProvider, DndAction, DragIcon, EventLoopProvider, EventLoopProxy as RootEventLoopProxy,
OwnedDisplayHandle as CoreOwnedDisplayHandle, EventLoopProxyProvider, OwnedDisplayHandle as CoreOwnedDisplayHandle,
}; };
use winit_core::keyboard::ModifiersState; use winit_core::keyboard::ModifiersState;
use winit_core::monitor::{Fullscreen, MonitorHandle as CoreMonitorHandle}; use winit_core::monitor::{Fullscreen, MonitorHandle as CoreMonitorHandle};
@@ -392,6 +392,41 @@ impl EventLoop {
} }
} }
impl EventLoopProvider for EventLoop {
fn run_app<A: ApplicationHandler + 'static>(
mut self,
mut app: A,
) -> Result<(), EventLoopError> {
let result = self.run_app_on_demand(&mut app);
// SAFETY: unsure that the state is dropped before the exit from the event loop.
drop(app);
result
}
fn create_proxy(&self) -> RootEventLoopProxy {
self.window_target().create_proxy()
}
fn owned_display_handle(&self) -> CoreOwnedDisplayHandle {
self.window_target().owned_display_handle()
}
fn listen_device_events(&self, allowed: DeviceEvents) {
self.window_target().listen_device_events(allowed);
}
fn set_control_flow(&self, control_flow: ControlFlow) {
self.window_target().set_control_flow(control_flow);
}
fn create_custom_cursor(
&self,
custom_cursor: CustomCursorSource,
) -> Result<CustomCursor, RequestError> {
self.window_target().create_custom_cursor(custom_cursor)
}
}
impl Drop for EventLoop { impl Drop for EventLoop {
fn drop(&mut self) { fn drop(&mut self) {
unsafe { unsafe {

View File

@@ -25,7 +25,7 @@ use winit_core::event::{DeviceId, StartCause, WindowEvent};
use winit_core::event_loop::pump_events::PumpStatus; use winit_core::event_loop::pump_events::PumpStatus;
use winit_core::event_loop::{ use winit_core::event_loop::{
ActiveEventLoop as RootActiveEventLoop, AsyncRequestSerial, ControlFlow, DeviceEvents, ActiveEventLoop as RootActiveEventLoop, AsyncRequestSerial, ControlFlow, DeviceEvents,
DndAction, EventLoopProxy as CoreEventLoopProxy, EventLoopProxyProvider, DndAction, EventLoopProvider, EventLoopProxy as CoreEventLoopProxy, EventLoopProxyProvider,
OwnedDisplayHandle as CoreOwnedDisplayHandle, OwnedDisplayHandle as CoreOwnedDisplayHandle,
}; };
use winit_core::monitor::MonitorHandle as CoreMonitorHandle; use winit_core::monitor::MonitorHandle as CoreMonitorHandle;
@@ -647,6 +647,41 @@ impl EventLoop {
} }
} }
impl EventLoopProvider for EventLoop {
fn run_app<A: ApplicationHandler + 'static>(
mut self,
mut app: A,
) -> Result<(), EventLoopError> {
let result = self.run_app_on_demand(&mut app);
// SAFETY: unsure that the state is dropped before the exit from the event loop.
drop(app);
result
}
fn create_proxy(&self) -> CoreEventLoopProxy {
self.window_target().create_proxy()
}
fn owned_display_handle(&self) -> CoreOwnedDisplayHandle {
self.window_target().owned_display_handle()
}
fn listen_device_events(&self, allowed: DeviceEvents) {
self.window_target().listen_device_events(allowed);
}
fn set_control_flow(&self, control_flow: ControlFlow) {
self.window_target().set_control_flow(control_flow);
}
fn create_custom_cursor(
&self,
custom_cursor: CustomCursorSource,
) -> Result<CoreCustomCursor, RequestError> {
self.window_target().create_custom_cursor(custom_cursor)
}
}
impl AsFd for EventLoop { impl AsFd for EventLoop {
fn as_fd(&self) -> BorrowedFd<'_> { fn as_fd(&self) -> BorrowedFd<'_> {
self.event_loop.as_fd() self.event_loop.as_fd()

View File

@@ -163,34 +163,8 @@ impl EventLoop {
/// If this requirement is prohibitive for you, consider using [`run_app_on_demand`] instead /// If this requirement is prohibitive for you, consider using [`run_app_on_demand`] instead
/// (though note that this is not available on iOS and web). /// (though note that this is not available on iOS and web).
#[inline] #[inline]
#[allow(unused_mut)] pub fn run_app<A: ApplicationHandler + 'static>(self, app: A) -> Result<(), EventLoopError> {
pub fn run_app<A: ApplicationHandler + 'static>( self.event_loop.run_app(app)
mut self,
mut app: A,
) -> Result<(), EventLoopError> {
#[cfg(any(
windows_platform,
macos_platform,
android_platform,
orbital_platform,
x11_platform,
wayland_platform,
))]
{
let result = self.event_loop.run_app_on_demand(&mut app);
// SAFETY: unsure that the state is dropped before the exit from the event loop.
drop(app);
result
}
#[cfg(web_platform)]
{
self.event_loop.register_app(app);
Ok(())
}
#[cfg(ios_platform)]
{
self.event_loop.run_app_never_return(app)
}
} }
/// Creates an [`EventLoopProxy`] that can be used to dispatch user events /// Creates an [`EventLoopProxy`] that can be used to dispatch user events

View File

@@ -9,9 +9,13 @@ use std::time::Duration;
pub(crate) use winit_common::xkb::{physicalkey_to_scancode, scancode_to_physicalkey}; pub(crate) use winit_common::xkb::{physicalkey_to_scancode, scancode_to_physicalkey};
use winit_core::application::ApplicationHandler; use winit_core::application::ApplicationHandler;
use winit_core::error::{EventLoopError, NotSupportedError}; use winit_core::cursor::{CustomCursor, CustomCursorSource};
use winit_core::event_loop::ActiveEventLoop; use winit_core::error::{EventLoopError, NotSupportedError, RequestError};
use winit_core::event_loop::pump_events::PumpStatus; use winit_core::event_loop::pump_events::PumpStatus;
use winit_core::event_loop::{
ActiveEventLoop, ControlFlow, DeviceEvents, EventLoopProvider, EventLoopProxy,
OwnedDisplayHandle,
};
#[cfg(wayland_platform)] #[cfg(wayland_platform)]
pub(crate) use winit_wayland as wayland; pub(crate) use winit_wayland as wayland;
#[cfg(x11_platform)] #[cfg(x11_platform)]
@@ -167,6 +171,41 @@ impl EventLoop {
} }
} }
impl EventLoopProvider for EventLoop {
fn run_app<A: ApplicationHandler + 'static>(
mut self,
mut app: A,
) -> Result<(), EventLoopError> {
let result = self.run_app_on_demand(&mut app);
// SAFETY: unsure that the state is dropped before the exit from the event loop.
drop(app);
result
}
fn create_proxy(&self) -> EventLoopProxy {
self.window_target().create_proxy()
}
fn owned_display_handle(&self) -> OwnedDisplayHandle {
self.window_target().owned_display_handle()
}
fn listen_device_events(&self, allowed: DeviceEvents) {
self.window_target().listen_device_events(allowed);
}
fn set_control_flow(&self, control_flow: ControlFlow) {
self.window_target().set_control_flow(control_flow);
}
fn create_custom_cursor(
&self,
custom_cursor: CustomCursorSource,
) -> Result<CustomCursor, RequestError> {
self.window_target().create_custom_cursor(custom_cursor)
}
}
impl AsFd for EventLoop { impl AsFd for EventLoop {
fn as_fd(&self) -> BorrowedFd<'_> { fn as_fd(&self) -> BorrowedFd<'_> {
x11_or_wayland!(match self; EventLoop(evlp) => evlp.as_fd()) x11_or_wayland!(match self; EventLoop(evlp) => evlp.as_fd())