From 5683787781bb0da573289c5ee2131c22ec513f13 Mon Sep 17 00:00:00 2001 From: nerditation Date: Mon, 28 Aug 2023 22:15:07 +0800 Subject: [PATCH 1/8] make `EventLoopWindowTarget` independent of UserEvent type the `EventLoopWindowTarget` is needed for window creation. conceptually, only `EventLoop` and `EventLoopProxy` need to be parameterized, and all other parts of the backend should be agnostic about the user event type, parallel to how `Event` is parameterized, but `WindowEvent` is not. this change removes the dependency on the type of user events from the `EventLoopWindowTarget` for the Windows backend, but keep a phantom data to keep the API intact. to achieve this, I moved the `Receiver` end of the mpsc channel from `ThreadMsgTargetData` into `EventLoop` itself, so the `UserEvent` is only passed between `EventLoop` and `EventLoopProxy`, all other part of the backend just use unit type as a placeholder for user events. it's similar to the macos backend where an erased `EventHandler` trait object is used so all component except `EventLoop` and `EventLoopProxy` need to be parameterized. however `EventLoop` of the Windows backend already use an `Box` to wrap the user provided event handler callback, so no need for an dedicated trait object, I just modified the wrapper to replace the placeholder user event with real value pulled from the channel. I find this is the approach which need minimum change to be made to existing code. but it does the job and could serve as a starting point to future Windows backend re-works. --- src/platform_impl/windows/event_loop.rs | 133 ++++++++++++------ .../windows/event_loop/runner.rs | 2 +- src/platform_impl/windows/window.rs | 2 +- 3 files changed, 94 insertions(+), 43 deletions(-) diff --git a/src/platform_impl/windows/event_loop.rs b/src/platform_impl/windows/event_loop.rs index b8b2e8eb11..ada3dc6028 100644 --- a/src/platform_impl/windows/event_loop.rs +++ b/src/platform_impl/windows/event_loop.rs @@ -98,17 +98,38 @@ use self::runner::RunnerState; use super::{window::set_skip_taskbar, SelectedCursor}; -pub(crate) struct WindowData { +/// some backends like macos uses an uninhabited `Never` type, +/// on windows, `UserEvent`s are also dispatched through the +/// WNDPROC callback, and due to the re-entrant nature of the +/// callback, recursively delivered events must be queued in a +/// buffer, the current implementation put this queue in +/// `EventLoopRunner`, which is shared between the event pumping +/// loop and the callback. because it's hard to decide from the +/// outside whether a event needs to be buffered, I decided not +/// use `Event` for the shared runner state, but use unit +/// as a placeholder so user events can be buffered as usual, +/// the real `UserEvent` is pulled from the mpsc channel directly +/// when the placeholder event is delivered to the event handler +type UserEventPlaceholder = (); + +// here below, the generic `EventLoopRunnerShared` is replaced with +// `EventLoopRunnerShared` so we can get rid +// of the generic parameter T in types which don't depend on T. +// this is the approach which requires minimum changes to current +// backend implementation. it should be considered transitional +// and should be refactored and cleaned up eventually, I hope. + +pub(crate) struct WindowData { pub window_state: Arc>, - pub event_loop_runner: EventLoopRunnerShared, + pub event_loop_runner: EventLoopRunnerShared, pub key_event_builder: KeyEventBuilder, pub _file_drop_handler: Option, pub userdata_removed: Cell, pub recurse_depth: Cell, } -impl WindowData { - fn send_event(&self, event: Event) { +impl WindowData { + fn send_event(&self, event: Event) { self.event_loop_runner.send_event(event); } @@ -117,13 +138,12 @@ impl WindowData { } } -struct ThreadMsgTargetData { - event_loop_runner: EventLoopRunnerShared, - user_event_receiver: Receiver, +struct ThreadMsgTargetData { + event_loop_runner: EventLoopRunnerShared, } -impl ThreadMsgTargetData { - fn send_event(&self, event: Event) { +impl ThreadMsgTargetData { + fn send_event(&self, event: Event) { self.event_loop_runner.send_event(event); } } @@ -136,7 +156,8 @@ pub(crate) enum ProcResult { } pub struct EventLoop { - thread_msg_sender: Sender, + user_event_sender: Sender, + user_event_receiver: Receiver, window_target: RootELW, msg_hook: Option bool + 'static>>, } @@ -160,7 +181,11 @@ impl Default for PlatformSpecificEventLoopAttributes { pub struct EventLoopWindowTarget { thread_id: u32, thread_msg_target: HWND, - pub(crate) runner_shared: EventLoopRunnerShared, + pub(crate) runner_shared: EventLoopRunnerShared, + // TODO + // eventually should be removed after all the backends refactored, + // but for now should this be invariant or contra-variant to T? + _marker: PhantomData<*mut T>, } impl EventLoop { @@ -186,20 +211,22 @@ impl EventLoop { let runner_shared = Rc::new(EventLoopRunner::new(thread_msg_target)); - let thread_msg_sender = - insert_event_target_window_data::(thread_msg_target, runner_shared.clone()); + let (user_event_sender, user_event_receiver) = mpsc::channel(); + insert_event_target_window_data(thread_msg_target, runner_shared.clone()); raw_input::register_all_mice_and_keyboards_for_raw_input( thread_msg_target, Default::default(), ); Ok(EventLoop { - thread_msg_sender, + user_event_sender, + user_event_receiver, window_target: RootELW { p: EventLoopWindowTarget { thread_id, thread_msg_target, runner_shared, + _marker: PhantomData, }, _marker: PhantomData, }, @@ -229,11 +256,28 @@ impl EventLoop { } let event_loop_windows_ref = &self.window_target; + let user_event_receiver = &self.user_event_receiver; // # Safety // We make sure to call runner.clear_event_handler() before // returning unsafe { - runner.set_event_handler(move |event| event_handler(event, event_loop_windows_ref)); + runner.set_event_handler(move |event| { + // the shared `EventLoopRunner` is not parameterized + // `EventLoopProxy::send_event()` calls `PostMessage` + // to wakeup and dispatch a placeholder `UserEvent`, + // when we received the placeholder event here, the + // real UserEvent(T) should already be put in the + // mpsc channel and ready to be pulled + let event = match event.map_nonuser_event() { + Ok(non_user_event) => non_user_event, + Err(_user_event_placeholder) => Event::UserEvent( + user_event_receiver + .try_recv() + .expect("user event signaled but not received"), + ), + }; + event_handler(event, event_loop_windows_ref) + }); } } @@ -273,6 +317,7 @@ impl EventLoop { { let runner = &self.window_target.p.runner_shared; let event_loop_windows_ref = &self.window_target; + let user_event_receiver = &self.user_event_receiver; // # Safety // We make sure to call runner.clear_event_handler() before @@ -282,7 +327,17 @@ impl EventLoop { // to leave the runner in an unsound state with an associated // event handler. unsafe { - runner.set_event_handler(move |event| event_handler(event, event_loop_windows_ref)); + runner.set_event_handler(move |event| { + let event = match event.map_nonuser_event() { + Ok(non_user_event) => non_user_event, + Err(_user_event_placeholder) => Event::UserEvent( + user_event_receiver + .recv() + .expect("user event signaled but not received"), + ), + }; + event_handler(event, event_loop_windows_ref) + }); runner.wakeup(); } } @@ -468,7 +523,7 @@ impl EventLoop { pub fn create_proxy(&self) -> EventLoopProxy { EventLoopProxy { target_window: self.window_target.p.thread_msg_target, - event_send: self.thread_msg_sender.clone(), + event_send: self.user_event_sender.clone(), } } @@ -782,7 +837,7 @@ fn create_event_target_window() -> HWND { let class = WNDCLASSEXW { cbSize: mem::size_of::() as u32, style: CS_HREDRAW | CS_VREDRAW, - lpfnWndProc: Some(thread_event_target_callback::), + lpfnWndProc: Some(thread_event_target_callback), cbClsExtra: 0, cbWndExtra: 0, hInstance: util::get_instance_handle(), @@ -835,21 +890,14 @@ fn create_event_target_window() -> HWND { } } -fn insert_event_target_window_data( +fn insert_event_target_window_data( thread_msg_target: HWND, - event_loop_runner: EventLoopRunnerShared, -) -> Sender { - let (tx, rx) = mpsc::channel(); - - let userdata = ThreadMsgTargetData { - event_loop_runner, - user_event_receiver: rx, - }; + event_loop_runner: EventLoopRunnerShared, +) { + let userdata = ThreadMsgTargetData { event_loop_runner }; let input_ptr = Box::into_raw(Box::new(userdata)); unsafe { super::set_window_long(thread_msg_target, GWL_USERDATA, input_ptr as isize) }; - - tx } /// Capture mouse input, allowing `window` to receive mouse events when the cursor is outside of @@ -879,7 +927,7 @@ fn normalize_pointer_pressure(pressure: u32) -> Option { /// Emit a `ModifiersChanged` event whenever modifiers have changed. /// Returns the current modifier state -fn update_modifiers(window: HWND, userdata: &WindowData) { +fn update_modifiers(window: HWND, userdata: &WindowData) { use crate::event::WindowEvent::ModifiersChanged; let modifiers = { @@ -901,7 +949,7 @@ fn update_modifiers(window: HWND, userdata: &WindowData) { } } -unsafe fn gain_active_focus(window: HWND, userdata: &WindowData) { +unsafe fn gain_active_focus(window: HWND, userdata: &WindowData) { use crate::event::WindowEvent::Focused; update_modifiers(window, userdata); @@ -912,7 +960,7 @@ unsafe fn gain_active_focus(window: HWND, userdata: &WindowData) { }); } -unsafe fn lose_active_focus(window: HWND, userdata: &WindowData) { +unsafe fn lose_active_focus(window: HWND, userdata: &WindowData) { use crate::event::WindowEvent::{Focused, ModifiersChanged}; userdata.window_state_lock().modifiers_state = ModifiersState::empty(); @@ -969,7 +1017,7 @@ pub(super) unsafe extern "system" fn public_window_callback( return DefWindowProcW(window, msg, wparam, lparam); }, (0, _) => return unsafe { DefWindowProcW(window, msg, wparam, lparam) }, - _ => userdata as *mut WindowData, + _ => userdata as *mut WindowData, }; let (result, userdata_removed, recurse_depth) = { @@ -993,12 +1041,12 @@ pub(super) unsafe extern "system" fn public_window_callback( result } -unsafe fn public_window_callback_inner( +unsafe fn public_window_callback_inner( window: HWND, msg: u32, wparam: WPARAM, lparam: LPARAM, - userdata: &WindowData, + userdata: &WindowData, ) -> LRESULT { let mut result = ProcResult::DefWindowProc(wparam); @@ -2295,14 +2343,14 @@ unsafe fn public_window_callback_inner( } } -unsafe extern "system" fn thread_event_target_callback( +unsafe extern "system" fn thread_event_target_callback( window: HWND, msg: u32, wparam: WPARAM, lparam: LPARAM, ) -> LRESULT { let userdata_ptr = - unsafe { super::get_window_long(window, GWL_USERDATA) } as *mut ThreadMsgTargetData; + unsafe { super::get_window_long(window, GWL_USERDATA) } as *mut ThreadMsgTargetData; if userdata_ptr.is_null() { // `userdata_ptr` will always be null for the first `WM_GETMINMAXINFO`, as well as `WM_NCCREATE` and // `WM_CREATE`. @@ -2355,9 +2403,12 @@ unsafe extern "system" fn thread_event_target_callback( } _ if msg == USER_EVENT_MSG_ID.get() => { - if let Ok(event) = userdata.user_event_receiver.recv() { - userdata.send_event(Event::UserEvent(event)); - } + // synthesis a placeholder UserEvent, so that if the callback is + // re-entered it can be buffered for later delivery. the real + // user event is still in the mpsc channel and will be pulled + // once the placeholder event is delivered to the wrapper + // `event_handler` + userdata.send_event(Event::UserEvent(())); 0 } _ if msg == EXEC_MSG_ID.get() => { @@ -2380,7 +2431,7 @@ unsafe extern "system" fn thread_event_target_callback( result } -unsafe fn handle_raw_input(userdata: &ThreadMsgTargetData, data: RAWINPUT) { +unsafe fn handle_raw_input(userdata: &ThreadMsgTargetData, data: RAWINPUT) { use crate::event::{ DeviceEvent::{Button, Key, Motion, MouseMotion, MouseWheel}, ElementState::{Pressed, Released}, diff --git a/src/platform_impl/windows/event_loop/runner.rs b/src/platform_impl/windows/event_loop/runner.rs index bb5eb56a33..ee8ab5e167 100644 --- a/src/platform_impl/windows/event_loop/runner.rs +++ b/src/platform_impl/windows/event_loop/runner.rs @@ -412,7 +412,7 @@ impl BufferedEvent { let window_flags = unsafe { let userdata = - get_window_long(window_id.0.into(), GWL_USERDATA) as *mut WindowData; + get_window_long(window_id.0.into(), GWL_USERDATA) as *mut WindowData; (*userdata).window_state_lock().window_flags }; window_flags.set_size((window_id.0).0, inner_size); diff --git a/src/platform_impl/windows/window.rs b/src/platform_impl/windows/window.rs index 65b879c62d..91e205628e 100644 --- a/src/platform_impl/windows/window.rs +++ b/src/platform_impl/windows/window.rs @@ -1122,7 +1122,7 @@ impl<'a, T: 'static> InitData<'a, T> { } } - unsafe fn create_window_data(&self, win: &Window) -> event_loop::WindowData { + unsafe fn create_window_data(&self, win: &Window) -> event_loop::WindowData { let file_drop_handler = if self.pl_attribs.drag_and_drop { let ole_init_result = unsafe { OleInitialize(ptr::null_mut()) }; // It is ok if the initialize result is `S_FALSE` because it might happen that From 2ca6d3a89e1678d08fa04be6b7e925ae1dfad70f Mon Sep 17 00:00:00 2001 From: nerditation Date: Mon, 28 Aug 2023 22:29:44 +0800 Subject: [PATCH 2/8] fix CI clippy failure. --- src/platform_impl/windows/event_loop.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/platform_impl/windows/event_loop.rs b/src/platform_impl/windows/event_loop.rs index ada3dc6028..d79206bb26 100644 --- a/src/platform_impl/windows/event_loop.rs +++ b/src/platform_impl/windows/event_loop.rs @@ -207,7 +207,7 @@ impl EventLoop { become_dpi_aware(); } - let thread_msg_target = create_event_target_window::(); + let thread_msg_target = create_event_target_window(); let runner_shared = Rc::new(EventLoopRunner::new(thread_msg_target)); @@ -830,7 +830,7 @@ static THREAD_EVENT_TARGET_WINDOW_CLASS: Lazy> = /// pub static TASKBAR_CREATED: LazyMessageId = LazyMessageId::new("TaskbarCreated\0"); -fn create_event_target_window() -> HWND { +fn create_event_target_window() -> HWND { use windows_sys::Win32::UI::WindowsAndMessaging::CS_HREDRAW; use windows_sys::Win32::UI::WindowsAndMessaging::CS_VREDRAW; unsafe { From fa99990efa0f7203ecc956ec261450c29348ab8c Mon Sep 17 00:00:00 2001 From: nerditation Date: Wed, 30 Aug 2023 08:57:52 +0800 Subject: [PATCH 3/8] make UserEventPlaceholder a new type instead of alias --- src/platform_impl/windows/event_loop.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/platform_impl/windows/event_loop.rs b/src/platform_impl/windows/event_loop.rs index d79206bb26..5f90c6b7d6 100644 --- a/src/platform_impl/windows/event_loop.rs +++ b/src/platform_impl/windows/event_loop.rs @@ -110,7 +110,7 @@ use super::{window::set_skip_taskbar, SelectedCursor}; /// as a placeholder so user events can be buffered as usual, /// the real `UserEvent` is pulled from the mpsc channel directly /// when the placeholder event is delivered to the event handler -type UserEventPlaceholder = (); +pub(crate) struct UserEventPlaceholder; // here below, the generic `EventLoopRunnerShared` is replaced with // `EventLoopRunnerShared` so we can get rid @@ -2408,7 +2408,7 @@ unsafe extern "system" fn thread_event_target_callback( // user event is still in the mpsc channel and will be pulled // once the placeholder event is delivered to the wrapper // `event_handler` - userdata.send_event(Event::UserEvent(())); + userdata.send_event(Event::UserEvent(UserEventPlaceholder)); 0 } _ if msg == EXEC_MSG_ID.get() => { From dac99dd6bda191db560d6536b4ed13982f7deaa5 Mon Sep 17 00:00:00 2001 From: nerditation Date: Wed, 30 Aug 2023 09:07:01 +0800 Subject: [PATCH 4/8] invariance is maintained by top-level EventLoopWindowTarget this field is transitional and her to keep API compatibility only. the correct variance and such is already ensured by the top-level `EventLoopWindowTarget`, just use `PhantomData` here. --- src/event_loop.rs | 2 +- src/platform_impl/windows/event_loop.rs | 5 +---- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/src/event_loop.rs b/src/event_loop.rs index 13e7488e80..e2591aa51e 100644 --- a/src/event_loop.rs +++ b/src/event_loop.rs @@ -50,7 +50,7 @@ pub struct EventLoop { /// `&EventLoop`. pub struct EventLoopWindowTarget { pub(crate) p: platform_impl::EventLoopWindowTarget, - pub(crate) _marker: PhantomData<*mut ()>, // Not Send nor Sync + pub(crate) _marker: PhantomData<*mut T>, // Not Send nor Sync + invariant over T } /// Object that allows building the event loop. diff --git a/src/platform_impl/windows/event_loop.rs b/src/platform_impl/windows/event_loop.rs index 5f90c6b7d6..6a3035bc9c 100644 --- a/src/platform_impl/windows/event_loop.rs +++ b/src/platform_impl/windows/event_loop.rs @@ -182,10 +182,7 @@ pub struct EventLoopWindowTarget { thread_id: u32, thread_msg_target: HWND, pub(crate) runner_shared: EventLoopRunnerShared, - // TODO - // eventually should be removed after all the backends refactored, - // but for now should this be invariant or contra-variant to T? - _marker: PhantomData<*mut T>, + _marker: PhantomData, } impl EventLoop { From 3b06f647f19edde57a1c717f4b98545ec6874325 Mon Sep 17 00:00:00 2001 From: Mads Marquart Date: Sun, 24 Dec 2023 01:49:47 +0100 Subject: [PATCH 5/8] Remove generic parameter T from EventLoopWindowTarget --- CHANGELOG.md | 1 + examples/child_window.rs | 2 +- examples/custom_cursors.rs | 2 +- src/cursor.rs | 9 ++---- src/event_loop.rs | 19 ++++++----- src/platform/android.rs | 2 +- src/platform/macos.rs | 2 +- src/platform/pump_events.rs | 4 +-- src/platform/run_on_demand.rs | 4 +-- src/platform/startup_notify.rs | 2 +- src/platform/wayland.rs | 2 +- src/platform/web.rs | 6 ++-- src/platform/x11.rs | 2 +- src/platform_impl/android/mod.rs | 27 +++++++--------- src/platform_impl/ios/event_loop.rs | 24 ++++++-------- src/platform_impl/ios/window.rs | 4 +-- src/platform_impl/linux/mod.rs | 20 ++++++------ .../linux/wayland/event_loop/mod.rs | 21 +++++------- src/platform_impl/linux/wayland/output.rs | 2 +- src/platform_impl/linux/wayland/window/mod.rs | 4 +-- .../linux/x11/event_processor.rs | 14 ++++---- src/platform_impl/linux/x11/mod.rs | 29 ++++++++--------- src/platform_impl/linux/x11/window.rs | 4 +-- src/platform_impl/macos/app_state.rs | 8 ++--- src/platform_impl/macos/cursor.rs | 5 +-- src/platform_impl/macos/event_loop.rs | 32 ++++++++----------- src/platform_impl/macos/window.rs | 4 +-- src/platform_impl/orbital/event_loop.rs | 18 ++++------- src/platform_impl/orbital/window.rs | 4 +-- src/platform_impl/web/cursor.rs | 4 +-- src/platform_impl/web/event_loop/mod.rs | 12 +++---- .../web/event_loop/window_target.rs | 18 ++--------- src/platform_impl/web/window.rs | 4 +-- src/platform_impl/windows/event_loop.rs | 24 ++++++-------- src/platform_impl/windows/window.rs | 25 +++++++-------- src/window.rs | 7 ++-- 36 files changed, 156 insertions(+), 215 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d222094316..7069c88f1e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ Unreleased` header. # Unreleased +- **Breaking:** Removed unnecessary generic parameter `T` from `EventLoopWindowTarget`. - On Windows, macOS, X11, Wayland and Web, implement setting images as cursors. See the `custom_cursors.rs` example. - Add `Window::set_custom_cursor` - Add `CustomCursor` diff --git a/examples/child_window.rs b/examples/child_window.rs index 9234d9e4e6..2693dbdc08 100644 --- a/examples/child_window.rs +++ b/examples/child_window.rs @@ -23,7 +23,7 @@ fn main() -> Result<(), impl std::error::Error> { fn spawn_child_window( parent: &Window, - event_loop: &EventLoopWindowTarget<()>, + event_loop: &EventLoopWindowTarget, windows: &mut HashMap, ) { let parent = parent.raw_window_handle().unwrap(); diff --git a/examples/custom_cursors.rs b/examples/custom_cursors.rs index c29dd863f2..4ffac80ae2 100644 --- a/examples/custom_cursors.rs +++ b/examples/custom_cursors.rs @@ -9,7 +9,7 @@ use winit::{ window::{CustomCursor, WindowBuilder}, }; -fn decode_cursor(bytes: &[u8], window_target: &EventLoopWindowTarget) -> CustomCursor { +fn decode_cursor(bytes: &[u8], window_target: &EventLoopWindowTarget) -> CustomCursor { let img = image::load_from_memory(bytes).unwrap().to_rgba8(); let samples = img.into_flat_samples(); let (_, w, h) = samples.extents(); diff --git a/src/cursor.rs b/src/cursor.rs index 08ac912d53..a821486485 100644 --- a/src/cursor.rs +++ b/src/cursor.rs @@ -87,7 +87,7 @@ pub struct CustomCursorBuilder { } impl CustomCursorBuilder { - pub fn build(self, window_target: &EventLoopWindowTarget) -> CustomCursor { + pub fn build(self, window_target: &EventLoopWindowTarget) -> CustomCursor { CustomCursor { inner: PlatformCustomCursor::build(self.inner, &window_target.p), } @@ -189,10 +189,7 @@ impl Eq for OnlyCursorImage {} #[allow(dead_code)] impl OnlyCursorImage { - fn build( - builder: OnlyCursorImageBuilder, - _: &platform_impl::EventLoopWindowTarget, - ) -> Self { + fn build(builder: OnlyCursorImageBuilder, _: &platform_impl::EventLoopWindowTarget) -> Self { Self(Arc::new(builder.0)) } } @@ -272,7 +269,7 @@ impl NoCustomCursor { Ok(Self) } - fn build(self, _: &platform_impl::EventLoopWindowTarget) -> NoCustomCursor { + fn build(self, _: &platform_impl::EventLoopWindowTarget) -> NoCustomCursor { self } } diff --git a/src/event_loop.rs b/src/event_loop.rs index e2591aa51e..15bf05c84b 100644 --- a/src/event_loop.rs +++ b/src/event_loop.rs @@ -48,9 +48,8 @@ pub struct EventLoop { /// your callback. [`EventLoop`] will coerce into this type (`impl Deref for /// EventLoop`), so functions that take this as a parameter can also take /// `&EventLoop`. -pub struct EventLoopWindowTarget { - pub(crate) p: platform_impl::EventLoopWindowTarget, - pub(crate) _marker: PhantomData<*mut T>, // Not Send nor Sync + invariant over T +pub struct EventLoopWindowTarget { + pub(crate) p: platform_impl::EventLoopWindowTarget, } /// Object that allows building the event loop. @@ -142,7 +141,7 @@ impl fmt::Debug for EventLoop { } } -impl fmt::Debug for EventLoopWindowTarget { +impl fmt::Debug for EventLoopWindowTarget { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.pad("EventLoopWindowTarget { .. }") } @@ -244,7 +243,7 @@ impl EventLoop { #[cfg(not(all(wasm_platform, target_feature = "exception-handling")))] pub fn run(self, event_handler: F) -> Result<(), EventLoopError> where - F: FnMut(Event, &EventLoopWindowTarget), + F: FnMut(Event, &EventLoopWindowTarget), { self.event_loop.run(event_handler) } @@ -301,13 +300,13 @@ impl AsRawFd for EventLoop { } impl Deref for EventLoop { - type Target = EventLoopWindowTarget; - fn deref(&self) -> &EventLoopWindowTarget { + type Target = EventLoopWindowTarget; + fn deref(&self) -> &EventLoopWindowTarget { self.event_loop.window_target() } } -impl EventLoopWindowTarget { +impl EventLoopWindowTarget { /// Returns the list of all the monitors available on the system. #[inline] pub fn available_monitors(&self) -> impl Iterator { @@ -373,7 +372,7 @@ impl EventLoopWindowTarget { } #[cfg(feature = "rwh_06")] -impl rwh_06::HasDisplayHandle for EventLoopWindowTarget { +impl rwh_06::HasDisplayHandle for EventLoopWindowTarget { fn display_handle(&self) -> Result, rwh_06::HandleError> { let raw = self.p.raw_display_handle_rwh_06()?; // SAFETY: The display will never be deallocated while the event loop is alive. @@ -382,7 +381,7 @@ impl rwh_06::HasDisplayHandle for EventLoopWindowTarget { } #[cfg(feature = "rwh_05")] -unsafe impl rwh_05::HasRawDisplayHandle for EventLoopWindowTarget { +unsafe impl rwh_05::HasRawDisplayHandle for EventLoopWindowTarget { /// Returns a [`rwh_05::RawDisplayHandle`] for the event loop. fn raw_display_handle(&self) -> rwh_05::RawDisplayHandle { self.p.raw_display_handle_rwh_05() diff --git a/src/platform/android.rs b/src/platform/android.rs index b5fde4ad49..c80fbeac29 100644 --- a/src/platform/android.rs +++ b/src/platform/android.rs @@ -30,7 +30,7 @@ impl WindowExtAndroid for Window { } } -impl EventLoopWindowTargetExtAndroid for EventLoopWindowTarget {} +impl EventLoopWindowTargetExtAndroid for EventLoopWindowTarget {} /// Additional methods on [`WindowBuilder`] that are specific to Android. pub trait WindowBuilderExtAndroid {} diff --git a/src/platform/macos.rs b/src/platform/macos.rs index 65cfbe8992..ac7b0a6fb4 100644 --- a/src/platform/macos.rs +++ b/src/platform/macos.rs @@ -386,7 +386,7 @@ pub trait EventLoopWindowTargetExtMacOS { fn allows_automatic_window_tabbing(&self) -> bool; } -impl EventLoopWindowTargetExtMacOS for EventLoopWindowTarget { +impl EventLoopWindowTargetExtMacOS for EventLoopWindowTarget { fn hide_application(&self) { self.p.hide_application() } diff --git a/src/platform/pump_events.rs b/src/platform/pump_events.rs index ccaf148586..403c52d978 100644 --- a/src/platform/pump_events.rs +++ b/src/platform/pump_events.rs @@ -174,7 +174,7 @@ pub trait EventLoopExtPumpEvents { /// callback. fn pump_events(&mut self, timeout: Option, event_handler: F) -> PumpStatus where - F: FnMut(Event, &EventLoopWindowTarget); + F: FnMut(Event, &EventLoopWindowTarget); } impl EventLoopExtPumpEvents for EventLoop { @@ -182,7 +182,7 @@ impl EventLoopExtPumpEvents for EventLoop { fn pump_events(&mut self, timeout: Option, event_handler: F) -> PumpStatus where - F: FnMut(Event, &EventLoopWindowTarget), + F: FnMut(Event, &EventLoopWindowTarget), { self.event_loop.pump_events(timeout, event_handler) } diff --git a/src/platform/run_on_demand.rs b/src/platform/run_on_demand.rs index 5326e92c74..03e49a961a 100644 --- a/src/platform/run_on_demand.rs +++ b/src/platform/run_on_demand.rs @@ -66,7 +66,7 @@ pub trait EventLoopExtRunOnDemand { /// [`set_control_flow()`]: EventLoopWindowTarget::set_control_flow() fn run_on_demand(&mut self, event_handler: F) -> Result<(), EventLoopError> where - F: FnMut(Event, &EventLoopWindowTarget); + F: FnMut(Event, &EventLoopWindowTarget); } impl EventLoopExtRunOnDemand for EventLoop { @@ -74,7 +74,7 @@ impl EventLoopExtRunOnDemand for EventLoop { fn run_on_demand(&mut self, event_handler: F) -> Result<(), EventLoopError> where - F: FnMut(Event, &EventLoopWindowTarget), + F: FnMut(Event, &EventLoopWindowTarget), { self.event_loop.run_on_demand(event_handler) } diff --git a/src/platform/startup_notify.rs b/src/platform/startup_notify.rs index 323c2fe624..207aff86cb 100644 --- a/src/platform/startup_notify.rs +++ b/src/platform/startup_notify.rs @@ -55,7 +55,7 @@ pub trait WindowBuilderExtStartupNotify { fn with_activation_token(self, token: ActivationToken) -> Self; } -impl EventLoopExtStartupNotify for EventLoopWindowTarget { +impl EventLoopExtStartupNotify for EventLoopWindowTarget { fn read_token_from_env(&self) -> Option { match self.p { #[cfg(wayland_platform)] diff --git a/src/platform/wayland.rs b/src/platform/wayland.rs index ba87651858..99ae6b295a 100644 --- a/src/platform/wayland.rs +++ b/src/platform/wayland.rs @@ -14,7 +14,7 @@ pub trait EventLoopWindowTargetExtWayland { fn is_wayland(&self) -> bool; } -impl EventLoopWindowTargetExtWayland for EventLoopWindowTarget { +impl EventLoopWindowTargetExtWayland for EventLoopWindowTarget { #[inline] fn is_wayland(&self) -> bool { self.p.is_wayland() diff --git a/src/platform/web.rs b/src/platform/web.rs index 2d79914924..f0f8d2e9ac 100644 --- a/src/platform/web.rs +++ b/src/platform/web.rs @@ -136,7 +136,7 @@ pub trait EventLoopExtWebSys { /// [^1]: `run()` is _not_ available on WASM when the target supports `exception-handling`. fn spawn(self, event_handler: F) where - F: 'static + FnMut(Event, &EventLoopWindowTarget); + F: 'static + FnMut(Event, &EventLoopWindowTarget); } impl EventLoopExtWebSys for EventLoop { @@ -144,7 +144,7 @@ impl EventLoopExtWebSys for EventLoop { fn spawn(self, event_handler: F) where - F: 'static + FnMut(Event, &EventLoopWindowTarget), + F: 'static + FnMut(Event, &EventLoopWindowTarget), { self.event_loop.spawn(event_handler) } @@ -166,7 +166,7 @@ pub trait EventLoopWindowTargetExtWebSys { fn poll_strategy(&self) -> PollStrategy; } -impl EventLoopWindowTargetExtWebSys for EventLoopWindowTarget { +impl EventLoopWindowTargetExtWebSys for EventLoopWindowTarget { #[inline] fn set_poll_strategy(&self, strategy: PollStrategy) { self.p.set_poll_strategy(strategy); diff --git a/src/platform/x11.rs b/src/platform/x11.rs index 5cbd2fe32a..194f02145f 100644 --- a/src/platform/x11.rs +++ b/src/platform/x11.rs @@ -48,7 +48,7 @@ pub trait EventLoopWindowTargetExtX11 { fn is_x11(&self) -> bool; } -impl EventLoopWindowTargetExtX11 for EventLoopWindowTarget { +impl EventLoopWindowTargetExtX11 for EventLoopWindowTarget { #[inline] fn is_x11(&self) -> bool { !self.p.is_wayland() diff --git a/src/platform_impl/android/mod.rs b/src/platform_impl/android/mod.rs index cf28c21bbe..159ab8448c 100644 --- a/src/platform_impl/android/mod.rs +++ b/src/platform_impl/android/mod.rs @@ -138,7 +138,7 @@ pub struct KeyEventExtra {} pub struct EventLoop { android_app: AndroidApp, - window_target: event_loop::EventLoopWindowTarget, + window_target: event_loop::EventLoopWindowTarget, redraw_flag: SharedFlag, user_events_sender: mpsc::Sender, user_events_receiver: PeekableReceiver, //must wake looper whenever something gets sent @@ -185,9 +185,7 @@ impl EventLoop { &redraw_flag, android_app.create_waker(), ), - _marker: std::marker::PhantomData, }, - _marker: std::marker::PhantomData, }, redraw_flag, user_events_sender, @@ -203,7 +201,7 @@ impl EventLoop { fn single_iteration(&mut self, main_event: Option>, callback: &mut F) where - F: FnMut(event::Event, &RootELW), + F: FnMut(event::Event, &RootELW), { trace!("Mainloop iteration"); @@ -375,7 +373,7 @@ impl EventLoop { callback: &mut F, ) -> InputStatus where - F: FnMut(event::Event, &RootELW), + F: FnMut(event::Event, &RootELW), { let mut input_status = InputStatus::Handled; match event { @@ -480,14 +478,14 @@ impl EventLoop { pub fn run(mut self, event_handler: F) -> Result<(), EventLoopError> where - F: FnMut(event::Event, &event_loop::EventLoopWindowTarget), + F: FnMut(event::Event, &event_loop::EventLoopWindowTarget), { self.run_on_demand(event_handler) } pub fn run_on_demand(&mut self, mut event_handler: F) -> Result<(), EventLoopError> where - F: FnMut(event::Event, &event_loop::EventLoopWindowTarget), + F: FnMut(event::Event, &event_loop::EventLoopWindowTarget), { if self.loop_running { return Err(EventLoopError::AlreadyRunning); @@ -510,7 +508,7 @@ impl EventLoop { pub fn pump_events(&mut self, timeout: Option, mut callback: F) -> PumpStatus where - F: FnMut(event::Event, &RootELW), + F: FnMut(event::Event, &RootELW), { if !self.loop_running { self.loop_running = true; @@ -543,7 +541,7 @@ impl EventLoop { fn poll_events_with_timeout(&mut self, mut timeout: Option, mut callback: F) where - F: FnMut(event::Event, &RootELW), + F: FnMut(event::Event, &RootELW), { let start = Instant::now(); @@ -619,7 +617,7 @@ impl EventLoop { }); } - pub fn window_target(&self) -> &event_loop::EventLoopWindowTarget { + pub fn window_target(&self) -> &event_loop::EventLoopWindowTarget { &self.window_target } @@ -663,15 +661,14 @@ impl EventLoopProxy { } } -pub struct EventLoopWindowTarget { +pub struct EventLoopWindowTarget { app: AndroidApp, control_flow: Cell, exit: Cell, redraw_requester: RedrawRequester, - _marker: std::marker::PhantomData, } -impl EventLoopWindowTarget { +impl EventLoopWindowTarget { pub fn primary_monitor(&self) -> Option { Some(MonitorHandle::new(self.app.clone())) } @@ -757,8 +754,8 @@ pub(crate) struct Window { } impl Window { - pub(crate) fn new( - el: &EventLoopWindowTarget, + pub(crate) fn new( + el: &EventLoopWindowTarget, _window_attrs: window::WindowAttributes, _: PlatformSpecificWindowBuilderAttributes, ) -> Result { diff --git a/src/platform_impl/ios/event_loop.rs b/src/platform_impl/ios/event_loop.rs index a260f78aec..029f2200e2 100644 --- a/src/platform_impl/ios/event_loop.rs +++ b/src/platform_impl/ios/event_loop.rs @@ -2,7 +2,6 @@ use std::{ collections::VecDeque, ffi::c_void, fmt::{self, Debug}, - marker::PhantomData, ptr, sync::mpsc::{self, Receiver, Sender}, }; @@ -34,12 +33,11 @@ use super::{ }; #[derive(Debug)] -pub struct EventLoopWindowTarget { +pub struct EventLoopWindowTarget { pub(super) mtm: MainThreadMarker, - p: PhantomData, } -impl EventLoopWindowTarget { +impl EventLoopWindowTarget { pub fn available_monitors(&self) -> VecDeque { monitor::uiscreens(self.mtm) } @@ -90,7 +88,7 @@ pub struct EventLoop { mtm: MainThreadMarker, sender: Sender, receiver: Receiver, - window_target: RootEventLoopWindowTarget, + window_target: RootEventLoopWindowTarget, } #[derive(Default, Debug, Copy, Clone, PartialEq, Eq, Hash)] @@ -123,18 +121,14 @@ impl EventLoop { sender, receiver, window_target: RootEventLoopWindowTarget { - p: EventLoopWindowTarget { - mtm, - p: PhantomData, - }, - _marker: PhantomData, + p: EventLoopWindowTarget { mtm }, }, }) } pub fn run(self, event_handler: F) -> ! where - F: FnMut(Event, &RootEventLoopWindowTarget), + F: FnMut(Event, &RootEventLoopWindowTarget), { unsafe { let application = UIApplication::shared(self.mtm); @@ -146,7 +140,7 @@ impl EventLoop { ); let event_handler = std::mem::transmute::< - Box, &RootEventLoopWindowTarget)>, + Box, &RootEventLoopWindowTarget)>, Box>, >(Box::new(event_handler)); @@ -175,7 +169,7 @@ impl EventLoop { EventLoopProxy::new(self.sender.clone()) } - pub fn window_target(&self) -> &RootEventLoopWindowTarget { + pub fn window_target(&self) -> &RootEventLoopWindowTarget { &self.window_target } } @@ -346,7 +340,7 @@ fn setup_control_flow_observers() { #[derive(Debug)] pub enum Never {} -type EventHandlerCallback = dyn FnMut(Event, &RootEventLoopWindowTarget) + 'static; +type EventHandlerCallback = dyn FnMut(Event, &RootEventLoopWindowTarget) + 'static; pub trait EventHandler: Debug { fn handle_nonuser_event(&mut self, event: Event); @@ -356,7 +350,7 @@ pub trait EventHandler: Debug { struct EventLoopHandler { f: Box>, receiver: Receiver, - event_loop: RootEventLoopWindowTarget, + event_loop: RootEventLoopWindowTarget, } impl Debug for EventLoopHandler { diff --git a/src/platform_impl/ios/window.rs b/src/platform_impl/ios/window.rs index e34801696e..19bc78be2b 100644 --- a/src/platform_impl/ios/window.rs +++ b/src/platform_impl/ios/window.rs @@ -409,8 +409,8 @@ pub struct Window { } impl Window { - pub(crate) fn new( - event_loop: &EventLoopWindowTarget, + pub(crate) fn new( + event_loop: &EventLoopWindowTarget, window_attributes: WindowAttributes, platform_attributes: PlatformSpecificWindowBuilderAttributes, ) -> Result { diff --git a/src/platform_impl/linux/mod.rs b/src/platform_impl/linux/mod.rs index 0cfd3cb8ba..98f32595c3 100644 --- a/src/platform_impl/linux/mod.rs +++ b/src/platform_impl/linux/mod.rs @@ -291,8 +291,8 @@ impl VideoMode { impl Window { #[inline] - pub(crate) fn new( - window_target: &EventLoopWindowTarget, + pub(crate) fn new( + window_target: &EventLoopWindowTarget, attribs: WindowAttributes, pl_attribs: PlatformSpecificWindowBuilderAttributes, ) -> Result { @@ -816,26 +816,26 @@ impl EventLoop { pub fn run(mut self, callback: F) -> Result<(), EventLoopError> where - F: FnMut(crate::event::Event, &RootELW), + F: FnMut(crate::event::Event, &RootELW), { self.run_on_demand(callback) } pub fn run_on_demand(&mut self, callback: F) -> Result<(), EventLoopError> where - F: FnMut(crate::event::Event, &RootELW), + F: FnMut(crate::event::Event, &RootELW), { x11_or_wayland!(match self; EventLoop(evlp) => evlp.run_on_demand(callback)) } pub fn pump_events(&mut self, timeout: Option, callback: F) -> PumpStatus where - F: FnMut(crate::event::Event, &RootELW), + F: FnMut(crate::event::Event, &RootELW), { x11_or_wayland!(match self; EventLoop(evlp) => evlp.pump_events(timeout, callback)) } - pub fn window_target(&self) -> &crate::event_loop::EventLoopWindowTarget { + pub fn window_target(&self) -> &crate::event_loop::EventLoopWindowTarget { x11_or_wayland!(match self; EventLoop(evlp) => evlp.window_target()) } } @@ -858,14 +858,14 @@ impl EventLoopProxy { } } -pub enum EventLoopWindowTarget { +pub enum EventLoopWindowTarget { #[cfg(wayland_platform)] - Wayland(wayland::EventLoopWindowTarget), + Wayland(wayland::EventLoopWindowTarget), #[cfg(x11_platform)] - X(x11::EventLoopWindowTarget), + X(x11::EventLoopWindowTarget), } -impl EventLoopWindowTarget { +impl EventLoopWindowTarget { #[inline] pub fn is_wayland(&self) -> bool { match *self { diff --git a/src/platform_impl/linux/wayland/event_loop/mod.rs b/src/platform_impl/linux/wayland/event_loop/mod.rs index e0d6a36d78..099f176ed4 100644 --- a/src/platform_impl/linux/wayland/event_loop/mod.rs +++ b/src/platform_impl/linux/wayland/event_loop/mod.rs @@ -2,7 +2,6 @@ use std::cell::{Cell, RefCell}; use std::io::Result as IOResult; -use std::marker::PhantomData; use std::mem; use std::os::unix::io::{AsFd, AsRawFd, BorrowedFd, RawFd}; use std::rc::Rc; @@ -63,7 +62,7 @@ pub struct EventLoop { connection: Connection, /// Event loop window target. - window_target: RootEventLoopWindowTarget, + window_target: RootEventLoopWindowTarget, // XXX drop after everything else, just to be safe. /// Calloop's event loop. @@ -167,7 +166,6 @@ impl EventLoop { control_flow: Cell::new(ControlFlow::default()), exit: Cell::new(None), state: RefCell::new(winit_state), - _marker: PhantomData, }; let event_loop = Self { @@ -182,7 +180,6 @@ impl EventLoop { event_loop, window_target: RootEventLoopWindowTarget { p: PlatformEventLoopWindowTarget::Wayland(window_target), - _marker: PhantomData, }, }; @@ -191,7 +188,7 @@ impl EventLoop { pub fn run_on_demand(&mut self, mut event_handler: F) -> Result<(), EventLoopError> where - F: FnMut(Event, &RootEventLoopWindowTarget), + F: FnMut(Event, &RootEventLoopWindowTarget), { if self.loop_running { return Err(EventLoopError::AlreadyRunning); @@ -222,7 +219,7 @@ impl EventLoop { pub fn pump_events(&mut self, timeout: Option, mut callback: F) -> PumpStatus where - F: FnMut(Event, &RootEventLoopWindowTarget), + F: FnMut(Event, &RootEventLoopWindowTarget), { if !self.loop_running { self.loop_running = true; @@ -249,7 +246,7 @@ impl EventLoop { pub fn poll_events_with_timeout(&mut self, mut timeout: Option, mut callback: F) where - F: FnMut(Event, &RootEventLoopWindowTarget), + F: FnMut(Event, &RootEventLoopWindowTarget), { let cause = loop { let start = Instant::now(); @@ -325,7 +322,7 @@ impl EventLoop { fn single_iteration(&mut self, callback: &mut F, cause: StartCause) where - F: FnMut(Event, &RootEventLoopWindowTarget), + F: FnMut(Event, &RootEventLoopWindowTarget), { // NOTE currently just indented to simplify the diff @@ -530,7 +527,7 @@ impl EventLoop { } #[inline] - pub fn window_target(&self) -> &RootEventLoopWindowTarget { + pub fn window_target(&self) -> &RootEventLoopWindowTarget { &self.window_target } @@ -602,7 +599,7 @@ impl AsRawFd for EventLoop { } } -pub struct EventLoopWindowTarget { +pub struct EventLoopWindowTarget { /// The event loop wakeup source. pub event_loop_awakener: calloop::ping::Ping, @@ -624,11 +621,9 @@ pub struct EventLoopWindowTarget { /// Connection to the wayland server. pub connection: Connection, - - _marker: std::marker::PhantomData, } -impl EventLoopWindowTarget { +impl EventLoopWindowTarget { #[inline] pub fn listen_device_events(&self, _allowed: DeviceEvents) {} diff --git a/src/platform_impl/linux/wayland/output.rs b/src/platform_impl/linux/wayland/output.rs index 4e288cdc06..7ac316ae58 100644 --- a/src/platform_impl/linux/wayland/output.rs +++ b/src/platform_impl/linux/wayland/output.rs @@ -9,7 +9,7 @@ use crate::platform_impl::platform::VideoMode as PlatformVideoMode; use super::event_loop::EventLoopWindowTarget; -impl EventLoopWindowTarget { +impl EventLoopWindowTarget { #[inline] pub fn available_monitors(&self) -> impl Iterator { self.state diff --git a/src/platform_impl/linux/wayland/window/mod.rs b/src/platform_impl/linux/wayland/window/mod.rs index 74ff1baf11..ad80e37a56 100644 --- a/src/platform_impl/linux/wayland/window/mod.rs +++ b/src/platform_impl/linux/wayland/window/mod.rs @@ -79,8 +79,8 @@ pub struct Window { } impl Window { - pub(crate) fn new( - event_loop_window_target: &EventLoopWindowTarget, + pub(crate) fn new( + event_loop_window_target: &EventLoopWindowTarget, attributes: WindowAttributes, platform_attributes: PlatformAttributes, ) -> Result { diff --git a/src/platform_impl/linux/x11/event_processor.rs b/src/platform_impl/linux/x11/event_processor.rs index 6395d35828..6702422580 100644 --- a/src/platform_impl/linux/x11/event_processor.rs +++ b/src/platform_impl/linux/x11/event_processor.rs @@ -36,7 +36,7 @@ use crate::{ /// The X11 documentation states: "Keycodes lie in the inclusive range `[8, 255]`". const KEYCODE_OFFSET: u8 = 8; -pub(super) struct EventProcessor { +pub(super) struct EventProcessor { pub(super) dnd: Dnd, pub(super) ime_receiver: ImeReceiver, pub(super) ime_event_receiver: ImeEventReceiver, @@ -44,7 +44,7 @@ pub(super) struct EventProcessor { pub(super) devices: RefCell>, pub(super) xi2ext: ExtensionInformation, pub(super) xkbext: ExtensionInformation, - pub(super) target: Rc>, + pub(super) target: Rc, pub(super) kb_state: KbdState, // Number of touch events currently in progress pub(super) num_touch: u32, @@ -59,7 +59,7 @@ pub(super) struct EventProcessor { pub(super) is_composing: bool, } -impl EventProcessor { +impl EventProcessor { pub(super) fn init_device(&self, device: xinput::DeviceId) { let wt = get_xtarget(&self.target); let mut devices = self.devices.borrow_mut(); @@ -134,7 +134,7 @@ impl EventProcessor { result != 0 } - pub(super) fn process_event(&mut self, xev: &mut ffi::XEvent, mut callback: F) + pub(super) fn process_event(&mut self, xev: &mut ffi::XEvent, mut callback: F) where F: FnMut(Event), { @@ -1377,8 +1377,8 @@ impl EventProcessor { } } - fn handle_pressed_keys( - wt: &super::EventLoopWindowTarget, + fn handle_pressed_keys( + wt: &super::EventLoopWindowTarget, window_id: crate::window::WindowId, state: ElementState, kb_state: &mut KbdState, @@ -1408,7 +1408,7 @@ impl EventProcessor { } } - fn process_dpi_change(&self, callback: &mut F) + fn process_dpi_change(&self, callback: &mut F) where F: FnMut(Event), { diff --git a/src/platform_impl/linux/x11/mod.rs b/src/platform_impl/linux/x11/mod.rs index 6d8d9fd305..f1d9ae2cea 100644 --- a/src/platform_impl/linux/x11/mod.rs +++ b/src/platform_impl/linux/x11/mod.rs @@ -143,7 +143,7 @@ impl PeekableReceiver { } } -pub struct EventLoopWindowTarget { +pub struct EventLoopWindowTarget { xconn: Arc, wm_delete_window: xproto::Atom, net_wm_ping: xproto::Atom, @@ -156,19 +156,18 @@ pub struct EventLoopWindowTarget { redraw_sender: WakeSender, activation_sender: WakeSender, device_events: Cell, - _marker: ::std::marker::PhantomData, } pub struct EventLoop { loop_running: bool, event_loop: Loop<'static, EventLoopState>, waker: calloop::ping::Ping, - event_processor: EventProcessor, + event_processor: EventProcessor, redraw_receiver: PeekableReceiver, user_receiver: PeekableReceiver, activation_receiver: PeekableReceiver, user_sender: Sender, - target: Rc>, + target: Rc, /// The current state of the event loop. state: EventLoopState, @@ -308,7 +307,6 @@ impl EventLoop { control_flow: Cell::new(ControlFlow::default()), exit: Cell::new(None), windows: Default::default(), - _marker: ::std::marker::PhantomData, ime_sender, xconn, wm_delete_window, @@ -329,7 +327,6 @@ impl EventLoop { let target = Rc::new(RootELW { p: super::EventLoopWindowTarget::X(window_target), - _marker: ::std::marker::PhantomData, }); let event_processor = EventProcessor { @@ -395,13 +392,13 @@ impl EventLoop { } } - pub(crate) fn window_target(&self) -> &RootELW { + pub(crate) fn window_target(&self) -> &RootELW { &self.target } pub fn run_on_demand(&mut self, mut event_handler: F) -> Result<(), EventLoopError> where - F: FnMut(Event, &RootELW), + F: FnMut(Event, &RootELW), { if self.loop_running { return Err(EventLoopError::AlreadyRunning); @@ -435,7 +432,7 @@ impl EventLoop { pub fn pump_events(&mut self, timeout: Option, mut callback: F) -> PumpStatus where - F: FnMut(Event, &RootELW), + F: FnMut(Event, &RootELW), { if !self.loop_running { self.loop_running = true; @@ -468,7 +465,7 @@ impl EventLoop { pub fn poll_events_with_timeout(&mut self, mut timeout: Option, mut callback: F) where - F: FnMut(Event, &RootELW), + F: FnMut(Event, &RootELW), { let start = Instant::now(); @@ -546,7 +543,7 @@ impl EventLoop { fn single_iteration(&mut self, callback: &mut F, cause: StartCause) where - F: FnMut(Event, &RootELW), + F: FnMut(Event, &RootELW), { callback(crate::event::Event::NewEvents(cause), &self.target); @@ -620,7 +617,7 @@ impl EventLoop { fn drain_events(&mut self, callback: &mut F) where - F: FnMut(Event, &RootELW), + F: FnMut(Event, &RootELW), { let target = &self.target; let mut xev = MaybeUninit::uninit(); @@ -671,7 +668,7 @@ impl AsRawFd for EventLoop { } } -pub(crate) fn get_xtarget(target: &RootELW) -> &EventLoopWindowTarget { +pub(crate) fn get_xtarget(target: &RootELW) -> &EventLoopWindowTarget { match target.p { super::EventLoopWindowTarget::X(ref target) => target, #[cfg(wayland_platform)] @@ -679,7 +676,7 @@ pub(crate) fn get_xtarget(target: &RootELW) -> &EventLoopWindowTarget { } } -impl EventLoopWindowTarget { +impl EventLoopWindowTarget { /// Returns the `XConnection` of this events loop. #[inline] pub(crate) fn x_connection(&self) -> &Arc { @@ -834,8 +831,8 @@ impl Deref for Window { } impl Window { - pub(crate) fn new( - event_loop: &EventLoopWindowTarget, + pub(crate) fn new( + event_loop: &EventLoopWindowTarget, attribs: WindowAttributes, pl_attribs: PlatformSpecificWindowBuilderAttributes, ) -> Result { diff --git a/src/platform_impl/linux/x11/window.rs b/src/platform_impl/linux/x11/window.rs index b7ea8e1a12..5da2d0d035 100644 --- a/src/platform_impl/linux/x11/window.rs +++ b/src/platform_impl/linux/x11/window.rs @@ -150,8 +150,8 @@ macro_rules! leap { impl UnownedWindow { #[allow(clippy::unnecessary_cast)] - pub(crate) fn new( - event_loop: &EventLoopWindowTarget, + pub(crate) fn new( + event_loop: &EventLoopWindowTarget, window_attrs: WindowAttributes, pl_attribs: PlatformSpecificWindowBuilderAttributes, ) -> Result { diff --git a/src/platform_impl/macos/app_state.rs b/src/platform_impl/macos/app_state.rs index 3630b06b8c..75e37b6d71 100644 --- a/src/platform_impl/macos/app_state.rs +++ b/src/platform_impl/macos/app_state.rs @@ -45,18 +45,18 @@ pub trait EventHandler: Debug { fn handle_user_events(&mut self); } -pub(crate) type Callback = RefCell, &RootWindowTarget)>; +pub(crate) type Callback = RefCell, &RootWindowTarget)>; struct EventLoopHandler { callback: Weak>, - window_target: Rc>, + window_target: Rc, receiver: Rc>, } impl EventLoopHandler { fn with_callback(&mut self, f: F) where - F: FnOnce(&mut EventLoopHandler, RefMut<'_, dyn FnMut(Event, &RootWindowTarget)>), + F: FnOnce(&mut EventLoopHandler, RefMut<'_, dyn FnMut(Event, &RootWindowTarget)>), { // `NSApplication` and our `HANDLER` are global state and so it's possible // that we could get a delegate callback after the application has exit an @@ -370,7 +370,7 @@ impl AppState { /// a call to `clear_callback` before returning to avoid undefined behaviour. pub unsafe fn set_callback( callback: Weak>, - window_target: Rc>, + window_target: Rc, receiver: Rc>, ) { *HANDLER.callback.lock().unwrap() = Some(Box::new(EventLoopHandler { diff --git a/src/platform_impl/macos/cursor.rs b/src/platform_impl/macos/cursor.rs index 8f84b5e88d..4f5a06cbe4 100644 --- a/src/platform_impl/macos/cursor.rs +++ b/src/platform_impl/macos/cursor.rs @@ -24,10 +24,7 @@ unsafe impl Send for CustomCursor {} unsafe impl Sync for CustomCursor {} impl CustomCursor { - pub(crate) fn build( - cursor: OnlyCursorImageBuilder, - _: &EventLoopWindowTarget, - ) -> CustomCursor { + pub(crate) fn build(cursor: OnlyCursorImageBuilder, _: &EventLoopWindowTarget) -> CustomCursor { Self(cursor_from_image(&cursor.0)) } } diff --git a/src/platform_impl/macos/event_loop.rs b/src/platform_impl/macos/event_loop.rs index 7bce3aba05..08597a3d4f 100644 --- a/src/platform_impl/macos/event_loop.rs +++ b/src/platform_impl/macos/event_loop.rs @@ -2,7 +2,6 @@ use std::{ any::Any, cell::{Cell, RefCell}, collections::VecDeque, - marker::PhantomData, mem, os::raw::c_void, panic::{catch_unwind, resume_unwind, AssertUnwindSafe, RefUnwindSafe, UnwindSafe}, @@ -74,12 +73,11 @@ impl PanicInfo { } #[derive(Debug)] -pub struct EventLoopWindowTarget { +pub struct EventLoopWindowTarget { mtm: MainThreadMarker, - p: PhantomData, } -impl EventLoopWindowTarget { +impl EventLoopWindowTarget { #[inline] pub fn available_monitors(&self) -> VecDeque { monitor::available_monitors() @@ -127,7 +125,7 @@ impl EventLoopWindowTarget { } } -impl EventLoopWindowTarget { +impl EventLoopWindowTarget { pub(crate) fn hide_application(&self) { NSApplication::sharedApplication(self.mtm).hide(None) } @@ -159,7 +157,7 @@ pub struct EventLoop { sender: mpsc::Sender, receiver: Rc>, - window_target: Rc>, + window_target: Rc, panic_info: Rc, /// We make sure that the callback closure is dropped during a panic @@ -228,24 +226,20 @@ impl EventLoop { sender, receiver: Rc::new(receiver), window_target: Rc::new(RootWindowTarget { - p: EventLoopWindowTarget { - mtm, - p: PhantomData, - }, - _marker: PhantomData, + p: EventLoopWindowTarget { mtm }, }), panic_info, _callback: None, }) } - pub fn window_target(&self) -> &RootWindowTarget { + pub fn window_target(&self) -> &RootWindowTarget { &self.window_target } pub fn run(mut self, callback: F) -> Result<(), EventLoopError> where - F: FnMut(Event, &RootWindowTarget), + F: FnMut(Event, &RootWindowTarget), { self.run_on_demand(callback) } @@ -256,7 +250,7 @@ impl EventLoop { // redundant wake ups. pub fn run_on_demand(&mut self, callback: F) -> Result<(), EventLoopError> where - F: FnMut(Event, &RootWindowTarget), + F: FnMut(Event, &RootWindowTarget), { if AppState::is_running() { return Err(EventLoopError::AlreadyRunning); @@ -273,8 +267,8 @@ impl EventLoop { let callback = unsafe { mem::transmute::< - Rc, &RootWindowTarget)>>, - Rc, &RootWindowTarget)>>, + Rc, &RootWindowTarget)>>, + Rc, &RootWindowTarget)>>, >(Rc::new(RefCell::new(callback))) }; @@ -340,7 +334,7 @@ impl EventLoop { pub fn pump_events(&mut self, timeout: Option, callback: F) -> PumpStatus where - F: FnMut(Event, &RootWindowTarget), + F: FnMut(Event, &RootWindowTarget), { // # Safety // We are erasing the lifetime of the application callback here so that we @@ -353,8 +347,8 @@ impl EventLoop { let callback = unsafe { mem::transmute::< - Rc, &RootWindowTarget)>>, - Rc, &RootWindowTarget)>>, + Rc, &RootWindowTarget)>>, + Rc, &RootWindowTarget)>>, >(Rc::new(RefCell::new(callback))) }; diff --git a/src/platform_impl/macos/window.rs b/src/platform_impl/macos/window.rs index 790a0ba196..719b46e3be 100644 --- a/src/platform_impl/macos/window.rs +++ b/src/platform_impl/macos/window.rs @@ -68,8 +68,8 @@ impl Drop for Window { } impl Window { - pub(crate) fn new( - _window_target: &EventLoopWindowTarget, + pub(crate) fn new( + _window_target: &EventLoopWindowTarget, attributes: WindowAttributes, pl_attribs: PlatformSpecificWindowBuilderAttributes, ) -> Result { diff --git a/src/platform_impl/orbital/event_loop.rs b/src/platform_impl/orbital/event_loop.rs index 6dd06c3a9c..86b796eb53 100644 --- a/src/platform_impl/orbital/event_loop.rs +++ b/src/platform_impl/orbital/event_loop.rs @@ -1,7 +1,6 @@ use std::{ cell::Cell, collections::VecDeque, - marker::PhantomData, mem, slice, sync::{mpsc, Arc, Mutex}, time::Instant, @@ -271,9 +270,9 @@ impl EventState { } } -pub struct EventLoop { +pub struct EventLoop { windows: Vec<(Arc, EventState)>, - window_target: event_loop::EventLoopWindowTarget, + window_target: event_loop::EventLoopWindowTarget, user_events_sender: mpsc::Sender, user_events_receiver: mpsc::Receiver, } @@ -314,9 +313,7 @@ impl EventLoop { destroys: Arc::new(Mutex::new(VecDeque::new())), event_socket, wake_socket, - p: PhantomData, }, - _marker: PhantomData, }, user_events_sender, user_events_receiver, @@ -466,10 +463,10 @@ impl EventLoop { pub fn run(mut self, mut event_handler_inner: F) -> Result<(), EventLoopError> where - F: FnMut(event::Event, &event_loop::EventLoopWindowTarget), + F: FnMut(event::Event, &event_loop::EventLoopWindowTarget), { let mut event_handler = - move |event: event::Event, window_target: &event_loop::EventLoopWindowTarget| { + move |event: event::Event, window_target: &event_loop::EventLoopWindowTarget| { event_handler_inner(event, window_target); }; @@ -676,7 +673,7 @@ impl EventLoop { Ok(()) } - pub fn window_target(&self) -> &event_loop::EventLoopWindowTarget { + pub fn window_target(&self) -> &event_loop::EventLoopWindowTarget { &self.window_target } @@ -716,7 +713,7 @@ impl Clone for EventLoopProxy { impl Unpin for EventLoopProxy {} -pub struct EventLoopWindowTarget { +pub struct EventLoopWindowTarget { control_flow: Cell, exit: Cell, pub(super) creates: Mutex>>, @@ -724,10 +721,9 @@ pub struct EventLoopWindowTarget { pub(super) destroys: Arc>>, pub(super) event_socket: Arc, pub(super) wake_socket: Arc, - p: PhantomData, } -impl EventLoopWindowTarget { +impl EventLoopWindowTarget { pub fn primary_monitor(&self) -> Option { Some(MonitorHandle) } diff --git a/src/platform_impl/orbital/window.rs b/src/platform_impl/orbital/window.rs index 3a5c74b7e1..8e509f04d7 100644 --- a/src/platform_impl/orbital/window.rs +++ b/src/platform_impl/orbital/window.rs @@ -33,8 +33,8 @@ pub struct Window { } impl Window { - pub(crate) fn new( - el: &EventLoopWindowTarget, + pub(crate) fn new( + el: &EventLoopWindowTarget, attrs: window::WindowAttributes, _: PlatformSpecificWindowBuilderAttributes, ) -> Result { diff --git a/src/platform_impl/web/cursor.rs b/src/platform_impl/web/cursor.rs index cd8922ecc8..7780064608 100644 --- a/src/platform_impl/web/cursor.rs +++ b/src/platform_impl/web/cursor.rs @@ -68,9 +68,9 @@ impl PartialEq for CustomCursor { impl Eq for CustomCursor {} impl CustomCursor { - pub(crate) fn build( + pub(crate) fn build( builder: CustomCursorBuilder, - window_target: &EventLoopWindowTarget, + window_target: &EventLoopWindowTarget, ) -> Self { Lazy::force(&DROP_HANDLER); diff --git a/src/platform_impl/web/event_loop/mod.rs b/src/platform_impl/web/event_loop/mod.rs index d0b7f5d37b..a1db32f9ee 100644 --- a/src/platform_impl/web/event_loop/mod.rs +++ b/src/platform_impl/web/event_loop/mod.rs @@ -1,4 +1,3 @@ -use std::marker::PhantomData; use std::sync::mpsc::{self, Receiver, Sender}; use crate::error::EventLoopError; @@ -16,7 +15,7 @@ pub use proxy::EventLoopProxy; pub use window_target::EventLoopWindowTarget; pub struct EventLoop { - elw: RootEventLoopWindowTarget, + elw: RootEventLoopWindowTarget, user_event_sender: Sender, user_event_receiver: Receiver, } @@ -29,7 +28,6 @@ impl EventLoop { let (user_event_sender, user_event_receiver) = mpsc::channel(); let elw = RootEventLoopWindowTarget { p: EventLoopWindowTarget::new(), - _marker: PhantomData, }; Ok(EventLoop { elw, @@ -40,11 +38,10 @@ impl EventLoop { pub fn run(self, mut event_handler: F) -> ! where - F: FnMut(Event, &RootEventLoopWindowTarget), + F: FnMut(Event, &RootEventLoopWindowTarget), { let target = RootEventLoopWindowTarget { p: self.elw.p.clone(), - _marker: PhantomData, }; // SAFETY: Don't use `move` to make sure we leak the `event_handler` and `target`. @@ -77,11 +74,10 @@ impl EventLoop { pub fn spawn(self, mut event_handler: F) where - F: 'static + FnMut(Event, &RootEventLoopWindowTarget), + F: 'static + FnMut(Event, &RootEventLoopWindowTarget), { let target = RootEventLoopWindowTarget { p: self.elw.p.clone(), - _marker: PhantomData, }; self.elw.p.run( @@ -105,7 +101,7 @@ impl EventLoop { EventLoopProxy::new(self.elw.p.waker(), self.user_event_sender.clone()) } - pub fn window_target(&self) -> &RootEventLoopWindowTarget { + pub fn window_target(&self) -> &RootEventLoopWindowTarget { &self.elw } } diff --git a/src/platform_impl/web/event_loop/window_target.rs b/src/platform_impl/web/event_loop/window_target.rs index 1921c6a732..e29c03df2b 100644 --- a/src/platform_impl/web/event_loop/window_target.rs +++ b/src/platform_impl/web/event_loop/window_target.rs @@ -2,7 +2,6 @@ use std::cell::{Cell, RefCell}; use std::clone::Clone; use std::collections::{vec_deque::IntoIter as VecDequeIter, VecDeque}; use std::iter; -use std::marker::PhantomData; use std::rc::{Rc, Weak}; use super::runner::{EventWrapper, Execution}; @@ -41,28 +40,17 @@ impl Clone for ModifiersShared { } } -pub struct EventLoopWindowTarget { +#[derive(Clone)] +pub struct EventLoopWindowTarget { pub(crate) runner: runner::Shared, modifiers: ModifiersShared, - _marker: PhantomData, } -impl Clone for EventLoopWindowTarget { - fn clone(&self) -> Self { - Self { - runner: self.runner.clone(), - modifiers: self.modifiers.clone(), - _marker: PhantomData, - } - } -} - -impl EventLoopWindowTarget { +impl EventLoopWindowTarget { pub fn new() -> Self { Self { runner: runner::Shared::new(), modifiers: ModifiersShared::default(), - _marker: PhantomData, } } diff --git a/src/platform_impl/web/window.rs b/src/platform_impl/web/window.rs index f3845dc810..7ff5240ba6 100644 --- a/src/platform_impl/web/window.rs +++ b/src/platform_impl/web/window.rs @@ -30,8 +30,8 @@ pub struct Inner { } impl Window { - pub(crate) fn new( - target: &EventLoopWindowTarget, + pub(crate) fn new( + target: &EventLoopWindowTarget, attr: WindowAttributes, platform_attr: PlatformSpecificWindowBuilderAttributes, ) -> Result { diff --git a/src/platform_impl/windows/event_loop.rs b/src/platform_impl/windows/event_loop.rs index 6a3035bc9c..0ab23bb95a 100644 --- a/src/platform_impl/windows/event_loop.rs +++ b/src/platform_impl/windows/event_loop.rs @@ -6,7 +6,6 @@ use std::{ cell::Cell, collections::VecDeque, ffi::c_void, - marker::PhantomData, mem, panic, ptr, rc::Rc, sync::{ @@ -158,7 +157,7 @@ pub(crate) enum ProcResult { pub struct EventLoop { user_event_sender: Sender, user_event_receiver: Receiver, - window_target: RootELW, + window_target: RootELW, msg_hook: Option bool + 'static>>, } @@ -178,11 +177,10 @@ impl Default for PlatformSpecificEventLoopAttributes { } } -pub struct EventLoopWindowTarget { +pub struct EventLoopWindowTarget { thread_id: u32, thread_msg_target: HWND, pub(crate) runner_shared: EventLoopRunnerShared, - _marker: PhantomData, } impl EventLoop { @@ -223,28 +221,26 @@ impl EventLoop { thread_id, thread_msg_target, runner_shared, - _marker: PhantomData, }, - _marker: PhantomData, }, msg_hook: attributes.msg_hook.take(), }) } - pub fn window_target(&self) -> &RootELW { + pub fn window_target(&self) -> &RootELW { &self.window_target } pub fn run(mut self, event_handler: F) -> Result<(), EventLoopError> where - F: FnMut(Event, &RootELW), + F: FnMut(Event, &RootELW), { self.run_on_demand(event_handler) } pub fn run_on_demand(&mut self, mut event_handler: F) -> Result<(), EventLoopError> where - F: FnMut(Event, &RootELW), + F: FnMut(Event, &RootELW), { { let runner = &self.window_target.p.runner_shared; @@ -309,7 +305,7 @@ impl EventLoop { pub fn pump_events(&mut self, timeout: Option, mut event_handler: F) -> PumpStatus where - F: FnMut(Event, &RootELW), + F: FnMut(Event, &RootELW), { { let runner = &self.window_target.p.runner_shared; @@ -529,7 +525,7 @@ impl EventLoop { } } -impl EventLoopWindowTarget { +impl EventLoopWindowTarget { #[inline(always)] pub(crate) fn create_thread_executor(&self) -> EventLoopThreadExecutor { EventLoopThreadExecutor { @@ -979,7 +975,7 @@ unsafe fn lose_active_focus(window: HWND, userdata: &WindowData) { // // Returning 0 tells the Win32 API that the message has been processed. // FIXME: detect WM_DWMCOMPOSITIONCHANGED and call DwmEnableBlurBehindWindow if necessary -pub(super) unsafe extern "system" fn public_window_callback( +pub(super) unsafe extern "system" fn public_window_callback( window: HWND, msg: u32, wparam: WPARAM, @@ -990,7 +986,7 @@ pub(super) unsafe extern "system" fn public_window_callback( let userdata_ptr = match (userdata, msg) { (0, WM_NCCREATE) => { let createstruct = unsafe { &mut *(lparam as *mut CREATESTRUCTW) }; - let initdata = unsafe { &mut *(createstruct.lpCreateParams as *mut InitData<'_, T>) }; + let initdata = unsafe { &mut *(createstruct.lpCreateParams as *mut InitData<'_>) }; let result = match unsafe { initdata.on_nccreate(window) } { Some(userdata) => unsafe { @@ -1008,7 +1004,7 @@ pub(super) unsafe extern "system" fn public_window_callback( (_, WM_CREATE) => unsafe { let createstruct = &mut *(lparam as *mut CREATESTRUCTW); let initdata = createstruct.lpCreateParams; - let initdata = &mut *(initdata as *mut InitData<'_, T>); + let initdata = &mut *(initdata as *mut InitData<'_>); initdata.on_create(); return DefWindowProcW(window, msg, wparam, lparam); diff --git a/src/platform_impl/windows/window.rs b/src/platform_impl/windows/window.rs index 91e205628e..2e46efc7e5 100644 --- a/src/platform_impl/windows/window.rs +++ b/src/platform_impl/windows/window.rs @@ -94,8 +94,8 @@ pub(crate) struct Window { } impl Window { - pub(crate) fn new( - event_loop: &EventLoopWindowTarget, + pub(crate) fn new( + event_loop: &EventLoopWindowTarget, w_attr: WindowAttributes, pl_attr: PlatformSpecificWindowBuilderAttributes, ) -> Result { @@ -1069,9 +1069,9 @@ impl Drop for Window { } } -pub(super) struct InitData<'a, T: 'static> { +pub(super) struct InitData<'a> { // inputs - pub event_loop: &'a EventLoopWindowTarget, + pub event_loop: &'a EventLoopWindowTarget, pub attributes: WindowAttributes, pub pl_attribs: PlatformSpecificWindowBuilderAttributes, pub window_flags: WindowFlags, @@ -1079,7 +1079,7 @@ pub(super) struct InitData<'a, T: 'static> { pub window: Option, } -impl<'a, T: 'static> InitData<'a, T> { +impl<'a> InitData<'a> { unsafe fn create_window(&self, window: HWND) -> Window { // Register for touch events if applicable { @@ -1262,18 +1262,15 @@ impl<'a, T: 'static> InitData<'a, T> { } } } -unsafe fn init( +unsafe fn init( attributes: WindowAttributes, pl_attribs: PlatformSpecificWindowBuilderAttributes, - event_loop: &EventLoopWindowTarget, -) -> Result -where - T: 'static, -{ + event_loop: &EventLoopWindowTarget, +) -> Result { let title = util::encode_wide(&attributes.title); let class_name = util::encode_wide(&pl_attribs.class_name); - unsafe { register_window_class::(&class_name) }; + unsafe { register_window_class(&class_name) }; let mut window_flags = WindowFlags::empty(); window_flags.set(WindowFlags::MARKER_DECORATIONS, attributes.decorations); @@ -1368,11 +1365,11 @@ where Ok(initdata.window.unwrap()) } -unsafe fn register_window_class(class_name: &[u16]) { +unsafe fn register_window_class(class_name: &[u16]) { let class = WNDCLASSEXW { cbSize: mem::size_of::() as u32, style: CS_HREDRAW | CS_VREDRAW, - lpfnWndProc: Some(super::event_loop::public_window_callback::), + lpfnWndProc: Some(super::event_loop::public_window_callback), cbClsExtra: 0, cbWndExtra: 0, hInstance: util::get_instance_handle(), diff --git a/src/window.rs b/src/window.rs index 8786435272..77f95dece9 100644 --- a/src/window.rs +++ b/src/window.rs @@ -506,10 +506,7 @@ impl WindowBuilder { /// - **Web:** The window is created but not inserted into the web page automatically. Please /// see the web platform module for more information. #[inline] - pub fn build( - self, - window_target: &EventLoopWindowTarget, - ) -> Result { + pub fn build(self, window_target: &EventLoopWindowTarget) -> Result { let window = platform_impl::Window::new(&window_target.p, self.window, self.platform_specific)?; window.maybe_queue_on_main(|w| w.request_redraw()); @@ -533,7 +530,7 @@ impl Window { /// /// [`WindowBuilder::new().build(event_loop)`]: WindowBuilder::build #[inline] - pub fn new(event_loop: &EventLoopWindowTarget) -> Result { + pub fn new(event_loop: &EventLoopWindowTarget) -> Result { let builder = WindowBuilder::new(); builder.build(event_loop) } From 8de68e14f393fad02d32b6f0a93f8216d94ac2c8 Mon Sep 17 00:00:00 2001 From: Mads Marquart Date: Sun, 24 Dec 2023 03:53:20 +0100 Subject: [PATCH 6/8] Replace EventLoopWindowTarget with ActiveEventLoop --- examples/child_window.rs | 4 +- examples/custom_cursors.rs | 7 +- src/cursor.rs | 6 +- src/event_loop.rs | 276 ++++++++++++------ src/lib.rs | 2 +- src/monitor.rs | 3 +- src/platform/android.rs | 7 +- src/platform/macos.rs | 16 +- src/platform/pump_events.rs | 12 +- src/platform/run_on_demand.rs | 15 +- src/platform/startup_notify.rs | 25 +- src/platform/wayland.rs | 25 +- src/platform/web.rs | 20 +- src/platform/x11.rs | 25 +- src/platform_impl/android/mod.rs | 39 ++- src/platform_impl/ios/event_loop.rs | 23 +- src/platform_impl/ios/mod.rs | 3 +- src/platform_impl/linux/mod.rs | 15 +- .../linux/wayland/event_loop/mod.rs | 34 +-- .../linux/x11/event_processor.rs | 4 +- src/platform_impl/linux/x11/mod.rs | 33 +-- src/platform_impl/macos/app_state.rs | 15 +- src/platform_impl/macos/event_loop.rs | 28 +- src/platform_impl/macos/mod.rs | 3 +- src/platform_impl/orbital/event_loop.rs | 51 ++-- src/platform_impl/orbital/mod.rs | 2 +- src/platform_impl/web/event_loop/mod.rs | 29 +- src/platform_impl/web/event_loop/runner.rs | 2 +- .../web/event_loop/window_target.rs | 2 +- src/platform_impl/web/mod.rs | 3 +- src/platform_impl/windows/event_loop.rs | 42 +-- src/platform_impl/windows/mod.rs | 3 +- src/window.rs | 16 +- 33 files changed, 448 insertions(+), 342 deletions(-) diff --git a/examples/child_window.rs b/examples/child_window.rs index 2693dbdc08..61f6539a68 100644 --- a/examples/child_window.rs +++ b/examples/child_window.rs @@ -16,14 +16,14 @@ fn main() -> Result<(), impl std::error::Error> { use winit::{ dpi::{LogicalPosition, LogicalSize, Position}, event::{ElementState, Event, KeyEvent, WindowEvent}, - event_loop::{EventLoop, EventLoopWindowTarget}, + event_loop::{ActiveEventLoop, EventLoop}, raw_window_handle::HasRawWindowHandle, window::{Window, WindowBuilder, WindowId}, }; fn spawn_child_window( parent: &Window, - event_loop: &EventLoopWindowTarget, + event_loop: ActiveEventLoop<'_>, windows: &mut HashMap, ) { let parent = parent.raw_window_handle().unwrap(); diff --git a/examples/custom_cursors.rs b/examples/custom_cursors.rs index 4ffac80ae2..5a77979496 100644 --- a/examples/custom_cursors.rs +++ b/examples/custom_cursors.rs @@ -4,19 +4,18 @@ use simple_logger::SimpleLogger; use winit::{ event::{ElementState, Event, KeyEvent, WindowEvent}, - event_loop::{EventLoop, EventLoopWindowTarget}, + event_loop::EventLoop, keyboard::Key, window::{CustomCursor, WindowBuilder}, }; -fn decode_cursor(bytes: &[u8], window_target: &EventLoopWindowTarget) -> CustomCursor { +fn decode_cursor(bytes: &[u8], event_loop: &EventLoop<()>) -> CustomCursor { let img = image::load_from_memory(bytes).unwrap().to_rgba8(); let samples = img.into_flat_samples(); let (_, w, h) = samples.extents(); let (w, h) = (w as u16, h as u16); let builder = CustomCursor::from_rgba(samples.samples, w, h, w / 2, h / 2).unwrap(); - - builder.build(window_target) + builder.build(event_loop) } #[cfg(not(wasm_platform))] diff --git a/src/cursor.rs b/src/cursor.rs index a821486485..1c27d83df6 100644 --- a/src/cursor.rs +++ b/src/cursor.rs @@ -3,7 +3,7 @@ use std::hash::Hasher; use std::sync::Arc; use std::{error::Error, hash::Hash}; -use crate::event_loop::EventLoopWindowTarget; +use crate::event_loop::MaybeActiveEventLoop; use crate::platform_impl::{self, PlatformCustomCursor, PlatformCustomCursorBuilder}; /// The maximum width and height for a cursor when using [`CustomCursor::from_rgba`]. @@ -87,9 +87,9 @@ pub struct CustomCursorBuilder { } impl CustomCursorBuilder { - pub fn build(self, window_target: &EventLoopWindowTarget) -> CustomCursor { + pub fn build<'a>(self, event_loop: impl MaybeActiveEventLoop<'a>) -> CustomCursor { CustomCursor { - inner: PlatformCustomCursor::build(self.inner, &window_target.p), + inner: PlatformCustomCursor::build(self.inner, event_loop.__inner()), } } } diff --git a/src/event_loop.rs b/src/event_loop.rs index 15bf05c84b..386f0ddf4d 100644 --- a/src/event_loop.rs +++ b/src/event_loop.rs @@ -8,7 +8,6 @@ //! See the root-level documentation for information on how to create and use an event loop to //! handle events. use std::marker::PhantomData; -use std::ops::Deref; #[cfg(any(x11_platform, wayland_platform))] use std::os::unix::io::{AsFd, AsRawFd, BorrowedFd, RawFd}; use std::sync::atomic::{AtomicBool, AtomicU64, Ordering}; @@ -37,19 +36,90 @@ use crate::{event::Event, monitor::MonitorHandle, platform_impl}; /// [`EventLoopProxy`] allows you to wake up an `EventLoop` from another thread. /// /// [`Window`]: crate::window::Window +// TODO: Don't allow window creation from this, since that is broken on macOS/iOS. pub struct EventLoop { pub(crate) event_loop: platform_impl::EventLoop, pub(crate) _marker: PhantomData<*mut ()>, // Not Send nor Sync } -/// Target that associates windows with an [`EventLoop`]. +/// An active event loop. /// -/// This type exists to allow you to create new windows while Winit executes -/// your callback. [`EventLoop`] will coerce into this type (`impl Deref for -/// EventLoop`), so functions that take this as a parameter can also take -/// `&EventLoop`. -pub struct EventLoopWindowTarget { - pub(crate) p: platform_impl::EventLoopWindowTarget, +/// This type exists to differentiate between functionality available when Winit +/// is executing your callback, and outside of it. +#[derive(Copy, Clone)] +pub struct ActiveEventLoop<'a> { + pub(crate) inner: platform_impl::ActiveEventLoop<'a>, +} + +impl fmt::Debug for ActiveEventLoop<'_> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.pad("ActiveEventLoop { .. }") + } +} + +impl ActiveEventLoop<'_> { + /// Sets the [`ControlFlow`]. + pub fn set_control_flow(&self, control_flow: ControlFlow) { + self.inner.set_control_flow(control_flow) + } + + /// Gets the current [`ControlFlow`]. + pub fn control_flow(&self) -> ControlFlow { + self.inner.control_flow() + } + + /// This exits the event loop. + /// + /// See [`LoopExiting`](Event::LoopExiting). + pub fn exit(&self) { + self.inner.exit() + } + + /// Returns if the [`EventLoop`] is about to stop. + /// + /// See [`exit()`](Self::exit). + pub fn exiting(&self) -> bool { + self.inner.exiting() + } + + /// Returns the primary monitor of the system. + /// + /// Returns `None` if it can't identify any monitor as a primary one. + /// + /// ## Platform-specific + /// + /// **Wayland / Web:** Always returns `None`. + #[inline] + pub fn primary_monitor(&self) -> Option { + self.inner + .primary_monitor() + .map(|inner| MonitorHandle { inner }) + } + + /// Returns the list of all the monitors available on the system. + #[inline] + pub fn available_monitors(&self) -> impl Iterator { + #[allow(clippy::useless_conversion)] // false positive on some platforms + self.inner + .available_monitors() + .into_iter() + .map(|inner| MonitorHandle { inner }) + } + + /// Change if or when [`DeviceEvent`]s are captured. + /// + /// Since the [`DeviceEvent`] capture can lead to high CPU usage for unfocused windows, winit + /// will ignore them by default for unfocused windows on Linux/BSD. This method allows changing + /// this at runtime to explicitly capture them again. + /// + /// ## Platform-specific + /// + /// - **Wayland / macOS / iOS / Android / Orbital:** Unsupported. + /// + /// [`DeviceEvent`]: crate::event::DeviceEvent + pub fn listen_device_events(&self, allowed: DeviceEvents) { + self.inner.listen_device_events(allowed); + } } /// Object that allows building the event loop. @@ -141,13 +211,7 @@ impl fmt::Debug for EventLoop { } } -impl fmt::Debug for EventLoopWindowTarget { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.pad("EventLoopWindowTarget { .. }") - } -} - -/// Set through [`EventLoopWindowTarget::set_control_flow()`]. +/// Set through [`ActiveEventLoop::set_control_flow()`]. /// /// Indicates the desired behavior of the event loop after [`Event::AboutToWait`] is emitted. /// @@ -236,16 +300,67 @@ impl EventLoop { /// /// This function won't be available with `target_feature = "exception-handling"`. /// - /// [`set_control_flow()`]: EventLoopWindowTarget::set_control_flow() + /// [`set_control_flow()`]: ActiveEventLoop::set_control_flow() /// [`run()`]: Self::run() /// [^1]: `EventLoopExtWebSys::spawn()` is only available on WASM. #[inline] #[cfg(not(all(wasm_platform, target_feature = "exception-handling")))] - pub fn run(self, event_handler: F) -> Result<(), EventLoopError> + pub fn run(self, mut event_handler: F) -> Result<(), EventLoopError> where - F: FnMut(Event, &EventLoopWindowTarget), + F: FnMut(Event, ActiveEventLoop<'_>), { - self.event_loop.run(event_handler) + self.event_loop + .run(move |event, inner| event_handler(event, ActiveEventLoop { inner })) + } + + /// Set the initial [`ControlFlow`]. + pub fn set_control_flow(&self, control_flow: ControlFlow) { + self.event_loop + .window_target() + .set_control_flow(control_flow) + } + + /// Returns the primary monitor of the system. + /// + /// Returns `None` if it can't identify any monitor as a primary one. + /// + /// ## Platform-specific + /// + /// **Wayland / Web:** Always returns `None`. + #[inline] + pub fn primary_monitor(&self) -> Option { + self.event_loop + .window_target() + .primary_monitor() + .map(|inner| MonitorHandle { inner }) + } + + /// Returns the list of all the monitors available on the system. + #[inline] + pub fn available_monitors(&self) -> impl Iterator { + #[allow(clippy::useless_conversion)] // false positive on some platforms + self.event_loop + .window_target() + .available_monitors() + .into_iter() + .map(|inner| MonitorHandle { inner }) + } + + /// Change if or when [`DeviceEvent`]s are captured. + /// + /// Since the [`DeviceEvent`] capture can lead to high CPU usage for unfocused windows, winit + /// will ignore them by default for unfocused windows on Linux/BSD. This method allows changing + /// this at runtime to explicitly capture them again. + /// + /// ## Platform-specific + /// + /// - **Wayland / macOS / iOS / Android / Orbital:** Unsupported. + /// + /// [`DeviceEvent`]: crate::event::DeviceEvent + pub fn listen_device_events(&self, allowed: DeviceEvents) { + self.event_loop + .window_target() + .listen_device_events(allowed); } /// Creates an [`EventLoopProxy`] that can be used to dispatch user events to the main event loop. @@ -259,7 +374,12 @@ impl EventLoop { #[cfg(feature = "rwh_06")] impl rwh_06::HasDisplayHandle for EventLoop { fn display_handle(&self) -> Result, rwh_06::HandleError> { - rwh_06::HasDisplayHandle::display_handle(&**self) + let raw = self + .event_loop + .window_target() + .raw_display_handle_rwh_06()?; + // SAFETY: The display will never be deallocated while the event loop is alive. + Ok(unsafe { rwh_06::DisplayHandle::borrow_raw(raw) }) } } @@ -267,7 +387,7 @@ impl rwh_06::HasDisplayHandle for EventLoop { unsafe impl rwh_05::HasRawDisplayHandle for EventLoop { /// Returns a [`rwh_05::RawDisplayHandle`] for the event loop. fn raw_display_handle(&self) -> rwh_05::RawDisplayHandle { - rwh_05::HasRawDisplayHandle::raw_display_handle(&**self) + self.event_loop.window_target().raw_display_handle_rwh_05() } } @@ -299,92 +419,44 @@ impl AsRawFd for EventLoop { } } -impl Deref for EventLoop { - type Target = EventLoopWindowTarget; - fn deref(&self) -> &EventLoopWindowTarget { - self.event_loop.window_target() +#[cfg(feature = "rwh_06")] +impl rwh_06::HasDisplayHandle for ActiveEventLoop<'_> { + fn display_handle(&self) -> Result, rwh_06::HandleError> { + let raw = self.inner.raw_display_handle_rwh_06()?; + // SAFETY: The display will never be deallocated while the event loop is alive. + Ok(unsafe { rwh_06::DisplayHandle::borrow_raw(raw) }) } } -impl EventLoopWindowTarget { - /// Returns the list of all the monitors available on the system. - #[inline] - pub fn available_monitors(&self) -> impl Iterator { - #[allow(clippy::useless_conversion)] // false positive on some platforms - self.p - .available_monitors() - .into_iter() - .map(|inner| MonitorHandle { inner }) - } - - /// Returns the primary monitor of the system. - /// - /// Returns `None` if it can't identify any monitor as a primary one. - /// - /// ## Platform-specific - /// - /// **Wayland / Web:** Always returns `None`. - #[inline] - pub fn primary_monitor(&self) -> Option { - self.p - .primary_monitor() - .map(|inner| MonitorHandle { inner }) - } - - /// Change if or when [`DeviceEvent`]s are captured. - /// - /// Since the [`DeviceEvent`] capture can lead to high CPU usage for unfocused windows, winit - /// will ignore them by default for unfocused windows on Linux/BSD. This method allows changing - /// this at runtime to explicitly capture them again. - /// - /// ## Platform-specific - /// - /// - **Wayland / macOS / iOS / Android / Orbital:** Unsupported. - /// - /// [`DeviceEvent`]: crate::event::DeviceEvent - pub fn listen_device_events(&self, allowed: DeviceEvents) { - self.p.listen_device_events(allowed); - } - - /// Sets the [`ControlFlow`]. - pub fn set_control_flow(&self, control_flow: ControlFlow) { - self.p.set_control_flow(control_flow) - } - - /// Gets the current [`ControlFlow`]. - pub fn control_flow(&self) -> ControlFlow { - self.p.control_flow() +#[cfg(feature = "rwh_05")] +unsafe impl rwh_05::HasRawDisplayHandle for ActiveEventLoop<'_> { + /// Returns a [`rwh_05::RawDisplayHandle`] for the event loop. + fn raw_display_handle(&self) -> rwh_05::RawDisplayHandle { + self.inner.raw_display_handle_rwh_05() } +} - /// This exits the event loop. - /// - /// See [`LoopExiting`](Event::LoopExiting). - pub fn exit(&self) { - self.p.exit() - } +mod private { + pub trait Sealed {} +} - /// Returns if the [`EventLoop`] is about to stop. - /// - /// See [`exit()`](Self::exit). - pub fn exiting(&self) -> bool { - self.p.exiting() - } +/// Trait to allow functions to be generic over [`EventLoop`] and [`ActiveEventLoop`]. +pub trait MaybeActiveEventLoop<'a>: private::Sealed { + #[doc(hidden)] + fn __inner(self) -> &'a platform_impl::EventLoopWindowTarget; } -#[cfg(feature = "rwh_06")] -impl rwh_06::HasDisplayHandle for EventLoopWindowTarget { - fn display_handle(&self) -> Result, rwh_06::HandleError> { - let raw = self.p.raw_display_handle_rwh_06()?; - // SAFETY: The display will never be deallocated while the event loop is alive. - Ok(unsafe { rwh_06::DisplayHandle::borrow_raw(raw) }) +impl private::Sealed for &EventLoop {} +impl<'a, T: 'static> MaybeActiveEventLoop<'a> for &'a EventLoop { + fn __inner(self) -> &'a platform_impl::EventLoopWindowTarget { + self.event_loop.window_target() } } -#[cfg(feature = "rwh_05")] -unsafe impl rwh_05::HasRawDisplayHandle for EventLoopWindowTarget { - /// Returns a [`rwh_05::RawDisplayHandle`] for the event loop. - fn raw_display_handle(&self) -> rwh_05::RawDisplayHandle { - self.p.raw_display_handle_rwh_05() +impl private::Sealed for ActiveEventLoop<'_> {} +impl<'a> MaybeActiveEventLoop<'a> for ActiveEventLoop<'a> { + fn __inner(self) -> &'a platform_impl::EventLoopWindowTarget { + self.inner } } @@ -472,3 +544,15 @@ impl AsyncRequestSerial { Self { serial } } } + +#[cfg(test)] +mod tests { + use super::*; + + #[allow(unused)] + fn assert_active_event_loop_covariance<'b>( + event_loop: ActiveEventLoop<'static>, + ) -> ActiveEventLoop<'b> { + event_loop + } +} diff --git a/src/lib.rs b/src/lib.rs index ce26ef0e9d..60450ced0d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -132,7 +132,7 @@ //! [`EventLoop`]: event_loop::EventLoop //! [`EventLoop::new()`]: event_loop::EventLoop::new //! [`EventLoop::run()`]: event_loop::EventLoop::run -//! [`exit()`]: event_loop::EventLoopWindowTarget::exit +//! [`exit()`]: event_loop::ActiveEventLoop::exit //! [`Window`]: window::Window //! [`WindowId`]: window::WindowId //! [`WindowBuilder`]: window::WindowBuilder diff --git a/src/monitor.rs b/src/monitor.rs index 45c355e529..d7421b50b9 100644 --- a/src/monitor.rs +++ b/src/monitor.rs @@ -3,7 +3,8 @@ //! If you want to get basic information about a monitor, you can use the //! [`MonitorHandle`] type. This is retrieved from one of the following //! methods, which return an iterator of [`MonitorHandle`]: -//! - [`EventLoopWindowTarget::available_monitors`](crate::event_loop::EventLoopWindowTarget::available_monitors). +//! - [`EventLoop::available_monitors`](crate::event_loop::EventLoop::available_monitors). +//! - [`ActiveEventLoop::available_monitors`](crate::event_loop::ActiveEventLoop::available_monitors). //! - [`Window::available_monitors`](crate::window::Window::available_monitors). use crate::{ dpi::{PhysicalPosition, PhysicalSize}, diff --git a/src/platform/android.rs b/src/platform/android.rs index c80fbeac29..a00a60fe94 100644 --- a/src/platform/android.rs +++ b/src/platform/android.rs @@ -1,5 +1,5 @@ use crate::{ - event_loop::{EventLoop, EventLoopBuilder, EventLoopWindowTarget}, + event_loop::{EventLoop, EventLoopBuilder}, window::{Window, WindowBuilder}, }; @@ -10,9 +10,6 @@ pub trait EventLoopExtAndroid {} impl EventLoopExtAndroid for EventLoop {} -/// Additional methods on [`EventLoopWindowTarget`] that are specific to Android. -pub trait EventLoopWindowTargetExtAndroid {} - /// Additional methods on [`Window`] that are specific to Android. pub trait WindowExtAndroid { fn content_rect(&self) -> Rect; @@ -30,8 +27,6 @@ impl WindowExtAndroid for Window { } } -impl EventLoopWindowTargetExtAndroid for EventLoopWindowTarget {} - /// Additional methods on [`WindowBuilder`] that are specific to Android. pub trait WindowBuilderExtAndroid {} diff --git a/src/platform/macos.rs b/src/platform/macos.rs index ac7b0a6fb4..b1ea1ff1db 100644 --- a/src/platform/macos.rs +++ b/src/platform/macos.rs @@ -4,7 +4,7 @@ use icrate::Foundation::MainThreadMarker; use objc2::rc::Id; use crate::{ - event_loop::{EventLoopBuilder, EventLoopWindowTarget}, + event_loop::{ActiveEventLoop, EventLoopBuilder}, monitor::MonitorHandle, window::{Window, WindowBuilder}, }; @@ -372,8 +372,8 @@ impl MonitorHandleExtMacOS for MonitorHandle { } } -/// Additional methods on [`EventLoopWindowTarget`] that are specific to macOS. -pub trait EventLoopWindowTargetExtMacOS { +/// Additional methods on [`ActiveEventLoop`] that are specific to macOS. +pub trait ActiveEventLoopExtMacOS { /// Hide the entire application. In most applications this is typically triggered with Command-H. fn hide_application(&self); /// Hide the other applications. In most applications this is typically triggered with Command+Option-H. @@ -386,21 +386,21 @@ pub trait EventLoopWindowTargetExtMacOS { fn allows_automatic_window_tabbing(&self) -> bool; } -impl EventLoopWindowTargetExtMacOS for EventLoopWindowTarget { +impl ActiveEventLoopExtMacOS for ActiveEventLoop<'_> { fn hide_application(&self) { - self.p.hide_application() + self.inner.hide_application() } fn hide_other_applications(&self) { - self.p.hide_other_applications() + self.inner.hide_other_applications() } fn set_allows_automatic_window_tabbing(&self, enabled: bool) { - self.p.set_allows_automatic_window_tabbing(enabled); + self.inner.set_allows_automatic_window_tabbing(enabled); } fn allows_automatic_window_tabbing(&self) -> bool { - self.p.allows_automatic_window_tabbing() + self.inner.allows_automatic_window_tabbing() } } diff --git a/src/platform/pump_events.rs b/src/platform/pump_events.rs index 403c52d978..bbcfa82835 100644 --- a/src/platform/pump_events.rs +++ b/src/platform/pump_events.rs @@ -2,7 +2,7 @@ use std::time::Duration; use crate::{ event::Event, - event_loop::{EventLoop, EventLoopWindowTarget}, + event_loop::{ActiveEventLoop, EventLoop}, }; /// The return status for `pump_events` @@ -174,16 +174,18 @@ pub trait EventLoopExtPumpEvents { /// callback. fn pump_events(&mut self, timeout: Option, event_handler: F) -> PumpStatus where - F: FnMut(Event, &EventLoopWindowTarget); + F: FnMut(Event, ActiveEventLoop<'_>); } impl EventLoopExtPumpEvents for EventLoop { type UserEvent = T; - fn pump_events(&mut self, timeout: Option, event_handler: F) -> PumpStatus + fn pump_events(&mut self, timeout: Option, mut event_handler: F) -> PumpStatus where - F: FnMut(Event, &EventLoopWindowTarget), + F: FnMut(Event, ActiveEventLoop<'_>), { - self.event_loop.pump_events(timeout, event_handler) + self.event_loop.pump_events(timeout, move |event, inner| { + event_handler(event, ActiveEventLoop { inner }) + }) } } diff --git a/src/platform/run_on_demand.rs b/src/platform/run_on_demand.rs index 03e49a961a..89c9923618 100644 --- a/src/platform/run_on_demand.rs +++ b/src/platform/run_on_demand.rs @@ -1,7 +1,7 @@ use crate::{ error::EventLoopError, event::Event, - event_loop::{EventLoop, EventLoopWindowTarget}, + event_loop::{ActiveEventLoop, EventLoop}, }; #[cfg(doc)] @@ -62,20 +62,21 @@ pub trait EventLoopExtRunOnDemand { doc = "[^1]: `spawn()` is only available on `wasm` platforms." )] /// - /// [`exit()`]: EventLoopWindowTarget::exit() - /// [`set_control_flow()`]: EventLoopWindowTarget::set_control_flow() + /// [`exit()`]: ActiveEventLoop::exit() + /// [`set_control_flow()`]: ActiveEventLoop::set_control_flow() fn run_on_demand(&mut self, event_handler: F) -> Result<(), EventLoopError> where - F: FnMut(Event, &EventLoopWindowTarget); + F: FnMut(Event, ActiveEventLoop<'_>); } impl EventLoopExtRunOnDemand for EventLoop { type UserEvent = T; - fn run_on_demand(&mut self, event_handler: F) -> Result<(), EventLoopError> + fn run_on_demand(&mut self, mut event_handler: F) -> Result<(), EventLoopError> where - F: FnMut(Event, &EventLoopWindowTarget), + F: FnMut(Event, ActiveEventLoop<'_>), { - self.event_loop.run_on_demand(event_handler) + self.event_loop + .run_on_demand(move |event, inner| event_handler(event, ActiveEventLoop { inner })) } } diff --git a/src/platform/startup_notify.rs b/src/platform/startup_notify.rs index 207aff86cb..df6aa3317f 100644 --- a/src/platform/startup_notify.rs +++ b/src/platform/startup_notify.rs @@ -24,7 +24,7 @@ use std::env; use crate::error::NotSupportedError; -use crate::event_loop::{AsyncRequestSerial, EventLoopWindowTarget}; +use crate::event_loop::{ActiveEventLoop, AsyncRequestSerial, EventLoop}; use crate::window::{ActivationToken, Window, WindowBuilder}; /// The variable which is used mostly on X11. @@ -55,13 +55,24 @@ pub trait WindowBuilderExtStartupNotify { fn with_activation_token(self, token: ActivationToken) -> Self; } -impl EventLoopExtStartupNotify for EventLoopWindowTarget { +impl EventLoopExtStartupNotify for EventLoop { fn read_token_from_env(&self) -> Option { - match self.p { - #[cfg(wayland_platform)] - crate::platform_impl::EventLoopWindowTarget::Wayland(_) => env::var(WAYLAND_VAR), - #[cfg(x11_platform)] - crate::platform_impl::EventLoopWindowTarget::X(_) => env::var(X11_VAR), + if self.event_loop.window_target().is_wayland() { + env::var(WAYLAND_VAR) + } else { + env::var(X11_VAR) + } + .ok() + .map(ActivationToken::_new) + } +} + +impl EventLoopExtStartupNotify for ActiveEventLoop<'_> { + fn read_token_from_env(&self) -> Option { + if self.inner.is_wayland() { + env::var(WAYLAND_VAR) + } else { + env::var(X11_VAR) } .ok() .map(ActivationToken::_new) diff --git a/src/platform/wayland.rs b/src/platform/wayland.rs index 99ae6b295a..32b98c295b 100644 --- a/src/platform/wayland.rs +++ b/src/platform/wayland.rs @@ -1,5 +1,5 @@ use crate::{ - event_loop::{EventLoopBuilder, EventLoopWindowTarget}, + event_loop::{ActiveEventLoop, EventLoop, EventLoopBuilder}, monitor::MonitorHandle, window::{Window, WindowBuilder}, }; @@ -8,16 +8,29 @@ use crate::platform_impl::{ApplicationName, Backend}; pub use crate::window::Theme; -/// Additional methods on [`EventLoopWindowTarget`] that are specific to Wayland. -pub trait EventLoopWindowTargetExtWayland { - /// True if the [`EventLoopWindowTarget`] uses Wayland. +/// Additional methods on [`EventLoop`] that are specific to Wayland. +pub trait EventLoopExtWayland { + /// True if the [`EventLoop`] uses Wayland. fn is_wayland(&self) -> bool; } -impl EventLoopWindowTargetExtWayland for EventLoopWindowTarget { +impl EventLoopExtWayland for EventLoop { #[inline] fn is_wayland(&self) -> bool { - self.p.is_wayland() + self.event_loop.window_target().is_wayland() + } +} + +/// Additional methods on [`ActiveEventLoop`] that are specific to Wayland. +pub trait ActiveEventLoopExtWayland { + /// True if the [`ActiveEventLoop`] uses Wayland. + fn is_wayland(&self) -> bool; +} + +impl ActiveEventLoopExtWayland for ActiveEventLoop<'_> { + #[inline] + fn is_wayland(&self) -> bool { + self.inner.is_wayland() } } diff --git a/src/platform/web.rs b/src/platform/web.rs index f0f8d2e9ac..4a067c1391 100644 --- a/src/platform/web.rs +++ b/src/platform/web.rs @@ -29,8 +29,7 @@ use crate::cursor::CustomCursorBuilder; use crate::event::Event; -use crate::event_loop::EventLoop; -use crate::event_loop::EventLoopWindowTarget; +use crate::event_loop::{ActiveEventLoop, EventLoop}; use crate::platform_impl::PlatformCustomCursorBuilder; use crate::window::CustomCursor; use crate::window::{Window, WindowBuilder}; @@ -136,21 +135,22 @@ pub trait EventLoopExtWebSys { /// [^1]: `run()` is _not_ available on WASM when the target supports `exception-handling`. fn spawn(self, event_handler: F) where - F: 'static + FnMut(Event, &EventLoopWindowTarget); + F: 'static + FnMut(Event, ActiveEventLoop<'_>); } impl EventLoopExtWebSys for EventLoop { type UserEvent = T; - fn spawn(self, event_handler: F) + fn spawn(self, mut event_handler: F) where - F: 'static + FnMut(Event, &EventLoopWindowTarget), + F: 'static + FnMut(Event, ActiveEventLoop<'_>), { - self.event_loop.spawn(event_handler) + self.event_loop + .spawn(move |event, inner| event_handler(event, ActiveEventLoop { inner })) } } -pub trait EventLoopWindowTargetExtWebSys { +pub trait ActiveEventLoopExtWebSys { /// Sets the strategy for [`ControlFlow::Poll`]. /// /// See [`PollStrategy`]. @@ -166,15 +166,15 @@ pub trait EventLoopWindowTargetExtWebSys { fn poll_strategy(&self) -> PollStrategy; } -impl EventLoopWindowTargetExtWebSys for EventLoopWindowTarget { +impl ActiveEventLoopExtWebSys for ActiveEventLoop<'_> { #[inline] fn set_poll_strategy(&self, strategy: PollStrategy) { - self.p.set_poll_strategy(strategy); + self.inner.set_poll_strategy(strategy); } #[inline] fn poll_strategy(&self) -> PollStrategy { - self.p.poll_strategy() + self.inner.poll_strategy() } } diff --git a/src/platform/x11.rs b/src/platform/x11.rs index 194f02145f..7cb7f765bf 100644 --- a/src/platform/x11.rs +++ b/src/platform/x11.rs @@ -1,5 +1,5 @@ use crate::{ - event_loop::{EventLoopBuilder, EventLoopWindowTarget}, + event_loop::{ActiveEventLoop, EventLoop, EventLoopBuilder}, monitor::MonitorHandle, window::{Window, WindowBuilder}, }; @@ -42,16 +42,29 @@ pub fn register_xlib_error_hook(hook: XlibErrorHook) { } } -/// Additional methods on [`EventLoopWindowTarget`] that are specific to X11. -pub trait EventLoopWindowTargetExtX11 { - /// True if the [`EventLoopWindowTarget`] uses X11. +/// Additional methods on [`EventLoop`] that are specific to X11. +pub trait EventLoopExtX11 { + /// True if the [`EventLoop`] uses X11. fn is_x11(&self) -> bool; } -impl EventLoopWindowTargetExtX11 for EventLoopWindowTarget { +impl EventLoopExtX11 for EventLoop { #[inline] fn is_x11(&self) -> bool { - !self.p.is_wayland() + !self.event_loop.window_target().is_wayland() + } +} + +/// Additional methods on [`ActiveEventLoop`] that are specific to X11. +pub trait ActiveEventLoopExtX11 { + /// True if the [`ActiveEventLoop`] uses X11. + fn is_x11(&self) -> bool; +} + +impl ActiveEventLoopExtX11 for ActiveEventLoop<'_> { + #[inline] + fn is_x11(&self) -> bool { + !self.inner.is_wayland() } } diff --git a/src/platform_impl/android/mod.rs b/src/platform_impl/android/mod.rs index 159ab8448c..4bfb27b153 100644 --- a/src/platform_impl/android/mod.rs +++ b/src/platform_impl/android/mod.rs @@ -21,7 +21,7 @@ use crate::{ dpi::{PhysicalPosition, PhysicalSize, Position, Size}, error, event::{self, Force, InnerSizeWriter, StartCause}, - event_loop::{self, ControlFlow, DeviceEvents, EventLoopWindowTarget as RootELW}, + event_loop::{self, ControlFlow, DeviceEvents}, platform::pump_events::PumpStatus, window::{ self, CursorGrabMode, ImePurpose, ResizeDirection, Theme, WindowButtons, WindowLevel, @@ -138,7 +138,7 @@ pub struct KeyEventExtra {} pub struct EventLoop { android_app: AndroidApp, - window_target: event_loop::EventLoopWindowTarget, + window_target: EventLoopWindowTarget, redraw_flag: SharedFlag, user_events_sender: mpsc::Sender, user_events_receiver: PeekableReceiver, //must wake looper whenever something gets sent @@ -176,16 +176,11 @@ impl EventLoop { Ok(Self { android_app: android_app.clone(), - window_target: event_loop::EventLoopWindowTarget { - p: EventLoopWindowTarget { - app: android_app.clone(), - control_flow: Cell::new(ControlFlow::default()), - exit: Cell::new(false), - redraw_requester: RedrawRequester::new( - &redraw_flag, - android_app.create_waker(), - ), - }, + window_target: EventLoopWindowTarget { + app: android_app.clone(), + control_flow: Cell::new(ControlFlow::default()), + exit: Cell::new(false), + redraw_requester: RedrawRequester::new(&redraw_flag, android_app.create_waker()), }, redraw_flag, user_events_sender, @@ -201,7 +196,7 @@ impl EventLoop { fn single_iteration(&mut self, main_event: Option>, callback: &mut F) where - F: FnMut(event::Event, &RootELW), + F: FnMut(event::Event, &EventLoopWindowTarget), { trace!("Mainloop iteration"); @@ -373,7 +368,7 @@ impl EventLoop { callback: &mut F, ) -> InputStatus where - F: FnMut(event::Event, &RootELW), + F: FnMut(event::Event, &EventLoopWindowTarget), { let mut input_status = InputStatus::Handled; match event { @@ -478,14 +473,14 @@ impl EventLoop { pub fn run(mut self, event_handler: F) -> Result<(), EventLoopError> where - F: FnMut(event::Event, &event_loop::EventLoopWindowTarget), + F: FnMut(event::Event, &EventLoopWindowTarget), { self.run_on_demand(event_handler) } pub fn run_on_demand(&mut self, mut event_handler: F) -> Result<(), EventLoopError> where - F: FnMut(event::Event, &event_loop::EventLoopWindowTarget), + F: FnMut(event::Event, &EventLoopWindowTarget), { if self.loop_running { return Err(EventLoopError::AlreadyRunning); @@ -508,7 +503,7 @@ impl EventLoop { pub fn pump_events(&mut self, timeout: Option, mut callback: F) -> PumpStatus where - F: FnMut(event::Event, &RootELW), + F: FnMut(event::Event, &EventLoopWindowTarget), { if !self.loop_running { self.loop_running = true; @@ -541,7 +536,7 @@ impl EventLoop { fn poll_events_with_timeout(&mut self, mut timeout: Option, mut callback: F) where - F: FnMut(event::Event, &RootELW), + F: FnMut(event::Event, &EventLoopWindowTarget), { let start = Instant::now(); @@ -617,7 +612,7 @@ impl EventLoop { }); } - pub fn window_target(&self) -> &event_loop::EventLoopWindowTarget { + pub fn window_target(&self) -> &EventLoopWindowTarget { &self.window_target } @@ -629,11 +624,11 @@ impl EventLoop { } fn control_flow(&self) -> ControlFlow { - self.window_target.p.control_flow() + self.window_target.control_flow() } fn exiting(&self) -> bool { - self.window_target.p.exiting() + self.window_target.exiting() } } @@ -661,6 +656,8 @@ impl EventLoopProxy { } } +pub type ActiveEventLoop<'a> = &'a EventLoopWindowTarget; + pub struct EventLoopWindowTarget { app: AndroidApp, control_flow: Cell, diff --git a/src/platform_impl/ios/event_loop.rs b/src/platform_impl/ios/event_loop.rs index 029f2200e2..05a1535dbe 100644 --- a/src/platform_impl/ios/event_loop.rs +++ b/src/platform_impl/ios/event_loop.rs @@ -19,10 +19,7 @@ use objc2::ClassType; use crate::{ error::EventLoopError, event::Event, - event_loop::{ - ControlFlow, DeviceEvents, EventLoopClosed, - EventLoopWindowTarget as RootEventLoopWindowTarget, - }, + event_loop::{ControlFlow, DeviceEvents, EventLoopClosed}, platform::ios::Idiom, }; @@ -32,6 +29,8 @@ use super::{ uikit::{UIApplication, UIApplicationMain, UIDevice, UIScreen}, }; +pub type ActiveEventLoop<'a> = &'a EventLoopWindowTarget; + #[derive(Debug)] pub struct EventLoopWindowTarget { pub(super) mtm: MainThreadMarker, @@ -88,7 +87,7 @@ pub struct EventLoop { mtm: MainThreadMarker, sender: Sender, receiver: Receiver, - window_target: RootEventLoopWindowTarget, + window_target: EventLoopWindowTarget, } #[derive(Default, Debug, Copy, Clone, PartialEq, Eq, Hash)] @@ -120,15 +119,13 @@ impl EventLoop { mtm, sender, receiver, - window_target: RootEventLoopWindowTarget { - p: EventLoopWindowTarget { mtm }, - }, + window_target: EventLoopWindowTarget { mtm }, }) } pub fn run(self, event_handler: F) -> ! where - F: FnMut(Event, &RootEventLoopWindowTarget), + F: FnMut(Event, &EventLoopWindowTarget), { unsafe { let application = UIApplication::shared(self.mtm); @@ -140,7 +137,7 @@ impl EventLoop { ); let event_handler = std::mem::transmute::< - Box, &RootEventLoopWindowTarget)>, + Box, &EventLoopWindowTarget)>, Box>, >(Box::new(event_handler)); @@ -169,7 +166,7 @@ impl EventLoop { EventLoopProxy::new(self.sender.clone()) } - pub fn window_target(&self) -> &RootEventLoopWindowTarget { + pub fn window_target(&self) -> &EventLoopWindowTarget { &self.window_target } } @@ -340,7 +337,7 @@ fn setup_control_flow_observers() { #[derive(Debug)] pub enum Never {} -type EventHandlerCallback = dyn FnMut(Event, &RootEventLoopWindowTarget) + 'static; +type EventHandlerCallback = dyn FnMut(Event, &EventLoopWindowTarget) + 'static; pub trait EventHandler: Debug { fn handle_nonuser_event(&mut self, event: Event); @@ -350,7 +347,7 @@ pub trait EventHandler: Debug { struct EventLoopHandler { f: Box>, receiver: Receiver, - event_loop: RootEventLoopWindowTarget, + event_loop: EventLoopWindowTarget, } impl Debug for EventLoopHandler { diff --git a/src/platform_impl/ios/mod.rs b/src/platform_impl/ios/mod.rs index d4d5a77f39..996c455736 100644 --- a/src/platform_impl/ios/mod.rs +++ b/src/platform_impl/ios/mod.rs @@ -70,7 +70,8 @@ use std::fmt; pub(crate) use self::{ event_loop::{ - EventLoop, EventLoopProxy, EventLoopWindowTarget, PlatformSpecificEventLoopAttributes, + ActiveEventLoop, EventLoop, EventLoopProxy, EventLoopWindowTarget, + PlatformSpecificEventLoopAttributes, }, monitor::{MonitorHandle, VideoMode}, window::{PlatformSpecificWindowBuilderAttributes, Window, WindowId}, diff --git a/src/platform_impl/linux/mod.rs b/src/platform_impl/linux/mod.rs index 98f32595c3..dc84f752c1 100644 --- a/src/platform_impl/linux/mod.rs +++ b/src/platform_impl/linux/mod.rs @@ -20,10 +20,7 @@ use crate::{ dpi::{PhysicalPosition, PhysicalSize, Position, Size}, error::{EventLoopError, ExternalError, NotSupportedError, OsError as RootOsError}, event::KeyEvent, - event_loop::{ - AsyncRequestSerial, ControlFlow, DeviceEvents, EventLoopClosed, - EventLoopWindowTarget as RootELW, - }, + event_loop::{AsyncRequestSerial, ControlFlow, DeviceEvents, EventLoopClosed}, icon::Icon, keyboard::{Key, PhysicalKey}, platform::{ @@ -816,26 +813,26 @@ impl EventLoop { pub fn run(mut self, callback: F) -> Result<(), EventLoopError> where - F: FnMut(crate::event::Event, &RootELW), + F: FnMut(crate::event::Event, &EventLoopWindowTarget), { self.run_on_demand(callback) } pub fn run_on_demand(&mut self, callback: F) -> Result<(), EventLoopError> where - F: FnMut(crate::event::Event, &RootELW), + F: FnMut(crate::event::Event, &EventLoopWindowTarget), { x11_or_wayland!(match self; EventLoop(evlp) => evlp.run_on_demand(callback)) } pub fn pump_events(&mut self, timeout: Option, callback: F) -> PumpStatus where - F: FnMut(crate::event::Event, &RootELW), + F: FnMut(crate::event::Event, &EventLoopWindowTarget), { x11_or_wayland!(match self; EventLoop(evlp) => evlp.pump_events(timeout, callback)) } - pub fn window_target(&self) -> &crate::event_loop::EventLoopWindowTarget { + pub fn window_target(&self) -> &EventLoopWindowTarget { x11_or_wayland!(match self; EventLoop(evlp) => evlp.window_target()) } } @@ -858,6 +855,8 @@ impl EventLoopProxy { } } +pub type ActiveEventLoop<'a> = &'a EventLoopWindowTarget; + pub enum EventLoopWindowTarget { #[cfg(wayland_platform)] Wayland(wayland::EventLoopWindowTarget), diff --git a/src/platform_impl/linux/wayland/event_loop/mod.rs b/src/platform_impl/linux/wayland/event_loop/mod.rs index 099f176ed4..a60cc5507c 100644 --- a/src/platform_impl/linux/wayland/event_loop/mod.rs +++ b/src/platform_impl/linux/wayland/event_loop/mod.rs @@ -18,9 +18,7 @@ use sctk::reexports::client::{Connection, QueueHandle}; use crate::dpi::{LogicalSize, PhysicalSize}; use crate::error::{EventLoopError, OsError as RootOsError}; use crate::event::{Event, InnerSizeWriter, StartCause, WindowEvent}; -use crate::event_loop::{ - ControlFlow, DeviceEvents, EventLoopWindowTarget as RootEventLoopWindowTarget, -}; +use crate::event_loop::{ControlFlow, DeviceEvents}; use crate::platform::pump_events::PumpStatus; use crate::platform_impl::platform::min_timeout; use crate::platform_impl::{EventLoopWindowTarget as PlatformEventLoopWindowTarget, OsError}; @@ -62,7 +60,7 @@ pub struct EventLoop { connection: Connection, /// Event loop window target. - window_target: RootEventLoopWindowTarget, + window_target: PlatformEventLoopWindowTarget, // XXX drop after everything else, just to be safe. /// Calloop's event loop. @@ -178,9 +176,7 @@ impl EventLoop { user_events_sender, pending_user_events, event_loop, - window_target: RootEventLoopWindowTarget { - p: PlatformEventLoopWindowTarget::Wayland(window_target), - }, + window_target: PlatformEventLoopWindowTarget::Wayland(window_target), }; Ok(event_loop) @@ -188,7 +184,7 @@ impl EventLoop { pub fn run_on_demand(&mut self, mut event_handler: F) -> Result<(), EventLoopError> where - F: FnMut(Event, &RootEventLoopWindowTarget), + F: FnMut(Event, &PlatformEventLoopWindowTarget), { if self.loop_running { return Err(EventLoopError::AlreadyRunning); @@ -219,7 +215,7 @@ impl EventLoop { pub fn pump_events(&mut self, timeout: Option, mut callback: F) -> PumpStatus where - F: FnMut(Event, &RootEventLoopWindowTarget), + F: FnMut(Event, &PlatformEventLoopWindowTarget), { if !self.loop_running { self.loop_running = true; @@ -246,7 +242,7 @@ impl EventLoop { pub fn poll_events_with_timeout(&mut self, mut timeout: Option, mut callback: F) where - F: FnMut(Event, &RootEventLoopWindowTarget), + F: FnMut(Event, &PlatformEventLoopWindowTarget), { let cause = loop { let start = Instant::now(); @@ -322,7 +318,7 @@ impl EventLoop { fn single_iteration(&mut self, callback: &mut F, cause: StartCause) where - F: FnMut(Event, &RootEventLoopWindowTarget), + F: FnMut(Event, &PlatformEventLoopWindowTarget), { // NOTE currently just indented to simplify the diff @@ -527,12 +523,12 @@ impl EventLoop { } #[inline] - pub fn window_target(&self) -> &RootEventLoopWindowTarget { + pub fn window_target(&self) -> &PlatformEventLoopWindowTarget { &self.window_target } fn with_state<'a, U: 'a, F: FnOnce(&'a mut WinitState) -> U>(&'a mut self, callback: F) -> U { - let state = match &mut self.window_target.p { + let state = match &mut self.window_target { PlatformEventLoopWindowTarget::Wayland(window_target) => window_target.state.get_mut(), #[cfg(x11_platform)] _ => unreachable!(), @@ -542,7 +538,7 @@ impl EventLoop { } fn loop_dispatch>>(&mut self, timeout: D) -> IOResult<()> { - let state = match &mut self.window_target.p { + let state = match &mut self.window_target { PlatformEventLoopWindowTarget::Wayland(window_target) => window_target.state.get_mut(), #[cfg(feature = "x11")] _ => unreachable!(), @@ -555,7 +551,7 @@ impl EventLoop { } fn roundtrip(&mut self) -> Result { - let state = match &mut self.window_target.p { + let state = match &mut self.window_target { PlatformEventLoopWindowTarget::Wayland(window_target) => window_target.state.get_mut(), #[cfg(feature = "x11")] _ => unreachable!(), @@ -571,19 +567,19 @@ impl EventLoop { } fn control_flow(&self) -> ControlFlow { - self.window_target.p.control_flow() + self.window_target.control_flow() } fn exiting(&self) -> bool { - self.window_target.p.exiting() + self.window_target.exiting() } fn set_exit_code(&self, code: i32) { - self.window_target.p.set_exit_code(code) + self.window_target.set_exit_code(code) } fn exit_code(&self) -> Option { - self.window_target.p.exit_code() + self.window_target.exit_code() } } diff --git a/src/platform_impl/linux/x11/event_processor.rs b/src/platform_impl/linux/x11/event_processor.rs index 6702422580..19e065d965 100644 --- a/src/platform_impl/linux/x11/event_processor.rs +++ b/src/platform_impl/linux/x11/event_processor.rs @@ -21,10 +21,10 @@ use super::{ Dnd, DndState, GenericEventCookie, ImeReceiver, ScrollOrientation, UnownedWindow, WindowId, }; +use crate::platform_impl::EventLoopWindowTarget as PlatformEventLoopWindowTarget; use crate::{ dpi::{PhysicalPosition, PhysicalSize}, event::{DeviceEvent, ElementState, Event, Ime, RawKeyEvent, TouchPhase, WindowEvent}, - event_loop::EventLoopWindowTarget as RootELW, keyboard::ModifiersState, platform_impl::platform::common::{keymap, xkb_state::KbdState}, }; @@ -44,7 +44,7 @@ pub(super) struct EventProcessor { pub(super) devices: RefCell>, pub(super) xi2ext: ExtensionInformation, pub(super) xkbext: ExtensionInformation, - pub(super) target: Rc, + pub(super) target: Rc, pub(super) kb_state: KbdState, // Number of touch events currently in progress pub(super) num_touch: u32, diff --git a/src/platform_impl/linux/x11/mod.rs b/src/platform_impl/linux/x11/mod.rs index f1d9ae2cea..07ee82a92d 100644 --- a/src/platform_impl/linux/x11/mod.rs +++ b/src/platform_impl/linux/x11/mod.rs @@ -69,10 +69,11 @@ use super::{common::xkb_state::KbdState, ControlFlow, OsError}; use crate::{ error::{EventLoopError, OsError as RootOsError}, event::{Event, StartCause, WindowEvent}, - event_loop::{DeviceEvents, EventLoopClosed, EventLoopWindowTarget as RootELW}, + event_loop::{DeviceEvents, EventLoopClosed}, platform::pump_events::PumpStatus, platform_impl::{ platform::{min_timeout, WindowId}, + EventLoopWindowTarget as PlatformEventLoopWindowTarget, PlatformSpecificWindowBuilderAttributes, }, window::WindowAttributes, @@ -167,7 +168,7 @@ pub struct EventLoop { user_receiver: PeekableReceiver, activation_receiver: PeekableReceiver, user_sender: Sender, - target: Rc, + target: Rc, /// The current state of the event loop. state: EventLoopState, @@ -325,9 +326,7 @@ impl EventLoop { // Set initial device event filter. window_target.update_listen_device_events(true); - let target = Rc::new(RootELW { - p: super::EventLoopWindowTarget::X(window_target), - }); + let target = Rc::new(PlatformEventLoopWindowTarget::X(window_target)); let event_processor = EventProcessor { target: target.clone(), @@ -392,13 +391,13 @@ impl EventLoop { } } - pub(crate) fn window_target(&self) -> &RootELW { + pub(crate) fn window_target(&self) -> &PlatformEventLoopWindowTarget { &self.target } pub fn run_on_demand(&mut self, mut event_handler: F) -> Result<(), EventLoopError> where - F: FnMut(Event, &RootELW), + F: FnMut(Event, &PlatformEventLoopWindowTarget), { if self.loop_running { return Err(EventLoopError::AlreadyRunning); @@ -432,7 +431,7 @@ impl EventLoop { pub fn pump_events(&mut self, timeout: Option, mut callback: F) -> PumpStatus where - F: FnMut(Event, &RootELW), + F: FnMut(Event, &PlatformEventLoopWindowTarget), { if !self.loop_running { self.loop_running = true; @@ -465,7 +464,7 @@ impl EventLoop { pub fn poll_events_with_timeout(&mut self, mut timeout: Option, mut callback: F) where - F: FnMut(Event, &RootELW), + F: FnMut(Event, &PlatformEventLoopWindowTarget), { let start = Instant::now(); @@ -543,7 +542,7 @@ impl EventLoop { fn single_iteration(&mut self, callback: &mut F, cause: StartCause) where - F: FnMut(Event, &RootELW), + F: FnMut(Event, &PlatformEventLoopWindowTarget), { callback(crate::event::Event::NewEvents(cause), &self.target); @@ -617,7 +616,7 @@ impl EventLoop { fn drain_events(&mut self, callback: &mut F) where - F: FnMut(Event, &RootELW), + F: FnMut(Event, &PlatformEventLoopWindowTarget), { let target = &self.target; let mut xev = MaybeUninit::uninit(); @@ -640,19 +639,19 @@ impl EventLoop { } fn control_flow(&self) -> ControlFlow { - self.target.p.control_flow() + self.target.control_flow() } fn exiting(&self) -> bool { - self.target.p.exiting() + self.target.exiting() } fn set_exit_code(&self, code: i32) { - self.target.p.set_exit_code(code) + self.target.set_exit_code(code) } fn exit_code(&self) -> Option { - self.target.p.exit_code() + self.target.exit_code() } } @@ -668,8 +667,8 @@ impl AsRawFd for EventLoop { } } -pub(crate) fn get_xtarget(target: &RootELW) -> &EventLoopWindowTarget { - match target.p { +pub(crate) fn get_xtarget(target: &PlatformEventLoopWindowTarget) -> &EventLoopWindowTarget { + match target { super::EventLoopWindowTarget::X(ref target) => target, #[cfg(wayland_platform)] _ => unreachable!(), diff --git a/src/platform_impl/macos/app_state.rs b/src/platform_impl/macos/app_state.rs index 75e37b6d71..3921928a47 100644 --- a/src/platform_impl/macos/app_state.rs +++ b/src/platform_impl/macos/app_state.rs @@ -19,12 +19,12 @@ use once_cell::sync::Lazy; use super::{ event::dummy_event, event_loop::PanicInfo, menu, observer::EventLoopWaker, util::Never, - window::WinitWindow, + window::WinitWindow, EventLoopWindowTarget, }; use crate::{ dpi::PhysicalSize, event::{Event, InnerSizeWriter, StartCause, WindowEvent}, - event_loop::{ControlFlow, EventLoopWindowTarget as RootWindowTarget}, + event_loop::ControlFlow, window::WindowId, }; @@ -45,18 +45,21 @@ pub trait EventHandler: Debug { fn handle_user_events(&mut self); } -pub(crate) type Callback = RefCell, &RootWindowTarget)>; +pub(crate) type Callback = RefCell, &EventLoopWindowTarget)>; struct EventLoopHandler { callback: Weak>, - window_target: Rc, + window_target: Rc, receiver: Rc>, } impl EventLoopHandler { fn with_callback(&mut self, f: F) where - F: FnOnce(&mut EventLoopHandler, RefMut<'_, dyn FnMut(Event, &RootWindowTarget)>), + F: FnOnce( + &mut EventLoopHandler, + RefMut<'_, dyn FnMut(Event, &EventLoopWindowTarget)>, + ), { // `NSApplication` and our `HANDLER` are global state and so it's possible // that we could get a delegate callback after the application has exit an @@ -370,7 +373,7 @@ impl AppState { /// a call to `clear_callback` before returning to avoid undefined behaviour. pub unsafe fn set_callback( callback: Weak>, - window_target: Rc, + window_target: Rc, receiver: Rc>, ) { *HANDLER.callback.lock().unwrap() = Some(Box::new(EventLoopHandler { diff --git a/src/platform_impl/macos/event_loop.rs b/src/platform_impl/macos/event_loop.rs index 08597a3d4f..cd1e9042f9 100644 --- a/src/platform_impl/macos/event_loop.rs +++ b/src/platform_impl/macos/event_loop.rs @@ -31,9 +31,7 @@ use super::event::dummy_event; use crate::{ error::EventLoopError, event::Event, - event_loop::{ - ControlFlow, DeviceEvents, EventLoopClosed, EventLoopWindowTarget as RootWindowTarget, - }, + event_loop::{ControlFlow, DeviceEvents, EventLoopClosed}, platform::{macos::ActivationPolicy, pump_events::PumpStatus}, platform_impl::platform::{ app::WinitApplication, @@ -77,6 +75,8 @@ pub struct EventLoopWindowTarget { mtm: MainThreadMarker, } +pub type ActiveEventLoop<'a> = &'a EventLoopWindowTarget; + impl EventLoopWindowTarget { #[inline] pub fn available_monitors(&self) -> VecDeque { @@ -157,7 +157,7 @@ pub struct EventLoop { sender: mpsc::Sender, receiver: Rc>, - window_target: Rc, + window_target: Rc, panic_info: Rc, /// We make sure that the callback closure is dropped during a panic @@ -225,21 +225,19 @@ impl EventLoop { _delegate: delegate, sender, receiver: Rc::new(receiver), - window_target: Rc::new(RootWindowTarget { - p: EventLoopWindowTarget { mtm }, - }), + window_target: Rc::new(EventLoopWindowTarget { mtm }), panic_info, _callback: None, }) } - pub fn window_target(&self) -> &RootWindowTarget { + pub fn window_target(&self) -> &EventLoopWindowTarget { &self.window_target } pub fn run(mut self, callback: F) -> Result<(), EventLoopError> where - F: FnMut(Event, &RootWindowTarget), + F: FnMut(Event, &EventLoopWindowTarget), { self.run_on_demand(callback) } @@ -250,7 +248,7 @@ impl EventLoop { // redundant wake ups. pub fn run_on_demand(&mut self, callback: F) -> Result<(), EventLoopError> where - F: FnMut(Event, &RootWindowTarget), + F: FnMut(Event, &EventLoopWindowTarget), { if AppState::is_running() { return Err(EventLoopError::AlreadyRunning); @@ -267,8 +265,8 @@ impl EventLoop { let callback = unsafe { mem::transmute::< - Rc, &RootWindowTarget)>>, - Rc, &RootWindowTarget)>>, + Rc, &EventLoopWindowTarget)>>, + Rc, &EventLoopWindowTarget)>>, >(Rc::new(RefCell::new(callback))) }; @@ -334,7 +332,7 @@ impl EventLoop { pub fn pump_events(&mut self, timeout: Option, callback: F) -> PumpStatus where - F: FnMut(Event, &RootWindowTarget), + F: FnMut(Event, &EventLoopWindowTarget), { // # Safety // We are erasing the lifetime of the application callback here so that we @@ -347,8 +345,8 @@ impl EventLoop { let callback = unsafe { mem::transmute::< - Rc, &RootWindowTarget)>>, - Rc, &RootWindowTarget)>>, + Rc, &EventLoopWindowTarget)>>, + Rc, &EventLoopWindowTarget)>>, >(Rc::new(RefCell::new(callback))) }; diff --git a/src/platform_impl/macos/mod.rs b/src/platform_impl/macos/mod.rs index 04aae45c69..d67207a264 100644 --- a/src/platform_impl/macos/mod.rs +++ b/src/platform_impl/macos/mod.rs @@ -20,7 +20,8 @@ use std::fmt; pub(crate) use self::{ event::KeyEventExtra, event_loop::{ - EventLoop, EventLoopProxy, EventLoopWindowTarget, PlatformSpecificEventLoopAttributes, + ActiveEventLoop, EventLoop, EventLoopProxy, EventLoopWindowTarget, + PlatformSpecificEventLoopAttributes, }, monitor::{MonitorHandle, VideoMode}, window::{PlatformSpecificWindowBuilderAttributes, WindowId}, diff --git a/src/platform_impl/orbital/event_loop.rs b/src/platform_impl/orbital/event_loop.rs index 86b796eb53..8dacaa7c23 100644 --- a/src/platform_impl/orbital/event_loop.rs +++ b/src/platform_impl/orbital/event_loop.rs @@ -14,7 +14,7 @@ use orbclient::{ use crate::{ error::EventLoopError, event::{self, Ime, Modifiers, StartCause}, - event_loop::{self, ControlFlow, DeviceEvents}, + event_loop::{ControlFlow, DeviceEvents, EventLoopClosed}, keyboard::{ Key, KeyCode, KeyLocation, ModifiersKeys, ModifiersState, NativeKey, NativeKeyCode, PhysicalKey, @@ -272,7 +272,7 @@ impl EventState { pub struct EventLoop { windows: Vec<(Arc, EventState)>, - window_target: event_loop::EventLoopWindowTarget, + window_target: EventLoopWindowTarget, user_events_sender: mpsc::Sender, user_events_receiver: mpsc::Receiver, } @@ -304,16 +304,14 @@ impl EventLoop { Ok(Self { windows: Vec::new(), - window_target: event_loop::EventLoopWindowTarget { - p: EventLoopWindowTarget { - control_flow: Cell::new(ControlFlow::default()), - exit: Cell::new(false), - creates: Mutex::new(VecDeque::new()), - redraws: Arc::new(Mutex::new(VecDeque::new())), - destroys: Arc::new(Mutex::new(VecDeque::new())), - event_socket, - wake_socket, - }, + window_target: EventLoopWindowTarget { + control_flow: Cell::new(ControlFlow::default()), + exit: Cell::new(false), + creates: Mutex::new(VecDeque::new()), + redraws: Arc::new(Mutex::new(VecDeque::new())), + destroys: Arc::new(Mutex::new(VecDeque::new())), + event_socket, + wake_socket, }, user_events_sender, user_events_receiver, @@ -463,10 +461,10 @@ impl EventLoop { pub fn run(mut self, mut event_handler_inner: F) -> Result<(), EventLoopError> where - F: FnMut(event::Event, &event_loop::EventLoopWindowTarget), + F: FnMut(event::Event, &EventLoopWindowTarget), { let mut event_handler = - move |event: event::Event, window_target: &event_loop::EventLoopWindowTarget| { + move |event: event::Event, window_target: &EventLoopWindowTarget| { event_handler_inner(event, window_target); }; @@ -481,7 +479,7 @@ impl EventLoop { // Handle window creates. while let Some(window) = { - let mut creates = self.window_target.p.creates.lock().unwrap(); + let mut creates = self.window_target.creates.lock().unwrap(); creates.pop_front() } { let window_id = WindowId { @@ -515,7 +513,7 @@ impl EventLoop { // Handle window destroys. while let Some(destroy_id) = { - let mut destroys = self.window_target.p.destroys.lock().unwrap(); + let mut destroys = self.window_target.destroys.lock().unwrap(); destroys.pop_front() } { event_handler( @@ -570,7 +568,7 @@ impl EventLoop { .expect("failed to acknowledge resize"); // Require redraw after resize. - let mut redraws = self.window_target.p.redraws.lock().unwrap(); + let mut redraws = self.window_target.redraws.lock().unwrap(); if !redraws.contains(&window_id) { redraws.push_back(window_id); } @@ -586,7 +584,7 @@ impl EventLoop { // To avoid deadlocks the redraws lock is not held during event processing. while let Some(window_id) = { - let mut redraws = self.window_target.p.redraws.lock().unwrap(); + let mut redraws = self.window_target.redraws.lock().unwrap(); redraws.pop_front() } { event_handler( @@ -600,11 +598,11 @@ impl EventLoop { event_handler(event::Event::AboutToWait, &self.window_target); - if self.window_target.p.exiting() { + if self.window_target.exiting() { break; } - let requested_resume = match self.window_target.p.control_flow() { + let requested_resume = match self.window_target.control_flow() { ControlFlow::Poll => { start_cause = StartCause::Poll; continue; @@ -618,7 +616,6 @@ impl EventLoop { let timeout_socket = TimeSocket::open().unwrap(); self.window_target - .p .event_socket .write(&syscall::Event { id: timeout_socket.0.fd, @@ -646,7 +643,7 @@ impl EventLoop { // Wait for event if needed. let mut event = syscall::Event::default(); - self.window_target.p.event_socket.read(&mut event).unwrap(); + self.window_target.event_socket.read(&mut event).unwrap(); // TODO: handle spurious wakeups (redraw caused wakeup but redraw already handled) match requested_resume { @@ -673,14 +670,14 @@ impl EventLoop { Ok(()) } - pub fn window_target(&self) -> &event_loop::EventLoopWindowTarget { + pub fn window_target(&self) -> &EventLoopWindowTarget { &self.window_target } pub fn create_proxy(&self) -> EventLoopProxy { EventLoopProxy { user_events_sender: self.user_events_sender.clone(), - wake_socket: self.window_target.p.wake_socket.clone(), + wake_socket: self.window_target.wake_socket.clone(), } } } @@ -691,10 +688,10 @@ pub struct EventLoopProxy { } impl EventLoopProxy { - pub fn send_event(&self, event: T) -> Result<(), event_loop::EventLoopClosed> { + pub fn send_event(&self, event: T) -> Result<(), EventLoopClosed> { self.user_events_sender .send(event) - .map_err(|mpsc::SendError(x)| event_loop::EventLoopClosed(x))?; + .map_err(|mpsc::SendError(x)| EventLoopClosed(x))?; self.wake_socket.wake().unwrap(); @@ -713,6 +710,8 @@ impl Clone for EventLoopProxy { impl Unpin for EventLoopProxy {} +pub type ActiveEventLoop<'a> = &'a EventLoopWindowTarget; + pub struct EventLoopWindowTarget { control_flow: Cell, exit: Cell, diff --git a/src/platform_impl/orbital/mod.rs b/src/platform_impl/orbital/mod.rs index e2ad1ce08c..dedecc32fc 100644 --- a/src/platform_impl/orbital/mod.rs +++ b/src/platform_impl/orbital/mod.rs @@ -6,7 +6,7 @@ use std::sync::Arc; use crate::dpi::{PhysicalPosition, PhysicalSize}; -pub use self::event_loop::{EventLoop, EventLoopProxy, EventLoopWindowTarget}; +pub use self::event_loop::{ActiveEventLoop, EventLoop, EventLoopProxy, EventLoopWindowTarget}; mod event_loop; pub use self::window::Window; diff --git a/src/platform_impl/web/event_loop/mod.rs b/src/platform_impl/web/event_loop/mod.rs index a1db32f9ee..0ecb9e5fbd 100644 --- a/src/platform_impl/web/event_loop/mod.rs +++ b/src/platform_impl/web/event_loop/mod.rs @@ -2,7 +2,6 @@ use std::sync::mpsc::{self, Receiver, Sender}; use crate::error::EventLoopError; use crate::event::Event; -use crate::event_loop::EventLoopWindowTarget as RootEventLoopWindowTarget; use super::{backend, device, window}; @@ -14,8 +13,10 @@ mod window_target; pub use proxy::EventLoopProxy; pub use window_target::EventLoopWindowTarget; +pub type ActiveEventLoop<'a> = &'a EventLoopWindowTarget; + pub struct EventLoop { - elw: RootEventLoopWindowTarget, + elw: EventLoopWindowTarget, user_event_sender: Sender, user_event_receiver: Receiver, } @@ -26,9 +27,7 @@ pub(crate) struct PlatformSpecificEventLoopAttributes {} impl EventLoop { pub(crate) fn new(_: &PlatformSpecificEventLoopAttributes) -> Result { let (user_event_sender, user_event_receiver) = mpsc::channel(); - let elw = RootEventLoopWindowTarget { - p: EventLoopWindowTarget::new(), - }; + let elw = EventLoopWindowTarget::new(); Ok(EventLoop { elw, user_event_sender, @@ -38,11 +37,9 @@ impl EventLoop { pub fn run(self, mut event_handler: F) -> ! where - F: FnMut(Event, &RootEventLoopWindowTarget), + F: FnMut(Event, &EventLoopWindowTarget), { - let target = RootEventLoopWindowTarget { - p: self.elw.p.clone(), - }; + let target = self.elw.clone(); // SAFETY: Don't use `move` to make sure we leak the `event_handler` and `target`. let handler: Box)> = Box::new(|event| { @@ -61,7 +58,7 @@ impl EventLoop { // because this function will never return and all resources not cleaned up by the point we // `throw` will leak, making this actually `'static`. let handler = unsafe { std::mem::transmute(handler) }; - self.elw.p.run(handler, false); + self.elw.run(handler, false); // Throw an exception to break out of Rust execution and use unreachable to tell the // compiler this function won't return, giving it a return type of '!' @@ -74,13 +71,11 @@ impl EventLoop { pub fn spawn(self, mut event_handler: F) where - F: 'static + FnMut(Event, &RootEventLoopWindowTarget), + F: 'static + FnMut(Event, &EventLoopWindowTarget), { - let target = RootEventLoopWindowTarget { - p: self.elw.p.clone(), - }; + let target = self.elw.clone(); - self.elw.p.run( + self.elw.run( Box::new(move |event| { let event = match event.map_nonuser_event() { Ok(event) => event, @@ -98,10 +93,10 @@ impl EventLoop { } pub fn create_proxy(&self) -> EventLoopProxy { - EventLoopProxy::new(self.elw.p.waker(), self.user_event_sender.clone()) + EventLoopProxy::new(self.elw.waker(), self.user_event_sender.clone()) } - pub fn window_target(&self) -> &RootEventLoopWindowTarget { + pub fn window_target(&self) -> &EventLoopWindowTarget { &self.elw } } diff --git a/src/platform_impl/web/event_loop/runner.rs b/src/platform_impl/web/event_loop/runner.rs index b029ab516f..e6ce280e0e 100644 --- a/src/platform_impl/web/event_loop/runner.rs +++ b/src/platform_impl/web/event_loop/runner.rs @@ -207,7 +207,7 @@ impl Shared { // Set the event callback to use for the event loop runner // This the event callback is a fairly thin layer over the user-provided callback that closes - // over a RootEventLoopWindowTarget reference + // over a EventLoopWindowTarget reference pub fn set_listener(&self, event_handler: Box) { { let mut runner = self.0.runner.borrow_mut(); diff --git a/src/platform_impl/web/event_loop/window_target.rs b/src/platform_impl/web/event_loop/window_target.rs index e29c03df2b..09c3e6fcf8 100644 --- a/src/platform_impl/web/event_loop/window_target.rs +++ b/src/platform_impl/web/event_loop/window_target.rs @@ -47,7 +47,7 @@ pub struct EventLoopWindowTarget { } impl EventLoopWindowTarget { - pub fn new() -> Self { + pub(crate) fn new() -> Self { Self { runner: runner::Shared::new(), modifiers: ModifiersShared::default(), diff --git a/src/platform_impl/web/mod.rs b/src/platform_impl/web/mod.rs index 56ca0eaf47..b20f2ab576 100644 --- a/src/platform_impl/web/mod.rs +++ b/src/platform_impl/web/mod.rs @@ -32,7 +32,8 @@ mod backend; pub use self::device::DeviceId; pub use self::error::OsError; pub(crate) use self::event_loop::{ - EventLoop, EventLoopProxy, EventLoopWindowTarget, PlatformSpecificEventLoopAttributes, + ActiveEventLoop, EventLoop, EventLoopProxy, EventLoopWindowTarget, + PlatformSpecificEventLoopAttributes, }; pub use self::monitor::{MonitorHandle, VideoMode}; pub use self::window::{PlatformSpecificWindowBuilderAttributes, Window, WindowId}; diff --git a/src/platform_impl/windows/event_loop.rs b/src/platform_impl/windows/event_loop.rs index 0ab23bb95a..423f971cd0 100644 --- a/src/platform_impl/windows/event_loop.rs +++ b/src/platform_impl/windows/event_loop.rs @@ -73,7 +73,7 @@ use crate::{ DeviceEvent, Event, Force, Ime, InnerSizeWriter, RawKeyEvent, Touch, TouchPhase, WindowEvent, }, - event_loop::{ControlFlow, DeviceEvents, EventLoopClosed, EventLoopWindowTarget as RootELW}, + event_loop::{ControlFlow, DeviceEvents, EventLoopClosed}, keyboard::ModifiersState, platform::pump_events::PumpStatus, platform_impl::platform::{ @@ -157,7 +157,7 @@ pub(crate) enum ProcResult { pub struct EventLoop { user_event_sender: Sender, user_event_receiver: Receiver, - window_target: RootELW, + window_target: EventLoopWindowTarget, msg_hook: Option bool + 'static>>, } @@ -177,6 +177,8 @@ impl Default for PlatformSpecificEventLoopAttributes { } } +pub type ActiveEventLoop<'a> = &'a EventLoopWindowTarget; + pub struct EventLoopWindowTarget { thread_id: u32, thread_msg_target: HWND, @@ -216,34 +218,32 @@ impl EventLoop { Ok(EventLoop { user_event_sender, user_event_receiver, - window_target: RootELW { - p: EventLoopWindowTarget { - thread_id, - thread_msg_target, - runner_shared, - }, + window_target: EventLoopWindowTarget { + thread_id, + thread_msg_target, + runner_shared, }, msg_hook: attributes.msg_hook.take(), }) } - pub fn window_target(&self) -> &RootELW { + pub fn window_target(&self) -> &EventLoopWindowTarget { &self.window_target } pub fn run(mut self, event_handler: F) -> Result<(), EventLoopError> where - F: FnMut(Event, &RootELW), + F: FnMut(Event, &EventLoopWindowTarget), { self.run_on_demand(event_handler) } pub fn run_on_demand(&mut self, mut event_handler: F) -> Result<(), EventLoopError> where - F: FnMut(Event, &RootELW), + F: FnMut(Event, &EventLoopWindowTarget), { { - let runner = &self.window_target.p.runner_shared; + let runner = &self.window_target.runner_shared; if runner.state() != RunnerState::Uninitialized { return Err(EventLoopError::AlreadyRunning); } @@ -288,7 +288,7 @@ impl EventLoop { } }; - let runner = &self.window_target.p.runner_shared; + let runner = &self.window_target.runner_shared; runner.loop_destroyed(); // # Safety @@ -305,10 +305,10 @@ impl EventLoop { pub fn pump_events(&mut self, timeout: Option, mut event_handler: F) -> PumpStatus where - F: FnMut(Event, &RootELW), + F: FnMut(Event, &EventLoopWindowTarget), { { - let runner = &self.window_target.p.runner_shared; + let runner = &self.window_target.runner_shared; let event_loop_windows_ref = &self.window_target; let user_event_receiver = &self.user_event_receiver; @@ -341,7 +341,7 @@ impl EventLoop { self.dispatch_peeked_messages(); } - let runner = &self.window_target.p.runner_shared; + let runner = &self.window_target.runner_shared; let status = if let Some(code) = runner.exit_code() { runner.loop_destroyed(); @@ -403,7 +403,7 @@ impl EventLoop { } } - let runner = &self.window_target.p.runner_shared; + let runner = &self.window_target.runner_shared; // We aim to be consistent with the MacOS backend which has a RunLoop // observer that will dispatch AboutToWait when about to wait for @@ -465,7 +465,7 @@ impl EventLoop { /// Dispatch all queued messages via `PeekMessageW` fn dispatch_peeked_messages(&mut self) { - let runner = &self.window_target.p.runner_shared; + let runner = &self.window_target.runner_shared; // We generally want to continue dispatching all pending messages // but we also allow dispatching to be interrupted as a means to @@ -515,13 +515,13 @@ impl EventLoop { pub fn create_proxy(&self) -> EventLoopProxy { EventLoopProxy { - target_window: self.window_target.p.thread_msg_target, + target_window: self.window_target.thread_msg_target, event_send: self.user_event_sender.clone(), } } fn exit_code(&self) -> Option { - self.window_target.p.exit_code() + self.window_target.exit_code() } } @@ -665,7 +665,7 @@ fn dur2timeout(dur: Duration) -> u32 { impl Drop for EventLoop { fn drop(&mut self) { unsafe { - DestroyWindow(self.window_target.p.thread_msg_target); + DestroyWindow(self.window_target.thread_msg_target); } } } diff --git a/src/platform_impl/windows/mod.rs b/src/platform_impl/windows/mod.rs index 13f4ecc6e0..6413ba0d70 100644 --- a/src/platform_impl/windows/mod.rs +++ b/src/platform_impl/windows/mod.rs @@ -8,7 +8,8 @@ use windows_sys::Win32::{ pub(crate) use self::{ event_loop::{ - EventLoop, EventLoopProxy, EventLoopWindowTarget, PlatformSpecificEventLoopAttributes, + ActiveEventLoop, EventLoop, EventLoopProxy, EventLoopWindowTarget, + PlatformSpecificEventLoopAttributes, }, icon::{SelectedCursor, WinIcon}, monitor::{MonitorHandle, VideoMode}, diff --git a/src/window.rs b/src/window.rs index 77f95dece9..fb20226551 100644 --- a/src/window.rs +++ b/src/window.rs @@ -4,7 +4,7 @@ use std::fmt; use crate::{ dpi::{PhysicalPosition, PhysicalSize, Position, Size}, error::{ExternalError, NotSupportedError, OsError}, - event_loop::EventLoopWindowTarget, + event_loop::MaybeActiveEventLoop, monitor::{MonitorHandle, VideoMode}, platform_impl, SendSyncWrapper, }; @@ -506,9 +506,9 @@ impl WindowBuilder { /// - **Web:** The window is created but not inserted into the web page automatically. Please /// see the web platform module for more information. #[inline] - pub fn build(self, window_target: &EventLoopWindowTarget) -> Result { + pub fn build<'a>(self, event_loop: impl MaybeActiveEventLoop<'a>) -> Result { let window = - platform_impl::Window::new(&window_target.p, self.window, self.platform_specific)?; + platform_impl::Window::new(event_loop.__inner(), self.window, self.platform_specific)?; window.maybe_queue_on_main(|w| w.request_redraw()); Ok(Window { window }) } @@ -530,7 +530,7 @@ impl Window { /// /// [`WindowBuilder::new().build(event_loop)`]: WindowBuilder::build #[inline] - pub fn new(event_loop: &EventLoopWindowTarget) -> Result { + pub fn new<'a>(event_loop: impl MaybeActiveEventLoop<'a>) -> Result { let builder = WindowBuilder::new(); builder.build(event_loop) } @@ -1494,9 +1494,9 @@ impl Window { /// Returns the list of all the monitors available on the system. /// - /// This is the same as [`EventLoopWindowTarget::available_monitors`], and is provided for convenience. + /// This is the same as [`ActiveEventLoop::available_monitors`], and is provided for convenience. /// - /// [`EventLoopWindowTarget::available_monitors`]: crate::event_loop::EventLoopWindowTarget::available_monitors + /// [`ActiveEventLoop::available_monitors`]: crate::event_loop::ActiveEventLoop::available_monitors #[inline] pub fn available_monitors(&self) -> impl Iterator { self.window.maybe_wait_on_main(|w| { @@ -1510,13 +1510,13 @@ impl Window { /// /// Returns `None` if it can't identify any monitor as a primary one. /// - /// This is the same as [`EventLoopWindowTarget::primary_monitor`], and is provided for convenience. + /// This is the same as [`ActiveEventLoop::primary_monitor`], and is provided for convenience. /// /// ## Platform-specific /// /// **Wayland / Web:** Always returns `None`. /// - /// [`EventLoopWindowTarget::primary_monitor`]: crate::event_loop::EventLoopWindowTarget::primary_monitor + /// [`ActiveEventLoop::primary_monitor`]: crate::event_loop::ActiveEventLoop::primary_monitor #[inline] pub fn primary_monitor(&self) -> Option { self.window From bb75f2d20a73e743c7b0cd6979b7ee7979b80785 Mon Sep 17 00:00:00 2001 From: Mads Marquart Date: Sun, 24 Dec 2023 03:13:48 +0100 Subject: [PATCH 7/8] Rename elwt -> event_loop --- examples/child_window.rs | 6 +++--- examples/control_flow.rs | 10 +++++----- examples/cursor.rs | 4 ++-- examples/cursor_grab.rs | 6 +++--- examples/custom_cursors.rs | 4 ++-- examples/custom_events.rs | 4 ++-- examples/drag_window.rs | 4 ++-- examples/focus.rs | 6 +++--- examples/fullscreen.rs | 14 ++++++++------ examples/handling_close.rs | 4 ++-- examples/ime.rs | 4 ++-- examples/key_binding.rs | 4 ++-- examples/mouse_wheel.rs | 4 ++-- examples/multithreaded.rs | 4 ++-- examples/multiwindow.rs | 8 ++++---- examples/request_redraw.rs | 4 ++-- examples/request_redraw_threaded.rs | 4 ++-- examples/resizable.rs | 4 ++-- examples/startup_notification.rs | 6 +++--- examples/theme.rs | 4 ++-- examples/timer.rs | 8 ++++---- examples/touchpad_gestures.rs | 4 ++-- examples/transparent.rs | 4 ++-- examples/web.rs | 4 ++-- examples/window.rs | 4 ++-- examples/window_buttons.rs | 4 ++-- examples/window_debug.rs | 6 +++--- examples/window_drag_resize.rs | 4 ++-- examples/window_icon.rs | 4 ++-- examples/window_on_demand.rs | 6 +++--- examples/window_option_as_alt.rs | 4 ++-- examples/window_pump_events.rs | 4 ++-- examples/window_resize_increments.rs | 4 ++-- examples/window_tabbing.rs | 6 +++--- examples/x11_embed.rs | 4 ++-- src/event.rs | 12 ++++++------ src/lib.rs | 4 ++-- src/platform/pump_events.rs | 4 ++-- src/window.rs | 4 ++-- 39 files changed, 102 insertions(+), 100 deletions(-) diff --git a/examples/child_window.rs b/examples/child_window.rs index 61f6539a68..244623d686 100644 --- a/examples/child_window.rs +++ b/examples/child_window.rs @@ -53,12 +53,12 @@ fn main() -> Result<(), impl std::error::Error> { println!("parent window: {parent_window:?})"); - event_loop.run(move |event: Event<()>, elwt| { + event_loop.run(move |event: Event<()>, event_loop| { if let Event::WindowEvent { event, window_id } = event { match event { WindowEvent::CloseRequested => { windows.clear(); - elwt.exit(); + event_loop.exit(); } WindowEvent::CursorEntered { device_id: _ } => { // On x11, println when the cursor entered in a window even if the child window is created @@ -75,7 +75,7 @@ fn main() -> Result<(), impl std::error::Error> { }, .. } => { - spawn_child_window(&parent_window, elwt, &mut windows); + spawn_child_window(&parent_window, event_loop, &mut windows); } WindowEvent::RedrawRequested => { if let Some(window) = windows.get(&window_id) { diff --git a/examples/control_flow.rs b/examples/control_flow.rs index 5032d0bffc..94ba2f943b 100644 --- a/examples/control_flow.rs +++ b/examples/control_flow.rs @@ -47,7 +47,7 @@ fn main() -> Result<(), impl std::error::Error> { let mut wait_cancelled = false; let mut close_requested = false; - event_loop.run(move |event, elwt| { + event_loop.run(move |event, event_loop| { use winit::event::StartCause; println!("{event:?}"); match event { @@ -104,22 +104,22 @@ fn main() -> Result<(), impl std::error::Error> { } match mode { - Mode::Wait => elwt.set_control_flow(ControlFlow::Wait), + Mode::Wait => event_loop.set_control_flow(ControlFlow::Wait), Mode::WaitUntil => { if !wait_cancelled { - elwt.set_control_flow(ControlFlow::WaitUntil( + event_loop.set_control_flow(ControlFlow::WaitUntil( time::Instant::now() + WAIT_TIME, )); } } Mode::Poll => { thread::sleep(POLL_SLEEP_TIME); - elwt.set_control_flow(ControlFlow::Poll); + event_loop.set_control_flow(ControlFlow::Poll); } }; if close_requested { - elwt.exit(); + event_loop.exit(); } } _ => (), diff --git a/examples/cursor.rs b/examples/cursor.rs index 83ab1064ff..eb0a4427cd 100644 --- a/examples/cursor.rs +++ b/examples/cursor.rs @@ -19,7 +19,7 @@ fn main() -> Result<(), impl std::error::Error> { let mut cursor_idx = 0; - event_loop.run(move |event, elwt| { + event_loop.run(move |event, event_loop| { if let Event::WindowEvent { event, .. } = event { match event { WindowEvent::KeyboardInput { @@ -42,7 +42,7 @@ fn main() -> Result<(), impl std::error::Error> { fill::fill_window(&window); } WindowEvent::CloseRequested => { - elwt.exit(); + event_loop.exit(); } _ => (), } diff --git a/examples/cursor_grab.rs b/examples/cursor_grab.rs index 27f8edfe8d..2388cbcefb 100644 --- a/examples/cursor_grab.rs +++ b/examples/cursor_grab.rs @@ -22,9 +22,9 @@ fn main() -> Result<(), impl std::error::Error> { let mut modifiers = ModifiersState::default(); - event_loop.run(move |event, elwt| match event { + event_loop.run(move |event, event_loop| match event { Event::WindowEvent { event, .. } => match event { - WindowEvent::CloseRequested => elwt.exit(), + WindowEvent::CloseRequested => event_loop.exit(), WindowEvent::KeyboardInput { event: KeyEvent { @@ -36,7 +36,7 @@ fn main() -> Result<(), impl std::error::Error> { } => { let result = match key { Key::Named(NamedKey::Escape) => { - elwt.exit(); + event_loop.exit(); Ok(()) } Key::Character(ch) => match ch.to_lowercase().as_str() { diff --git a/examples/custom_cursors.rs b/examples/custom_cursors.rs index 5a77979496..f193c7ca69 100644 --- a/examples/custom_cursors.rs +++ b/examples/custom_cursors.rs @@ -48,7 +48,7 @@ fn main() -> Result<(), impl std::error::Error> { decode_cursor(include_bytes!("data/cross2.png"), &event_loop), ]; - event_loop.run(move |event, _elwt| match event { + event_loop.run(move |event, _event_loop| match event { Event::WindowEvent { event, .. } => match event { WindowEvent::KeyboardInput { event: @@ -81,7 +81,7 @@ fn main() -> Result<(), impl std::error::Error> { } WindowEvent::CloseRequested => { #[cfg(not(wasm_platform))] - _elwt.exit(); + _event_loop.exit(); } _ => (), }, diff --git a/examples/custom_events.rs b/examples/custom_events.rs index 50501e6758..55a1348885 100644 --- a/examples/custom_events.rs +++ b/examples/custom_events.rs @@ -40,12 +40,12 @@ fn main() -> Result<(), impl std::error::Error> { } }); - event_loop.run(move |event, elwt| match event { + event_loop.run(move |event, event_loop| match event { Event::UserEvent(event) => println!("user event: {event:?}"), Event::WindowEvent { event: WindowEvent::CloseRequested, .. - } => elwt.exit(), + } => event_loop.exit(), Event::WindowEvent { event: WindowEvent::RedrawRequested, .. diff --git a/examples/drag_window.rs b/examples/drag_window.rs index 2d13ce431c..fc93a9bf3e 100644 --- a/examples/drag_window.rs +++ b/examples/drag_window.rs @@ -22,12 +22,12 @@ fn main() -> Result<(), impl std::error::Error> { let mut entered_id = window_2.id(); let mut cursor_location = None; - event_loop.run(move |event, elwt| match event { + event_loop.run(move |event, event_loop| match event { Event::NewEvents(StartCause::Init) => { eprintln!("Switch which window is to be dragged by pressing \"x\".") } Event::WindowEvent { event, window_id } => match event { - WindowEvent::CloseRequested => elwt.exit(), + WindowEvent::CloseRequested => event_loop.exit(), WindowEvent::CursorMoved { position, .. } => cursor_location = Some(position), WindowEvent::MouseInput { state, button, .. } => { let window = if (window_id == window_1.id() && switched) diff --git a/examples/focus.rs b/examples/focus.rs index 29d3c621db..3603a18341 100644 --- a/examples/focus.rs +++ b/examples/focus.rs @@ -27,7 +27,7 @@ fn main() -> Result<(), impl std::error::Error> { .unwrap(); let mut deadline = time::Instant::now() + time::Duration::from_secs(3); - event_loop.run(move |event, elwt| { + event_loop.run(move |event, event_loop| { match event { Event::NewEvents(StartCause::ResumeTimeReached { .. }) => { // Timeout reached; focus the window. @@ -36,7 +36,7 @@ fn main() -> Result<(), impl std::error::Error> { window.focus_window(); } Event::WindowEvent { event, window_id } if window_id == window.id() => match event { - WindowEvent::CloseRequested => elwt.exit(), + WindowEvent::CloseRequested => event_loop.exit(), WindowEvent::RedrawRequested => { // Notify the windowing system that we'll be presenting to the window. window.pre_present_notify(); @@ -51,6 +51,6 @@ fn main() -> Result<(), impl std::error::Error> { _ => (), } - elwt.set_control_flow(winit::event_loop::ControlFlow::WaitUntil(deadline)); + event_loop.set_control_flow(winit::event_loop::ControlFlow::WaitUntil(deadline)); }) } diff --git a/examples/fullscreen.rs b/examples/fullscreen.rs index fca98401c9..cbf61bb4bd 100644 --- a/examples/fullscreen.rs +++ b/examples/fullscreen.rs @@ -52,10 +52,10 @@ fn main() -> Result<(), impl std::error::Error> { println!("- I\tToggle mIn size limit"); println!("- A\tToggle mAx size limit"); - event_loop.run(move |event, elwt| { + event_loop.run(move |event, event_loop| { if let Event::WindowEvent { event, .. } = event { match event { - WindowEvent::CloseRequested => elwt.exit(), + WindowEvent::CloseRequested => event_loop.exit(), WindowEvent::KeyboardInput { event: KeyEvent { @@ -65,7 +65,7 @@ fn main() -> Result<(), impl std::error::Error> { }, .. } => match key { - Key::Named(NamedKey::Escape) => elwt.exit(), + Key::Named(NamedKey::Escape) => event_loop.exit(), // WARNING: Consider using `key_without_modifers()` if available on your platform. // See the `key_binding` example Key::Character(ch) => match ch.to_lowercase().as_str() { @@ -88,12 +88,14 @@ fn main() -> Result<(), impl std::error::Error> { } "s" => { monitor_index += 1; - if let Some(mon) = elwt.available_monitors().nth(monitor_index) { + if let Some(mon) = event_loop.available_monitors().nth(monitor_index) { monitor = mon; } else { monitor_index = 0; - monitor = - elwt.available_monitors().next().expect("no monitor found!"); + monitor = event_loop + .available_monitors() + .next() + .expect("no monitor found!"); } println!("Monitor: {:?}", monitor.name()); diff --git a/examples/handling_close.rs b/examples/handling_close.rs index fdc671d25d..63c2a92876 100644 --- a/examples/handling_close.rs +++ b/examples/handling_close.rs @@ -22,7 +22,7 @@ fn main() -> Result<(), impl std::error::Error> { let mut close_requested = false; - event_loop.run(move |event, elwt| { + event_loop.run(move |event, event_loop| { if let Event::WindowEvent { event, .. } = event { match event { WindowEvent::CloseRequested => { @@ -64,7 +64,7 @@ fn main() -> Result<(), impl std::error::Error> { // event loop (i.e. if it's a multi-window application), you need to // drop the window. That closes it, and results in `Destroyed` being // sent. - elwt.exit(); + event_loop.exit(); } } Key::Character("n") => { diff --git a/examples/ime.rs b/examples/ime.rs index 79c2416411..97ddf70e3f 100644 --- a/examples/ime.rs +++ b/examples/ime.rs @@ -39,10 +39,10 @@ fn main() -> Result<(), impl std::error::Error> { let mut cursor_position = PhysicalPosition::new(0.0, 0.0); let mut ime_pos = PhysicalPosition::new(0.0, 0.0); - event_loop.run(move |event, elwt| { + event_loop.run(move |event, event_loop| { if let Event::WindowEvent { event, .. } = event { match event { - WindowEvent::CloseRequested => elwt.exit(), + WindowEvent::CloseRequested => event_loop.exit(), WindowEvent::CursorMoved { position, .. } => { cursor_position = position; } diff --git a/examples/key_binding.rs b/examples/key_binding.rs index b640889708..c61d0a7f5f 100644 --- a/examples/key_binding.rs +++ b/examples/key_binding.rs @@ -31,10 +31,10 @@ fn main() -> Result<(), impl std::error::Error> { let mut modifiers = ModifiersState::default(); - event_loop.run(move |event, elwt| { + event_loop.run(move |event, event_loop| { if let Event::WindowEvent { event, .. } = event { match event { - WindowEvent::CloseRequested => elwt.exit(), + WindowEvent::CloseRequested => event_loop.exit(), WindowEvent::ModifiersChanged(new) => { modifiers = new.state(); } diff --git a/examples/mouse_wheel.rs b/examples/mouse_wheel.rs index cda0673a0e..9066c697e6 100644 --- a/examples/mouse_wheel.rs +++ b/examples/mouse_wheel.rs @@ -34,10 +34,10 @@ In both cases the example window should move like the content of a scroll area i In other words, the deltas indicate the direction in which to move the content (in this case the window)." ); - event_loop.run(move |event, elwt| { + event_loop.run(move |event, event_loop| { if let Event::WindowEvent { event, .. } = event { match event { - WindowEvent::CloseRequested => elwt.exit(), + WindowEvent::CloseRequested => event_loop.exit(), WindowEvent::MouseWheel { delta, .. } => match delta { winit::event::MouseScrollDelta::LineDelta(x, y) => { println!("mouse wheel Line Delta: ({x},{y})"); diff --git a/examples/multithreaded.rs b/examples/multithreaded.rs index 2b02d8fd3c..3288c3e495 100644 --- a/examples/multithreaded.rs +++ b/examples/multithreaded.rs @@ -173,9 +173,9 @@ fn main() -> Result<(), impl std::error::Error> { } }); } - event_loop.run(move |event, elwt| { + event_loop.run(move |event, event_loop| { if window_senders.is_empty() { - elwt.exit() + event_loop.exit() } match event { Event::WindowEvent { event, window_id } => match event { diff --git a/examples/multiwindow.rs b/examples/multiwindow.rs index 07a9b84eef..4e3cfeb3fa 100644 --- a/examples/multiwindow.rs +++ b/examples/multiwindow.rs @@ -26,7 +26,7 @@ fn main() -> Result<(), impl std::error::Error> { println!("Press N to open a new window."); - event_loop.run(move |event, elwt| { + event_loop.run(move |event, event_loop| { if let Event::WindowEvent { event, window_id } = event { match event { WindowEvent::CloseRequested => { @@ -36,7 +36,7 @@ fn main() -> Result<(), impl std::error::Error> { windows.remove(&window_id); if windows.is_empty() { - elwt.exit(); + event_loop.exit(); } } WindowEvent::KeyboardInput { @@ -44,9 +44,9 @@ fn main() -> Result<(), impl std::error::Error> { is_synthetic: false, .. } if event.state == ElementState::Pressed => match event.logical_key { - Key::Named(NamedKey::Escape) => elwt.exit(), + Key::Named(NamedKey::Escape) => event_loop.exit(), Key::Character(c) if c == "n" || c == "N" => { - let window = Window::new(elwt).unwrap(); + let window = Window::new(event_loop).unwrap(); println!("Opened a new window: {:?}", window.id()); windows.insert(window.id(), window); } diff --git a/examples/request_redraw.rs b/examples/request_redraw.rs index a058bd6019..01b1e66f83 100644 --- a/examples/request_redraw.rs +++ b/examples/request_redraw.rs @@ -19,12 +19,12 @@ fn main() -> Result<(), impl std::error::Error> { .build(&event_loop) .unwrap(); - event_loop.run(move |event, elwt| { + event_loop.run(move |event, event_loop| { println!("{event:?}"); if let Event::WindowEvent { event, .. } = event { match event { - WindowEvent::CloseRequested => elwt.exit(), + WindowEvent::CloseRequested => event_loop.exit(), WindowEvent::MouseInput { state: ElementState::Released, .. diff --git a/examples/request_redraw_threaded.rs b/examples/request_redraw_threaded.rs index 6070c2ae0e..b704b901bc 100644 --- a/examples/request_redraw_threaded.rs +++ b/examples/request_redraw_threaded.rs @@ -33,14 +33,14 @@ fn main() -> Result<(), impl std::error::Error> { } }); - event_loop.run(move |event, elwt| { + event_loop.run(move |event, event_loop| { println!("{event:?}"); match event { Event::WindowEvent { event: WindowEvent::CloseRequested, .. - } => elwt.exit(), + } => event_loop.exit(), Event::WindowEvent { event: WindowEvent::RedrawRequested, .. diff --git a/examples/resizable.rs b/examples/resizable.rs index 134c34388d..fd288697d6 100644 --- a/examples/resizable.rs +++ b/examples/resizable.rs @@ -27,10 +27,10 @@ fn main() -> Result<(), impl std::error::Error> { .build(&event_loop) .unwrap(); - event_loop.run(move |event, elwt| { + event_loop.run(move |event, event_loop| { if let Event::WindowEvent { event, .. } = event { match event { - WindowEvent::CloseRequested => elwt.exit(), + WindowEvent::CloseRequested => event_loop.exit(), WindowEvent::KeyboardInput { event: KeyEvent { diff --git a/examples/startup_notification.rs b/examples/startup_notification.rs index 0cbf4d3652..1f3a1006ed 100644 --- a/examples/startup_notification.rs +++ b/examples/startup_notification.rs @@ -31,7 +31,7 @@ mod example { let mut counter = 0; let mut create_first_window = false; - event_loop.run(move |event, elwt| { + event_loop.run(move |event, event_loop| { match event { Event::Resumed => create_first_window = true, @@ -60,7 +60,7 @@ mod example { // Remove the window from the map. windows.remove(&window_id); if windows.is_empty() { - elwt.exit(); + event_loop.exit(); return; } } @@ -92,7 +92,7 @@ mod example { builder = builder.with_activation_token(token); } - Rc::new(builder.build(elwt).unwrap()) + Rc::new(builder.build(event_loop).unwrap()) }; // Add the window to the map. diff --git a/examples/theme.rs b/examples/theme.rs index 6b7f8a4f11..3775161801 100644 --- a/examples/theme.rs +++ b/examples/theme.rs @@ -27,10 +27,10 @@ fn main() -> Result<(), impl std::error::Error> { println!(" (L) Light theme"); println!(" (D) Dark theme"); - event_loop.run(move |event, elwt| { + event_loop.run(move |event, event_loop| { if let Event::WindowEvent { window_id, event } = event { match event { - WindowEvent::CloseRequested => elwt.exit(), + WindowEvent::CloseRequested => event_loop.exit(), WindowEvent::ThemeChanged(theme) if window_id == window.id() => { println!("Theme is changed: {theme:?}") } diff --git a/examples/timer.rs b/examples/timer.rs index 62c0eee4bb..bcc6c38063 100644 --- a/examples/timer.rs +++ b/examples/timer.rs @@ -27,21 +27,21 @@ fn main() -> Result<(), impl std::error::Error> { let timer_length = Duration::new(1, 0); - event_loop.run(move |event, elwt| { + event_loop.run(move |event, event_loop| { println!("{event:?}"); match event { Event::NewEvents(StartCause::Init) => { - elwt.set_control_flow(ControlFlow::WaitUntil(Instant::now() + timer_length)); + event_loop.set_control_flow(ControlFlow::WaitUntil(Instant::now() + timer_length)); } Event::NewEvents(StartCause::ResumeTimeReached { .. }) => { - elwt.set_control_flow(ControlFlow::WaitUntil(Instant::now() + timer_length)); + event_loop.set_control_flow(ControlFlow::WaitUntil(Instant::now() + timer_length)); println!("\nTimer\n"); } Event::WindowEvent { event: WindowEvent::CloseRequested, .. - } => elwt.exit(), + } => event_loop.exit(), Event::WindowEvent { event: WindowEvent::RedrawRequested, .. diff --git a/examples/touchpad_gestures.rs b/examples/touchpad_gestures.rs index 6d9015bf02..ca3732b025 100644 --- a/examples/touchpad_gestures.rs +++ b/examples/touchpad_gestures.rs @@ -19,10 +19,10 @@ fn main() -> Result<(), impl std::error::Error> { println!("Only supported on macOS at the moment."); - event_loop.run(move |event, elwt| { + event_loop.run(move |event, event_loop| { if let Event::WindowEvent { event, .. } = event { match event { - WindowEvent::CloseRequested => elwt.exit(), + WindowEvent::CloseRequested => event_loop.exit(), WindowEvent::TouchpadMagnify { delta, .. } => { if delta > 0.0 { println!("Zoomed in {delta}"); diff --git a/examples/transparent.rs b/examples/transparent.rs index ee149a87d0..15158c901b 100644 --- a/examples/transparent.rs +++ b/examples/transparent.rs @@ -22,12 +22,12 @@ fn main() -> Result<(), impl std::error::Error> { window.set_title("A fantastic window!"); - event_loop.run(move |event, elwt| { + event_loop.run(move |event, event_loop| { println!("{event:?}"); if let Event::WindowEvent { event, .. } = event { match event { - WindowEvent::CloseRequested => elwt.exit(), + WindowEvent::CloseRequested => event_loop.exit(), WindowEvent::RedrawRequested => { fill::fill_window(&window); } diff --git a/examples/web.rs b/examples/web.rs index febc903a38..5d44e358be 100644 --- a/examples/web.rs +++ b/examples/web.rs @@ -21,7 +21,7 @@ pub fn main() -> Result<(), impl std::error::Error> { #[cfg(wasm_platform)] let log_list = wasm::insert_canvas_and_create_log_list(&window); - event_loop.run(move |event, elwt| { + event_loop.run(move |event, event_loop| { #[cfg(wasm_platform)] wasm::log_event(&log_list, &event); @@ -29,7 +29,7 @@ pub fn main() -> Result<(), impl std::error::Error> { Event::WindowEvent { event: WindowEvent::CloseRequested, window_id, - } if window_id == window.id() => elwt.exit(), + } if window_id == window.id() => event_loop.exit(), Event::AboutToWait => { window.request_redraw(); } diff --git a/examples/window.rs b/examples/window.rs index 488aa38af0..8ff79fc1df 100644 --- a/examples/window.rs +++ b/examples/window.rs @@ -20,12 +20,12 @@ fn main() -> Result<(), impl std::error::Error> { .build(&event_loop) .unwrap(); - event_loop.run(move |event, elwt| { + event_loop.run(move |event, event_loop| { println!("{event:?}"); match event { Event::WindowEvent { event, window_id } if window_id == window.id() => match event { - WindowEvent::CloseRequested => elwt.exit(), + WindowEvent::CloseRequested => event_loop.exit(), WindowEvent::RedrawRequested => { // Notify the windowing system that we'll be presenting to the window. window.pre_present_notify(); diff --git a/examples/window_buttons.rs b/examples/window_buttons.rs index d5b8a5be98..38e56154a8 100644 --- a/examples/window_buttons.rs +++ b/examples/window_buttons.rs @@ -31,7 +31,7 @@ fn main() -> Result<(), impl std::error::Error> { event_loop.listen_device_events(DeviceEvents::Always); - event_loop.run(move |event, elwt| { + event_loop.run(move |event, event_loop| { if let Event::WindowEvent { window_id, event } = event { match event { WindowEvent::KeyboardInput { @@ -57,7 +57,7 @@ fn main() -> Result<(), impl std::error::Error> { } _ => (), }, - WindowEvent::CloseRequested if window_id == window.id() => elwt.exit(), + WindowEvent::CloseRequested if window_id == window.id() => event_loop.exit(), WindowEvent::RedrawRequested => { fill::fill_window(&window); } diff --git a/examples/window_debug.rs b/examples/window_debug.rs index c6bf5b9053..fc59a03bfc 100644 --- a/examples/window_debug.rs +++ b/examples/window_debug.rs @@ -38,7 +38,7 @@ fn main() -> Result<(), impl std::error::Error> { event_loop.listen_device_events(DeviceEvents::Always); - event_loop.run(move |event, elwt| { + event_loop.run(move |event, event_loop| { match event { // This used to use the virtual key, but the new API // only provides the `physical_key` (`Code`). @@ -113,7 +113,7 @@ fn main() -> Result<(), impl std::error::Error> { window.set_minimized(minimized); } "q" => { - elwt.exit(); + event_loop.exit(); } "v" => { visible = !visible; @@ -125,7 +125,7 @@ fn main() -> Result<(), impl std::error::Error> { } _ => (), }, - WindowEvent::CloseRequested if window_id == window.id() => elwt.exit(), + WindowEvent::CloseRequested if window_id == window.id() => event_loop.exit(), WindowEvent::RedrawRequested => { fill::fill_window(&window); } diff --git a/examples/window_drag_resize.rs b/examples/window_drag_resize.rs index b1d3cba43d..517cc37037 100644 --- a/examples/window_drag_resize.rs +++ b/examples/window_drag_resize.rs @@ -27,12 +27,12 @@ fn main() -> Result<(), impl std::error::Error> { let mut border = false; let mut cursor_location = None; - event_loop.run(move |event, elwt| match event { + event_loop.run(move |event, event_loop| match event { Event::NewEvents(StartCause::Init) => { eprintln!("Press 'B' to toggle borderless") } Event::WindowEvent { event, .. } => match event { - WindowEvent::CloseRequested => elwt.exit(), + WindowEvent::CloseRequested => event_loop.exit(), WindowEvent::CursorMoved { position, .. } => { if !window.is_decorated() { let new_location = diff --git a/examples/window_icon.rs b/examples/window_icon.rs index 0f19780106..08fa6e333b 100644 --- a/examples/window_icon.rs +++ b/examples/window_icon.rs @@ -33,10 +33,10 @@ fn main() -> Result<(), impl std::error::Error> { .build(&event_loop) .unwrap(); - event_loop.run(move |event, elwt| { + event_loop.run(move |event, event_loop| { if let Event::WindowEvent { event, .. } = event { match event { - WindowEvent::CloseRequested => elwt.exit(), + WindowEvent::CloseRequested => event_loop.exit(), WindowEvent::DroppedFile(path) => { window.set_window_icon(Some(load_icon(&path))); } diff --git a/examples/window_on_demand.rs b/examples/window_on_demand.rs index ca9a448a26..29bd8ddc1d 100644 --- a/examples/window_on_demand.rs +++ b/examples/window_on_demand.rs @@ -30,7 +30,7 @@ fn main() -> Result<(), impl std::error::Error> { fn run_app(event_loop: &mut EventLoop<()>, idx: usize) -> Result<(), EventLoopError> { let mut app = App::default(); - event_loop.run_on_demand(move |event, elwt| { + event_loop.run_on_demand(move |event, event_loop| { println!("Run {idx}: {:?}", event); if let Some(window) = &app.window { @@ -59,7 +59,7 @@ fn main() -> Result<(), impl std::error::Error> { } if id == window_id => { println!("--------------------------------------------------------- Window {idx} Destroyed"); app.window_id = None; - elwt.exit(); + event_loop.exit(); } _ => (), } @@ -67,7 +67,7 @@ fn main() -> Result<(), impl std::error::Error> { let window = WindowBuilder::new() .with_title("Fantastic window number one!") .with_inner_size(winit::dpi::LogicalSize::new(128.0, 128.0)) - .build(elwt) + .build(event_loop) .unwrap(); app.window_id = Some(window.id()); app.window = Some(window); diff --git a/examples/window_option_as_alt.rs b/examples/window_option_as_alt.rs index 28fb93bd99..90c9bbf6e4 100644 --- a/examples/window_option_as_alt.rs +++ b/examples/window_option_as_alt.rs @@ -31,11 +31,11 @@ fn main() -> Result<(), impl std::error::Error> { let mut option_as_alt = window.option_as_alt(); - event_loop.run(move |event, elwt| match event { + event_loop.run(move |event, event_loop| match event { Event::WindowEvent { event: WindowEvent::CloseRequested, window_id, - } if window_id == window.id() => elwt.exit(), + } if window_id == window.id() => event_loop.exit(), Event::WindowEvent { event, .. } => match event { WindowEvent::MouseInput { state: ElementState::Pressed, diff --git a/examples/window_pump_events.rs b/examples/window_pump_events.rs index 040ad7f001..0a73e107b3 100644 --- a/examples/window_pump_events.rs +++ b/examples/window_pump_events.rs @@ -32,7 +32,7 @@ fn main() -> std::process::ExitCode { 'main: loop { let timeout = Some(Duration::ZERO); - let status = event_loop.pump_events(timeout, |event, elwt| { + let status = event_loop.pump_events(timeout, |event, event_loop| { if let Event::WindowEvent { event, .. } = &event { // Print only Window events to reduce noise println!("{event:?}"); @@ -42,7 +42,7 @@ fn main() -> std::process::ExitCode { Event::WindowEvent { event: WindowEvent::CloseRequested, window_id, - } if window_id == window.id() => elwt.exit(), + } if window_id == window.id() => event_loop.exit(), Event::AboutToWait => { window.request_redraw(); } diff --git a/examples/window_resize_increments.rs b/examples/window_resize_increments.rs index 834050585a..702fb057eb 100644 --- a/examples/window_resize_increments.rs +++ b/examples/window_resize_increments.rs @@ -24,9 +24,9 @@ fn main() -> Result<(), impl std::error::Error> { let mut has_increments = true; - event_loop.run(move |event, elwt| match event { + event_loop.run(move |event, event_loop| match event { Event::WindowEvent { event, window_id } if window_id == window.id() => match event { - WindowEvent::CloseRequested => elwt.exit(), + WindowEvent::CloseRequested => event_loop.exit(), WindowEvent::KeyboardInput { event, .. } if event.logical_key == NamedKey::Space && event.state == ElementState::Released => diff --git a/examples/window_tabbing.rs b/examples/window_tabbing.rs index 9413ae9a39..eaddc82f03 100644 --- a/examples/window_tabbing.rs +++ b/examples/window_tabbing.rs @@ -30,7 +30,7 @@ fn main() -> Result<(), impl std::error::Error> { println!("Press N to open a new window."); - event_loop.run(move |event, elwt| { + event_loop.run(move |event, event_loop| { if let Event::WindowEvent { event, window_id } = event { match event { WindowEvent::CloseRequested => { @@ -40,7 +40,7 @@ fn main() -> Result<(), impl std::error::Error> { windows.remove(&window_id); if windows.is_empty() { - elwt.exit(); + event_loop.exit(); } } WindowEvent::Resized(_) => { @@ -62,7 +62,7 @@ fn main() -> Result<(), impl std::error::Error> { let tabbing_id = windows.get(&window_id).unwrap().tabbing_identifier(); let window = WindowBuilder::new() .with_tabbing_identifier(&tabbing_id) - .build(elwt) + .build(event_loop) .unwrap(); println!("Added a new tab: {:?}", window.id()); windows.insert(window.id(), window); diff --git a/examples/x11_embed.rs b/examples/x11_embed.rs index e66482eba3..4b80b0f2f5 100644 --- a/examples/x11_embed.rs +++ b/examples/x11_embed.rs @@ -32,12 +32,12 @@ mod imple { .build(&event_loop) .unwrap(); - event_loop.run(move |event, elwt| { + event_loop.run(move |event, event_loop| { match event { Event::WindowEvent { event: WindowEvent::CloseRequested, window_id, - } if window_id == window.id() => elwt.exit(), + } if window_id == window.id() => event_loop.exit(), Event::AboutToWait => { window.request_redraw(); } diff --git a/src/event.rs b/src/event.rs index 6a4b33cf7f..696f13e6c8 100644 --- a/src/event.rs +++ b/src/event.rs @@ -9,22 +9,22 @@ //! ```rust,ignore //! let mut start_cause = StartCause::Init; //! -//! while !elwt.exiting() { -//! event_handler(NewEvents(start_cause), elwt); +//! while !event_loop.exiting() { +//! event_handler(NewEvents(start_cause), event_loop); //! //! for e in (window events, user events, device events) { -//! event_handler(e, elwt); +//! event_handler(e, event_loop); //! } //! //! for w in (redraw windows) { -//! event_handler(RedrawRequested(w), elwt); +//! event_handler(RedrawRequested(w), event_loop); //! } //! -//! event_handler(AboutToWait, elwt); +//! event_handler(AboutToWait, event_loop); //! start_cause = wait_if_necessary(); //! } //! -//! event_handler(LoopExiting, elwt); +//! event_handler(LoopExiting, event_loop); //! ``` //! //! This leaves out timing details like [`ControlFlow::WaitUntil`] but hopefully diff --git a/src/lib.rs b/src/lib.rs index 60450ced0d..de4ec09093 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -78,14 +78,14 @@ //! // input, and uses significantly less power/CPU time than ControlFlow::Poll. //! event_loop.set_control_flow(ControlFlow::Wait); //! -//! event_loop.run(move |event, elwt| { +//! event_loop.run(move |event, event_loop| { //! match event { //! Event::WindowEvent { //! event: WindowEvent::CloseRequested, //! .. //! } => { //! println!("The close button was pressed; stopping"); -//! elwt.exit(); +//! event_loop.exit(); //! }, //! Event::AboutToWait => { //! // Application update code. diff --git a/src/platform/pump_events.rs b/src/platform/pump_events.rs index bbcfa82835..7bb98a161b 100644 --- a/src/platform/pump_events.rs +++ b/src/platform/pump_events.rs @@ -63,7 +63,7 @@ pub trait EventLoopExtPumpEvents { /// /// 'main: loop { /// let timeout = Some(Duration::ZERO); - /// let status = event_loop.pump_events(timeout, |event, elwt| { + /// let status = event_loop.pump_events(timeout, |event, event_loop| { /// # if let Event::WindowEvent { event, .. } = &event { /// # // Print only Window events to reduce noise /// # println!("{event:?}"); @@ -73,7 +73,7 @@ pub trait EventLoopExtPumpEvents { /// Event::WindowEvent { /// event: WindowEvent::CloseRequested, /// window_id, - /// } if window_id == window.id() => elwt.exit(), + /// } if window_id == window.id() => event_loop.exit(), /// Event::AboutToWait => { /// window.request_redraw(); /// } diff --git a/src/window.rs b/src/window.rs index fb20226551..4a3cf10d9b 100644 --- a/src/window.rs +++ b/src/window.rs @@ -42,12 +42,12 @@ pub use cursor_icon::{CursorIcon, ParseError as CursorIconParseError}; /// event_loop.set_control_flow(ControlFlow::Wait); /// let window = Window::new(&event_loop).unwrap(); /// -/// event_loop.run(move |event, elwt| { +/// event_loop.run(move |event, event_loop| { /// match event { /// Event::WindowEvent { /// event: WindowEvent::CloseRequested, /// .. -/// } => elwt.exit(), +/// } => event_loop.exit(), /// _ => (), /// } /// }); From 8d50b90ba99a780c83e54fe1f98d7a62fb1ff074 Mon Sep 17 00:00:00 2001 From: Mads Marquart Date: Fri, 12 Jan 2024 23:32:16 +0100 Subject: [PATCH 8/8] Initial ApplicationHandler --- examples/control_flow.rs | 213 ++++++++++++++++++-------------- examples/cursor_grab.rs | 101 ++++++++++----- src/event_helper.rs | 257 +++++++++++++++++++++++++++++++++++++++ src/event_loop.rs | 14 ++- src/handler.rs | 159 ++++++++++++++++++++++++ src/lib.rs | 2 + 6 files changed, 620 insertions(+), 126 deletions(-) create mode 100644 src/event_helper.rs create mode 100644 src/handler.rs diff --git a/examples/control_flow.rs b/examples/control_flow.rs index 94ba2f943b..19c27be72d 100644 --- a/examples/control_flow.rs +++ b/examples/control_flow.rs @@ -8,10 +8,11 @@ use web_time as time; use simple_logger::SimpleLogger; use winit::{ - event::{ElementState, Event, KeyEvent, WindowEvent}, - event_loop::{ControlFlow, EventLoop}, + event::{ElementState, KeyEvent, WindowEvent}, + event_loop::{ActiveEventLoop, ControlFlow, EventLoop}, + handler::ApplicationHandler, keyboard::{Key, NamedKey}, - window::WindowBuilder, + window::{Window, WindowBuilder, WindowId}, }; #[path = "util/fill.rs"] @@ -27,102 +28,134 @@ enum Mode { const WAIT_TIME: time::Duration = time::Duration::from_millis(100); const POLL_SLEEP_TIME: time::Duration = time::Duration::from_millis(100); -fn main() -> Result<(), impl std::error::Error> { - SimpleLogger::new().init().unwrap(); - - println!("Press '1' to switch to Wait mode."); - println!("Press '2' to switch to WaitUntil mode."); - println!("Press '3' to switch to Poll mode."); - println!("Press 'R' to toggle request_redraw() calls."); - println!("Press 'Esc' to close the window."); +struct App { + window: Window, + mode: Mode, + request_redraw: bool, + wait_cancelled: bool, + close_requested: bool, +} - let event_loop = EventLoop::new().unwrap(); - let window = WindowBuilder::new() - .with_title("Press 1, 2, 3 to change control flow mode. Press R to toggle redraw requests.") - .build(&event_loop) - .unwrap(); - - let mut mode = Mode::Wait; - let mut request_redraw = false; - let mut wait_cancelled = false; - let mut close_requested = false; - - event_loop.run(move |event, event_loop| { - use winit::event::StartCause; - println!("{event:?}"); +impl ApplicationHandler for App { + fn window_event( + &mut self, + _active: ActiveEventLoop<'_>, + _window_id: WindowId, + event: WindowEvent, + ) { match event { - Event::NewEvents(start_cause) => { - wait_cancelled = match start_cause { - StartCause::WaitCancelled { .. } => mode == Mode::WaitUntil, - _ => false, - } + WindowEvent::CloseRequested => { + self.close_requested = true; } - Event::WindowEvent { event, .. } => match event { - WindowEvent::CloseRequested => { - close_requested = true; + WindowEvent::KeyboardInput { + event: + KeyEvent { + logical_key: key, + state: ElementState::Pressed, + .. + }, + .. + } => match key.as_ref() { + // WARNING: Consider using `key_without_modifers()` if available on your platform. + // See the `key_binding` example + Key::Character("1") => { + self.mode = Mode::Wait; + println!("\nmode: {:?}\n", self.mode); + } + Key::Character("2") => { + self.mode = Mode::WaitUntil; + println!("\nmode: {:?}\n", self.mode); + } + Key::Character("3") => { + self.mode = Mode::Poll; + println!("\nmode: {:?}\n", self.mode); } - WindowEvent::KeyboardInput { - event: - KeyEvent { - logical_key: key, - state: ElementState::Pressed, - .. - }, - .. - } => match key.as_ref() { - // WARNING: Consider using `key_without_modifers()` if available on your platform. - // See the `key_binding` example - Key::Character("1") => { - mode = Mode::Wait; - println!("\nmode: {mode:?}\n"); - } - Key::Character("2") => { - mode = Mode::WaitUntil; - println!("\nmode: {mode:?}\n"); - } - Key::Character("3") => { - mode = Mode::Poll; - println!("\nmode: {mode:?}\n"); - } - Key::Character("r") => { - request_redraw = !request_redraw; - println!("\nrequest_redraw: {request_redraw}\n"); - } - Key::Named(NamedKey::Escape) => { - close_requested = true; - } - _ => (), - }, - WindowEvent::RedrawRequested => { - fill::fill_window(&window); + Key::Character("r") => { + self.request_redraw = !self.request_redraw; + println!("\nrequest_redraw: {}\n", self.request_redraw); + } + Key::Named(NamedKey::Escape) => { + self.close_requested = true; } _ => (), }, - Event::AboutToWait => { - if request_redraw && !wait_cancelled && !close_requested { - window.request_redraw(); - } + WindowEvent::RedrawRequested => { + fill::fill_window(&self.window); + } + _ => (), + } + } + + fn start_wait_cancelled( + &mut self, + _active: ActiveEventLoop<'_>, + _start: time::Instant, + _requested_resume: Option, + ) { + self.wait_cancelled = self.mode == Mode::WaitUntil; + } + + fn start_resume_time_reached( + &mut self, + _active: ActiveEventLoop<'_>, + _start: time::Instant, + _requested_resume: time::Instant, + ) { + self.wait_cancelled = false; + } - match mode { - Mode::Wait => event_loop.set_control_flow(ControlFlow::Wait), - Mode::WaitUntil => { - if !wait_cancelled { - event_loop.set_control_flow(ControlFlow::WaitUntil( - time::Instant::now() + WAIT_TIME, - )); - } - } - Mode::Poll => { - thread::sleep(POLL_SLEEP_TIME); - event_loop.set_control_flow(ControlFlow::Poll); - } - }; - - if close_requested { - event_loop.exit(); + fn start_poll(&mut self, _active: ActiveEventLoop<'_>) { + self.wait_cancelled = false; + } + + fn about_to_wait(&mut self, active: ActiveEventLoop<'_>) { + if self.request_redraw && !self.wait_cancelled && !self.close_requested { + self.window.request_redraw(); + } + + match self.mode { + Mode::Wait => active.set_control_flow(ControlFlow::Wait), + Mode::WaitUntil => { + if !self.wait_cancelled { + active + .set_control_flow(ControlFlow::WaitUntil(time::Instant::now() + WAIT_TIME)); } } - _ => (), + Mode::Poll => { + thread::sleep(POLL_SLEEP_TIME); + active.set_control_flow(ControlFlow::Poll); + } + }; + + if self.close_requested { + active.exit(); } - }) + } +} + +fn main() -> Result<(), impl std::error::Error> { + SimpleLogger::new().init().unwrap(); + + println!("Press '1' to switch to Wait mode."); + println!("Press '2' to switch to WaitUntil mode."); + println!("Press '3' to switch to Poll mode."); + println!("Press 'R' to toggle request_redraw() calls."); + println!("Press 'Esc' to close the window."); + + let event_loop = EventLoop::new().unwrap(); + + let app = App { + window: WindowBuilder::new() + .with_title( + "Press 1, 2, 3 to change control flow mode. Press R to toggle redraw requests.", + ) + .build(&event_loop) + .unwrap(), + mode: Mode::Wait, + request_redraw: false, + wait_cancelled: false, + close_requested: false, + }; + + event_loop.run_with(app) } diff --git a/examples/cursor_grab.rs b/examples/cursor_grab.rs index 2388cbcefb..2c60d8d6fb 100644 --- a/examples/cursor_grab.rs +++ b/examples/cursor_grab.rs @@ -2,29 +2,30 @@ use simple_logger::SimpleLogger; use winit::{ - event::{DeviceEvent, ElementState, Event, KeyEvent, WindowEvent}, - event_loop::EventLoop, + event::{ButtonId, DeviceId, ElementState, KeyEvent, WindowEvent}, + event_loop::{ActiveEventLoop, EventLoop}, + handler::{ApplicationHandler, DeviceEventHandler}, keyboard::{Key, ModifiersState, NamedKey}, - window::{CursorGrabMode, WindowBuilder}, + window::{CursorGrabMode, Window, WindowBuilder, WindowId}, }; #[path = "util/fill.rs"] mod fill; -fn main() -> Result<(), impl std::error::Error> { - SimpleLogger::new().init().unwrap(); - let event_loop = EventLoop::new().unwrap(); - - let window = WindowBuilder::new() - .with_title("Super Cursor Grab'n'Hide Simulator 9000") - .build(&event_loop) - .unwrap(); - - let mut modifiers = ModifiersState::default(); +struct App { + window: Window, + modifiers: ModifiersState, +} - event_loop.run(move |event, event_loop| match event { - Event::WindowEvent { event, .. } => match event { - WindowEvent::CloseRequested => event_loop.exit(), +impl ApplicationHandler for App { + fn window_event( + &mut self, + active: ActiveEventLoop<'_>, + _window_id: WindowId, + event: WindowEvent, + ) { + match event { + WindowEvent::CloseRequested => active.exit(), WindowEvent::KeyboardInput { event: KeyEvent { @@ -36,15 +37,15 @@ fn main() -> Result<(), impl std::error::Error> { } => { let result = match key { Key::Named(NamedKey::Escape) => { - event_loop.exit(); + active.exit(); Ok(()) } Key::Character(ch) => match ch.to_lowercase().as_str() { - "g" => window.set_cursor_grab(CursorGrabMode::Confined), - "l" => window.set_cursor_grab(CursorGrabMode::Locked), - "a" => window.set_cursor_grab(CursorGrabMode::None), + "g" => self.window.set_cursor_grab(CursorGrabMode::Confined), + "l" => self.window.set_cursor_grab(CursorGrabMode::Locked), + "a" => self.window.set_cursor_grab(CursorGrabMode::None), "h" => { - window.set_cursor_visible(modifiers.shift_key()); + self.window.set_cursor_visible(self.modifiers.shift_key()); Ok(()) } _ => Ok(()), @@ -56,18 +57,52 @@ fn main() -> Result<(), impl std::error::Error> { println!("error: {err}"); } } - WindowEvent::ModifiersChanged(new) => modifiers = new.state(), - WindowEvent::RedrawRequested => fill::fill_window(&window), + WindowEvent::ModifiersChanged(new) => self.modifiers = new.state(), + WindowEvent::RedrawRequested => fill::fill_window(&self.window), _ => (), - }, - Event::DeviceEvent { event, .. } => match event { - DeviceEvent::MouseMotion { delta } => println!("mouse moved: {delta:?}"), - DeviceEvent::Button { button, state } => match state { - ElementState::Pressed => println!("mouse button {button} pressed"), - ElementState::Released => println!("mouse button {button} released"), - }, - _ => (), - }, - _ => (), + } + } + + fn device_event(&mut self) -> Option<&mut dyn DeviceEventHandler> { + Some(self) + } +} + +impl DeviceEventHandler for App { + fn mouse_motion( + &mut self, + _active: ActiveEventLoop<'_>, + _device_id: DeviceId, + delta: (f64, f64), + ) { + println!("mouse moved: {delta:?}"); + } + + fn button( + &mut self, + _active: ActiveEventLoop<'_>, + _device_id: DeviceId, + button: ButtonId, + state: ElementState, + ) { + match state { + ElementState::Pressed => println!("mouse button {button} pressed"), + ElementState::Released => println!("mouse button {button} released"), + } + } +} + +fn main() -> Result<(), impl std::error::Error> { + SimpleLogger::new().init().unwrap(); + let event_loop = EventLoop::new().unwrap(); + + let window = WindowBuilder::new() + .with_title("Super Cursor Grab'n'Hide Simulator 9000") + .build(&event_loop) + .unwrap(); + + event_loop.run_with(App { + window, + modifiers: ModifiersState::default(), }) } diff --git a/src/event_helper.rs b/src/event_helper.rs new file mode 100644 index 0000000000..d8c9750bde --- /dev/null +++ b/src/event_helper.rs @@ -0,0 +1,257 @@ +//! Helpers to convert between closure-style and handler trait style. +//! +//! This is only in the interim, and will be removed in the future. +use std::marker::PhantomData; +#[cfg(not(wasm_platform))] +use std::time::Instant; + +use crate::{ + event::{ + AxisId, ButtonId, DeviceEvent, DeviceId, ElementState, Event, MouseScrollDelta, + RawKeyEvent, StartCause, WindowEvent, + }, + event_loop::ActiveEventLoop, + handler::{ApplicationHandler, DeviceEventHandler}, + window::WindowId, +}; + +#[cfg(wasm_platform)] +use web_time::Instant; + +pub(crate) fn map_event>( + handler: &mut A, + event: Event, + active: ActiveEventLoop<'_>, +) { + match event { + Event::NewEvents(StartCause::Init) => handler.init(active), + Event::LoopExiting => handler.exit(active), + Event::Suspended => handler.suspend(active), + Event::Resumed => handler.resume(active), + Event::WindowEvent { window_id, event } => handler.window_event(active, window_id, event), + Event::DeviceEvent { device_id, event } => { + if let Some(handler) = handler.device_event() { + match event { + DeviceEvent::Added => handler.added(active, device_id), + DeviceEvent::Removed => handler.removed(active, device_id), + DeviceEvent::MouseMotion { delta } => { + handler.mouse_motion(active, device_id, delta) + } + DeviceEvent::MouseWheel { delta } => { + handler.mouse_wheel(active, device_id, delta) + } + DeviceEvent::Motion { axis, value } => { + handler.motion(active, device_id, axis, value) + } + DeviceEvent::Button { button, state } => { + handler.button(active, device_id, button, state) + } + DeviceEvent::Key(raw) => handler.key(active, device_id, raw), + } + } + } + Event::UserEvent(event) => handler.user_event(active, event), + Event::NewEvents(StartCause::ResumeTimeReached { + start, + requested_resume, + }) => handler.start_resume_time_reached(active, start, requested_resume), + Event::NewEvents(StartCause::WaitCancelled { + start, + requested_resume, + }) => handler.start_wait_cancelled(active, start, requested_resume), + Event::NewEvents(StartCause::Poll) => handler.start_poll(active), + Event::AboutToWait => handler.about_to_wait(active), + Event::MemoryWarning => handler.memory_warning(active), + } +} + +/// Introduce helper type around closure. +/// +/// This is done to avoid implementing these traits on the closures directly, +/// since we don't want that implementation to be part of the public API. +pub(crate) struct MapEventHelper { + p: PhantomData, + f: F, +} + +impl MapEventHelper { + pub(crate) fn new(f: F) -> Self { + Self { p: PhantomData, f } + } +} + +impl ApplicationHandler for MapEventHelper +where + F: FnMut(Event, ActiveEventLoop<'_>), +{ + fn window_event( + &mut self, + active: ActiveEventLoop<'_>, + window_id: WindowId, + event: WindowEvent, + ) { + (self.f)(Event::WindowEvent { window_id, event }, active) + } + + fn init(&mut self, active: ActiveEventLoop<'_>) { + (self.f)(Event::NewEvents(StartCause::Init), active) + } + + fn resume(&mut self, active: ActiveEventLoop<'_>) { + (self.f)(Event::Resumed, active) + } + + fn suspend(&mut self, active: ActiveEventLoop<'_>) { + (self.f)(Event::Suspended, active) + } + + fn user_event(&mut self, active: ActiveEventLoop<'_>, event: T) { + (self.f)(Event::UserEvent(event), active) + } + + fn exit(&mut self, active: ActiveEventLoop<'_>) { + (self.f)(Event::LoopExiting, active) + } + + fn start_wait_cancelled( + &mut self, + active: ActiveEventLoop<'_>, + start: Instant, + requested_resume: Option, + ) { + (self.f)( + Event::NewEvents(StartCause::WaitCancelled { + start, + requested_resume, + }), + active, + ) + } + + fn start_resume_time_reached( + &mut self, + active: ActiveEventLoop<'_>, + start: Instant, + requested_resume: Instant, + ) { + (self.f)( + Event::NewEvents(StartCause::ResumeTimeReached { + start, + requested_resume, + }), + active, + ) + } + + fn start_poll(&mut self, active: ActiveEventLoop<'_>) { + (self.f)(Event::NewEvents(StartCause::Poll), active) + } + + fn about_to_wait(&mut self, active: ActiveEventLoop<'_>) { + (self.f)(Event::AboutToWait, active) + } + + fn memory_warning(&mut self, active: ActiveEventLoop<'_>) { + (self.f)(Event::MemoryWarning, active) + } + + fn device_event(&mut self) -> Option<&mut dyn DeviceEventHandler> { + Some(self) + } +} + +impl, ActiveEventLoop<'_>)> DeviceEventHandler + for MapEventHelper +{ + fn added(&mut self, active: ActiveEventLoop<'_>, device_id: DeviceId) { + (self.f)( + Event::DeviceEvent { + device_id, + event: DeviceEvent::Added, + }, + active, + ) + } + + fn removed(&mut self, active: ActiveEventLoop<'_>, device_id: DeviceId) { + (self.f)( + Event::DeviceEvent { + device_id, + event: DeviceEvent::Removed, + }, + active, + ) + } + + fn mouse_motion( + &mut self, + active: ActiveEventLoop<'_>, + device_id: DeviceId, + delta: (f64, f64), + ) { + (self.f)( + Event::DeviceEvent { + device_id, + event: DeviceEvent::MouseMotion { delta }, + }, + active, + ) + } + + fn mouse_wheel( + &mut self, + active: ActiveEventLoop<'_>, + device_id: DeviceId, + delta: MouseScrollDelta, + ) { + (self.f)( + Event::DeviceEvent { + device_id, + event: DeviceEvent::MouseWheel { delta }, + }, + active, + ) + } + + fn motion( + &mut self, + active: ActiveEventLoop<'_>, + device_id: DeviceId, + axis: AxisId, + value: f64, + ) { + (self.f)( + Event::DeviceEvent { + device_id, + event: DeviceEvent::Motion { axis, value }, + }, + active, + ) + } + + fn button( + &mut self, + active: ActiveEventLoop<'_>, + device_id: DeviceId, + button: ButtonId, + state: ElementState, + ) { + (self.f)( + Event::DeviceEvent { + device_id, + event: DeviceEvent::Button { button, state }, + }, + active, + ) + } + + fn key(&mut self, active: ActiveEventLoop<'_>, device_id: DeviceId, raw: RawKeyEvent) { + (self.f)( + Event::DeviceEvent { + device_id, + event: DeviceEvent::Key(raw), + }, + active, + ) + } +} diff --git a/src/event_loop.rs b/src/event_loop.rs index 386f0ddf4d..c7550d7ec3 100644 --- a/src/event_loop.rs +++ b/src/event_loop.rs @@ -19,7 +19,10 @@ use std::time::{Duration, Instant}; use web_time::{Duration, Instant}; use crate::error::EventLoopError; -use crate::{event::Event, monitor::MonitorHandle, platform_impl}; +use crate::event::Event; +use crate::event_helper::{map_event, MapEventHelper}; +use crate::handler::ApplicationHandler; +use crate::{monitor::MonitorHandle, platform_impl}; /// Provides a way to retrieve events from the system and from the windows that were registered to /// the events loop. @@ -305,12 +308,17 @@ impl EventLoop { /// [^1]: `EventLoopExtWebSys::spawn()` is only available on WASM. #[inline] #[cfg(not(all(wasm_platform, target_feature = "exception-handling")))] - pub fn run(self, mut event_handler: F) -> Result<(), EventLoopError> + pub fn run(self, handler: F) -> Result<(), EventLoopError> where F: FnMut(Event, ActiveEventLoop<'_>), { + self.run_with(MapEventHelper::new(handler)) + } + + #[cfg(not(all(wasm_platform, target_feature = "exception-handling")))] + pub fn run_with>(self, mut handler: A) -> Result<(), EventLoopError> { self.event_loop - .run(move |event, inner| event_handler(event, ActiveEventLoop { inner })) + .run(|event, inner| map_event(&mut handler, event, ActiveEventLoop { inner })) } /// Set the initial [`ControlFlow`]. diff --git a/src/handler.rs b/src/handler.rs new file mode 100644 index 0000000000..ac0b409934 --- /dev/null +++ b/src/handler.rs @@ -0,0 +1,159 @@ +#[cfg(not(wasm_platform))] +use std::time::Instant; + +use crate::{ + event::{AxisId, ButtonId, DeviceId, ElementState, MouseScrollDelta, RawKeyEvent, WindowEvent}, + event_loop::ActiveEventLoop, + window::WindowId, +}; + +#[cfg(wasm_platform)] +use web_time::Instant; + +// Design choice: Always pass `ActiveEventLoop<'_>`, never allow the user to +// store that, to make it possible for backends to migrate to `&mut`. +pub trait ApplicationHandler { + // TODO: Migrate this to a trait too + fn window_event( + &mut self, + active: ActiveEventLoop<'_>, + window_id: WindowId, + event: WindowEvent, + ); + + // Default noop events + + fn init(&mut self, active: ActiveEventLoop<'_>) { + let _ = active; + } + + fn resume(&mut self, active: ActiveEventLoop<'_>) { + let _ = active; + } + + fn suspend(&mut self, active: ActiveEventLoop<'_>) { + let _ = active; + } + + fn user_event(&mut self, active: ActiveEventLoop<'_>, event: T) { + let _ = active; + let _ = event; + } + + fn memory_warning(&mut self, active: ActiveEventLoop<'_>) { + let _ = active; + } + + // TODO: Migrate this to `Drop` + fn exit(&mut self, active: ActiveEventLoop<'_>) { + let _ = active; + } + + // TODO: Figure out better timer support + + fn start_wait_cancelled( + &mut self, + active: ActiveEventLoop<'_>, + start: Instant, + requested_resume: Option, + ) { + let _ = active; + let _ = start; + let _ = requested_resume; + } + + fn start_resume_time_reached( + &mut self, + active: ActiveEventLoop<'_>, + start: Instant, + requested_resume: Instant, + ) { + let _ = active; + let _ = start; + let _ = requested_resume; + } + + fn start_poll(&mut self, active: ActiveEventLoop<'_>) { + let _ = active; + } + + fn about_to_wait(&mut self, active: ActiveEventLoop<'_>) { + let _ = active; + } + + // TODO: Consider returning `&mut dyn DeviceEventHandler` instead, + // and have this return a noop implementation by default. + // + // Note that we cannot return `impl DeviceEventHandler`, since + // `ApplicationHandler` has to remain object safe. + #[inline(always)] + fn device_event(&mut self) -> Option<&mut dyn DeviceEventHandler> { + None + } +} + +pub trait DeviceEventHandler { + fn added(&mut self, active: ActiveEventLoop<'_>, device_id: DeviceId) { + let _ = active; + let _ = device_id; + } + + fn removed(&mut self, active: ActiveEventLoop<'_>, device_id: DeviceId) { + let _ = active; + let _ = device_id; + } + + fn mouse_motion( + &mut self, + active: ActiveEventLoop<'_>, + device_id: DeviceId, + delta: (f64, f64), + ) { + let _ = active; + let _ = device_id; + let _ = delta; + } + + fn mouse_wheel( + &mut self, + active: ActiveEventLoop<'_>, + device_id: DeviceId, + delta: MouseScrollDelta, + ) { + let _ = active; + let _ = device_id; + let _ = delta; + } + + fn motion( + &mut self, + active: ActiveEventLoop<'_>, + device_id: DeviceId, + axis: AxisId, + value: f64, + ) { + let _ = active; + let _ = device_id; + let _ = axis; + let _ = value; + } + + fn button( + &mut self, + active: ActiveEventLoop<'_>, + device_id: DeviceId, + button: ButtonId, + state: ElementState, + ) { + let _ = active; + let _ = device_id; + let _ = button; + let _ = state; + } + + fn key(&mut self, active: ActiveEventLoop<'_>, device_id: DeviceId, raw: RawKeyEvent) { + let _ = active; + let _ = device_id; + let _ = raw; + } +} diff --git a/src/lib.rs b/src/lib.rs index de4ec09093..b8a3a9ded7 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -170,6 +170,8 @@ extern crate serde; extern crate bitflags; pub mod dpi; +mod event_helper; +pub mod handler; #[macro_use] pub mod error; mod cursor;