use std::marker::PhantomData;
#[cfg(any(x11_platform, wayland_platform))]
use std::os::unix::io::{AsFd, AsRawFd, BorrowedFd, RawFd};
use rwh_06::{DisplayHandle, HandleError, HasDisplayHandle};
pub use winit_core::event_loop::*;
use crate::application::ApplicationHandler;
use crate::cursor::{CustomCursor, CustomCursorSource};
use crate::error::{EventLoopError, RequestError};
use crate::platform_impl;
#[derive(Debug)]
pub struct EventLoop {
pub(crate) event_loop: platform_impl::EventLoop,
pub(crate) _marker: PhantomData<*mut ()>, }
#[derive(Default, Debug, PartialEq, Eq, Hash)]
pub struct EventLoopBuilder {
pub(crate) platform_specific: platform_impl::PlatformSpecificEventLoopAttributes,
}
impl EventLoopBuilder {
#[cfg_attr(
android_platform,
doc = "[`.with_android_app(app)`]: \
crate::platform::android::EventLoopBuilderExtAndroid::with_android_app"
)]
#[cfg_attr(
not(android_platform),
doc = "[`.with_android_app(app)`]: #only-available-on-android"
)]
#[inline]
pub fn build(&mut self) -> Result<EventLoop, EventLoopError> {
let _entered = tracing::debug_span!("winit::EventLoopBuilder::build").entered();
#[allow(clippy::unnecessary_mut_passed)]
Ok(EventLoop {
event_loop: platform_impl::EventLoop::new(&mut self.platform_specific)?,
_marker: PhantomData,
})
}
}
impl EventLoop {
#[inline]
pub fn new() -> Result<EventLoop, EventLoopError> {
Self::builder().build()
}
#[inline]
pub fn builder() -> EventLoopBuilder {
EventLoopBuilder { platform_specific: Default::default() }
}
#[inline]
pub fn run_app<A: ApplicationHandler + 'static>(self, app: A) -> Result<(), EventLoopError> {
self.event_loop.run_app(app)
}
pub fn create_proxy(&self) -> EventLoopProxy {
self.event_loop.window_target().create_proxy()
}
pub fn owned_display_handle(&self) -> OwnedDisplayHandle {
self.event_loop.window_target().owned_display_handle()
}
pub fn listen_device_events(&self, allowed: DeviceEvents) {
let _entered = tracing::debug_span!(
"winit::EventLoop::listen_device_events",
allowed = ?allowed
)
.entered();
self.event_loop.window_target().listen_device_events(allowed)
}
pub fn set_control_flow(&self, control_flow: ControlFlow) {
self.event_loop.window_target().set_control_flow(control_flow);
}
pub fn create_custom_cursor(
&self,
custom_cursor: CustomCursorSource,
) -> Result<CustomCursor, RequestError> {
self.event_loop.window_target().create_custom_cursor(custom_cursor)
}
}
impl EventLoopProvider for EventLoop {
fn run_app<A: ApplicationHandler + 'static>(self, app: A) -> Result<(), EventLoopError> {
self.run_app(app)
}
fn create_proxy(&self) -> EventLoopProxy {
self.create_proxy()
}
fn owned_display_handle(&self) -> OwnedDisplayHandle {
self.owned_display_handle()
}
fn listen_device_events(&self, allowed: DeviceEvents) {
self.listen_device_events(allowed);
}
fn set_control_flow(&self, control_flow: ControlFlow) {
self.set_control_flow(control_flow);
}
fn create_custom_cursor(
&self,
custom_cursor: CustomCursorSource,
) -> Result<CustomCursor, RequestError> {
self.create_custom_cursor(custom_cursor)
}
}
impl HasDisplayHandle for EventLoop {
fn display_handle(&self) -> Result<DisplayHandle<'_>, HandleError> {
HasDisplayHandle::display_handle(self.event_loop.window_target().rwh_06_handle())
}
}
#[cfg(any(x11_platform, wayland_platform))]
impl AsFd for EventLoop {
fn as_fd(&self) -> BorrowedFd<'_> {
self.event_loop.as_fd()
}
}
#[cfg(any(x11_platform, wayland_platform))]
impl AsRawFd for EventLoop {
fn as_raw_fd(&self) -> RawFd {
self.event_loop.as_raw_fd()
}
}
#[cfg(any(
windows_platform,
macos_platform,
android_platform,
orbital_platform,
x11_platform,
wayland_platform,
docsrs,
))]
impl winit_core::event_loop::pump_events::EventLoopExtPumpEvents for EventLoop {
fn pump_app_events<A: ApplicationHandler>(
&mut self,
timeout: Option<std::time::Duration>,
app: A,
) -> winit_core::event_loop::pump_events::PumpStatus {
self.event_loop.pump_app_events(timeout, app)
}
}
#[allow(unused_imports)]
#[cfg(any(
windows_platform,
macos_platform,
android_platform,
orbital_platform,
x11_platform,
wayland_platform,
docsrs,
))]
impl winit_core::event_loop::run_on_demand::EventLoopExtRunOnDemand for EventLoop {
fn run_app_on_demand<A: ApplicationHandler>(&mut self, app: A) -> Result<(), EventLoopError> {
self.event_loop.run_app_on_demand(app)
}
}
#[cfg(any(web_platform, docsrs))]
impl winit_core::event_loop::register::EventLoopExtRegister for EventLoop {
fn register_app<A: ApplicationHandler + 'static>(self, app: A) {
self.event_loop.register_app(app)
}
}
#[cfg(android_platform)]
impl winit_android::EventLoopExtAndroid for EventLoop {
fn android_app(&self) -> &winit_android::activity::AndroidApp {
&self.event_loop.android_app
}
}
#[cfg(android_platform)]
impl winit_android::EventLoopBuilderExtAndroid for EventLoopBuilder {
fn with_android_app(&mut self, app: winit_android::activity::AndroidApp) -> &mut Self {
self.platform_specific.android_app = Some(app);
self
}
fn handle_volume_keys(&mut self) -> &mut Self {
self.platform_specific.ignore_volume_keys = false;
self
}
}
#[cfg(macos_platform)]
impl winit_appkit::EventLoopBuilderExtMacOS for EventLoopBuilder {
#[inline]
fn with_activation_policy(
&mut self,
activation_policy: winit_appkit::ActivationPolicy,
) -> &mut Self {
self.platform_specific.activation_policy = Some(activation_policy);
self
}
#[inline]
fn with_default_menu(&mut self, enable: bool) -> &mut Self {
self.platform_specific.default_menu = enable;
self
}
#[inline]
fn with_activate_ignoring_other_apps(&mut self, ignore: bool) -> &mut Self {
self.platform_specific.activate_ignoring_other_apps = ignore;
self
}
}
#[cfg(wayland_platform)]
impl winit_wayland::EventLoopExtWayland for EventLoop {
#[inline]
fn is_wayland(&self) -> bool {
self.event_loop.is_wayland()
}
}
#[cfg(wayland_platform)]
impl winit_wayland::EventLoopBuilderExtWayland for EventLoopBuilder {
#[inline]
fn with_wayland(&mut self) -> &mut Self {
self.platform_specific.forced_backend = Some(crate::platform_impl::Backend::Wayland);
self
}
#[inline]
fn with_any_thread(&mut self, any_thread: bool) -> &mut Self {
self.platform_specific.any_thread = any_thread;
self
}
}
#[cfg(web_platform)]
impl winit_web::EventLoopExtWeb for EventLoop {
fn set_poll_strategy(&self, strategy: winit_web::PollStrategy) {
self.event_loop.set_poll_strategy(strategy);
}
fn poll_strategy(&self) -> winit_web::PollStrategy {
self.event_loop.poll_strategy()
}
fn set_wait_until_strategy(&self, strategy: winit_web::WaitUntilStrategy) {
self.event_loop.set_wait_until_strategy(strategy);
}
fn wait_until_strategy(&self) -> winit_web::WaitUntilStrategy {
self.event_loop.wait_until_strategy()
}
fn has_multiple_screens(&self) -> Result<bool, winit_core::error::NotSupportedError> {
self.event_loop.has_multiple_screens()
}
fn request_detailed_monitor_permission(&self) -> winit_web::MonitorPermissionFuture {
self.event_loop.request_detailed_monitor_permission()
}
fn has_detailed_monitor_permission(&self) -> winit_web::HasMonitorPermissionFuture {
self.event_loop.has_detailed_monitor_permission()
}
}
#[cfg(windows_platform)]
impl winit_win32::EventLoopBuilderExtWindows for EventLoopBuilder {
#[inline]
fn with_any_thread(&mut self, any_thread: bool) -> &mut Self {
self.platform_specific.any_thread = any_thread;
self
}
#[inline]
fn with_dpi_aware(&mut self, dpi_aware: bool) -> &mut Self {
self.platform_specific.dpi_aware = dpi_aware;
self
}
#[inline]
fn with_msg_hook<F>(&mut self, callback: F) -> &mut Self
where
F: FnMut(*const core::ffi::c_void) -> bool + 'static,
{
self.platform_specific.msg_hook = Some(Box::new(callback));
self
}
}
#[cfg(x11_platform)]
impl winit_x11::EventLoopExtX11 for EventLoop {
#[inline]
fn is_x11(&self) -> bool {
!self.event_loop.is_wayland()
}
}
#[cfg(x11_platform)]
impl winit_x11::EventLoopBuilderExtX11 for EventLoopBuilder {
#[inline]
fn with_x11(&mut self) -> &mut Self {
self.platform_specific.forced_backend = Some(crate::platform_impl::Backend::X);
self
}
#[inline]
fn with_any_thread(&mut self, any_thread: bool) -> &mut Self {
self.platform_specific.any_thread = any_thread;
self
}
}
#[allow(dead_code)]
fn test_run_on_demand_cannot_access_event_loop() {}