From e2557b70f7bb40ae34684672a875ea3070bb21eb Mon Sep 17 00:00:00 2001 From: Kirill Chibisov Date: Fri, 28 Jul 2023 18:44:15 +0400 Subject: [PATCH] Remove `lifetime` from the `Event` Lifetimes don't work nicely when dealing with multithreaded environments in the current design of the existing winit's event handling model, so remove it in favor of `Weak` fences passed to client, so they could try to update the size. Fixes #1387. --- CHANGELOG.md | 2 + examples/child_window.rs | 2 +- examples/multithreaded.rs | 4 +- src/event.rs | 269 +----------------- src/event_loop.rs | 2 +- src/platform/pump_events.rs | 12 +- src/platform/run_ondemand.rs | 12 +- src/platform/web.rs | 12 +- src/platform_impl/android/mod.rs | 26 +- src/platform_impl/ios/app_state.rs | 11 +- src/platform_impl/ios/event_loop.rs | 10 +- src/platform_impl/ios/mod.rs | 2 +- src/platform_impl/linux/mod.rs | 10 +- .../linux/wayland/event_loop/mod.rs | 16 +- .../linux/wayland/event_loop/sink.rs | 6 +- .../linux/x11/event_processor.rs | 25 +- src/platform_impl/linux/x11/mod.rs | 10 +- src/platform_impl/macos/app_state.rs | 23 +- src/platform_impl/macos/event.rs | 2 +- src/platform_impl/macos/event_loop.rs | 14 +- src/platform_impl/macos/view.rs | 2 +- src/platform_impl/macos/window_delegate.rs | 2 +- src/platform_impl/web/event_loop/mod.rs | 6 +- src/platform_impl/web/event_loop/runner.rs | 8 +- src/platform_impl/web/mod.rs | 2 +- src/platform_impl/web/web_sys/canvas.rs | 25 +- src/platform_impl/windows/drop_handler.rs | 6 +- src/platform_impl/windows/event_loop.rs | 18 +- .../windows/event_loop/runner.rs | 36 ++- 29 files changed, 169 insertions(+), 406 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 38f8156e81a..d4d914a5b1e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,8 @@ And please only add new entries to the top of this list, right below the `# Unre # Unreleased +- **Breaking:** Remove `PartialEq` implementation from the event. +- **Breaking:** Remove `lifetime` from the event. - **Breaking:** `ActivationTokenDone` event which could be requested with the new `startup_notify` module, see its docs for more. - On Wayland, make double clicking and moving the CSD frame more reliable. - On macOS, add tabbing APIs on `WindowExtMacOS` and `EventLoopWindowTargetExtMacOS`. diff --git a/examples/child_window.rs b/examples/child_window.rs index 65135b79e03..9d3bc053462 100644 --- a/examples/child_window.rs +++ b/examples/child_window.rs @@ -46,7 +46,7 @@ fn main() -> Result<(), impl std::error::Error> { println!("parent window: {parent_window:?})"); - event_loop.run(move |event: Event<'_, ()>, event_loop, control_flow| { + event_loop.run(move |event: Event<()>, event_loop, control_flow| { *control_flow = ControlFlow::Wait; if let Event::WindowEvent { event, window_id } = event { diff --git a/examples/multithreaded.rs b/examples/multithreaded.rs index bd9f9004ddd..c15578216b8 100644 --- a/examples/multithreaded.rs +++ b/examples/multithreaded.rs @@ -195,9 +195,7 @@ fn main() -> Result<(), impl std::error::Error> { } _ => { if let Some(tx) = window_senders.get(&window_id) { - if let Some(event) = event.to_static() { - tx.send(event).unwrap(); - } + tx.send(event).unwrap(); } } }, diff --git a/src/event.rs b/src/event.rs index eccc347fb1b..fd7b08e5c2d 100644 --- a/src/event.rs +++ b/src/event.rs @@ -34,10 +34,12 @@ //! //! [`EventLoop::run(...)`]: crate::event_loop::EventLoop::run //! [`ControlFlow::WaitUntil`]: crate::event_loop::ControlFlow::WaitUntil -use smol_str::SmolStr; use std::path::PathBuf; +use std::sync::{Mutex, Weak}; #[cfg(not(wasm_platform))] use std::time::Instant; + +use smol_str::SmolStr; #[cfg(wasm_platform)] use web_time::Instant; @@ -54,8 +56,8 @@ use crate::{ /// Describes a generic event. /// /// See the module-level docs for more information on the event loop manages each event. -#[derive(Debug, PartialEq)] -pub enum Event<'a, T: 'static> { +#[derive(Debug)] +pub enum Event { /// Emitted when new events arrive from the OS to be processed. /// /// This event type is useful as a place to put code that should be done before you start @@ -67,7 +69,7 @@ pub enum Event<'a, T: 'static> { /// Emitted when the OS sends an event to a winit window. WindowEvent { window_id: WindowId, - event: WindowEvent<'a>, + event: WindowEvent, }, /// Emitted when the OS sends an event to a device. @@ -261,33 +263,9 @@ pub enum Event<'a, T: 'static> { LoopDestroyed, } -impl Clone for Event<'static, T> { - fn clone(&self) -> Self { - use self::Event::*; - match self { - WindowEvent { window_id, event } => WindowEvent { - window_id: *window_id, - event: event.clone(), - }, - UserEvent(event) => UserEvent(event.clone()), - DeviceEvent { device_id, event } => DeviceEvent { - device_id: *device_id, - event: event.clone(), - }, - NewEvents(cause) => NewEvents(*cause), - MainEventsCleared => MainEventsCleared, - RedrawRequested(wid) => RedrawRequested(*wid), - RedrawEventsCleared => RedrawEventsCleared, - LoopDestroyed => LoopDestroyed, - Suspended => Suspended, - Resumed => Resumed, - } - } -} - -impl<'a, T> Event<'a, T> { +impl Event { #[allow(clippy::result_large_err)] - pub fn map_nonuser_event(self) -> Result, Event<'a, T>> { + pub fn map_nonuser_event(self) -> Result, Event> { use self::Event::*; match self { UserEvent(_) => Err(self), @@ -302,26 +280,6 @@ impl<'a, T> Event<'a, T> { Resumed => Ok(Resumed), } } - - /// If the event doesn't contain a reference, turn it into an event with a `'static` lifetime. - /// Otherwise, return `None`. - pub fn to_static(self) -> Option> { - use self::Event::*; - match self { - WindowEvent { window_id, event } => event - .to_static() - .map(|event| WindowEvent { window_id, event }), - UserEvent(event) => Some(UserEvent(event)), - DeviceEvent { device_id, event } => Some(DeviceEvent { device_id, event }), - NewEvents(cause) => Some(NewEvents(cause)), - MainEventsCleared => Some(MainEventsCleared), - RedrawRequested(wid) => Some(RedrawRequested(wid)), - RedrawEventsCleared => Some(RedrawEventsCleared), - LoopDestroyed => Some(LoopDestroyed), - Suspended => Some(Suspended), - Resumed => Some(Resumed), - } - } } /// Describes the reason the event loop is resuming. @@ -355,8 +313,8 @@ pub enum StartCause { } /// Describes an event from a [`Window`]. -#[derive(Debug, PartialEq)] -pub enum WindowEvent<'a> { +#[derive(Debug, Clone)] +pub enum WindowEvent { /// The activation token was delivered back and now could be used. /// #[cfg_attr( @@ -590,7 +548,9 @@ pub enum WindowEvent<'a> { /// For more information about DPI in general, see the [`dpi`](crate::dpi) module. ScaleFactorChanged { scale_factor: f64, - new_inner_size: &'a mut PhysicalSize, + /// The pointer could be upgraded successfully only from the callback for this event, + /// otherwise it'll always fail to do so. + new_inner_size: Weak>>, }, /// The system window theme has changed. @@ -619,209 +579,6 @@ pub enum WindowEvent<'a> { Occluded(bool), } -impl Clone for WindowEvent<'static> { - fn clone(&self) -> Self { - use self::WindowEvent::*; - return match self { - ActivationTokenDone { serial, token } => ActivationTokenDone { - serial: *serial, - token: token.clone(), - }, - Resized(size) => Resized(*size), - Moved(pos) => Moved(*pos), - CloseRequested => CloseRequested, - Destroyed => Destroyed, - DroppedFile(file) => DroppedFile(file.clone()), - HoveredFile(file) => HoveredFile(file.clone()), - HoveredFileCancelled => HoveredFileCancelled, - Focused(f) => Focused(*f), - KeyboardInput { - device_id, - event, - is_synthetic, - } => KeyboardInput { - device_id: *device_id, - event: event.clone(), - is_synthetic: *is_synthetic, - }, - Ime(preedit_state) => Ime(preedit_state.clone()), - ModifiersChanged(modifiers) => ModifiersChanged(*modifiers), - CursorMoved { - device_id, - position, - } => CursorMoved { - device_id: *device_id, - position: *position, - }, - CursorEntered { device_id } => CursorEntered { - device_id: *device_id, - }, - CursorLeft { device_id } => CursorLeft { - device_id: *device_id, - }, - MouseWheel { - device_id, - delta, - phase, - } => MouseWheel { - device_id: *device_id, - delta: *delta, - phase: *phase, - }, - MouseInput { - device_id, - state, - button, - } => MouseInput { - device_id: *device_id, - state: *state, - button: *button, - }, - TouchpadMagnify { - device_id, - delta, - phase, - } => TouchpadMagnify { - device_id: *device_id, - delta: *delta, - phase: *phase, - }, - SmartMagnify { device_id } => SmartMagnify { - device_id: *device_id, - }, - TouchpadRotate { - device_id, - delta, - phase, - } => TouchpadRotate { - device_id: *device_id, - delta: *delta, - phase: *phase, - }, - TouchpadPressure { - device_id, - pressure, - stage, - } => TouchpadPressure { - device_id: *device_id, - pressure: *pressure, - stage: *stage, - }, - AxisMotion { - device_id, - axis, - value, - } => AxisMotion { - device_id: *device_id, - axis: *axis, - value: *value, - }, - Touch(touch) => Touch(*touch), - ThemeChanged(theme) => ThemeChanged(*theme), - ScaleFactorChanged { .. } => { - unreachable!("Static event can't be about scale factor changing") - } - Occluded(occluded) => Occluded(*occluded), - }; - } -} - -impl<'a> WindowEvent<'a> { - pub fn to_static(self) -> Option> { - use self::WindowEvent::*; - match self { - ActivationTokenDone { serial, token } => Some(ActivationTokenDone { serial, token }), - Resized(size) => Some(Resized(size)), - Moved(position) => Some(Moved(position)), - CloseRequested => Some(CloseRequested), - Destroyed => Some(Destroyed), - DroppedFile(file) => Some(DroppedFile(file)), - HoveredFile(file) => Some(HoveredFile(file)), - HoveredFileCancelled => Some(HoveredFileCancelled), - Focused(focused) => Some(Focused(focused)), - KeyboardInput { - device_id, - event, - is_synthetic, - } => Some(KeyboardInput { - device_id, - event, - is_synthetic, - }), - ModifiersChanged(modifers) => Some(ModifiersChanged(modifers)), - Ime(event) => Some(Ime(event)), - CursorMoved { - device_id, - position, - } => Some(CursorMoved { - device_id, - position, - }), - CursorEntered { device_id } => Some(CursorEntered { device_id }), - CursorLeft { device_id } => Some(CursorLeft { device_id }), - MouseWheel { - device_id, - delta, - phase, - } => Some(MouseWheel { - device_id, - delta, - phase, - }), - MouseInput { - device_id, - state, - button, - } => Some(MouseInput { - device_id, - state, - button, - }), - TouchpadMagnify { - device_id, - delta, - phase, - } => Some(TouchpadMagnify { - device_id, - delta, - phase, - }), - SmartMagnify { device_id } => Some(SmartMagnify { device_id }), - TouchpadRotate { - device_id, - delta, - phase, - } => Some(TouchpadRotate { - device_id, - delta, - phase, - }), - TouchpadPressure { - device_id, - pressure, - stage, - } => Some(TouchpadPressure { - device_id, - pressure, - stage, - }), - AxisMotion { - device_id, - axis, - value, - } => Some(AxisMotion { - device_id, - axis, - value, - }), - Touch(touch) => Some(Touch(touch)), - ThemeChanged(theme) => Some(ThemeChanged(theme)), - ScaleFactorChanged { .. } => None, - Occluded(occluded) => Some(Occluded(occluded)), - } - } -} - /// Identifier of an input device. /// /// Whenever you receive an event arising from a particular input device, this event contains a `DeviceId` which diff --git a/src/event_loop.rs b/src/event_loop.rs index 87ec9535c2f..e27830876c7 100644 --- a/src/event_loop.rs +++ b/src/event_loop.rs @@ -314,7 +314,7 @@ impl EventLoop { #[inline] pub fn run(self, event_handler: F) -> Result<(), RunLoopError> where - F: 'static + FnMut(Event<'_, T>, &EventLoopWindowTarget, &mut ControlFlow), + F: 'static + FnMut(Event, &EventLoopWindowTarget, &mut ControlFlow), { self.event_loop.run(event_handler) } diff --git a/src/platform/pump_events.rs b/src/platform/pump_events.rs index 71f49de7e4e..524d8e791bc 100644 --- a/src/platform/pump_events.rs +++ b/src/platform/pump_events.rs @@ -174,11 +174,7 @@ pub trait EventLoopExtPumpEvents { /// callback. fn pump_events(&mut self, timeout: Option, event_handler: F) -> PumpStatus where - F: FnMut( - Event<'_, Self::UserEvent>, - &EventLoopWindowTarget, - &mut ControlFlow, - ); + F: FnMut(Event, &EventLoopWindowTarget, &mut ControlFlow); } impl EventLoopExtPumpEvents for EventLoop { @@ -186,11 +182,7 @@ impl EventLoopExtPumpEvents for EventLoop { fn pump_events(&mut self, timeout: Option, event_handler: F) -> PumpStatus where - F: FnMut( - Event<'_, Self::UserEvent>, - &EventLoopWindowTarget, - &mut ControlFlow, - ), + F: FnMut(Event, &EventLoopWindowTarget, &mut ControlFlow), { self.event_loop.pump_events(timeout, event_handler) } diff --git a/src/platform/run_ondemand.rs b/src/platform/run_ondemand.rs index 9f4871db45d..c1e36326350 100644 --- a/src/platform/run_ondemand.rs +++ b/src/platform/run_ondemand.rs @@ -59,11 +59,7 @@ pub trait EventLoopExtRunOnDemand { /// - **iOS:** It's not possible to stop and start an `NSApplication` repeatedly on iOS. fn run_ondemand(&mut self, event_handler: F) -> Result<(), RunLoopError> where - F: FnMut( - Event<'_, Self::UserEvent>, - &EventLoopWindowTarget, - &mut ControlFlow, - ); + F: FnMut(Event, &EventLoopWindowTarget, &mut ControlFlow); } impl EventLoopExtRunOnDemand for EventLoop { @@ -71,11 +67,7 @@ impl EventLoopExtRunOnDemand for EventLoop { fn run_ondemand(&mut self, event_handler: F) -> Result<(), RunLoopError> where - F: FnMut( - Event<'_, Self::UserEvent>, - &EventLoopWindowTarget, - &mut ControlFlow, - ), + F: FnMut(Event, &EventLoopWindowTarget, &mut ControlFlow), { self.event_loop.run_ondemand(event_handler) } diff --git a/src/platform/web.rs b/src/platform/web.rs index 9aef7df6b24..7a1bb66fe60 100644 --- a/src/platform/web.rs +++ b/src/platform/web.rs @@ -116,11 +116,7 @@ pub trait EventLoopExtWebSys { fn spawn(self, event_handler: F) where F: 'static - + FnMut( - Event<'_, Self::UserEvent>, - &EventLoopWindowTarget, - &mut ControlFlow, - ); + + FnMut(Event, &EventLoopWindowTarget, &mut ControlFlow); } impl EventLoopExtWebSys for EventLoop { @@ -129,11 +125,7 @@ impl EventLoopExtWebSys for EventLoop { fn spawn(self, event_handler: F) where F: 'static - + FnMut( - Event<'_, Self::UserEvent>, - &EventLoopWindowTarget, - &mut ControlFlow, - ), + + FnMut(Event, &EventLoopWindowTarget, &mut ControlFlow), { self.event_loop.spawn(event_handler) } diff --git a/src/platform_impl/android/mod.rs b/src/platform_impl/android/mod.rs index e9c2506f33f..ebe834e1511 100644 --- a/src/platform_impl/android/mod.rs +++ b/src/platform_impl/android/mod.rs @@ -5,7 +5,7 @@ use std::{ hash::Hash, sync::{ atomic::{AtomicBool, Ordering}, - mpsc, Arc, RwLock, + mpsc, Arc, Mutex, RwLock, }, time::{Duration, Instant}, }; @@ -169,12 +169,12 @@ impl Default for PlatformSpecificEventLoopAttributes { } fn sticky_exit_callback( - evt: event::Event<'_, T>, + evt: event::Event, target: &RootELW, control_flow: &mut ControlFlow, callback: &mut F, ) where - F: FnMut(event::Event<'_, T>, &RootELW, &mut ControlFlow), + F: FnMut(event::Event, &RootELW, &mut ControlFlow), { // make ControlFlow::ExitWithCode sticky by providing a dummy // control flow reference if it is already ExitWithCode. @@ -219,7 +219,7 @@ impl EventLoop { fn single_iteration(&mut self, main_event: Option>, callback: &mut F) where - F: FnMut(event::Event<'_, T>, &RootELW, &mut ControlFlow), + F: FnMut(event::Event, &RootELW, &mut ControlFlow), { trace!("Mainloop iteration"); @@ -289,11 +289,13 @@ impl EventLoop { let old_scale_factor = monitor.scale_factor(); let scale_factor = monitor.scale_factor(); if (scale_factor - old_scale_factor).abs() < f64::EPSILON { - let mut size = MonitorHandle::new(self.android_app.clone()).size(); + let new_inner_size = Arc::new(Mutex::new( + MonitorHandle::new(self.android_app.clone()).size(), + )); let event = event::Event::WindowEvent { window_id: window::WindowId(WindowId), event: event::WindowEvent::ScaleFactorChanged { - new_inner_size: &mut size, + new_inner_size: Arc::downgrade(&new_inner_size), scale_factor, }, }; @@ -529,14 +531,14 @@ impl EventLoop { pub fn run(mut self, event_handler: F) -> Result<(), RunLoopError> where F: 'static - + FnMut(event::Event<'_, T>, &event_loop::EventLoopWindowTarget, &mut ControlFlow), + + FnMut(event::Event, &event_loop::EventLoopWindowTarget, &mut ControlFlow), { self.run_ondemand(event_handler) } pub fn run_ondemand(&mut self, mut event_handler: F) -> Result<(), RunLoopError> where - F: FnMut(event::Event<'_, T>, &event_loop::EventLoopWindowTarget, &mut ControlFlow), + F: FnMut(event::Event, &event_loop::EventLoopWindowTarget, &mut ControlFlow), { if self.loop_running { return Err(RunLoopError::AlreadyRunning); @@ -559,7 +561,7 @@ impl EventLoop { pub fn pump_events(&mut self, timeout: Option, mut callback: F) -> PumpStatus where - F: FnMut(event::Event<'_, T>, &RootELW, &mut ControlFlow), + F: FnMut(event::Event, &RootELW, &mut ControlFlow), { if !self.loop_running { self.loop_running = true; @@ -599,7 +601,7 @@ impl EventLoop { fn poll_events_with_timeout(&mut self, mut timeout: Option, mut callback: F) where - F: FnMut(event::Event<'_, T>, &RootELW, &mut ControlFlow), + F: FnMut(event::Event, &RootELW, &mut ControlFlow), { let start = Instant::now(); @@ -1002,8 +1004,8 @@ pub struct MonitorHandle { app: AndroidApp, } impl PartialOrd for MonitorHandle { - fn partial_cmp(&self, _other: &Self) -> Option { - Some(std::cmp::Ordering::Equal) + fn partial_cmp(&self, other: &Self) -> Option { + Some(self.cmp(other)) } } impl Ord for MonitorHandle { diff --git a/src/platform_impl/ios/app_state.rs b/src/platform_impl/ios/app_state.rs index 8743a7f2a33..0b3bec858ef 100644 --- a/src/platform_impl/ios/app_state.rs +++ b/src/platform_impl/ios/app_state.rs @@ -6,6 +6,7 @@ use std::{ mem, os::raw::c_void, ptr, + sync::{Arc, Mutex}, time::Instant, }; @@ -57,7 +58,7 @@ enum UserCallbackTransitionResult<'a> { }, } -impl Event<'static, Never> { +impl Event { fn is_redraw(&self) -> bool { matches!(self, Event::RedrawRequested(_)) } @@ -817,18 +818,18 @@ fn handle_hidpi_proxy( scale_factor: f64, window: Id, ) { - let mut size = suggested_size.to_physical(scale_factor); - let new_inner_size = &mut size; + let new_inner_size = Arc::new(Mutex::new(suggested_size.to_physical(scale_factor))); let event = Event::WindowEvent { window_id: RootWindowId(window.id()), event: WindowEvent::ScaleFactorChanged { scale_factor, - new_inner_size, + new_inner_size: Arc::downgrade(&new_inner_size), }, }; event_handler.handle_nonuser_event(event, &mut control_flow); let (view, screen_frame) = get_view_and_screen_frame(&window); - let physical_size = *new_inner_size; + let physical_size = *new_inner_size.lock().unwrap(); + drop(new_inner_size); let logical_size = physical_size.to_logical(scale_factor); let size = CGSize::new(logical_size.width, logical_size.height); let new_frame: CGRect = CGRect::new(screen_frame.origin, size); diff --git a/src/platform_impl/ios/event_loop.rs b/src/platform_impl/ios/event_loop.rs index 8649c8c7a85..36e78223b82 100644 --- a/src/platform_impl/ios/event_loop.rs +++ b/src/platform_impl/ios/event_loop.rs @@ -33,7 +33,7 @@ use crate::{ #[derive(Debug)] pub(crate) enum EventWrapper { - StaticEvent(Event<'static, Never>), + StaticEvent(Event), EventProxy(EventProxy), } @@ -106,7 +106,7 @@ impl EventLoop { pub fn run(self, event_handler: F) -> ! where - F: 'static + FnMut(Event<'_, T>, &RootEventLoopWindowTarget, &mut ControlFlow), + F: 'static + FnMut(Event, &RootEventLoopWindowTarget, &mut ControlFlow), { unsafe { let application = UIApplication::shared(MainThreadMarker::new().unwrap()); @@ -315,7 +315,7 @@ fn setup_control_flow_observers() { pub enum Never {} pub trait EventHandler: Debug { - fn handle_nonuser_event(&mut self, event: Event<'_, Never>, control_flow: &mut ControlFlow); + fn handle_nonuser_event(&mut self, event: Event, control_flow: &mut ControlFlow); fn handle_user_events(&mut self, control_flow: &mut ControlFlow); } @@ -334,10 +334,10 @@ impl Debug for EventLoopHandler { impl EventHandler for EventLoopHandler where - F: 'static + FnMut(Event<'_, T>, &RootEventLoopWindowTarget, &mut ControlFlow), + F: 'static + FnMut(Event, &RootEventLoopWindowTarget, &mut ControlFlow), T: 'static, { - fn handle_nonuser_event(&mut self, event: Event<'_, Never>, control_flow: &mut ControlFlow) { + fn handle_nonuser_event(&mut self, event: Event, control_flow: &mut ControlFlow) { (self.f)( event.map_nonuser_event().unwrap(), &self.event_loop, diff --git a/src/platform_impl/ios/mod.rs b/src/platform_impl/ios/mod.rs index d94681547d9..4bfdd1bc24c 100644 --- a/src/platform_impl/ios/mod.rs +++ b/src/platform_impl/ios/mod.rs @@ -89,7 +89,7 @@ pub(crate) use self::{ use self::uikit::UIScreen; pub(crate) use crate::icon::NoIcon as PlatformIcon; -pub(self) use crate::platform_impl::Fullscreen; +pub(crate) use crate::platform_impl::Fullscreen; #[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] pub struct DeviceId { diff --git a/src/platform_impl/linux/mod.rs b/src/platform_impl/linux/mod.rs index 4c2a43c7c54..5c5f1fd1019 100644 --- a/src/platform_impl/linux/mod.rs +++ b/src/platform_impl/linux/mod.rs @@ -832,21 +832,21 @@ impl EventLoop { pub fn run(mut self, callback: F) -> Result<(), RunLoopError> where - F: FnMut(crate::event::Event<'_, T>, &RootELW, &mut ControlFlow), + F: FnMut(crate::event::Event, &RootELW, &mut ControlFlow), { self.run_ondemand(callback) } pub fn run_ondemand(&mut self, callback: F) -> Result<(), RunLoopError> where - F: FnMut(crate::event::Event<'_, T>, &RootELW, &mut ControlFlow), + F: FnMut(crate::event::Event, &RootELW, &mut ControlFlow), { x11_or_wayland!(match self; EventLoop(evlp) => evlp.run_ondemand(callback)) } pub fn pump_events(&mut self, timeout: Option, callback: F) -> PumpStatus where - F: FnMut(crate::event::Event<'_, T>, &RootELW, &mut ControlFlow), + F: FnMut(crate::event::Event, &RootELW, &mut ControlFlow), { x11_or_wayland!(match self; EventLoop(evlp) => evlp.pump_events(timeout, callback)) } @@ -928,12 +928,12 @@ impl EventLoopWindowTarget { } fn sticky_exit_callback( - evt: Event<'_, T>, + evt: Event, target: &RootELW, control_flow: &mut ControlFlow, callback: &mut F, ) where - F: FnMut(Event<'_, T>, &RootELW, &mut ControlFlow), + F: FnMut(Event, &RootELW, &mut ControlFlow), { // make ControlFlow::ExitWithCode sticky by providing a dummy // control flow reference if it is already ExitWithCode. diff --git a/src/platform_impl/linux/wayland/event_loop/mod.rs b/src/platform_impl/linux/wayland/event_loop/mod.rs index 053b0f26a9c..380364ae105 100644 --- a/src/platform_impl/linux/wayland/event_loop/mod.rs +++ b/src/platform_impl/linux/wayland/event_loop/mod.rs @@ -7,6 +7,7 @@ use std::marker::PhantomData; use std::mem; use std::rc::Rc; use std::sync::atomic::Ordering; +use std::sync::{Arc, Mutex}; use std::time::{Duration, Instant}; use raw_window_handle::{RawDisplayHandle, WaylandDisplayHandle}; @@ -147,7 +148,7 @@ impl EventLoop { pub fn run_ondemand(&mut self, mut event_handler: F) -> Result<(), RunLoopError> where - F: FnMut(Event<'_, T>, &RootEventLoopWindowTarget, &mut ControlFlow), + F: FnMut(Event, &RootEventLoopWindowTarget, &mut ControlFlow), { if self.loop_running { return Err(RunLoopError::AlreadyRunning); @@ -178,7 +179,7 @@ impl EventLoop { pub fn pump_events(&mut self, timeout: Option, mut callback: F) -> PumpStatus where - F: FnMut(Event<'_, T>, &RootEventLoopWindowTarget, &mut ControlFlow), + F: FnMut(Event, &RootEventLoopWindowTarget, &mut ControlFlow), { if !self.loop_running { self.loop_running = true; @@ -216,7 +217,7 @@ impl EventLoop { pub fn poll_events_with_timeout(&mut self, mut timeout: Option, mut callback: F) where - F: FnMut(Event<'_, T>, &RootEventLoopWindowTarget, &mut ControlFlow), + F: FnMut(Event, &RootEventLoopWindowTarget, &mut ControlFlow), { let start = Instant::now(); @@ -321,7 +322,7 @@ impl EventLoop { fn single_iteration(&mut self, mut callback: &mut F, cause: StartCause) where - F: FnMut(Event<'_, T>, &RootEventLoopWindowTarget, &mut ControlFlow), + F: FnMut(Event, &RootEventLoopWindowTarget, &mut ControlFlow), { // NOTE currently just indented to simplify the diff @@ -370,7 +371,7 @@ impl EventLoop { for mut compositor_update in compositor_updates.drain(..) { let window_id = compositor_update.window_id; if let Some(scale_factor) = compositor_update.scale_factor { - let mut physical_size = self.with_state(|state| { + let physical_size = self.with_state(|state| { let windows = state.windows.get_mut(); let mut window = windows.get(&window_id).unwrap().lock().unwrap(); @@ -383,12 +384,13 @@ impl EventLoop { // Stash the old window size. let old_physical_size = physical_size; + let new_inner_size = Arc::new(Mutex::new(physical_size)); sticky_exit_callback( Event::WindowEvent { window_id: crate::window::WindowId(window_id), event: WindowEvent::ScaleFactorChanged { scale_factor, - new_inner_size: &mut physical_size, + new_inner_size: Arc::downgrade(&new_inner_size), }, }, &self.window_target, @@ -396,6 +398,8 @@ impl EventLoop { &mut callback, ); + let physical_size = *new_inner_size.lock().unwrap(); + drop(new_inner_size); let new_logical_size = physical_size.to_logical(scale_factor); // Resize the window when user altered the size. diff --git a/src/platform_impl/linux/wayland/event_loop/sink.rs b/src/platform_impl/linux/wayland/event_loop/sink.rs index 0bf2ae5833e..5b356be454f 100644 --- a/src/platform_impl/linux/wayland/event_loop/sink.rs +++ b/src/platform_impl/linux/wayland/event_loop/sink.rs @@ -12,7 +12,7 @@ use super::{DeviceId, WindowId}; /// to the winit's user. #[derive(Default)] pub struct EventSink { - pub window_events: Vec>, + pub window_events: Vec>, } impl EventSink { @@ -31,7 +31,7 @@ impl EventSink { /// Add new window event to a queue. #[inline] - pub fn push_window_event(&mut self, event: WindowEvent<'static>, window_id: WindowId) { + pub fn push_window_event(&mut self, event: WindowEvent, window_id: WindowId) { self.window_events.push(Event::WindowEvent { event, window_id: RootWindowId(window_id), @@ -44,7 +44,7 @@ impl EventSink { } #[inline] - pub fn drain(&mut self) -> Drain<'_, Event<'static, ()>> { + pub fn drain(&mut self) -> Drain<'_, Event<()>> { self.window_events.drain(..) } } diff --git a/src/platform_impl/linux/x11/event_processor.rs b/src/platform_impl/linux/x11/event_processor.rs index e2cee68ff37..e6a28f83920 100644 --- a/src/platform_impl/linux/x11/event_processor.rs +++ b/src/platform_impl/linux/x11/event_processor.rs @@ -4,7 +4,7 @@ use std::{ os::raw::{c_char, c_int, c_long, c_ulong}, rc::Rc, slice, - sync::Arc, + sync::{Arc, Mutex}, }; use x11rb::protocol::xproto::{self, ConnectionExt as _}; @@ -126,7 +126,7 @@ impl EventProcessor { pub(super) fn process_event(&mut self, xev: &mut ffi::XEvent, mut callback: F) where - F: FnMut(Event<'_, T>), + F: FnMut(Event), { let wt = get_xtarget(&self.target); let atoms = wt.x_connection().atoms(); @@ -437,19 +437,23 @@ impl EventProcessor { ); let old_inner_size = PhysicalSize::new(width, height); - let mut new_inner_size = PhysicalSize::new(new_width, new_height); + let new_inner_size = PhysicalSize::new(new_width, new_height); // Unlock shared state to prevent deadlock in callback below drop(shared_state_lock); + let inner_size = Arc::new(Mutex::new(new_inner_size)); callback(Event::WindowEvent { window_id, event: WindowEvent::ScaleFactorChanged { scale_factor: new_scale_factor, - new_inner_size: &mut new_inner_size, + new_inner_size: Arc::downgrade(&inner_size), }, }); + let new_inner_size = *inner_size.lock().unwrap(); + drop(inner_size); + if new_inner_size != old_inner_size { window.request_inner_size_physical( new_inner_size.width, @@ -1308,17 +1312,20 @@ impl EventProcessor { let window_id = crate::window::WindowId(*window_id); let old_inner_size = PhysicalSize::new(width, height); - let mut new_inner_size = - PhysicalSize::new(new_width, new_height); - + let inner_size = Arc::new(Mutex::new( + PhysicalSize::new(new_width, new_height), + )); callback(Event::WindowEvent { window_id, event: WindowEvent::ScaleFactorChanged { scale_factor: new_monitor.scale_factor, - new_inner_size: &mut new_inner_size, + new_inner_size: Arc::downgrade(&inner_size), }, }); + let new_inner_size = *inner_size.lock().unwrap(); + drop(inner_size); + if new_inner_size != old_inner_size { let (new_width, new_height) = new_inner_size.into(); window.request_inner_size_physical( @@ -1400,7 +1407,7 @@ impl EventProcessor { kb_state: &mut KbdState, callback: &mut F, ) where - F: FnMut(Event<'_, T>), + F: FnMut(Event), { let device_id = mkdid(util::VIRTUAL_CORE_KEYBOARD.into()); diff --git a/src/platform_impl/linux/x11/mod.rs b/src/platform_impl/linux/x11/mod.rs index be7c442f860..d3058c32a1a 100644 --- a/src/platform_impl/linux/x11/mod.rs +++ b/src/platform_impl/linux/x11/mod.rs @@ -434,7 +434,7 @@ impl EventLoop { pub fn run_ondemand(&mut self, mut event_handler: F) -> Result<(), RunLoopError> where - F: FnMut(Event<'_, T>, &RootELW, &mut ControlFlow), + F: FnMut(Event, &RootELW, &mut ControlFlow), { if self.loop_running { return Err(RunLoopError::AlreadyRunning); @@ -468,7 +468,7 @@ impl EventLoop { pub fn pump_events(&mut self, timeout: Option, mut callback: F) -> PumpStatus where - F: FnMut(Event<'_, T>, &RootELW, &mut ControlFlow), + F: FnMut(Event, &RootELW, &mut ControlFlow), { if !self.loop_running { self.loop_running = true; @@ -512,7 +512,7 @@ impl EventLoop { pub fn poll_events_with_timeout(&mut self, mut timeout: Option, mut callback: F) where - F: FnMut(Event<'_, T>, &RootELW, &mut ControlFlow), + F: FnMut(Event, &RootELW, &mut ControlFlow), { let start = Instant::now(); @@ -595,7 +595,7 @@ impl EventLoop { fn single_iteration(&mut self, callback: &mut F, cause: StartCause) where - F: FnMut(Event<'_, T>, &RootELW, &mut ControlFlow), + F: FnMut(Event, &RootELW, &mut ControlFlow), { let mut control_flow = self.control_flow; @@ -701,7 +701,7 @@ impl EventLoop { fn drain_events(&mut self, callback: &mut F, control_flow: &mut ControlFlow) where - F: FnMut(Event<'_, T>, &RootELW, &mut ControlFlow), + F: FnMut(Event, &RootELW, &mut ControlFlow), { let target = &self.target; let mut xev = MaybeUninit::uninit(); diff --git a/src/platform_impl/macos/app_state.rs b/src/platform_impl/macos/app_state.rs index 18f727314a7..8069f756058 100644 --- a/src/platform_impl/macos/app_state.rs +++ b/src/platform_impl/macos/app_state.rs @@ -6,7 +6,7 @@ use std::{ rc::{Rc, Weak}, sync::{ atomic::{AtomicBool, Ordering}, - Mutex, MutexGuard, + Arc, Mutex, MutexGuard, }, time::Instant, }; @@ -34,8 +34,8 @@ use crate::{ static HANDLER: Lazy = Lazy::new(Default::default); -impl<'a, Never> Event<'a, Never> { - fn userify(self) -> Event<'a, T> { +impl Event { + fn userify(self) -> Event { self.map_nonuser_event() // `Never` can't be constructed, so the `UserEvent` variant can't // be present here. @@ -45,12 +45,11 @@ impl<'a, Never> Event<'a, Never> { pub trait EventHandler: Debug { // Not sure probably it should accept Event<'static, Never> - fn handle_nonuser_event(&mut self, event: Event<'_, Never>, control_flow: &mut ControlFlow); + fn handle_nonuser_event(&mut self, event: Event, control_flow: &mut ControlFlow); fn handle_user_events(&mut self, control_flow: &mut ControlFlow); } -pub(crate) type Callback = - RefCell, &RootWindowTarget, &mut ControlFlow)>; +pub(crate) type Callback = RefCell, &RootWindowTarget, &mut ControlFlow)>; struct EventLoopHandler { callback: Weak>, @@ -62,7 +61,7 @@ impl EventLoopHandler { where F: FnOnce( &mut EventLoopHandler, - RefMut<'_, dyn FnMut(Event<'_, T>, &RootWindowTarget, &mut ControlFlow)>, + RefMut<'_, dyn FnMut(Event, &RootWindowTarget, &mut ControlFlow)>, ), { // The `NSApp` and our `HANDLER` are global state and so it's possible that @@ -90,7 +89,7 @@ impl Debug for EventLoopHandler { } impl EventHandler for EventLoopHandler { - fn handle_nonuser_event(&mut self, event: Event<'_, Never>, control_flow: &mut ControlFlow) { + fn handle_nonuser_event(&mut self, event: Event, control_flow: &mut ControlFlow) { self.with_callback(|this, mut callback| { if let ControlFlow::ExitWithCode(code) = *control_flow { // XXX: why isn't event dispatching simply skipped after control_flow = ExitWithCode? @@ -338,19 +337,19 @@ impl Handler { suggested_size: LogicalSize, scale_factor: f64, ) { - let mut size = suggested_size.to_physical(scale_factor); - let new_inner_size = &mut size; + let new_inner_size = Arc::new(Mutex::new(suggested_size.to_physical(scale_factor))); let event = Event::WindowEvent { window_id: WindowId(window.id()), event: WindowEvent::ScaleFactorChanged { scale_factor, - new_inner_size, + new_inner_size: Arc::downgrade(&new_inner_size), }, }; callback.handle_nonuser_event(event, &mut self.control_flow.lock().unwrap()); - let physical_size = *new_inner_size; + let physical_size = *new_inner_size.lock().unwrap(); + drop(new_inner_size); let logical_size = physical_size.to_logical(scale_factor); let size = NSSize::new(logical_size.width, logical_size.height); window.setContentSize(size); diff --git a/src/platform_impl/macos/event.rs b/src/platform_impl/macos/event.rs index 785647e3f25..c67d7d90e1f 100644 --- a/src/platform_impl/macos/event.rs +++ b/src/platform_impl/macos/event.rs @@ -24,7 +24,7 @@ use crate::{ #[derive(Debug)] pub(crate) enum EventWrapper { - StaticEvent(Event<'static, Never>), + StaticEvent(Event), EventProxy(EventProxy), } diff --git a/src/platform_impl/macos/event_loop.rs b/src/platform_impl/macos/event_loop.rs index 176c90e759b..4721bfd41e3 100644 --- a/src/platform_impl/macos/event_loop.rs +++ b/src/platform_impl/macos/event_loop.rs @@ -195,7 +195,7 @@ impl EventLoop { pub fn run(mut self, callback: F) -> Result<(), RunLoopError> where - F: 'static + FnMut(Event<'_, T>, &RootWindowTarget, &mut ControlFlow), + F: 'static + FnMut(Event, &RootWindowTarget, &mut ControlFlow), { self.run_ondemand(callback) } @@ -206,7 +206,7 @@ impl EventLoop { // redundant wake ups. pub fn run_ondemand(&mut self, callback: F) -> Result<(), RunLoopError> where - F: FnMut(Event<'_, T>, &RootWindowTarget, &mut ControlFlow), + F: FnMut(Event, &RootWindowTarget, &mut ControlFlow), { if AppState::is_running() { return Err(RunLoopError::AlreadyRunning); @@ -223,8 +223,8 @@ impl EventLoop { let callback = unsafe { mem::transmute::< - Rc, &RootWindowTarget, &mut ControlFlow)>>, - Rc, &RootWindowTarget, &mut ControlFlow)>>, + Rc, &RootWindowTarget, &mut ControlFlow)>>, + Rc, &RootWindowTarget, &mut ControlFlow)>>, >(Rc::new(RefCell::new(callback))) }; @@ -293,7 +293,7 @@ impl EventLoop { pub fn pump_events(&mut self, timeout: Option, callback: F) -> PumpStatus where - F: FnMut(Event<'_, T>, &RootWindowTarget, &mut ControlFlow), + F: FnMut(Event, &RootWindowTarget, &mut ControlFlow), { // # Safety // We are erasing the lifetime of the application callback here so that we @@ -306,8 +306,8 @@ impl EventLoop { let callback = unsafe { mem::transmute::< - Rc, &RootWindowTarget, &mut ControlFlow)>>, - Rc, &RootWindowTarget, &mut ControlFlow)>>, + Rc, &RootWindowTarget, &mut ControlFlow)>>, + Rc, &RootWindowTarget, &mut ControlFlow)>>, >(Rc::new(RefCell::new(callback))) }; diff --git a/src/platform_impl/macos/view.rs b/src/platform_impl/macos/view.rs index d1fd18ce158..ac2da0f46ef 100644 --- a/src/platform_impl/macos/view.rs +++ b/src/platform_impl/macos/view.rs @@ -817,7 +817,7 @@ impl WinitView { WindowId(self.window().id()) } - fn queue_event(&self, event: WindowEvent<'static>) { + fn queue_event(&self, event: WindowEvent) { let event = Event::WindowEvent { window_id: self.window_id(), event, diff --git a/src/platform_impl/macos/window_delegate.rs b/src/platform_impl/macos/window_delegate.rs index 0b50de82983..024979d8c20 100644 --- a/src/platform_impl/macos/window_delegate.rs +++ b/src/platform_impl/macos/window_delegate.rs @@ -438,7 +438,7 @@ impl WinitWindowDelegate { } } - pub(crate) fn queue_event(&self, event: WindowEvent<'static>) { + pub(crate) fn queue_event(&self, event: WindowEvent) { let event = Event::WindowEvent { window_id: WindowId(self.window.id()), event, diff --git a/src/platform_impl/web/event_loop/mod.rs b/src/platform_impl/web/event_loop/mod.rs index 1dcee878402..4ed003679a6 100644 --- a/src/platform_impl/web/event_loop/mod.rs +++ b/src/platform_impl/web/event_loop/mod.rs @@ -31,7 +31,7 @@ impl EventLoop { pub fn run(self, event_handler: F) -> ! where - F: 'static + FnMut(Event<'_, T>, &RootEventLoopWindowTarget, &mut ControlFlow), + F: 'static + FnMut(Event, &RootEventLoopWindowTarget, &mut ControlFlow), { self.spawn_inner(event_handler, false); @@ -46,14 +46,14 @@ impl EventLoop { pub fn spawn(self, event_handler: F) where - F: 'static + FnMut(Event<'_, T>, &RootEventLoopWindowTarget, &mut ControlFlow), + F: 'static + FnMut(Event, &RootEventLoopWindowTarget, &mut ControlFlow), { self.spawn_inner(event_handler, true); } fn spawn_inner(self, mut event_handler: F, event_loop_recreation: bool) where - F: 'static + FnMut(Event<'_, T>, &RootEventLoopWindowTarget, &mut ControlFlow), + F: 'static + FnMut(Event, &RootEventLoopWindowTarget, &mut ControlFlow), { let target = RootEventLoopWindowTarget { p: self.elw.p.clone(), diff --git a/src/platform_impl/web/event_loop/runner.rs b/src/platform_impl/web/event_loop/runner.rs index dd71a325b15..27faef0ed6b 100644 --- a/src/platform_impl/web/event_loop/runner.rs +++ b/src/platform_impl/web/event_loop/runner.rs @@ -24,7 +24,7 @@ use web_time::{Duration, Instant}; pub struct Shared(Rc>); -pub(super) type EventHandler = dyn FnMut(Event<'_, T>, &mut ControlFlow); +pub(super) type EventHandler = dyn FnMut(Event, &mut ControlFlow); impl Clone for Shared { fn clone(&self) -> Self { @@ -748,7 +748,7 @@ impl Shared { } pub(crate) enum EventWrapper { - Event(Event<'static, T>), + Event(Event), ScaleChange { canvas: Weak>, size: PhysicalSize, @@ -756,8 +756,8 @@ pub(crate) enum EventWrapper { }, } -impl From> for EventWrapper { - fn from(value: Event<'static, T>) -> Self { +impl From> for EventWrapper { + fn from(value: Event) -> Self { Self::Event(value) } } diff --git a/src/platform_impl/web/mod.rs b/src/platform_impl/web/mod.rs index dc178179b4a..3abd2684144 100644 --- a/src/platform_impl/web/mod.rs +++ b/src/platform_impl/web/mod.rs @@ -38,4 +38,4 @@ pub use self::window::{PlatformSpecificWindowBuilderAttributes, Window, WindowId pub(crate) use self::keyboard::KeyEventExtra; pub(crate) use crate::icon::NoIcon as PlatformIcon; -pub(self) use crate::platform_impl::Fullscreen; +pub(crate) use crate::platform_impl::Fullscreen; diff --git a/src/platform_impl/web/web_sys/canvas.rs b/src/platform_impl/web/web_sys/canvas.rs index 0c42c59b8d0..729475726c1 100644 --- a/src/platform_impl/web/web_sys/canvas.rs +++ b/src/platform_impl/web/web_sys/canvas.rs @@ -14,7 +14,7 @@ use crate::window::{WindowAttributes, WindowId as RootWindowId}; use std::cell::{Cell, RefCell}; use std::rc::Rc; use std::sync::atomic::AtomicBool; -use std::sync::Arc; +use std::sync::{Arc, Mutex}; use js_sys::Promise; use smol_str::SmolStr; @@ -451,20 +451,25 @@ impl Canvas { pub(crate) fn handle_scale_change( &self, runner: &super::super::event_loop::runner::Shared, - event_handler: impl FnOnce(crate::event::Event<'_, T>), + event_handler: impl FnOnce(crate::event::Event), current_size: PhysicalSize, scale: f64, ) { // First, we send the `ScaleFactorChanged` event: self.set_current_size(current_size); - let mut new_size = current_size; - event_handler(crate::event::Event::WindowEvent { - window_id: RootWindowId(self.id), - event: crate::event::WindowEvent::ScaleFactorChanged { - scale_factor: scale, - new_inner_size: &mut new_size, - }, - }); + let new_size = { + let new_size = Arc::new(Mutex::new(current_size)); + event_handler(crate::event::Event::WindowEvent { + window_id: RootWindowId(self.id), + event: crate::event::WindowEvent::ScaleFactorChanged { + scale_factor: scale, + new_inner_size: Arc::downgrade(&new_size), + }, + }); + + let new_size = *new_size.lock().unwrap(); + new_size + }; if current_size != new_size { // Then we resize the canvas to the new size, a new diff --git a/src/platform_impl/windows/drop_handler.rs b/src/platform_impl/windows/drop_handler.rs index 5de7cd0c7fc..84bebbd1076 100644 --- a/src/platform_impl/windows/drop_handler.rs +++ b/src/platform_impl/windows/drop_handler.rs @@ -30,7 +30,7 @@ pub struct FileDropHandlerData { pub interface: IDropTarget, refcount: AtomicUsize, window: HWND, - send_event: Box)>, + send_event: Box)>, cursor_effect: u32, hovered_is_valid: bool, /* If the currently hovered item is not valid there must not be any `HoveredFileCancelled` emitted */ } @@ -41,7 +41,7 @@ pub struct FileDropHandler { #[allow(non_snake_case)] impl FileDropHandler { - pub fn new(window: HWND, send_event: Box)>) -> FileDropHandler { + pub fn new(window: HWND, send_event: Box)>) -> FileDropHandler { let data = Box::new(FileDropHandlerData { interface: IDropTarget { lpVtbl: &DROP_TARGET_VTBL as *const IDropTargetVtbl, @@ -211,7 +211,7 @@ impl FileDropHandler { } impl FileDropHandlerData { - fn send_event(&self, event: Event<'static, ()>) { + fn send_event(&self, event: Event<()>) { (self.send_event)(event); } } diff --git a/src/platform_impl/windows/event_loop.rs b/src/platform_impl/windows/event_loop.rs index 2b0de9236f4..d5811eca2d9 100644 --- a/src/platform_impl/windows/event_loop.rs +++ b/src/platform_impl/windows/event_loop.rs @@ -142,7 +142,7 @@ pub(crate) struct WindowData { } impl WindowData { - unsafe fn send_event(&self, event: Event<'_, T>) { + unsafe fn send_event(&self, event: Event) { self.event_loop_runner.send_event(event); } @@ -157,7 +157,7 @@ struct ThreadMsgTargetData { } impl ThreadMsgTargetData { - unsafe fn send_event(&self, event: Event<'_, T>) { + unsafe fn send_event(&self, event: Event) { self.event_loop_runner.send_event(event); } } @@ -245,14 +245,14 @@ impl EventLoop { pub fn run(mut self, event_handler: F) -> Result<(), RunLoopError> where - F: 'static + FnMut(Event<'_, T>, &RootELW, &mut ControlFlow), + F: 'static + FnMut(Event, &RootELW, &mut ControlFlow), { self.run_ondemand(event_handler) } pub fn run_ondemand(&mut self, mut event_handler: F) -> Result<(), RunLoopError> where - F: FnMut(Event<'_, T>, &RootELW, &mut ControlFlow), + F: FnMut(Event, &RootELW, &mut ControlFlow), { { let runner = &self.window_target.p.runner_shared; @@ -298,7 +298,7 @@ impl EventLoop { pub fn pump_events(&mut self, timeout: Option, mut event_handler: F) -> PumpStatus where - F: FnMut(Event<'_, T>, &RootELW, &mut ControlFlow), + F: FnMut(Event, &RootELW, &mut ControlFlow), { { let runner = &self.window_target.p.runner_shared; @@ -2051,7 +2051,7 @@ unsafe fn public_window_callback_inner( // `allow_resize` prevents us from re-applying DPI adjustment to the restored size after // exiting fullscreen (the restored size is already DPI adjusted). - let mut new_physical_inner_size = match allow_resize { + let new_physical_inner_size = match allow_resize { // We calculate our own size because the default suggested rect doesn't do a great job // of preserving the window's logical size. true => old_physical_inner_size @@ -2060,14 +2060,18 @@ unsafe fn public_window_callback_inner( false => old_physical_inner_size, }; + let new_inner_size = Arc::new(Mutex::new(new_physical_inner_size)); userdata.send_event(Event::WindowEvent { window_id: RootWindowId(WindowId(window)), event: ScaleFactorChanged { scale_factor: new_scale_factor, - new_inner_size: &mut new_physical_inner_size, + new_inner_size: Arc::downgrade(&new_inner_size), }, }); + let new_physical_inner_size = *new_inner_size.lock().unwrap(); + drop(new_inner_size); + let dragging_window: bool; { diff --git a/src/platform_impl/windows/event_loop/runner.rs b/src/platform_impl/windows/event_loop/runner.rs index c39b3f70045..a46bdbcd368 100644 --- a/src/platform_impl/windows/event_loop/runner.rs +++ b/src/platform_impl/windows/event_loop/runner.rs @@ -4,6 +4,7 @@ use std::{ collections::VecDeque, mem, panic, rc::Rc, + sync::{Arc, Mutex}, time::Instant, }; @@ -22,7 +23,7 @@ use crate::{ pub(crate) type EventLoopRunnerShared = Rc>; -type EventHandler = Cell, &mut ControlFlow)>>>; +type EventHandler = Cell, &mut ControlFlow)>>>; pub(crate) struct EventLoopRunner { // The event loop's win32 handles @@ -59,7 +60,7 @@ pub(crate) enum RunnerState { } enum BufferedEvent { - Event(Event<'static, T>), + Event(Event), ScaleFactorChanged(WindowId, f64, PhysicalSize), } @@ -90,11 +91,11 @@ impl EventLoopRunner { /// undefined behaviour. pub(crate) unsafe fn set_event_handler(&self, f: F) where - F: FnMut(Event<'_, T>, &mut ControlFlow), + F: FnMut(Event, &mut ControlFlow), { let old_event_handler = self.event_handler.replace(mem::transmute::< - Option, &mut ControlFlow)>>, - Option, &mut ControlFlow)>>, + Option, &mut ControlFlow)>>, + Option, &mut ControlFlow)>>, >(Some(Box::new(f)))); assert!(old_event_handler.is_none()); } @@ -196,7 +197,7 @@ impl EventLoopRunner { self.move_state_to(RunnerState::HandlingMainEvents); } - pub(crate) fn send_event(&self, event: Event<'_, T>) { + pub(crate) fn send_event(&self, event: Event) { if let Event::RedrawRequested(_) = event { self.call_event_handler(event); // As a rule, to ensure that `pump_events` can't block an external event loop @@ -219,7 +220,7 @@ impl EventLoopRunner { self.move_state_to(RunnerState::Destroyed); } - fn call_event_handler(&self, event: Event<'_, T>) { + fn call_event_handler(&self, event: Event) { self.catch_unwind(|| { let mut control_flow = self.control_flow.take(); let mut event_handler = self.event_handler.take() @@ -364,7 +365,7 @@ impl EventLoopRunner { } impl BufferedEvent { - pub fn from_event(event: Event<'_, T>) -> BufferedEvent { + pub fn from_event(event: Event) -> BufferedEvent { match event { Event::WindowEvent { event: @@ -373,29 +374,36 @@ impl BufferedEvent { new_inner_size, }, window_id, - } => BufferedEvent::ScaleFactorChanged(window_id, scale_factor, *new_inner_size), - event => BufferedEvent::Event(event.to_static().unwrap()), + } => BufferedEvent::ScaleFactorChanged( + window_id, + scale_factor, + *new_inner_size.upgrade().unwrap().lock().unwrap(), + ), + event => BufferedEvent::Event(event), } } - pub fn dispatch_event(self, dispatch: impl FnOnce(Event<'_, T>)) { + pub fn dispatch_event(self, dispatch: impl FnOnce(Event)) { match self { Self::Event(event) => dispatch(event), - Self::ScaleFactorChanged(window_id, scale_factor, mut new_inner_size) => { + Self::ScaleFactorChanged(window_id, scale_factor, new_inner_size) => { + let new_inner_size = Arc::new(Mutex::new(new_inner_size)); dispatch(Event::WindowEvent { window_id, event: WindowEvent::ScaleFactorChanged { scale_factor, - new_inner_size: &mut new_inner_size, + new_inner_size: Arc::downgrade(&new_inner_size), }, }); + let inner_size = *new_inner_size.lock().unwrap(); + drop(new_inner_size); let window_flags = unsafe { let userdata = 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, new_inner_size); + window_flags.set_size((window_id.0).0, inner_size); } } }