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_loop::pump_events::PumpStatus;
use winit_core::event_loop::{
ActiveEventLoop as RootActiveEventLoop, ControlFlow, DeviceEvents,
ActiveEventLoop as RootActiveEventLoop, ControlFlow, DeviceEvents, EventLoopProvider,
EventLoopProxy as CoreEventLoopProxy, EventLoopProxyProvider,
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 {
wake_up: AtomicBool,
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::{
ActiveEventLoop as RootActiveEventLoop, AsyncRequestSerial, ControlFlow, DeviceEvents,
DndAction, DragIcon, EventLoopProxy as CoreEventLoopProxy,
DndAction, DragIcon, EventLoopProvider, EventLoopProxy as CoreEventLoopProxy,
OwnedDisplayHandle as CoreOwnedDisplayHandle,
};
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;
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_loop::pump_events::PumpStatus;
use winit_core::event_loop::{
ActiveEventLoop as RootActiveEventLoop, ControlFlow, DeviceEvents,
ActiveEventLoop as RootActiveEventLoop, ControlFlow, DeviceEvents, EventLoopProvider,
EventLoopProxy as CoreEventLoopProxy, EventLoopProxyProvider,
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)]
pub struct EventLoopProxy {
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::error::{EventLoopError, NotSupportedError, RequestError};
use winit_core::event_loop::{
ActiveEventLoop as RootActiveEventLoop, ControlFlow, DeviceEvents,
ActiveEventLoop as RootActiveEventLoop, ControlFlow, DeviceEvents, EventLoopProvider,
EventLoopProxy as CoreEventLoopProxy, OwnedDisplayHandle as CoreOwnedDisplayHandle,
};
use winit_core::monitor::MonitorHandle as CoreMonitorHandle;
@@ -333,3 +333,32 @@ impl EventLoop {
&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::{
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::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 {
fn as_fd(&self) -> BorrowedFd<'_> {
self.event_loop.as_fd()

View File

@@ -1,8 +1,12 @@
use std::sync::atomic::{AtomicBool, Ordering};
use winit_core::application::ApplicationHandler;
use winit_core::error::{EventLoopError, NotSupportedError};
use winit_core::event_loop::ActiveEventLoop as RootActiveEventLoop;
use winit_core::cursor::{CustomCursor as CoreCustomCursor, CustomCursorSource};
use winit_core::error::{EventLoopError, NotSupportedError, RequestError};
use winit_core::event_loop::{
ActiveEventLoop as RootActiveEventLoop, ControlFlow, DeviceEvents, EventLoopProvider,
EventLoopProxy, OwnedDisplayHandle,
};
use crate::{
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::{
ActiveEventLoop as RootActiveEventLoop, AsyncRequestSerial, ControlFlow, DeviceEvents,
DndAction, DragIcon, EventLoopProxy as RootEventLoopProxy, EventLoopProxyProvider,
OwnedDisplayHandle as CoreOwnedDisplayHandle,
DndAction, DragIcon, EventLoopProvider, EventLoopProxy as RootEventLoopProxy,
EventLoopProxyProvider, OwnedDisplayHandle as CoreOwnedDisplayHandle,
};
use winit_core::keyboard::ModifiersState;
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 {
fn drop(&mut self) {
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::{
ActiveEventLoop as RootActiveEventLoop, AsyncRequestSerial, ControlFlow, DeviceEvents,
DndAction, EventLoopProxy as CoreEventLoopProxy, EventLoopProxyProvider,
DndAction, EventLoopProvider, EventLoopProxy as CoreEventLoopProxy, EventLoopProxyProvider,
OwnedDisplayHandle as CoreOwnedDisplayHandle,
};
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 {
fn as_fd(&self) -> BorrowedFd<'_> {
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
/// (though note that this is not available on iOS and web).
#[inline]
#[allow(unused_mut)]
pub fn run_app<A: ApplicationHandler + 'static>(
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)
}
pub fn run_app<A: ApplicationHandler + 'static>(self, app: A) -> Result<(), EventLoopError> {
self.event_loop.run_app(app)
}
/// 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};
use winit_core::application::ApplicationHandler;
use winit_core::error::{EventLoopError, NotSupportedError};
use winit_core::event_loop::ActiveEventLoop;
use winit_core::cursor::{CustomCursor, CustomCursorSource};
use winit_core::error::{EventLoopError, NotSupportedError, RequestError};
use winit_core::event_loop::pump_events::PumpStatus;
use winit_core::event_loop::{
ActiveEventLoop, ControlFlow, DeviceEvents, EventLoopProvider, EventLoopProxy,
OwnedDisplayHandle,
};
#[cfg(wayland_platform)]
pub(crate) use winit_wayland as wayland;
#[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 {
fn as_fd(&self) -> BorrowedFd<'_> {
x11_or_wayland!(match self; EventLoop(evlp) => evlp.as_fd())