api: refactor ActiveEventLoop into trait
This should help with further extensions because the backend event loops are used directly now.
This commit is contained in:
parent
f5304815a1
commit
f07153b8e0
33 changed files with 1058 additions and 1071 deletions
|
|
@ -16,7 +16,7 @@ use super::observer::{EventLoopWaker, RunLoop};
|
|||
use super::{menu, WindowId};
|
||||
use crate::application::ApplicationHandler;
|
||||
use crate::event::{StartCause, WindowEvent};
|
||||
use crate::event_loop::{ActiveEventLoop as RootActiveEventLoop, ControlFlow};
|
||||
use crate::event_loop::ControlFlow;
|
||||
use crate::window::WindowId as RootWindowId;
|
||||
|
||||
#[derive(Debug)]
|
||||
|
|
@ -282,7 +282,7 @@ impl ApplicationDelegate {
|
|||
#[track_caller]
|
||||
pub fn maybe_queue_with_handler(
|
||||
&self,
|
||||
callback: impl FnOnce(&mut dyn ApplicationHandler, &RootActiveEventLoop) + 'static,
|
||||
callback: impl FnOnce(&mut dyn ApplicationHandler, &ActiveEventLoop) + 'static,
|
||||
) {
|
||||
// Most programmer actions in AppKit (e.g. change window fullscreen, set focused, etc.)
|
||||
// result in an event being queued, and applied at a later point.
|
||||
|
|
@ -302,11 +302,9 @@ impl ApplicationDelegate {
|
|||
}
|
||||
|
||||
#[track_caller]
|
||||
fn with_handler(
|
||||
&self,
|
||||
callback: impl FnOnce(&mut dyn ApplicationHandler, &RootActiveEventLoop),
|
||||
) {
|
||||
let event_loop = ActiveEventLoop::new_root(self.retain());
|
||||
fn with_handler(&self, callback: impl FnOnce(&mut dyn ApplicationHandler, &ActiveEventLoop)) {
|
||||
let event_loop =
|
||||
ActiveEventLoop { delegate: self.retain(), mtm: MainThreadMarker::from(self) };
|
||||
self.ivars().event_handler.handle(callback, &event_loop);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ use std::cell::RefCell;
|
|||
use std::{fmt, mem};
|
||||
|
||||
use crate::application::ApplicationHandler;
|
||||
use crate::event_loop::ActiveEventLoop as RootActiveEventLoop;
|
||||
use crate::platform_impl::ActiveEventLoop;
|
||||
|
||||
#[derive(Default)]
|
||||
pub(crate) struct EventHandler {
|
||||
|
|
@ -110,8 +110,8 @@ impl EventHandler {
|
|||
|
||||
pub(crate) fn handle(
|
||||
&self,
|
||||
callback: impl FnOnce(&mut dyn ApplicationHandler, &RootActiveEventLoop),
|
||||
event_loop: &RootActiveEventLoop,
|
||||
callback: impl FnOnce(&mut dyn ApplicationHandler, &ActiveEventLoop),
|
||||
event_loop: &ActiveEventLoop,
|
||||
) {
|
||||
match self.inner.try_borrow_mut().as_deref_mut() {
|
||||
Ok(Some(user_app)) => {
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
use std::any::Any;
|
||||
use std::cell::Cell;
|
||||
use std::collections::VecDeque;
|
||||
use std::marker::PhantomData;
|
||||
use std::os::raw::c_void;
|
||||
use std::panic::{catch_unwind, resume_unwind, RefUnwindSafe, UnwindSafe};
|
||||
use std::ptr;
|
||||
|
|
@ -25,14 +23,21 @@ use super::app::WinitApplication;
|
|||
use super::app_state::ApplicationDelegate;
|
||||
use super::cursor::CustomCursor;
|
||||
use super::event::dummy_event;
|
||||
use super::monitor::{self, MonitorHandle};
|
||||
use super::monitor;
|
||||
use super::observer::setup_control_flow_observers;
|
||||
use crate::application::ApplicationHandler;
|
||||
use crate::error::{EventLoopError, ExternalError};
|
||||
use crate::event_loop::{ActiveEventLoop as RootWindowTarget, ControlFlow, DeviceEvents};
|
||||
use crate::event_loop::{
|
||||
ActiveEventLoop as RootActiveEventLoop, ControlFlow, DeviceEvents,
|
||||
EventLoopProxy as RootEventLoopProxy, OwnedDisplayHandle as RootOwnedDisplayHandle,
|
||||
};
|
||||
use crate::monitor::MonitorHandle as RootMonitorHandle;
|
||||
use crate::platform::macos::ActivationPolicy;
|
||||
use crate::platform::pump_events::PumpStatus;
|
||||
use crate::window::{CustomCursor as RootCustomCursor, CustomCursorSource, Theme};
|
||||
use crate::platform_impl::Window;
|
||||
use crate::window::{
|
||||
CustomCursor as RootCustomCursor, CustomCursorSource, Theme, Window as RootWindow,
|
||||
};
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct PanicInfo {
|
||||
|
|
@ -66,85 +71,15 @@ impl PanicInfo {
|
|||
|
||||
#[derive(Debug)]
|
||||
pub struct ActiveEventLoop {
|
||||
delegate: Retained<ApplicationDelegate>,
|
||||
pub(super) delegate: Retained<ApplicationDelegate>,
|
||||
pub(super) mtm: MainThreadMarker,
|
||||
}
|
||||
|
||||
impl ActiveEventLoop {
|
||||
pub fn create_proxy(&self) -> EventLoopProxy {
|
||||
EventLoopProxy::new(self.delegate.proxy_wake_up())
|
||||
}
|
||||
|
||||
pub(super) fn new_root(delegate: Retained<ApplicationDelegate>) -> RootWindowTarget {
|
||||
let mtm = MainThreadMarker::from(&*delegate);
|
||||
let p = Self { delegate, mtm };
|
||||
RootWindowTarget { p, _marker: PhantomData }
|
||||
}
|
||||
|
||||
pub(super) fn app_delegate(&self) -> &ApplicationDelegate {
|
||||
&self.delegate
|
||||
}
|
||||
|
||||
pub fn create_custom_cursor(
|
||||
&self,
|
||||
source: CustomCursorSource,
|
||||
) -> Result<RootCustomCursor, ExternalError> {
|
||||
Ok(RootCustomCursor { inner: CustomCursor::new(source.inner)? })
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn available_monitors(&self) -> VecDeque<MonitorHandle> {
|
||||
monitor::available_monitors()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn primary_monitor(&self) -> Option<MonitorHandle> {
|
||||
let monitor = monitor::primary_monitor();
|
||||
Some(monitor)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn listen_device_events(&self, _allowed: DeviceEvents) {}
|
||||
|
||||
#[inline]
|
||||
pub fn system_theme(&self) -> Option<Theme> {
|
||||
let app = NSApplication::sharedApplication(self.mtm);
|
||||
|
||||
if app.respondsToSelector(sel!(effectiveAppearance)) {
|
||||
Some(super::window_delegate::appearance_to_theme(&app.effectiveAppearance()))
|
||||
} else {
|
||||
Some(Theme::Light)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "rwh_06")]
|
||||
#[inline]
|
||||
pub fn raw_display_handle_rwh_06(
|
||||
&self,
|
||||
) -> Result<rwh_06::RawDisplayHandle, rwh_06::HandleError> {
|
||||
Ok(rwh_06::RawDisplayHandle::AppKit(rwh_06::AppKitDisplayHandle::new()))
|
||||
}
|
||||
|
||||
pub(crate) fn set_control_flow(&self, control_flow: ControlFlow) {
|
||||
self.delegate.set_control_flow(control_flow)
|
||||
}
|
||||
|
||||
pub(crate) fn control_flow(&self) -> ControlFlow {
|
||||
self.delegate.control_flow()
|
||||
}
|
||||
|
||||
pub(crate) fn exit(&self) {
|
||||
self.delegate.exit()
|
||||
}
|
||||
|
||||
pub(crate) fn exiting(&self) -> bool {
|
||||
self.delegate.exiting()
|
||||
}
|
||||
|
||||
pub(crate) fn owned_display_handle(&self) -> OwnedDisplayHandle {
|
||||
OwnedDisplayHandle
|
||||
}
|
||||
|
||||
pub(crate) fn hide_application(&self) {
|
||||
NSApplication::sharedApplication(self.mtm).hide(None)
|
||||
}
|
||||
|
|
@ -162,6 +97,86 @@ impl ActiveEventLoop {
|
|||
}
|
||||
}
|
||||
|
||||
impl RootActiveEventLoop for ActiveEventLoop {
|
||||
fn create_proxy(&self) -> RootEventLoopProxy {
|
||||
let event_loop_proxy = EventLoopProxy::new(self.delegate.proxy_wake_up());
|
||||
RootEventLoopProxy { event_loop_proxy }
|
||||
}
|
||||
|
||||
fn create_window(
|
||||
&self,
|
||||
window_attributes: crate::window::WindowAttributes,
|
||||
) -> Result<crate::window::Window, crate::error::OsError> {
|
||||
let window = Window::new(self, window_attributes)?;
|
||||
Ok(RootWindow { window })
|
||||
}
|
||||
|
||||
fn create_custom_cursor(
|
||||
&self,
|
||||
source: CustomCursorSource,
|
||||
) -> Result<RootCustomCursor, ExternalError> {
|
||||
Ok(RootCustomCursor { inner: CustomCursor::new(source.inner)? })
|
||||
}
|
||||
|
||||
fn available_monitors(&self) -> Box<dyn Iterator<Item = RootMonitorHandle>> {
|
||||
Box::new(monitor::available_monitors().into_iter().map(|inner| RootMonitorHandle { inner }))
|
||||
}
|
||||
|
||||
fn primary_monitor(&self) -> Option<crate::monitor::MonitorHandle> {
|
||||
let monitor = monitor::primary_monitor();
|
||||
Some(RootMonitorHandle { inner: monitor })
|
||||
}
|
||||
|
||||
fn listen_device_events(&self, _allowed: DeviceEvents) {}
|
||||
|
||||
fn system_theme(&self) -> Option<Theme> {
|
||||
let app = NSApplication::sharedApplication(self.mtm);
|
||||
|
||||
if app.respondsToSelector(sel!(effectiveAppearance)) {
|
||||
Some(super::window_delegate::appearance_to_theme(&app.effectiveAppearance()))
|
||||
} else {
|
||||
Some(Theme::Light)
|
||||
}
|
||||
}
|
||||
|
||||
fn set_control_flow(&self, control_flow: ControlFlow) {
|
||||
self.delegate.set_control_flow(control_flow)
|
||||
}
|
||||
|
||||
fn control_flow(&self) -> ControlFlow {
|
||||
self.delegate.control_flow()
|
||||
}
|
||||
|
||||
fn exit(&self) {
|
||||
self.delegate.exit()
|
||||
}
|
||||
|
||||
fn exiting(&self) -> bool {
|
||||
self.delegate.exiting()
|
||||
}
|
||||
|
||||
fn owned_display_handle(&self) -> RootOwnedDisplayHandle {
|
||||
RootOwnedDisplayHandle { platform: OwnedDisplayHandle }
|
||||
}
|
||||
|
||||
fn as_any(&self) -> &dyn Any {
|
||||
self
|
||||
}
|
||||
|
||||
#[cfg(feature = "rwh_06")]
|
||||
fn rwh_06_handle(&self) -> &dyn rwh_06::HasDisplayHandle {
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "rwh_06")]
|
||||
impl rwh_06::HasDisplayHandle for ActiveEventLoop {
|
||||
fn display_handle(&self) -> Result<rwh_06::DisplayHandle<'_>, rwh_06::HandleError> {
|
||||
let raw = rwh_06::RawDisplayHandle::AppKit(rwh_06::AppKitDisplayHandle::new());
|
||||
unsafe { Ok(rwh_06::DisplayHandle::borrow_raw(raw)) }
|
||||
}
|
||||
}
|
||||
|
||||
pub struct EventLoop {
|
||||
/// Store a reference to the application for convenience.
|
||||
///
|
||||
|
|
@ -174,7 +189,7 @@ pub struct EventLoop {
|
|||
/// keep it around here as well.
|
||||
delegate: Retained<ApplicationDelegate>,
|
||||
|
||||
window_target: RootWindowTarget,
|
||||
window_target: ActiveEventLoop,
|
||||
panic_info: Rc<PanicInfo>,
|
||||
}
|
||||
|
||||
|
|
@ -235,15 +250,12 @@ impl EventLoop {
|
|||
Ok(EventLoop {
|
||||
app,
|
||||
delegate: delegate.clone(),
|
||||
window_target: RootWindowTarget {
|
||||
p: ActiveEventLoop { delegate, mtm },
|
||||
_marker: PhantomData,
|
||||
},
|
||||
window_target: ActiveEventLoop { delegate, mtm },
|
||||
panic_info,
|
||||
})
|
||||
}
|
||||
|
||||
pub fn window_target(&self) -> &RootWindowTarget {
|
||||
pub fn window_target(&self) -> &dyn RootActiveEventLoop {
|
||||
&self.window_target
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ use objc2_foundation::{
|
|||
use objc2_ui_kit::{UIApplication, UICoordinateSpace, UIView, UIWindow};
|
||||
|
||||
use super::window::WinitUIWindow;
|
||||
use super::ActiveEventLoop;
|
||||
use crate::dpi::PhysicalSize;
|
||||
use crate::event::{Event, InnerSizeWriter, StartCause, WindowEvent};
|
||||
use crate::event_loop::{ActiveEventLoop as RootActiveEventLoop, ControlFlow};
|
||||
|
|
@ -43,8 +44,8 @@ macro_rules! bug_assert {
|
|||
|
||||
pub(crate) struct EventLoopHandler {
|
||||
#[allow(clippy::type_complexity)]
|
||||
pub(crate) handler: Box<dyn FnMut(Event, &RootActiveEventLoop)>,
|
||||
pub(crate) event_loop: RootActiveEventLoop,
|
||||
pub(crate) handler: Box<dyn FnMut(Event, &dyn RootActiveEventLoop)>,
|
||||
pub(crate) event_loop: ActiveEventLoop,
|
||||
}
|
||||
|
||||
impl fmt::Debug for EventLoopHandler {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
use std::collections::VecDeque;
|
||||
use std::any::Any;
|
||||
use std::ffi::{c_char, c_int, c_void};
|
||||
use std::marker::PhantomData;
|
||||
use std::ptr::{self, NonNull};
|
||||
use std::sync::atomic::{AtomicBool, Ordering as AtomicOrdering};
|
||||
use std::sync::Arc;
|
||||
|
|
@ -21,73 +20,95 @@ use super::app_delegate::AppDelegate;
|
|||
use super::app_state::{AppState, EventLoopHandler};
|
||||
use super::{app_state, monitor, MonitorHandle};
|
||||
use crate::application::ApplicationHandler;
|
||||
use crate::error::{EventLoopError, ExternalError, NotSupportedError};
|
||||
use crate::error::{EventLoopError, ExternalError, NotSupportedError, OsError};
|
||||
use crate::event::Event;
|
||||
use crate::event_loop::{ActiveEventLoop as RootActiveEventLoop, ControlFlow, DeviceEvents};
|
||||
use crate::window::{CustomCursor, CustomCursorSource, Theme};
|
||||
use crate::event_loop::{
|
||||
ActiveEventLoop as RootActiveEventLoop, ControlFlow, DeviceEvents,
|
||||
EventLoopProxy as RootEventLoopProxy, OwnedDisplayHandle as RootOwnedDisplayHandle,
|
||||
};
|
||||
use crate::monitor::MonitorHandle as RootMonitorHandle;
|
||||
use crate::platform_impl::Window;
|
||||
use crate::window::{CustomCursor, CustomCursorSource, Theme, Window as RootWindow};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct ActiveEventLoop {
|
||||
pub(crate) struct ActiveEventLoop {
|
||||
pub(super) mtm: MainThreadMarker,
|
||||
}
|
||||
|
||||
impl ActiveEventLoop {
|
||||
pub fn create_proxy(&self) -> EventLoopProxy {
|
||||
EventLoopProxy::new(AppState::get_mut(self.mtm).proxy_wake_up())
|
||||
impl RootActiveEventLoop for ActiveEventLoop {
|
||||
fn create_proxy(&self) -> crate::event_loop::EventLoopProxy {
|
||||
let event_loop_proxy = EventLoopProxy::new(AppState::get_mut(self.mtm).proxy_wake_up());
|
||||
RootEventLoopProxy { event_loop_proxy }
|
||||
}
|
||||
|
||||
pub fn create_custom_cursor(
|
||||
fn create_window(
|
||||
&self,
|
||||
window_attributes: crate::window::WindowAttributes,
|
||||
) -> Result<RootWindow, OsError> {
|
||||
let window = Window::new(self, window_attributes)?;
|
||||
Ok(RootWindow { window })
|
||||
}
|
||||
|
||||
fn create_custom_cursor(
|
||||
&self,
|
||||
_source: CustomCursorSource,
|
||||
) -> Result<CustomCursor, ExternalError> {
|
||||
Err(ExternalError::NotSupported(NotSupportedError::new()))
|
||||
}
|
||||
|
||||
pub fn available_monitors(&self) -> VecDeque<MonitorHandle> {
|
||||
monitor::uiscreens(self.mtm)
|
||||
fn available_monitors(&self) -> Box<dyn Iterator<Item = RootMonitorHandle>> {
|
||||
Box::new(monitor::uiscreens(self.mtm).into_iter().map(|inner| RootMonitorHandle { inner }))
|
||||
}
|
||||
|
||||
pub fn primary_monitor(&self) -> Option<MonitorHandle> {
|
||||
fn primary_monitor(&self) -> Option<crate::monitor::MonitorHandle> {
|
||||
#[allow(deprecated)]
|
||||
Some(MonitorHandle::new(UIScreen::mainScreen(self.mtm)))
|
||||
let monitor = MonitorHandle::new(UIScreen::mainScreen(self.mtm));
|
||||
Some(RootMonitorHandle { inner: monitor })
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn listen_device_events(&self, _allowed: DeviceEvents) {}
|
||||
fn listen_device_events(&self, _allowed: DeviceEvents) {}
|
||||
|
||||
#[inline]
|
||||
pub fn system_theme(&self) -> Option<Theme> {
|
||||
None
|
||||
}
|
||||
|
||||
#[cfg(feature = "rwh_06")]
|
||||
#[inline]
|
||||
pub fn raw_display_handle_rwh_06(
|
||||
&self,
|
||||
) -> Result<rwh_06::RawDisplayHandle, rwh_06::HandleError> {
|
||||
Ok(rwh_06::RawDisplayHandle::UiKit(rwh_06::UiKitDisplayHandle::new()))
|
||||
}
|
||||
|
||||
pub(crate) fn set_control_flow(&self, control_flow: ControlFlow) {
|
||||
fn set_control_flow(&self, control_flow: ControlFlow) {
|
||||
AppState::get_mut(self.mtm).set_control_flow(control_flow)
|
||||
}
|
||||
|
||||
pub(crate) fn control_flow(&self) -> ControlFlow {
|
||||
fn system_theme(&self) -> Option<Theme> {
|
||||
None
|
||||
}
|
||||
|
||||
fn control_flow(&self) -> ControlFlow {
|
||||
AppState::get_mut(self.mtm).control_flow()
|
||||
}
|
||||
|
||||
pub(crate) fn exit(&self) {
|
||||
fn exit(&self) {
|
||||
// https://developer.apple.com/library/archive/qa/qa1561/_index.html
|
||||
// it is not possible to quit an iOS app gracefully and programmatically
|
||||
tracing::warn!("`ControlFlow::Exit` ignored on iOS");
|
||||
}
|
||||
|
||||
pub(crate) fn exiting(&self) -> bool {
|
||||
fn exiting(&self) -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
pub(crate) fn owned_display_handle(&self) -> OwnedDisplayHandle {
|
||||
OwnedDisplayHandle
|
||||
fn owned_display_handle(&self) -> RootOwnedDisplayHandle {
|
||||
RootOwnedDisplayHandle { platform: OwnedDisplayHandle }
|
||||
}
|
||||
|
||||
fn as_any(&self) -> &dyn Any {
|
||||
self
|
||||
}
|
||||
|
||||
#[cfg(feature = "rwh_06")]
|
||||
fn rwh_06_handle(&self) -> &dyn rwh_06::HasDisplayHandle {
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "rwh_06")]
|
||||
impl rwh_06::HasDisplayHandle for ActiveEventLoop {
|
||||
fn display_handle(&self) -> Result<rwh_06::DisplayHandle<'_>, rwh_06::HandleError> {
|
||||
let raw = rwh_06::RawDisplayHandle::UiKit(rwh_06::UiKitDisplayHandle::new());
|
||||
unsafe { Ok(rwh_06::DisplayHandle::borrow_raw(raw)) }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -107,7 +128,7 @@ impl OwnedDisplayHandle {
|
|||
fn map_user_event<'a, A: ApplicationHandler + 'a>(
|
||||
mut app: A,
|
||||
proxy_wake_up: Arc<AtomicBool>,
|
||||
) -> impl FnMut(Event, &RootActiveEventLoop) + 'a {
|
||||
) -> impl FnMut(Event, &dyn RootActiveEventLoop) + 'a {
|
||||
move |event, window_target| match event {
|
||||
Event::NewEvents(cause) => app.new_events(window_target, cause),
|
||||
Event::WindowEvent { window_id, event } => {
|
||||
|
|
@ -132,7 +153,7 @@ fn map_user_event<'a, A: ApplicationHandler + 'a>(
|
|||
|
||||
pub struct EventLoop {
|
||||
mtm: MainThreadMarker,
|
||||
window_target: RootActiveEventLoop,
|
||||
window_target: ActiveEventLoop,
|
||||
}
|
||||
|
||||
#[derive(Default, Debug, Copy, Clone, PartialEq, Eq, Hash)]
|
||||
|
|
@ -157,10 +178,7 @@ impl EventLoop {
|
|||
// this line sets up the main run loop before `UIApplicationMain`
|
||||
setup_control_flow_observers();
|
||||
|
||||
Ok(EventLoop {
|
||||
mtm,
|
||||
window_target: RootActiveEventLoop { p: ActiveEventLoop { mtm }, _marker: PhantomData },
|
||||
})
|
||||
Ok(EventLoop { mtm, window_target: ActiveEventLoop { mtm } })
|
||||
}
|
||||
|
||||
pub fn run_app<A: ApplicationHandler>(self, app: A) -> ! {
|
||||
|
|
@ -177,8 +195,8 @@ impl EventLoop {
|
|||
|
||||
let handler = unsafe {
|
||||
std::mem::transmute::<
|
||||
Box<dyn FnMut(Event, &RootActiveEventLoop)>,
|
||||
Box<dyn FnMut(Event, &RootActiveEventLoop)>,
|
||||
Box<dyn FnMut(Event, &dyn RootActiveEventLoop)>,
|
||||
Box<dyn FnMut(Event, &dyn RootActiveEventLoop)>,
|
||||
>(Box::new(handler))
|
||||
};
|
||||
|
||||
|
|
@ -206,7 +224,7 @@ impl EventLoop {
|
|||
unreachable!()
|
||||
}
|
||||
|
||||
pub fn window_target(&self) -> &RootActiveEventLoop {
|
||||
pub fn window_target(&self) -> &dyn RootActiveEventLoop {
|
||||
&self.window_target
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue