mirror of
https://github.com/italicsjenga/winit-sonoma-fix.git
synced 2024-12-23 22:01:31 +11:00
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 `InnerSizeWriter` fences passed to client, so they could try to update the size. Fixes #1387.
This commit is contained in:
parent
2b2dd6b65d
commit
9ac3259a79
|
@ -9,6 +9,8 @@ And please only add new entries to the top of this list, right below the `# Unre
|
||||||
# Unreleased
|
# Unreleased
|
||||||
|
|
||||||
- On Windows, added `WindowBuilderExtWindows::with_class_name` to customize the internal class name.
|
- On Windows, added `WindowBuilderExtWindows::with_class_name` to customize the internal class name.
|
||||||
|
- **Breaking:** Remove lifetime parameter from `Event` and `WindowEvent`.
|
||||||
|
- **Breaking:** `ScaleFactorChanged` now contains a writer instead of a reference to update inner size.
|
||||||
- On iOS, always wake the event loop when transitioning from `ControlFlow::Poll` to `ControlFlow::Poll`.
|
- On iOS, always wake the event loop when transitioning from `ControlFlow::Poll` to `ControlFlow::Poll`.
|
||||||
- **Breaking:** `ActivationTokenDone` event which could be requested with the new `startup_notify` module, see its docs for more.
|
- **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 Wayland, make double clicking and moving the CSD frame more reliable.
|
||||||
|
|
|
@ -46,7 +46,7 @@ fn main() -> Result<(), impl std::error::Error> {
|
||||||
|
|
||||||
println!("parent window: {parent_window:?})");
|
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;
|
*control_flow = ControlFlow::Wait;
|
||||||
|
|
||||||
if let Event::WindowEvent { event, window_id } = event {
|
if let Event::WindowEvent { event, window_id } = event {
|
||||||
|
|
|
@ -195,11 +195,9 @@ fn main() -> Result<(), impl std::error::Error> {
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
if let Some(tx) = window_senders.get(&window_id) {
|
if let Some(tx) = window_senders.get(&window_id) {
|
||||||
if let Some(event) = event.to_static() {
|
|
||||||
tx.send(event).unwrap();
|
tx.send(event).unwrap();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
},
|
},
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,8 @@ use crate::platform_impl;
|
||||||
pub enum ExternalError {
|
pub enum ExternalError {
|
||||||
/// The operation is not supported by the backend.
|
/// The operation is not supported by the backend.
|
||||||
NotSupported(NotSupportedError),
|
NotSupported(NotSupportedError),
|
||||||
|
/// The operation was ignored.
|
||||||
|
Ignored,
|
||||||
/// The OS cannot perform the operation.
|
/// The OS cannot perform the operation.
|
||||||
Os(OsError),
|
Os(OsError),
|
||||||
}
|
}
|
||||||
|
@ -74,6 +76,7 @@ impl fmt::Display for ExternalError {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
|
||||||
match self {
|
match self {
|
||||||
ExternalError::NotSupported(e) => e.fmt(f),
|
ExternalError::NotSupported(e) => e.fmt(f),
|
||||||
|
ExternalError::Ignored => write!(f, "Operation was ignored"),
|
||||||
ExternalError::Os(e) => e.fmt(f),
|
ExternalError::Os(e) => e.fmt(f),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
302
src/event.rs
302
src/event.rs
|
@ -33,13 +33,16 @@
|
||||||
//!
|
//!
|
||||||
//! [`EventLoop::run(...)`]: crate::event_loop::EventLoop::run
|
//! [`EventLoop::run(...)`]: crate::event_loop::EventLoop::run
|
||||||
//! [`ControlFlow::WaitUntil`]: crate::event_loop::ControlFlow::WaitUntil
|
//! [`ControlFlow::WaitUntil`]: crate::event_loop::ControlFlow::WaitUntil
|
||||||
use smol_str::SmolStr;
|
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
use std::sync::{Mutex, Weak};
|
||||||
#[cfg(not(wasm_platform))]
|
#[cfg(not(wasm_platform))]
|
||||||
use std::time::Instant;
|
use std::time::Instant;
|
||||||
|
|
||||||
|
use smol_str::SmolStr;
|
||||||
#[cfg(wasm_platform)]
|
#[cfg(wasm_platform)]
|
||||||
use web_time::Instant;
|
use web_time::Instant;
|
||||||
|
|
||||||
|
use crate::error::ExternalError;
|
||||||
#[cfg(doc)]
|
#[cfg(doc)]
|
||||||
use crate::window::Window;
|
use crate::window::Window;
|
||||||
use crate::{
|
use crate::{
|
||||||
|
@ -53,8 +56,8 @@ use crate::{
|
||||||
/// Describes a generic event.
|
/// Describes a generic event.
|
||||||
///
|
///
|
||||||
/// See the module-level docs for more information on the event loop manages each event.
|
/// See the module-level docs for more information on the event loop manages each event.
|
||||||
#[derive(Debug, PartialEq)]
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
pub enum Event<'a, T: 'static> {
|
pub enum Event<T: 'static> {
|
||||||
/// Emitted when new events arrive from the OS to be processed.
|
/// 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
|
/// This event type is useful as a place to put code that should be done before you start
|
||||||
|
@ -66,7 +69,7 @@ pub enum Event<'a, T: 'static> {
|
||||||
/// Emitted when the OS sends an event to a winit window.
|
/// Emitted when the OS sends an event to a winit window.
|
||||||
WindowEvent {
|
WindowEvent {
|
||||||
window_id: WindowId,
|
window_id: WindowId,
|
||||||
event: WindowEvent<'a>,
|
event: WindowEvent,
|
||||||
},
|
},
|
||||||
|
|
||||||
/// Emitted when the OS sends an event to a device.
|
/// Emitted when the OS sends an event to a device.
|
||||||
|
@ -237,32 +240,9 @@ pub enum Event<'a, T: 'static> {
|
||||||
LoopExiting,
|
LoopExiting,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Clone> Clone for Event<'static, T> {
|
impl<T> Event<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),
|
|
||||||
AboutToWait => AboutToWait,
|
|
||||||
RedrawRequested(wid) => RedrawRequested(*wid),
|
|
||||||
LoopExiting => LoopExiting,
|
|
||||||
Suspended => Suspended,
|
|
||||||
Resumed => Resumed,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a, T> Event<'a, T> {
|
|
||||||
#[allow(clippy::result_large_err)]
|
#[allow(clippy::result_large_err)]
|
||||||
pub fn map_nonuser_event<U>(self) -> Result<Event<'a, U>, Event<'a, T>> {
|
pub fn map_nonuser_event<U>(self) -> Result<Event<U>, Event<T>> {
|
||||||
use self::Event::*;
|
use self::Event::*;
|
||||||
match self {
|
match self {
|
||||||
UserEvent(_) => Err(self),
|
UserEvent(_) => Err(self),
|
||||||
|
@ -276,25 +256,6 @@ impl<'a, T> Event<'a, T> {
|
||||||
Resumed => Ok(Resumed),
|
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<Event<'static, T>> {
|
|
||||||
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)),
|
|
||||||
AboutToWait => Some(AboutToWait),
|
|
||||||
RedrawRequested(wid) => Some(RedrawRequested(wid)),
|
|
||||||
LoopExiting => Some(LoopExiting),
|
|
||||||
Suspended => Some(Suspended),
|
|
||||||
Resumed => Some(Resumed),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Describes the reason the event loop is resuming.
|
/// Describes the reason the event loop is resuming.
|
||||||
|
@ -328,8 +289,8 @@ pub enum StartCause {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Describes an event from a [`Window`].
|
/// Describes an event from a [`Window`].
|
||||||
#[derive(Debug, PartialEq)]
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
pub enum WindowEvent<'a> {
|
pub enum WindowEvent {
|
||||||
/// The activation token was delivered back and now could be used.
|
/// The activation token was delivered back and now could be used.
|
||||||
///
|
///
|
||||||
#[cfg_attr(
|
#[cfg_attr(
|
||||||
|
@ -563,7 +524,10 @@ pub enum WindowEvent<'a> {
|
||||||
/// For more information about DPI in general, see the [`dpi`](crate::dpi) module.
|
/// For more information about DPI in general, see the [`dpi`](crate::dpi) module.
|
||||||
ScaleFactorChanged {
|
ScaleFactorChanged {
|
||||||
scale_factor: f64,
|
scale_factor: f64,
|
||||||
new_inner_size: &'a mut PhysicalSize<u32>,
|
/// Handle to update inner size during scale changes.
|
||||||
|
///
|
||||||
|
/// See [`InnerSizeWriter`] docs for more details.
|
||||||
|
inner_size_writer: InnerSizeWriter,
|
||||||
},
|
},
|
||||||
|
|
||||||
/// The system window theme has changed.
|
/// The system window theme has changed.
|
||||||
|
@ -592,209 +556,6 @@ pub enum WindowEvent<'a> {
|
||||||
Occluded(bool),
|
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<WindowEvent<'static>> {
|
|
||||||
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.
|
/// Identifier of an input device.
|
||||||
///
|
///
|
||||||
/// Whenever you receive an event arising from a particular input device, this event contains a `DeviceId` which
|
/// Whenever you receive an event arising from a particular input device, this event contains a `DeviceId` which
|
||||||
|
@ -1301,3 +1062,36 @@ pub enum MouseScrollDelta {
|
||||||
/// and move the content right and down (to reveal more things left and up).
|
/// and move the content right and down (to reveal more things left and up).
|
||||||
PixelDelta(PhysicalPosition<f64>),
|
PixelDelta(PhysicalPosition<f64>),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Handle to synchroniously change the size of the window from the
|
||||||
|
/// [`WindowEvent`].
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub struct InnerSizeWriter {
|
||||||
|
pub(crate) new_inner_size: Weak<Mutex<PhysicalSize<u32>>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl InnerSizeWriter {
|
||||||
|
#[cfg(not(orbital_platform))]
|
||||||
|
pub(crate) fn new(new_inner_size: Weak<Mutex<PhysicalSize<u32>>>) -> Self {
|
||||||
|
Self { new_inner_size }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Try to request inner size which will be set synchroniously on the window.
|
||||||
|
pub fn request_inner_size(
|
||||||
|
&mut self,
|
||||||
|
new_inner_size: PhysicalSize<u32>,
|
||||||
|
) -> Result<(), ExternalError> {
|
||||||
|
if let Some(inner) = self.new_inner_size.upgrade() {
|
||||||
|
*inner.lock().unwrap() = new_inner_size;
|
||||||
|
Ok(())
|
||||||
|
} else {
|
||||||
|
Err(ExternalError::Ignored)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PartialEq for InnerSizeWriter {
|
||||||
|
fn eq(&self, other: &Self) -> bool {
|
||||||
|
self.new_inner_size.as_ptr() == other.new_inner_size.as_ptr()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -314,7 +314,7 @@ impl<T> EventLoop<T> {
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn run<F>(self, event_handler: F) -> Result<(), RunLoopError>
|
pub fn run<F>(self, event_handler: F) -> Result<(), RunLoopError>
|
||||||
where
|
where
|
||||||
F: 'static + FnMut(Event<'_, T>, &EventLoopWindowTarget<T>, &mut ControlFlow),
|
F: 'static + FnMut(Event<T>, &EventLoopWindowTarget<T>, &mut ControlFlow),
|
||||||
{
|
{
|
||||||
self.event_loop.run(event_handler)
|
self.event_loop.run(event_handler)
|
||||||
}
|
}
|
||||||
|
|
|
@ -174,11 +174,7 @@ pub trait EventLoopExtPumpEvents {
|
||||||
/// callback.
|
/// callback.
|
||||||
fn pump_events<F>(&mut self, timeout: Option<Duration>, event_handler: F) -> PumpStatus
|
fn pump_events<F>(&mut self, timeout: Option<Duration>, event_handler: F) -> PumpStatus
|
||||||
where
|
where
|
||||||
F: FnMut(
|
F: FnMut(Event<Self::UserEvent>, &EventLoopWindowTarget<Self::UserEvent>, &mut ControlFlow);
|
||||||
Event<'_, Self::UserEvent>,
|
|
||||||
&EventLoopWindowTarget<Self::UserEvent>,
|
|
||||||
&mut ControlFlow,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> EventLoopExtPumpEvents for EventLoop<T> {
|
impl<T> EventLoopExtPumpEvents for EventLoop<T> {
|
||||||
|
@ -186,11 +182,7 @@ impl<T> EventLoopExtPumpEvents for EventLoop<T> {
|
||||||
|
|
||||||
fn pump_events<F>(&mut self, timeout: Option<Duration>, event_handler: F) -> PumpStatus
|
fn pump_events<F>(&mut self, timeout: Option<Duration>, event_handler: F) -> PumpStatus
|
||||||
where
|
where
|
||||||
F: FnMut(
|
F: FnMut(Event<Self::UserEvent>, &EventLoopWindowTarget<Self::UserEvent>, &mut ControlFlow),
|
||||||
Event<'_, Self::UserEvent>,
|
|
||||||
&EventLoopWindowTarget<Self::UserEvent>,
|
|
||||||
&mut ControlFlow,
|
|
||||||
),
|
|
||||||
{
|
{
|
||||||
self.event_loop.pump_events(timeout, event_handler)
|
self.event_loop.pump_events(timeout, event_handler)
|
||||||
}
|
}
|
||||||
|
|
|
@ -59,11 +59,7 @@ pub trait EventLoopExtRunOnDemand {
|
||||||
/// - **iOS:** It's not possible to stop and start an `NSApplication` repeatedly on iOS.
|
/// - **iOS:** It's not possible to stop and start an `NSApplication` repeatedly on iOS.
|
||||||
fn run_ondemand<F>(&mut self, event_handler: F) -> Result<(), RunLoopError>
|
fn run_ondemand<F>(&mut self, event_handler: F) -> Result<(), RunLoopError>
|
||||||
where
|
where
|
||||||
F: FnMut(
|
F: FnMut(Event<Self::UserEvent>, &EventLoopWindowTarget<Self::UserEvent>, &mut ControlFlow);
|
||||||
Event<'_, Self::UserEvent>,
|
|
||||||
&EventLoopWindowTarget<Self::UserEvent>,
|
|
||||||
&mut ControlFlow,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> EventLoopExtRunOnDemand for EventLoop<T> {
|
impl<T> EventLoopExtRunOnDemand for EventLoop<T> {
|
||||||
|
@ -71,11 +67,7 @@ impl<T> EventLoopExtRunOnDemand for EventLoop<T> {
|
||||||
|
|
||||||
fn run_ondemand<F>(&mut self, event_handler: F) -> Result<(), RunLoopError>
|
fn run_ondemand<F>(&mut self, event_handler: F) -> Result<(), RunLoopError>
|
||||||
where
|
where
|
||||||
F: FnMut(
|
F: FnMut(Event<Self::UserEvent>, &EventLoopWindowTarget<Self::UserEvent>, &mut ControlFlow),
|
||||||
Event<'_, Self::UserEvent>,
|
|
||||||
&EventLoopWindowTarget<Self::UserEvent>,
|
|
||||||
&mut ControlFlow,
|
|
||||||
),
|
|
||||||
{
|
{
|
||||||
self.event_loop.run_ondemand(event_handler)
|
self.event_loop.run_ondemand(event_handler)
|
||||||
}
|
}
|
||||||
|
|
|
@ -116,11 +116,7 @@ pub trait EventLoopExtWebSys {
|
||||||
fn spawn<F>(self, event_handler: F)
|
fn spawn<F>(self, event_handler: F)
|
||||||
where
|
where
|
||||||
F: 'static
|
F: 'static
|
||||||
+ FnMut(
|
+ FnMut(Event<Self::UserEvent>, &EventLoopWindowTarget<Self::UserEvent>, &mut ControlFlow);
|
||||||
Event<'_, Self::UserEvent>,
|
|
||||||
&EventLoopWindowTarget<Self::UserEvent>,
|
|
||||||
&mut ControlFlow,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> EventLoopExtWebSys for EventLoop<T> {
|
impl<T> EventLoopExtWebSys for EventLoop<T> {
|
||||||
|
@ -129,11 +125,7 @@ impl<T> EventLoopExtWebSys for EventLoop<T> {
|
||||||
fn spawn<F>(self, event_handler: F)
|
fn spawn<F>(self, event_handler: F)
|
||||||
where
|
where
|
||||||
F: 'static
|
F: 'static
|
||||||
+ FnMut(
|
+ FnMut(Event<Self::UserEvent>, &EventLoopWindowTarget<Self::UserEvent>, &mut ControlFlow),
|
||||||
Event<'_, Self::UserEvent>,
|
|
||||||
&EventLoopWindowTarget<Self::UserEvent>,
|
|
||||||
&mut ControlFlow,
|
|
||||||
),
|
|
||||||
{
|
{
|
||||||
self.event_loop.spawn(event_handler)
|
self.event_loop.spawn(event_handler)
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@ use std::{
|
||||||
hash::Hash,
|
hash::Hash,
|
||||||
sync::{
|
sync::{
|
||||||
atomic::{AtomicBool, Ordering},
|
atomic::{AtomicBool, Ordering},
|
||||||
mpsc, Arc, RwLock,
|
mpsc, Arc, Mutex, RwLock,
|
||||||
},
|
},
|
||||||
time::{Duration, Instant},
|
time::{Duration, Instant},
|
||||||
};
|
};
|
||||||
|
@ -22,7 +22,7 @@ use raw_window_handle::{
|
||||||
use crate::{
|
use crate::{
|
||||||
dpi::{PhysicalPosition, PhysicalSize, Position, Size},
|
dpi::{PhysicalPosition, PhysicalSize, Position, Size},
|
||||||
error,
|
error,
|
||||||
event::{self, StartCause},
|
event::{self, InnerSizeWriter, StartCause},
|
||||||
event_loop::{self, ControlFlow, EventLoopWindowTarget as RootELW},
|
event_loop::{self, ControlFlow, EventLoopWindowTarget as RootELW},
|
||||||
keyboard::NativeKey,
|
keyboard::NativeKey,
|
||||||
platform::pump_events::PumpStatus,
|
platform::pump_events::PumpStatus,
|
||||||
|
@ -169,12 +169,12 @@ impl Default for PlatformSpecificEventLoopAttributes {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn sticky_exit_callback<T, F>(
|
fn sticky_exit_callback<T, F>(
|
||||||
evt: event::Event<'_, T>,
|
evt: event::Event<T>,
|
||||||
target: &RootELW<T>,
|
target: &RootELW<T>,
|
||||||
control_flow: &mut ControlFlow,
|
control_flow: &mut ControlFlow,
|
||||||
callback: &mut F,
|
callback: &mut F,
|
||||||
) where
|
) where
|
||||||
F: FnMut(event::Event<'_, T>, &RootELW<T>, &mut ControlFlow),
|
F: FnMut(event::Event<T>, &RootELW<T>, &mut ControlFlow),
|
||||||
{
|
{
|
||||||
// make ControlFlow::ExitWithCode sticky by providing a dummy
|
// make ControlFlow::ExitWithCode sticky by providing a dummy
|
||||||
// control flow reference if it is already ExitWithCode.
|
// control flow reference if it is already ExitWithCode.
|
||||||
|
@ -219,7 +219,7 @@ impl<T: 'static> EventLoop<T> {
|
||||||
|
|
||||||
fn single_iteration<F>(&mut self, main_event: Option<MainEvent<'_>>, callback: &mut F)
|
fn single_iteration<F>(&mut self, main_event: Option<MainEvent<'_>>, callback: &mut F)
|
||||||
where
|
where
|
||||||
F: FnMut(event::Event<'_, T>, &RootELW<T>, &mut ControlFlow),
|
F: FnMut(event::Event<T>, &RootELW<T>, &mut ControlFlow),
|
||||||
{
|
{
|
||||||
trace!("Mainloop iteration");
|
trace!("Mainloop iteration");
|
||||||
|
|
||||||
|
@ -289,11 +289,15 @@ impl<T: 'static> EventLoop<T> {
|
||||||
let old_scale_factor = monitor.scale_factor();
|
let old_scale_factor = monitor.scale_factor();
|
||||||
let scale_factor = monitor.scale_factor();
|
let scale_factor = monitor.scale_factor();
|
||||||
if (scale_factor - old_scale_factor).abs() < f64::EPSILON {
|
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 {
|
let event = event::Event::WindowEvent {
|
||||||
window_id: window::WindowId(WindowId),
|
window_id: window::WindowId(WindowId),
|
||||||
event: event::WindowEvent::ScaleFactorChanged {
|
event: event::WindowEvent::ScaleFactorChanged {
|
||||||
new_inner_size: &mut size,
|
inner_size_writer: InnerSizeWriter::new(Arc::downgrade(
|
||||||
|
&new_inner_size,
|
||||||
|
)),
|
||||||
scale_factor,
|
scale_factor,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
@ -523,14 +527,14 @@ impl<T: 'static> EventLoop<T> {
|
||||||
pub fn run<F>(mut self, event_handler: F) -> Result<(), RunLoopError>
|
pub fn run<F>(mut self, event_handler: F) -> Result<(), RunLoopError>
|
||||||
where
|
where
|
||||||
F: 'static
|
F: 'static
|
||||||
+ FnMut(event::Event<'_, T>, &event_loop::EventLoopWindowTarget<T>, &mut ControlFlow),
|
+ FnMut(event::Event<T>, &event_loop::EventLoopWindowTarget<T>, &mut ControlFlow),
|
||||||
{
|
{
|
||||||
self.run_ondemand(event_handler)
|
self.run_ondemand(event_handler)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn run_ondemand<F>(&mut self, mut event_handler: F) -> Result<(), RunLoopError>
|
pub fn run_ondemand<F>(&mut self, mut event_handler: F) -> Result<(), RunLoopError>
|
||||||
where
|
where
|
||||||
F: FnMut(event::Event<'_, T>, &event_loop::EventLoopWindowTarget<T>, &mut ControlFlow),
|
F: FnMut(event::Event<T>, &event_loop::EventLoopWindowTarget<T>, &mut ControlFlow),
|
||||||
{
|
{
|
||||||
if self.loop_running {
|
if self.loop_running {
|
||||||
return Err(RunLoopError::AlreadyRunning);
|
return Err(RunLoopError::AlreadyRunning);
|
||||||
|
@ -553,7 +557,7 @@ impl<T: 'static> EventLoop<T> {
|
||||||
|
|
||||||
pub fn pump_events<F>(&mut self, timeout: Option<Duration>, mut callback: F) -> PumpStatus
|
pub fn pump_events<F>(&mut self, timeout: Option<Duration>, mut callback: F) -> PumpStatus
|
||||||
where
|
where
|
||||||
F: FnMut(event::Event<'_, T>, &RootELW<T>, &mut ControlFlow),
|
F: FnMut(event::Event<T>, &RootELW<T>, &mut ControlFlow),
|
||||||
{
|
{
|
||||||
if !self.loop_running {
|
if !self.loop_running {
|
||||||
self.loop_running = true;
|
self.loop_running = true;
|
||||||
|
@ -593,7 +597,7 @@ impl<T: 'static> EventLoop<T> {
|
||||||
|
|
||||||
fn poll_events_with_timeout<F>(&mut self, mut timeout: Option<Duration>, mut callback: F)
|
fn poll_events_with_timeout<F>(&mut self, mut timeout: Option<Duration>, mut callback: F)
|
||||||
where
|
where
|
||||||
F: FnMut(event::Event<'_, T>, &RootELW<T>, &mut ControlFlow),
|
F: FnMut(event::Event<T>, &RootELW<T>, &mut ControlFlow),
|
||||||
{
|
{
|
||||||
let start = Instant::now();
|
let start = Instant::now();
|
||||||
|
|
||||||
|
@ -996,8 +1000,8 @@ pub struct MonitorHandle {
|
||||||
app: AndroidApp,
|
app: AndroidApp,
|
||||||
}
|
}
|
||||||
impl PartialOrd for MonitorHandle {
|
impl PartialOrd for MonitorHandle {
|
||||||
fn partial_cmp(&self, _other: &Self) -> Option<std::cmp::Ordering> {
|
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
|
||||||
Some(std::cmp::Ordering::Equal)
|
Some(self.cmp(other))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl Ord for MonitorHandle {
|
impl Ord for MonitorHandle {
|
||||||
|
|
|
@ -6,6 +6,7 @@ use std::{
|
||||||
mem,
|
mem,
|
||||||
os::raw::c_void,
|
os::raw::c_void,
|
||||||
ptr,
|
ptr,
|
||||||
|
sync::{Arc, Mutex},
|
||||||
time::Instant,
|
time::Instant,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -25,7 +26,7 @@ use super::uikit::UIView;
|
||||||
use super::view::WinitUIWindow;
|
use super::view::WinitUIWindow;
|
||||||
use crate::{
|
use crate::{
|
||||||
dpi::LogicalSize,
|
dpi::LogicalSize,
|
||||||
event::{Event, StartCause, WindowEvent},
|
event::{Event, InnerSizeWriter, StartCause, WindowEvent},
|
||||||
event_loop::ControlFlow,
|
event_loop::ControlFlow,
|
||||||
platform_impl::platform::{
|
platform_impl::platform::{
|
||||||
event_loop::{EventHandler, EventProxy, EventWrapper, Never},
|
event_loop::{EventHandler, EventProxy, EventWrapper, Never},
|
||||||
|
@ -57,7 +58,7 @@ enum UserCallbackTransitionResult<'a> {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Event<'static, Never> {
|
impl Event<Never> {
|
||||||
fn is_redraw(&self) -> bool {
|
fn is_redraw(&self) -> bool {
|
||||||
matches!(self, Event::RedrawRequested(_))
|
matches!(self, Event::RedrawRequested(_))
|
||||||
}
|
}
|
||||||
|
@ -807,18 +808,18 @@ fn handle_hidpi_proxy(
|
||||||
scale_factor: f64,
|
scale_factor: f64,
|
||||||
window: Id<WinitUIWindow>,
|
window: Id<WinitUIWindow>,
|
||||||
) {
|
) {
|
||||||
let mut size = suggested_size.to_physical(scale_factor);
|
let new_inner_size = Arc::new(Mutex::new(suggested_size.to_physical(scale_factor)));
|
||||||
let new_inner_size = &mut size;
|
|
||||||
let event = Event::WindowEvent {
|
let event = Event::WindowEvent {
|
||||||
window_id: RootWindowId(window.id()),
|
window_id: RootWindowId(window.id()),
|
||||||
event: WindowEvent::ScaleFactorChanged {
|
event: WindowEvent::ScaleFactorChanged {
|
||||||
scale_factor,
|
scale_factor,
|
||||||
new_inner_size,
|
inner_size_writer: InnerSizeWriter::new(Arc::downgrade(&new_inner_size)),
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
event_handler.handle_nonuser_event(event, &mut control_flow);
|
event_handler.handle_nonuser_event(event, &mut control_flow);
|
||||||
let (view, screen_frame) = get_view_and_screen_frame(&window);
|
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 logical_size = physical_size.to_logical(scale_factor);
|
||||||
let size = CGSize::new(logical_size.width, logical_size.height);
|
let size = CGSize::new(logical_size.width, logical_size.height);
|
||||||
let new_frame: CGRect = CGRect::new(screen_frame.origin, size);
|
let new_frame: CGRect = CGRect::new(screen_frame.origin, size);
|
||||||
|
|
|
@ -33,7 +33,7 @@ use crate::{
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub(crate) enum EventWrapper {
|
pub(crate) enum EventWrapper {
|
||||||
StaticEvent(Event<'static, Never>),
|
StaticEvent(Event<Never>),
|
||||||
EventProxy(EventProxy),
|
EventProxy(EventProxy),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -106,7 +106,7 @@ impl<T: 'static> EventLoop<T> {
|
||||||
|
|
||||||
pub fn run<F>(self, event_handler: F) -> !
|
pub fn run<F>(self, event_handler: F) -> !
|
||||||
where
|
where
|
||||||
F: 'static + FnMut(Event<'_, T>, &RootEventLoopWindowTarget<T>, &mut ControlFlow),
|
F: 'static + FnMut(Event<T>, &RootEventLoopWindowTarget<T>, &mut ControlFlow),
|
||||||
{
|
{
|
||||||
unsafe {
|
unsafe {
|
||||||
let application = UIApplication::shared(MainThreadMarker::new().unwrap());
|
let application = UIApplication::shared(MainThreadMarker::new().unwrap());
|
||||||
|
@ -315,7 +315,7 @@ fn setup_control_flow_observers() {
|
||||||
pub enum Never {}
|
pub enum Never {}
|
||||||
|
|
||||||
pub trait EventHandler: Debug {
|
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<Never>, control_flow: &mut ControlFlow);
|
||||||
fn handle_user_events(&mut self, control_flow: &mut ControlFlow);
|
fn handle_user_events(&mut self, control_flow: &mut ControlFlow);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -334,10 +334,10 @@ impl<F, T: 'static> Debug for EventLoopHandler<F, T> {
|
||||||
|
|
||||||
impl<F, T> EventHandler for EventLoopHandler<F, T>
|
impl<F, T> EventHandler for EventLoopHandler<F, T>
|
||||||
where
|
where
|
||||||
F: 'static + FnMut(Event<'_, T>, &RootEventLoopWindowTarget<T>, &mut ControlFlow),
|
F: 'static + FnMut(Event<T>, &RootEventLoopWindowTarget<T>, &mut ControlFlow),
|
||||||
T: 'static,
|
T: 'static,
|
||||||
{
|
{
|
||||||
fn handle_nonuser_event(&mut self, event: Event<'_, Never>, control_flow: &mut ControlFlow) {
|
fn handle_nonuser_event(&mut self, event: Event<Never>, control_flow: &mut ControlFlow) {
|
||||||
(self.f)(
|
(self.f)(
|
||||||
event.map_nonuser_event().unwrap(),
|
event.map_nonuser_event().unwrap(),
|
||||||
&self.event_loop,
|
&self.event_loop,
|
||||||
|
|
|
@ -89,7 +89,7 @@ pub(crate) use self::{
|
||||||
|
|
||||||
use self::uikit::UIScreen;
|
use self::uikit::UIScreen;
|
||||||
pub(crate) use crate::icon::NoIcon as PlatformIcon;
|
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)]
|
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||||
pub struct DeviceId {
|
pub struct DeviceId {
|
||||||
|
|
|
@ -48,7 +48,7 @@ use crate::{
|
||||||
};
|
};
|
||||||
|
|
||||||
pub(crate) use crate::icon::RgbaIcon as PlatformIcon;
|
pub(crate) use crate::icon::RgbaIcon as PlatformIcon;
|
||||||
pub(self) use crate::platform_impl::Fullscreen;
|
pub(crate) use crate::platform_impl::Fullscreen;
|
||||||
|
|
||||||
pub mod common;
|
pub mod common;
|
||||||
#[cfg(wayland_platform)]
|
#[cfg(wayland_platform)]
|
||||||
|
@ -832,21 +832,21 @@ impl<T: 'static> EventLoop<T> {
|
||||||
|
|
||||||
pub fn run<F>(mut self, callback: F) -> Result<(), RunLoopError>
|
pub fn run<F>(mut self, callback: F) -> Result<(), RunLoopError>
|
||||||
where
|
where
|
||||||
F: FnMut(crate::event::Event<'_, T>, &RootELW<T>, &mut ControlFlow),
|
F: FnMut(crate::event::Event<T>, &RootELW<T>, &mut ControlFlow),
|
||||||
{
|
{
|
||||||
self.run_ondemand(callback)
|
self.run_ondemand(callback)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn run_ondemand<F>(&mut self, callback: F) -> Result<(), RunLoopError>
|
pub fn run_ondemand<F>(&mut self, callback: F) -> Result<(), RunLoopError>
|
||||||
where
|
where
|
||||||
F: FnMut(crate::event::Event<'_, T>, &RootELW<T>, &mut ControlFlow),
|
F: FnMut(crate::event::Event<T>, &RootELW<T>, &mut ControlFlow),
|
||||||
{
|
{
|
||||||
x11_or_wayland!(match self; EventLoop(evlp) => evlp.run_ondemand(callback))
|
x11_or_wayland!(match self; EventLoop(evlp) => evlp.run_ondemand(callback))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn pump_events<F>(&mut self, timeout: Option<Duration>, callback: F) -> PumpStatus
|
pub fn pump_events<F>(&mut self, timeout: Option<Duration>, callback: F) -> PumpStatus
|
||||||
where
|
where
|
||||||
F: FnMut(crate::event::Event<'_, T>, &RootELW<T>, &mut ControlFlow),
|
F: FnMut(crate::event::Event<T>, &RootELW<T>, &mut ControlFlow),
|
||||||
{
|
{
|
||||||
x11_or_wayland!(match self; EventLoop(evlp) => evlp.pump_events(timeout, callback))
|
x11_or_wayland!(match self; EventLoop(evlp) => evlp.pump_events(timeout, callback))
|
||||||
}
|
}
|
||||||
|
@ -928,12 +928,12 @@ impl<T> EventLoopWindowTarget<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn sticky_exit_callback<T, F>(
|
fn sticky_exit_callback<T, F>(
|
||||||
evt: Event<'_, T>,
|
evt: Event<T>,
|
||||||
target: &RootELW<T>,
|
target: &RootELW<T>,
|
||||||
control_flow: &mut ControlFlow,
|
control_flow: &mut ControlFlow,
|
||||||
callback: &mut F,
|
callback: &mut F,
|
||||||
) where
|
) where
|
||||||
F: FnMut(Event<'_, T>, &RootELW<T>, &mut ControlFlow),
|
F: FnMut(Event<T>, &RootELW<T>, &mut ControlFlow),
|
||||||
{
|
{
|
||||||
// make ControlFlow::ExitWithCode sticky by providing a dummy
|
// make ControlFlow::ExitWithCode sticky by providing a dummy
|
||||||
// control flow reference if it is already ExitWithCode.
|
// control flow reference if it is already ExitWithCode.
|
||||||
|
|
|
@ -7,6 +7,7 @@ use std::marker::PhantomData;
|
||||||
use std::mem;
|
use std::mem;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use std::sync::atomic::Ordering;
|
use std::sync::atomic::Ordering;
|
||||||
|
use std::sync::{Arc, Mutex};
|
||||||
use std::time::{Duration, Instant};
|
use std::time::{Duration, Instant};
|
||||||
|
|
||||||
use raw_window_handle::{RawDisplayHandle, WaylandDisplayHandle};
|
use raw_window_handle::{RawDisplayHandle, WaylandDisplayHandle};
|
||||||
|
@ -17,7 +18,7 @@ use sctk::reexports::client::{Connection, Proxy, QueueHandle, WaylandSource};
|
||||||
|
|
||||||
use crate::dpi::{LogicalSize, PhysicalSize};
|
use crate::dpi::{LogicalSize, PhysicalSize};
|
||||||
use crate::error::{OsError as RootOsError, RunLoopError};
|
use crate::error::{OsError as RootOsError, RunLoopError};
|
||||||
use crate::event::{Event, StartCause, WindowEvent};
|
use crate::event::{Event, InnerSizeWriter, StartCause, WindowEvent};
|
||||||
use crate::event_loop::{ControlFlow, EventLoopWindowTarget as RootEventLoopWindowTarget};
|
use crate::event_loop::{ControlFlow, EventLoopWindowTarget as RootEventLoopWindowTarget};
|
||||||
use crate::platform::pump_events::PumpStatus;
|
use crate::platform::pump_events::PumpStatus;
|
||||||
use crate::platform_impl::platform::min_timeout;
|
use crate::platform_impl::platform::min_timeout;
|
||||||
|
@ -147,7 +148,7 @@ impl<T: 'static> EventLoop<T> {
|
||||||
|
|
||||||
pub fn run_ondemand<F>(&mut self, mut event_handler: F) -> Result<(), RunLoopError>
|
pub fn run_ondemand<F>(&mut self, mut event_handler: F) -> Result<(), RunLoopError>
|
||||||
where
|
where
|
||||||
F: FnMut(Event<'_, T>, &RootEventLoopWindowTarget<T>, &mut ControlFlow),
|
F: FnMut(Event<T>, &RootEventLoopWindowTarget<T>, &mut ControlFlow),
|
||||||
{
|
{
|
||||||
if self.loop_running {
|
if self.loop_running {
|
||||||
return Err(RunLoopError::AlreadyRunning);
|
return Err(RunLoopError::AlreadyRunning);
|
||||||
|
@ -178,7 +179,7 @@ impl<T: 'static> EventLoop<T> {
|
||||||
|
|
||||||
pub fn pump_events<F>(&mut self, timeout: Option<Duration>, mut callback: F) -> PumpStatus
|
pub fn pump_events<F>(&mut self, timeout: Option<Duration>, mut callback: F) -> PumpStatus
|
||||||
where
|
where
|
||||||
F: FnMut(Event<'_, T>, &RootEventLoopWindowTarget<T>, &mut ControlFlow),
|
F: FnMut(Event<T>, &RootEventLoopWindowTarget<T>, &mut ControlFlow),
|
||||||
{
|
{
|
||||||
if !self.loop_running {
|
if !self.loop_running {
|
||||||
self.loop_running = true;
|
self.loop_running = true;
|
||||||
|
@ -216,7 +217,7 @@ impl<T: 'static> EventLoop<T> {
|
||||||
|
|
||||||
pub fn poll_events_with_timeout<F>(&mut self, mut timeout: Option<Duration>, mut callback: F)
|
pub fn poll_events_with_timeout<F>(&mut self, mut timeout: Option<Duration>, mut callback: F)
|
||||||
where
|
where
|
||||||
F: FnMut(Event<'_, T>, &RootEventLoopWindowTarget<T>, &mut ControlFlow),
|
F: FnMut(Event<T>, &RootEventLoopWindowTarget<T>, &mut ControlFlow),
|
||||||
{
|
{
|
||||||
let start = Instant::now();
|
let start = Instant::now();
|
||||||
|
|
||||||
|
@ -321,7 +322,7 @@ impl<T: 'static> EventLoop<T> {
|
||||||
|
|
||||||
fn single_iteration<F>(&mut self, mut callback: &mut F, cause: StartCause)
|
fn single_iteration<F>(&mut self, mut callback: &mut F, cause: StartCause)
|
||||||
where
|
where
|
||||||
F: FnMut(Event<'_, T>, &RootEventLoopWindowTarget<T>, &mut ControlFlow),
|
F: FnMut(Event<T>, &RootEventLoopWindowTarget<T>, &mut ControlFlow),
|
||||||
{
|
{
|
||||||
// NOTE currently just indented to simplify the diff
|
// NOTE currently just indented to simplify the diff
|
||||||
|
|
||||||
|
@ -370,7 +371,7 @@ impl<T: 'static> EventLoop<T> {
|
||||||
for mut compositor_update in compositor_updates.drain(..) {
|
for mut compositor_update in compositor_updates.drain(..) {
|
||||||
let window_id = compositor_update.window_id;
|
let window_id = compositor_update.window_id;
|
||||||
if let Some(scale_factor) = compositor_update.scale_factor {
|
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 windows = state.windows.get_mut();
|
||||||
let mut window = windows.get(&window_id).unwrap().lock().unwrap();
|
let mut window = windows.get(&window_id).unwrap().lock().unwrap();
|
||||||
|
|
||||||
|
@ -383,12 +384,15 @@ impl<T: 'static> EventLoop<T> {
|
||||||
// Stash the old window size.
|
// Stash the old window size.
|
||||||
let old_physical_size = physical_size;
|
let old_physical_size = physical_size;
|
||||||
|
|
||||||
|
let new_inner_size = Arc::new(Mutex::new(physical_size));
|
||||||
sticky_exit_callback(
|
sticky_exit_callback(
|
||||||
Event::WindowEvent {
|
Event::WindowEvent {
|
||||||
window_id: crate::window::WindowId(window_id),
|
window_id: crate::window::WindowId(window_id),
|
||||||
event: WindowEvent::ScaleFactorChanged {
|
event: WindowEvent::ScaleFactorChanged {
|
||||||
scale_factor,
|
scale_factor,
|
||||||
new_inner_size: &mut physical_size,
|
inner_size_writer: InnerSizeWriter::new(Arc::downgrade(
|
||||||
|
&new_inner_size,
|
||||||
|
)),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
&self.window_target,
|
&self.window_target,
|
||||||
|
@ -396,6 +400,8 @@ impl<T: 'static> EventLoop<T> {
|
||||||
&mut callback,
|
&mut callback,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
let physical_size = *new_inner_size.lock().unwrap();
|
||||||
|
drop(new_inner_size);
|
||||||
let new_logical_size = physical_size.to_logical(scale_factor);
|
let new_logical_size = physical_size.to_logical(scale_factor);
|
||||||
|
|
||||||
// Resize the window when user altered the size.
|
// Resize the window when user altered the size.
|
||||||
|
|
|
@ -12,7 +12,7 @@ use super::{DeviceId, WindowId};
|
||||||
/// to the winit's user.
|
/// to the winit's user.
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct EventSink {
|
pub struct EventSink {
|
||||||
pub window_events: Vec<Event<'static, ()>>,
|
pub window_events: Vec<Event<()>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl EventSink {
|
impl EventSink {
|
||||||
|
@ -31,7 +31,7 @@ impl EventSink {
|
||||||
|
|
||||||
/// Add new window event to a queue.
|
/// Add new window event to a queue.
|
||||||
#[inline]
|
#[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 {
|
self.window_events.push(Event::WindowEvent {
|
||||||
event,
|
event,
|
||||||
window_id: RootWindowId(window_id),
|
window_id: RootWindowId(window_id),
|
||||||
|
@ -44,7 +44,7 @@ impl EventSink {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn drain(&mut self) -> Drain<'_, Event<'static, ()>> {
|
pub fn drain(&mut self) -> Drain<'_, Event<()>> {
|
||||||
self.window_events.drain(..)
|
self.window_events.drain(..)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,7 @@ use std::{
|
||||||
os::raw::{c_char, c_int, c_long, c_ulong},
|
os::raw::{c_char, c_int, c_long, c_ulong},
|
||||||
rc::Rc,
|
rc::Rc,
|
||||||
slice,
|
slice,
|
||||||
sync::Arc,
|
sync::{Arc, Mutex},
|
||||||
};
|
};
|
||||||
|
|
||||||
use x11rb::protocol::xproto::{self, ConnectionExt as _};
|
use x11rb::protocol::xproto::{self, ConnectionExt as _};
|
||||||
|
@ -16,7 +16,6 @@ use super::{
|
||||||
WindowId, XExtension,
|
WindowId, XExtension,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::platform_impl::platform::x11::ime::{ImeEvent, ImeEventReceiver, ImeRequest};
|
|
||||||
use crate::{
|
use crate::{
|
||||||
dpi::{PhysicalPosition, PhysicalSize},
|
dpi::{PhysicalPosition, PhysicalSize},
|
||||||
event::{DeviceEvent, ElementState, Event, Ime, RawKeyEvent, TouchPhase, WindowEvent},
|
event::{DeviceEvent, ElementState, Event, Ime, RawKeyEvent, TouchPhase, WindowEvent},
|
||||||
|
@ -24,6 +23,10 @@ use crate::{
|
||||||
keyboard::ModifiersState,
|
keyboard::ModifiersState,
|
||||||
platform_impl::platform::common::{keymap, xkb_state::KbdState},
|
platform_impl::platform::common::{keymap, xkb_state::KbdState},
|
||||||
};
|
};
|
||||||
|
use crate::{
|
||||||
|
event::InnerSizeWriter,
|
||||||
|
platform_impl::platform::x11::ime::{ImeEvent, ImeEventReceiver, ImeRequest},
|
||||||
|
};
|
||||||
|
|
||||||
/// The X11 documentation states: "Keycodes lie in the inclusive range `[8, 255]`".
|
/// The X11 documentation states: "Keycodes lie in the inclusive range `[8, 255]`".
|
||||||
const KEYCODE_OFFSET: u8 = 8;
|
const KEYCODE_OFFSET: u8 = 8;
|
||||||
|
@ -126,7 +129,7 @@ impl<T: 'static> EventProcessor<T> {
|
||||||
|
|
||||||
pub(super) fn process_event<F>(&mut self, xev: &mut ffi::XEvent, mut callback: F)
|
pub(super) fn process_event<F>(&mut self, xev: &mut ffi::XEvent, mut callback: F)
|
||||||
where
|
where
|
||||||
F: FnMut(Event<'_, T>),
|
F: FnMut(Event<T>),
|
||||||
{
|
{
|
||||||
let wt = get_xtarget(&self.target);
|
let wt = get_xtarget(&self.target);
|
||||||
let atoms = wt.x_connection().atoms();
|
let atoms = wt.x_connection().atoms();
|
||||||
|
@ -437,19 +440,25 @@ impl<T: 'static> EventProcessor<T> {
|
||||||
);
|
);
|
||||||
|
|
||||||
let old_inner_size = PhysicalSize::new(width, height);
|
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
|
// Unlock shared state to prevent deadlock in callback below
|
||||||
drop(shared_state_lock);
|
drop(shared_state_lock);
|
||||||
|
|
||||||
|
let inner_size = Arc::new(Mutex::new(new_inner_size));
|
||||||
callback(Event::WindowEvent {
|
callback(Event::WindowEvent {
|
||||||
window_id,
|
window_id,
|
||||||
event: WindowEvent::ScaleFactorChanged {
|
event: WindowEvent::ScaleFactorChanged {
|
||||||
scale_factor: new_scale_factor,
|
scale_factor: new_scale_factor,
|
||||||
new_inner_size: &mut new_inner_size,
|
inner_size_writer: InnerSizeWriter::new(Arc::downgrade(
|
||||||
|
&inner_size,
|
||||||
|
)),
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
let new_inner_size = *inner_size.lock().unwrap();
|
||||||
|
drop(inner_size);
|
||||||
|
|
||||||
if new_inner_size != old_inner_size {
|
if new_inner_size != old_inner_size {
|
||||||
window.request_inner_size_physical(
|
window.request_inner_size_physical(
|
||||||
new_inner_size.width,
|
new_inner_size.width,
|
||||||
|
@ -1308,17 +1317,22 @@ impl<T: 'static> EventProcessor<T> {
|
||||||
|
|
||||||
let window_id = crate::window::WindowId(*window_id);
|
let window_id = crate::window::WindowId(*window_id);
|
||||||
let old_inner_size = PhysicalSize::new(width, height);
|
let old_inner_size = PhysicalSize::new(width, height);
|
||||||
let mut new_inner_size =
|
let inner_size = Arc::new(Mutex::new(
|
||||||
PhysicalSize::new(new_width, new_height);
|
PhysicalSize::new(new_width, new_height),
|
||||||
|
));
|
||||||
callback(Event::WindowEvent {
|
callback(Event::WindowEvent {
|
||||||
window_id,
|
window_id,
|
||||||
event: WindowEvent::ScaleFactorChanged {
|
event: WindowEvent::ScaleFactorChanged {
|
||||||
scale_factor: new_monitor.scale_factor,
|
scale_factor: new_monitor.scale_factor,
|
||||||
new_inner_size: &mut new_inner_size,
|
inner_size_writer: InnerSizeWriter::new(
|
||||||
|
Arc::downgrade(&inner_size),
|
||||||
|
),
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
let new_inner_size = *inner_size.lock().unwrap();
|
||||||
|
drop(inner_size);
|
||||||
|
|
||||||
if new_inner_size != old_inner_size {
|
if new_inner_size != old_inner_size {
|
||||||
let (new_width, new_height) = new_inner_size.into();
|
let (new_width, new_height) = new_inner_size.into();
|
||||||
window.request_inner_size_physical(
|
window.request_inner_size_physical(
|
||||||
|
@ -1400,7 +1414,7 @@ impl<T: 'static> EventProcessor<T> {
|
||||||
kb_state: &mut KbdState,
|
kb_state: &mut KbdState,
|
||||||
callback: &mut F,
|
callback: &mut F,
|
||||||
) where
|
) where
|
||||||
F: FnMut(Event<'_, T>),
|
F: FnMut(Event<T>),
|
||||||
{
|
{
|
||||||
let device_id = mkdid(util::VIRTUAL_CORE_KEYBOARD.into());
|
let device_id = mkdid(util::VIRTUAL_CORE_KEYBOARD.into());
|
||||||
|
|
||||||
|
|
|
@ -434,7 +434,7 @@ impl<T: 'static> EventLoop<T> {
|
||||||
|
|
||||||
pub fn run_ondemand<F>(&mut self, mut event_handler: F) -> Result<(), RunLoopError>
|
pub fn run_ondemand<F>(&mut self, mut event_handler: F) -> Result<(), RunLoopError>
|
||||||
where
|
where
|
||||||
F: FnMut(Event<'_, T>, &RootELW<T>, &mut ControlFlow),
|
F: FnMut(Event<T>, &RootELW<T>, &mut ControlFlow),
|
||||||
{
|
{
|
||||||
if self.loop_running {
|
if self.loop_running {
|
||||||
return Err(RunLoopError::AlreadyRunning);
|
return Err(RunLoopError::AlreadyRunning);
|
||||||
|
@ -468,7 +468,7 @@ impl<T: 'static> EventLoop<T> {
|
||||||
|
|
||||||
pub fn pump_events<F>(&mut self, timeout: Option<Duration>, mut callback: F) -> PumpStatus
|
pub fn pump_events<F>(&mut self, timeout: Option<Duration>, mut callback: F) -> PumpStatus
|
||||||
where
|
where
|
||||||
F: FnMut(Event<'_, T>, &RootELW<T>, &mut ControlFlow),
|
F: FnMut(Event<T>, &RootELW<T>, &mut ControlFlow),
|
||||||
{
|
{
|
||||||
if !self.loop_running {
|
if !self.loop_running {
|
||||||
self.loop_running = true;
|
self.loop_running = true;
|
||||||
|
@ -512,7 +512,7 @@ impl<T: 'static> EventLoop<T> {
|
||||||
|
|
||||||
pub fn poll_events_with_timeout<F>(&mut self, mut timeout: Option<Duration>, mut callback: F)
|
pub fn poll_events_with_timeout<F>(&mut self, mut timeout: Option<Duration>, mut callback: F)
|
||||||
where
|
where
|
||||||
F: FnMut(Event<'_, T>, &RootELW<T>, &mut ControlFlow),
|
F: FnMut(Event<T>, &RootELW<T>, &mut ControlFlow),
|
||||||
{
|
{
|
||||||
let start = Instant::now();
|
let start = Instant::now();
|
||||||
|
|
||||||
|
@ -595,7 +595,7 @@ impl<T: 'static> EventLoop<T> {
|
||||||
|
|
||||||
fn single_iteration<F>(&mut self, callback: &mut F, cause: StartCause)
|
fn single_iteration<F>(&mut self, callback: &mut F, cause: StartCause)
|
||||||
where
|
where
|
||||||
F: FnMut(Event<'_, T>, &RootELW<T>, &mut ControlFlow),
|
F: FnMut(Event<T>, &RootELW<T>, &mut ControlFlow),
|
||||||
{
|
{
|
||||||
let mut control_flow = self.control_flow;
|
let mut control_flow = self.control_flow;
|
||||||
|
|
||||||
|
@ -694,7 +694,7 @@ impl<T: 'static> EventLoop<T> {
|
||||||
|
|
||||||
fn drain_events<F>(&mut self, callback: &mut F, control_flow: &mut ControlFlow)
|
fn drain_events<F>(&mut self, callback: &mut F, control_flow: &mut ControlFlow)
|
||||||
where
|
where
|
||||||
F: FnMut(Event<'_, T>, &RootELW<T>, &mut ControlFlow),
|
F: FnMut(Event<T>, &RootELW<T>, &mut ControlFlow),
|
||||||
{
|
{
|
||||||
let target = &self.target;
|
let target = &self.target;
|
||||||
let mut xev = MaybeUninit::uninit();
|
let mut xev = MaybeUninit::uninit();
|
||||||
|
|
|
@ -6,7 +6,7 @@ use std::{
|
||||||
rc::{Rc, Weak},
|
rc::{Rc, Weak},
|
||||||
sync::{
|
sync::{
|
||||||
atomic::{AtomicBool, Ordering},
|
atomic::{AtomicBool, Ordering},
|
||||||
Mutex, MutexGuard,
|
Arc, Mutex, MutexGuard,
|
||||||
},
|
},
|
||||||
time::Instant,
|
time::Instant,
|
||||||
};
|
};
|
||||||
|
@ -19,7 +19,7 @@ use once_cell::sync::Lazy;
|
||||||
use super::appkit::{NSApp, NSApplication, NSApplicationActivationPolicy, NSEvent};
|
use super::appkit::{NSApp, NSApplication, NSApplicationActivationPolicy, NSEvent};
|
||||||
use crate::{
|
use crate::{
|
||||||
dpi::LogicalSize,
|
dpi::LogicalSize,
|
||||||
event::{Event, StartCause, WindowEvent},
|
event::{Event, InnerSizeWriter, StartCause, WindowEvent},
|
||||||
event_loop::{ControlFlow, EventLoopWindowTarget as RootWindowTarget},
|
event_loop::{ControlFlow, EventLoopWindowTarget as RootWindowTarget},
|
||||||
platform_impl::platform::{
|
platform_impl::platform::{
|
||||||
event::{EventProxy, EventWrapper},
|
event::{EventProxy, EventWrapper},
|
||||||
|
@ -34,8 +34,8 @@ use crate::{
|
||||||
|
|
||||||
static HANDLER: Lazy<Handler> = Lazy::new(Default::default);
|
static HANDLER: Lazy<Handler> = Lazy::new(Default::default);
|
||||||
|
|
||||||
impl<'a, Never> Event<'a, Never> {
|
impl<Never> Event<Never> {
|
||||||
fn userify<T: 'static>(self) -> Event<'a, T> {
|
fn userify<T: 'static>(self) -> Event<T> {
|
||||||
self.map_nonuser_event()
|
self.map_nonuser_event()
|
||||||
// `Never` can't be constructed, so the `UserEvent` variant can't
|
// `Never` can't be constructed, so the `UserEvent` variant can't
|
||||||
// be present here.
|
// be present here.
|
||||||
|
@ -45,12 +45,11 @@ impl<'a, Never> Event<'a, Never> {
|
||||||
|
|
||||||
pub trait EventHandler: Debug {
|
pub trait EventHandler: Debug {
|
||||||
// Not sure probably it should accept Event<'static, Never>
|
// 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<Never>, control_flow: &mut ControlFlow);
|
||||||
fn handle_user_events(&mut self, control_flow: &mut ControlFlow);
|
fn handle_user_events(&mut self, control_flow: &mut ControlFlow);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) type Callback<T> =
|
pub(crate) type Callback<T> = RefCell<dyn FnMut(Event<T>, &RootWindowTarget<T>, &mut ControlFlow)>;
|
||||||
RefCell<dyn FnMut(Event<'_, T>, &RootWindowTarget<T>, &mut ControlFlow)>;
|
|
||||||
|
|
||||||
struct EventLoopHandler<T: 'static> {
|
struct EventLoopHandler<T: 'static> {
|
||||||
callback: Weak<Callback<T>>,
|
callback: Weak<Callback<T>>,
|
||||||
|
@ -62,7 +61,7 @@ impl<T> EventLoopHandler<T> {
|
||||||
where
|
where
|
||||||
F: FnOnce(
|
F: FnOnce(
|
||||||
&mut EventLoopHandler<T>,
|
&mut EventLoopHandler<T>,
|
||||||
RefMut<'_, dyn FnMut(Event<'_, T>, &RootWindowTarget<T>, &mut ControlFlow)>,
|
RefMut<'_, dyn FnMut(Event<T>, &RootWindowTarget<T>, &mut ControlFlow)>,
|
||||||
),
|
),
|
||||||
{
|
{
|
||||||
// The `NSApp` and our `HANDLER` are global state and so it's possible that
|
// The `NSApp` and our `HANDLER` are global state and so it's possible that
|
||||||
|
@ -90,7 +89,7 @@ impl<T> Debug for EventLoopHandler<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> EventHandler for EventLoopHandler<T> {
|
impl<T> EventHandler for EventLoopHandler<T> {
|
||||||
fn handle_nonuser_event(&mut self, event: Event<'_, Never>, control_flow: &mut ControlFlow) {
|
fn handle_nonuser_event(&mut self, event: Event<Never>, control_flow: &mut ControlFlow) {
|
||||||
self.with_callback(|this, mut callback| {
|
self.with_callback(|this, mut callback| {
|
||||||
if let ControlFlow::ExitWithCode(code) = *control_flow {
|
if let ControlFlow::ExitWithCode(code) = *control_flow {
|
||||||
// XXX: why isn't event dispatching simply skipped after control_flow = ExitWithCode?
|
// XXX: why isn't event dispatching simply skipped after control_flow = ExitWithCode?
|
||||||
|
@ -338,19 +337,19 @@ impl Handler {
|
||||||
suggested_size: LogicalSize<f64>,
|
suggested_size: LogicalSize<f64>,
|
||||||
scale_factor: f64,
|
scale_factor: f64,
|
||||||
) {
|
) {
|
||||||
let mut size = suggested_size.to_physical(scale_factor);
|
let new_inner_size = Arc::new(Mutex::new(suggested_size.to_physical(scale_factor)));
|
||||||
let new_inner_size = &mut size;
|
|
||||||
let event = Event::WindowEvent {
|
let event = Event::WindowEvent {
|
||||||
window_id: WindowId(window.id()),
|
window_id: WindowId(window.id()),
|
||||||
event: WindowEvent::ScaleFactorChanged {
|
event: WindowEvent::ScaleFactorChanged {
|
||||||
scale_factor,
|
scale_factor,
|
||||||
new_inner_size,
|
inner_size_writer: InnerSizeWriter::new(Arc::downgrade(&new_inner_size)),
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
callback.handle_nonuser_event(event, &mut self.control_flow.lock().unwrap());
|
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 logical_size = physical_size.to_logical(scale_factor);
|
||||||
let size = NSSize::new(logical_size.width, logical_size.height);
|
let size = NSSize::new(logical_size.width, logical_size.height);
|
||||||
window.setContentSize(size);
|
window.setContentSize(size);
|
||||||
|
|
|
@ -24,7 +24,7 @@ use crate::{
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub(crate) enum EventWrapper {
|
pub(crate) enum EventWrapper {
|
||||||
StaticEvent(Event<'static, Never>),
|
StaticEvent(Event<Never>),
|
||||||
EventProxy(EventProxy),
|
EventProxy(EventProxy),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -195,7 +195,7 @@ impl<T> EventLoop<T> {
|
||||||
|
|
||||||
pub fn run<F>(mut self, callback: F) -> Result<(), RunLoopError>
|
pub fn run<F>(mut self, callback: F) -> Result<(), RunLoopError>
|
||||||
where
|
where
|
||||||
F: 'static + FnMut(Event<'_, T>, &RootWindowTarget<T>, &mut ControlFlow),
|
F: 'static + FnMut(Event<T>, &RootWindowTarget<T>, &mut ControlFlow),
|
||||||
{
|
{
|
||||||
self.run_ondemand(callback)
|
self.run_ondemand(callback)
|
||||||
}
|
}
|
||||||
|
@ -206,7 +206,7 @@ impl<T> EventLoop<T> {
|
||||||
// redundant wake ups.
|
// redundant wake ups.
|
||||||
pub fn run_ondemand<F>(&mut self, callback: F) -> Result<(), RunLoopError>
|
pub fn run_ondemand<F>(&mut self, callback: F) -> Result<(), RunLoopError>
|
||||||
where
|
where
|
||||||
F: FnMut(Event<'_, T>, &RootWindowTarget<T>, &mut ControlFlow),
|
F: FnMut(Event<T>, &RootWindowTarget<T>, &mut ControlFlow),
|
||||||
{
|
{
|
||||||
if AppState::is_running() {
|
if AppState::is_running() {
|
||||||
return Err(RunLoopError::AlreadyRunning);
|
return Err(RunLoopError::AlreadyRunning);
|
||||||
|
@ -223,8 +223,8 @@ impl<T> EventLoop<T> {
|
||||||
|
|
||||||
let callback = unsafe {
|
let callback = unsafe {
|
||||||
mem::transmute::<
|
mem::transmute::<
|
||||||
Rc<RefCell<dyn FnMut(Event<'_, T>, &RootWindowTarget<T>, &mut ControlFlow)>>,
|
Rc<RefCell<dyn FnMut(Event<T>, &RootWindowTarget<T>, &mut ControlFlow)>>,
|
||||||
Rc<RefCell<dyn FnMut(Event<'_, T>, &RootWindowTarget<T>, &mut ControlFlow)>>,
|
Rc<RefCell<dyn FnMut(Event<T>, &RootWindowTarget<T>, &mut ControlFlow)>>,
|
||||||
>(Rc::new(RefCell::new(callback)))
|
>(Rc::new(RefCell::new(callback)))
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -293,7 +293,7 @@ impl<T> EventLoop<T> {
|
||||||
|
|
||||||
pub fn pump_events<F>(&mut self, timeout: Option<Duration>, callback: F) -> PumpStatus
|
pub fn pump_events<F>(&mut self, timeout: Option<Duration>, callback: F) -> PumpStatus
|
||||||
where
|
where
|
||||||
F: FnMut(Event<'_, T>, &RootWindowTarget<T>, &mut ControlFlow),
|
F: FnMut(Event<T>, &RootWindowTarget<T>, &mut ControlFlow),
|
||||||
{
|
{
|
||||||
// # Safety
|
// # Safety
|
||||||
// We are erasing the lifetime of the application callback here so that we
|
// We are erasing the lifetime of the application callback here so that we
|
||||||
|
@ -306,8 +306,8 @@ impl<T> EventLoop<T> {
|
||||||
|
|
||||||
let callback = unsafe {
|
let callback = unsafe {
|
||||||
mem::transmute::<
|
mem::transmute::<
|
||||||
Rc<RefCell<dyn FnMut(Event<'_, T>, &RootWindowTarget<T>, &mut ControlFlow)>>,
|
Rc<RefCell<dyn FnMut(Event<T>, &RootWindowTarget<T>, &mut ControlFlow)>>,
|
||||||
Rc<RefCell<dyn FnMut(Event<'_, T>, &RootWindowTarget<T>, &mut ControlFlow)>>,
|
Rc<RefCell<dyn FnMut(Event<T>, &RootWindowTarget<T>, &mut ControlFlow)>>,
|
||||||
>(Rc::new(RefCell::new(callback)))
|
>(Rc::new(RefCell::new(callback)))
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -821,7 +821,7 @@ impl WinitView {
|
||||||
WindowId(self.window().id())
|
WindowId(self.window().id())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn queue_event(&self, event: WindowEvent<'static>) {
|
fn queue_event(&self, event: WindowEvent) {
|
||||||
let event = Event::WindowEvent {
|
let event = Event::WindowEvent {
|
||||||
window_id: self.window_id(),
|
window_id: self.window_id(),
|
||||||
event,
|
event,
|
||||||
|
|
|
@ -442,7 +442,7 @@ impl WinitWindowDelegate {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn queue_event(&self, event: WindowEvent<'static>) {
|
pub(crate) fn queue_event(&self, event: WindowEvent) {
|
||||||
let event = Event::WindowEvent {
|
let event = Event::WindowEvent {
|
||||||
window_id: WindowId(self.window.id()),
|
window_id: WindowId(self.window.id()),
|
||||||
event,
|
event,
|
||||||
|
|
|
@ -308,7 +308,7 @@ impl<T: 'static> EventLoop<T> {
|
||||||
event_state: &mut EventState,
|
event_state: &mut EventState,
|
||||||
mut event_handler: F,
|
mut event_handler: F,
|
||||||
) where
|
) where
|
||||||
F: FnMut(event::Event<'_, T>),
|
F: FnMut(event::Event<T>),
|
||||||
{
|
{
|
||||||
match event_option {
|
match event_option {
|
||||||
EventOption::Key(KeyEvent {
|
EventOption::Key(KeyEvent {
|
||||||
|
@ -446,11 +446,11 @@ impl<T: 'static> EventLoop<T> {
|
||||||
pub fn run<F>(mut self, mut event_handler_inner: F) -> Result<(), RunLoopError>
|
pub fn run<F>(mut self, mut event_handler_inner: F) -> Result<(), RunLoopError>
|
||||||
where
|
where
|
||||||
F: 'static
|
F: 'static
|
||||||
+ FnMut(event::Event<'_, T>, &event_loop::EventLoopWindowTarget<T>, &mut ControlFlow),
|
+ FnMut(event::Event<T>, &event_loop::EventLoopWindowTarget<T>, &mut ControlFlow),
|
||||||
{
|
{
|
||||||
// Wrapper for event handler function that prevents ExitWithCode from being unset.
|
// Wrapper for event handler function that prevents ExitWithCode from being unset.
|
||||||
let mut event_handler =
|
let mut event_handler =
|
||||||
move |event: event::Event<'_, T>,
|
move |event: event::Event<T>,
|
||||||
window_target: &event_loop::EventLoopWindowTarget<T>,
|
window_target: &event_loop::EventLoopWindowTarget<T>,
|
||||||
control_flow: &mut ControlFlow| {
|
control_flow: &mut ControlFlow| {
|
||||||
if let ControlFlow::ExitWithCode(code) = control_flow {
|
if let ControlFlow::ExitWithCode(code) = control_flow {
|
||||||
|
|
|
@ -31,7 +31,7 @@ impl<T> EventLoop<T> {
|
||||||
|
|
||||||
pub fn run<F>(self, event_handler: F) -> !
|
pub fn run<F>(self, event_handler: F) -> !
|
||||||
where
|
where
|
||||||
F: 'static + FnMut(Event<'_, T>, &RootEventLoopWindowTarget<T>, &mut ControlFlow),
|
F: 'static + FnMut(Event<T>, &RootEventLoopWindowTarget<T>, &mut ControlFlow),
|
||||||
{
|
{
|
||||||
self.spawn_inner(event_handler, false);
|
self.spawn_inner(event_handler, false);
|
||||||
|
|
||||||
|
@ -46,14 +46,14 @@ impl<T> EventLoop<T> {
|
||||||
|
|
||||||
pub fn spawn<F>(self, event_handler: F)
|
pub fn spawn<F>(self, event_handler: F)
|
||||||
where
|
where
|
||||||
F: 'static + FnMut(Event<'_, T>, &RootEventLoopWindowTarget<T>, &mut ControlFlow),
|
F: 'static + FnMut(Event<T>, &RootEventLoopWindowTarget<T>, &mut ControlFlow),
|
||||||
{
|
{
|
||||||
self.spawn_inner(event_handler, true);
|
self.spawn_inner(event_handler, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn spawn_inner<F>(self, mut event_handler: F, event_loop_recreation: bool)
|
fn spawn_inner<F>(self, mut event_handler: F, event_loop_recreation: bool)
|
||||||
where
|
where
|
||||||
F: 'static + FnMut(Event<'_, T>, &RootEventLoopWindowTarget<T>, &mut ControlFlow),
|
F: 'static + FnMut(Event<T>, &RootEventLoopWindowTarget<T>, &mut ControlFlow),
|
||||||
{
|
{
|
||||||
let target = RootEventLoopWindowTarget {
|
let target = RootEventLoopWindowTarget {
|
||||||
p: self.elw.p.clone(),
|
p: self.elw.p.clone(),
|
||||||
|
|
|
@ -24,7 +24,7 @@ use web_time::{Duration, Instant};
|
||||||
|
|
||||||
pub struct Shared<T: 'static>(Rc<Execution<T>>);
|
pub struct Shared<T: 'static>(Rc<Execution<T>>);
|
||||||
|
|
||||||
pub(super) type EventHandler<T> = dyn FnMut(Event<'_, T>, &mut ControlFlow);
|
pub(super) type EventHandler<T> = dyn FnMut(Event<T>, &mut ControlFlow);
|
||||||
|
|
||||||
impl<T> Clone for Shared<T> {
|
impl<T> Clone for Shared<T> {
|
||||||
fn clone(&self) -> Self {
|
fn clone(&self) -> Self {
|
||||||
|
@ -748,7 +748,7 @@ impl<T: 'static> Shared<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) enum EventWrapper<T: 'static> {
|
pub(crate) enum EventWrapper<T: 'static> {
|
||||||
Event(Event<'static, T>),
|
Event(Event<T>),
|
||||||
ScaleChange {
|
ScaleChange {
|
||||||
canvas: Weak<RefCell<backend::Canvas>>,
|
canvas: Weak<RefCell<backend::Canvas>>,
|
||||||
size: PhysicalSize<u32>,
|
size: PhysicalSize<u32>,
|
||||||
|
@ -756,8 +756,8 @@ pub(crate) enum EventWrapper<T: 'static> {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> From<Event<'static, T>> for EventWrapper<T> {
|
impl<T> From<Event<T>> for EventWrapper<T> {
|
||||||
fn from(value: Event<'static, T>) -> Self {
|
fn from(value: Event<T>) -> Self {
|
||||||
Self::Event(value)
|
Self::Event(value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,4 +38,4 @@ pub use self::window::{PlatformSpecificWindowBuilderAttributes, Window, WindowId
|
||||||
|
|
||||||
pub(crate) use self::keyboard::KeyEventExtra;
|
pub(crate) use self::keyboard::KeyEventExtra;
|
||||||
pub(crate) use crate::icon::NoIcon as PlatformIcon;
|
pub(crate) use crate::icon::NoIcon as PlatformIcon;
|
||||||
pub(self) use crate::platform_impl::Fullscreen;
|
pub(crate) use crate::platform_impl::Fullscreen;
|
||||||
|
|
|
@ -1,20 +1,7 @@
|
||||||
use super::super::WindowId;
|
|
||||||
use super::event_handle::EventListenerHandle;
|
|
||||||
use super::intersection_handle::IntersectionObserverHandle;
|
|
||||||
use super::media_query_handle::MediaQueryListHandle;
|
|
||||||
use super::pointer::PointerHandler;
|
|
||||||
use super::{event, fullscreen, ButtonsState, ResizeScaleHandle};
|
|
||||||
use crate::dpi::{LogicalPosition, PhysicalPosition, PhysicalSize};
|
|
||||||
use crate::error::OsError as RootOE;
|
|
||||||
use crate::event::{Force, MouseButton, MouseScrollDelta};
|
|
||||||
use crate::keyboard::{Key, KeyCode, KeyLocation, ModifiersState};
|
|
||||||
use crate::platform_impl::{OsError, PlatformSpecificWindowBuilderAttributes};
|
|
||||||
use crate::window::{WindowAttributes, WindowId as RootWindowId};
|
|
||||||
|
|
||||||
use std::cell::{Cell, RefCell};
|
use std::cell::{Cell, RefCell};
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use std::sync::atomic::AtomicBool;
|
use std::sync::atomic::AtomicBool;
|
||||||
use std::sync::Arc;
|
use std::sync::{Arc, Mutex};
|
||||||
|
|
||||||
use js_sys::Promise;
|
use js_sys::Promise;
|
||||||
use smol_str::SmolStr;
|
use smol_str::SmolStr;
|
||||||
|
@ -24,6 +11,20 @@ use web_sys::{
|
||||||
CssStyleDeclaration, Document, Event, FocusEvent, HtmlCanvasElement, KeyboardEvent, WheelEvent,
|
CssStyleDeclaration, Document, Event, FocusEvent, HtmlCanvasElement, KeyboardEvent, WheelEvent,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
use crate::dpi::{LogicalPosition, PhysicalPosition, PhysicalSize};
|
||||||
|
use crate::error::OsError as RootOE;
|
||||||
|
use crate::event::{Force, InnerSizeWriter, MouseButton, MouseScrollDelta};
|
||||||
|
use crate::keyboard::{Key, KeyCode, KeyLocation, ModifiersState};
|
||||||
|
use crate::platform_impl::{OsError, PlatformSpecificWindowBuilderAttributes};
|
||||||
|
use crate::window::{WindowAttributes, WindowId as RootWindowId};
|
||||||
|
|
||||||
|
use super::super::WindowId;
|
||||||
|
use super::event_handle::EventListenerHandle;
|
||||||
|
use super::intersection_handle::IntersectionObserverHandle;
|
||||||
|
use super::media_query_handle::MediaQueryListHandle;
|
||||||
|
use super::pointer::PointerHandler;
|
||||||
|
use super::{event, fullscreen, ButtonsState, ResizeScaleHandle};
|
||||||
|
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
pub struct Canvas {
|
pub struct Canvas {
|
||||||
common: Common,
|
common: Common,
|
||||||
|
@ -451,21 +452,26 @@ impl Canvas {
|
||||||
pub(crate) fn handle_scale_change<T: 'static>(
|
pub(crate) fn handle_scale_change<T: 'static>(
|
||||||
&self,
|
&self,
|
||||||
runner: &super::super::event_loop::runner::Shared<T>,
|
runner: &super::super::event_loop::runner::Shared<T>,
|
||||||
event_handler: impl FnOnce(crate::event::Event<'_, T>),
|
event_handler: impl FnOnce(crate::event::Event<T>),
|
||||||
current_size: PhysicalSize<u32>,
|
current_size: PhysicalSize<u32>,
|
||||||
scale: f64,
|
scale: f64,
|
||||||
) {
|
) {
|
||||||
// First, we send the `ScaleFactorChanged` event:
|
// First, we send the `ScaleFactorChanged` event:
|
||||||
self.set_current_size(current_size);
|
self.set_current_size(current_size);
|
||||||
let mut new_size = current_size;
|
let new_size = {
|
||||||
|
let new_size = Arc::new(Mutex::new(current_size));
|
||||||
event_handler(crate::event::Event::WindowEvent {
|
event_handler(crate::event::Event::WindowEvent {
|
||||||
window_id: RootWindowId(self.id),
|
window_id: RootWindowId(self.id),
|
||||||
event: crate::event::WindowEvent::ScaleFactorChanged {
|
event: crate::event::WindowEvent::ScaleFactorChanged {
|
||||||
scale_factor: scale,
|
scale_factor: scale,
|
||||||
new_inner_size: &mut new_size,
|
inner_size_writer: InnerSizeWriter::new(Arc::downgrade(&new_size)),
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
let new_size = *new_size.lock().unwrap();
|
||||||
|
new_size
|
||||||
|
};
|
||||||
|
|
||||||
if current_size != new_size {
|
if current_size != new_size {
|
||||||
// Then we resize the canvas to the new size, a new
|
// Then we resize the canvas to the new size, a new
|
||||||
// `Resized` event will be sent by the `ResizeObserver`:
|
// `Resized` event will be sent by the `ResizeObserver`:
|
||||||
|
|
|
@ -30,7 +30,7 @@ pub struct FileDropHandlerData {
|
||||||
pub interface: IDropTarget,
|
pub interface: IDropTarget,
|
||||||
refcount: AtomicUsize,
|
refcount: AtomicUsize,
|
||||||
window: HWND,
|
window: HWND,
|
||||||
send_event: Box<dyn Fn(Event<'static, ()>)>,
|
send_event: Box<dyn Fn(Event<()>)>,
|
||||||
cursor_effect: u32,
|
cursor_effect: u32,
|
||||||
hovered_is_valid: bool, /* If the currently hovered item is not valid there must not be any `HoveredFileCancelled` emitted */
|
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)]
|
#[allow(non_snake_case)]
|
||||||
impl FileDropHandler {
|
impl FileDropHandler {
|
||||||
pub fn new(window: HWND, send_event: Box<dyn Fn(Event<'static, ()>)>) -> FileDropHandler {
|
pub fn new(window: HWND, send_event: Box<dyn Fn(Event<()>)>) -> FileDropHandler {
|
||||||
let data = Box::new(FileDropHandlerData {
|
let data = Box::new(FileDropHandlerData {
|
||||||
interface: IDropTarget {
|
interface: IDropTarget {
|
||||||
lpVtbl: &DROP_TARGET_VTBL as *const IDropTargetVtbl,
|
lpVtbl: &DROP_TARGET_VTBL as *const IDropTargetVtbl,
|
||||||
|
@ -211,7 +211,7 @@ impl FileDropHandler {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FileDropHandlerData {
|
impl FileDropHandlerData {
|
||||||
fn send_event(&self, event: Event<'static, ()>) {
|
fn send_event(&self, event: Event<()>) {
|
||||||
(self.send_event)(event);
|
(self.send_event)(event);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -76,7 +76,10 @@ use windows_sys::Win32::{
|
||||||
use crate::{
|
use crate::{
|
||||||
dpi::{PhysicalPosition, PhysicalSize},
|
dpi::{PhysicalPosition, PhysicalSize},
|
||||||
error::RunLoopError,
|
error::RunLoopError,
|
||||||
event::{DeviceEvent, Event, Force, Ime, RawKeyEvent, Touch, TouchPhase, WindowEvent},
|
event::{
|
||||||
|
DeviceEvent, Event, Force, Ime, InnerSizeWriter, RawKeyEvent, Touch, TouchPhase,
|
||||||
|
WindowEvent,
|
||||||
|
},
|
||||||
event_loop::{ControlFlow, DeviceEvents, EventLoopClosed, EventLoopWindowTarget as RootELW},
|
event_loop::{ControlFlow, DeviceEvents, EventLoopClosed, EventLoopWindowTarget as RootELW},
|
||||||
keyboard::{KeyCode, ModifiersState},
|
keyboard::{KeyCode, ModifiersState},
|
||||||
platform::{pump_events::PumpStatus, scancode::KeyCodeExtScancode},
|
platform::{pump_events::PumpStatus, scancode::KeyCodeExtScancode},
|
||||||
|
@ -142,7 +145,7 @@ pub(crate) struct WindowData<T: 'static> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> WindowData<T> {
|
impl<T> WindowData<T> {
|
||||||
unsafe fn send_event(&self, event: Event<'_, T>) {
|
unsafe fn send_event(&self, event: Event<T>) {
|
||||||
self.event_loop_runner.send_event(event);
|
self.event_loop_runner.send_event(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -157,7 +160,7 @@ struct ThreadMsgTargetData<T: 'static> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> ThreadMsgTargetData<T> {
|
impl<T> ThreadMsgTargetData<T> {
|
||||||
unsafe fn send_event(&self, event: Event<'_, T>) {
|
unsafe fn send_event(&self, event: Event<T>) {
|
||||||
self.event_loop_runner.send_event(event);
|
self.event_loop_runner.send_event(event);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -245,14 +248,14 @@ impl<T: 'static> EventLoop<T> {
|
||||||
|
|
||||||
pub fn run<F>(mut self, event_handler: F) -> Result<(), RunLoopError>
|
pub fn run<F>(mut self, event_handler: F) -> Result<(), RunLoopError>
|
||||||
where
|
where
|
||||||
F: 'static + FnMut(Event<'_, T>, &RootELW<T>, &mut ControlFlow),
|
F: 'static + FnMut(Event<T>, &RootELW<T>, &mut ControlFlow),
|
||||||
{
|
{
|
||||||
self.run_ondemand(event_handler)
|
self.run_ondemand(event_handler)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn run_ondemand<F>(&mut self, mut event_handler: F) -> Result<(), RunLoopError>
|
pub fn run_ondemand<F>(&mut self, mut event_handler: F) -> Result<(), RunLoopError>
|
||||||
where
|
where
|
||||||
F: FnMut(Event<'_, T>, &RootELW<T>, &mut ControlFlow),
|
F: FnMut(Event<T>, &RootELW<T>, &mut ControlFlow),
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
let runner = &self.window_target.p.runner_shared;
|
let runner = &self.window_target.p.runner_shared;
|
||||||
|
@ -298,7 +301,7 @@ impl<T: 'static> EventLoop<T> {
|
||||||
|
|
||||||
pub fn pump_events<F>(&mut self, timeout: Option<Duration>, mut event_handler: F) -> PumpStatus
|
pub fn pump_events<F>(&mut self, timeout: Option<Duration>, mut event_handler: F) -> PumpStatus
|
||||||
where
|
where
|
||||||
F: FnMut(Event<'_, T>, &RootELW<T>, &mut ControlFlow),
|
F: FnMut(Event<T>, &RootELW<T>, &mut ControlFlow),
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
let runner = &self.window_target.p.runner_shared;
|
let runner = &self.window_target.p.runner_shared;
|
||||||
|
@ -2051,7 +2054,7 @@ unsafe fn public_window_callback_inner<T: 'static>(
|
||||||
|
|
||||||
// `allow_resize` prevents us from re-applying DPI adjustment to the restored size after
|
// `allow_resize` prevents us from re-applying DPI adjustment to the restored size after
|
||||||
// exiting fullscreen (the restored size is already DPI adjusted).
|
// 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
|
// We calculate our own size because the default suggested rect doesn't do a great job
|
||||||
// of preserving the window's logical size.
|
// of preserving the window's logical size.
|
||||||
true => old_physical_inner_size
|
true => old_physical_inner_size
|
||||||
|
@ -2060,14 +2063,18 @@ unsafe fn public_window_callback_inner<T: 'static>(
|
||||||
false => old_physical_inner_size,
|
false => old_physical_inner_size,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let new_inner_size = Arc::new(Mutex::new(new_physical_inner_size));
|
||||||
userdata.send_event(Event::WindowEvent {
|
userdata.send_event(Event::WindowEvent {
|
||||||
window_id: RootWindowId(WindowId(window)),
|
window_id: RootWindowId(WindowId(window)),
|
||||||
event: ScaleFactorChanged {
|
event: ScaleFactorChanged {
|
||||||
scale_factor: new_scale_factor,
|
scale_factor: new_scale_factor,
|
||||||
new_inner_size: &mut new_physical_inner_size,
|
inner_size_writer: InnerSizeWriter::new(Arc::downgrade(&new_inner_size)),
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
let new_physical_inner_size = *new_inner_size.lock().unwrap();
|
||||||
|
drop(new_inner_size);
|
||||||
|
|
||||||
let dragging_window: bool;
|
let dragging_window: bool;
|
||||||
|
|
||||||
{
|
{
|
||||||
|
|
|
@ -4,6 +4,7 @@ use std::{
|
||||||
collections::VecDeque,
|
collections::VecDeque,
|
||||||
mem, panic,
|
mem, panic,
|
||||||
rc::Rc,
|
rc::Rc,
|
||||||
|
sync::{Arc, Mutex},
|
||||||
time::Instant,
|
time::Instant,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -11,7 +12,7 @@ use windows_sys::Win32::Foundation::HWND;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
dpi::PhysicalSize,
|
dpi::PhysicalSize,
|
||||||
event::{Event, StartCause, WindowEvent},
|
event::{Event, InnerSizeWriter, StartCause, WindowEvent},
|
||||||
event_loop::ControlFlow,
|
event_loop::ControlFlow,
|
||||||
platform_impl::platform::{
|
platform_impl::platform::{
|
||||||
event_loop::{WindowData, GWL_USERDATA},
|
event_loop::{WindowData, GWL_USERDATA},
|
||||||
|
@ -22,7 +23,7 @@ use crate::{
|
||||||
|
|
||||||
pub(crate) type EventLoopRunnerShared<T> = Rc<EventLoopRunner<T>>;
|
pub(crate) type EventLoopRunnerShared<T> = Rc<EventLoopRunner<T>>;
|
||||||
|
|
||||||
type EventHandler<T> = Cell<Option<Box<dyn FnMut(Event<'_, T>, &mut ControlFlow)>>>;
|
type EventHandler<T> = Cell<Option<Box<dyn FnMut(Event<T>, &mut ControlFlow)>>>;
|
||||||
|
|
||||||
pub(crate) struct EventLoopRunner<T: 'static> {
|
pub(crate) struct EventLoopRunner<T: 'static> {
|
||||||
// The event loop's win32 handles
|
// The event loop's win32 handles
|
||||||
|
@ -59,7 +60,7 @@ pub(crate) enum RunnerState {
|
||||||
}
|
}
|
||||||
|
|
||||||
enum BufferedEvent<T: 'static> {
|
enum BufferedEvent<T: 'static> {
|
||||||
Event(Event<'static, T>),
|
Event(Event<T>),
|
||||||
ScaleFactorChanged(WindowId, f64, PhysicalSize<u32>),
|
ScaleFactorChanged(WindowId, f64, PhysicalSize<u32>),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -90,11 +91,11 @@ impl<T> EventLoopRunner<T> {
|
||||||
/// undefined behaviour.
|
/// undefined behaviour.
|
||||||
pub(crate) unsafe fn set_event_handler<F>(&self, f: F)
|
pub(crate) unsafe fn set_event_handler<F>(&self, f: F)
|
||||||
where
|
where
|
||||||
F: FnMut(Event<'_, T>, &mut ControlFlow),
|
F: FnMut(Event<T>, &mut ControlFlow),
|
||||||
{
|
{
|
||||||
let old_event_handler = self.event_handler.replace(mem::transmute::<
|
let old_event_handler = self.event_handler.replace(mem::transmute::<
|
||||||
Option<Box<dyn FnMut(Event<'_, T>, &mut ControlFlow)>>,
|
Option<Box<dyn FnMut(Event<T>, &mut ControlFlow)>>,
|
||||||
Option<Box<dyn FnMut(Event<'_, T>, &mut ControlFlow)>>,
|
Option<Box<dyn FnMut(Event<T>, &mut ControlFlow)>>,
|
||||||
>(Some(Box::new(f))));
|
>(Some(Box::new(f))));
|
||||||
assert!(old_event_handler.is_none());
|
assert!(old_event_handler.is_none());
|
||||||
}
|
}
|
||||||
|
@ -196,7 +197,7 @@ impl<T> EventLoopRunner<T> {
|
||||||
self.move_state_to(RunnerState::HandlingMainEvents);
|
self.move_state_to(RunnerState::HandlingMainEvents);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn send_event(&self, event: Event<'_, T>) {
|
pub(crate) fn send_event(&self, event: Event<T>) {
|
||||||
if let Event::RedrawRequested(_) = event {
|
if let Event::RedrawRequested(_) = event {
|
||||||
self.call_event_handler(event);
|
self.call_event_handler(event);
|
||||||
// As a rule, to ensure that `pump_events` can't block an external event loop
|
// As a rule, to ensure that `pump_events` can't block an external event loop
|
||||||
|
@ -219,7 +220,7 @@ impl<T> EventLoopRunner<T> {
|
||||||
self.move_state_to(RunnerState::Destroyed);
|
self.move_state_to(RunnerState::Destroyed);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn call_event_handler(&self, event: Event<'_, T>) {
|
fn call_event_handler(&self, event: Event<T>) {
|
||||||
self.catch_unwind(|| {
|
self.catch_unwind(|| {
|
||||||
let mut control_flow = self.control_flow.take();
|
let mut control_flow = self.control_flow.take();
|
||||||
let mut event_handler = self.event_handler.take()
|
let mut event_handler = self.event_handler.take()
|
||||||
|
@ -361,38 +362,50 @@ impl<T> EventLoopRunner<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> BufferedEvent<T> {
|
impl<T> BufferedEvent<T> {
|
||||||
pub fn from_event(event: Event<'_, T>) -> BufferedEvent<T> {
|
pub fn from_event(event: Event<T>) -> BufferedEvent<T> {
|
||||||
match event {
|
match event {
|
||||||
Event::WindowEvent {
|
Event::WindowEvent {
|
||||||
event:
|
event:
|
||||||
WindowEvent::ScaleFactorChanged {
|
WindowEvent::ScaleFactorChanged {
|
||||||
scale_factor,
|
scale_factor,
|
||||||
new_inner_size,
|
inner_size_writer,
|
||||||
},
|
},
|
||||||
window_id,
|
window_id,
|
||||||
} => BufferedEvent::ScaleFactorChanged(window_id, scale_factor, *new_inner_size),
|
} => BufferedEvent::ScaleFactorChanged(
|
||||||
event => BufferedEvent::Event(event.to_static().unwrap()),
|
window_id,
|
||||||
|
scale_factor,
|
||||||
|
*inner_size_writer
|
||||||
|
.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<T>)) {
|
||||||
match self {
|
match self {
|
||||||
Self::Event(event) => dispatch(event),
|
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 {
|
dispatch(Event::WindowEvent {
|
||||||
window_id,
|
window_id,
|
||||||
event: WindowEvent::ScaleFactorChanged {
|
event: WindowEvent::ScaleFactorChanged {
|
||||||
scale_factor,
|
scale_factor,
|
||||||
new_inner_size: &mut new_inner_size,
|
inner_size_writer: InnerSizeWriter::new(Arc::downgrade(&new_inner_size)),
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
let inner_size = *new_inner_size.lock().unwrap();
|
||||||
|
drop(new_inner_size);
|
||||||
|
|
||||||
let window_flags = unsafe {
|
let window_flags = unsafe {
|
||||||
let userdata =
|
let userdata =
|
||||||
get_window_long(window_id.0.into(), GWL_USERDATA) as *mut WindowData<T>;
|
get_window_long(window_id.0.into(), GWL_USERDATA) as *mut WindowData<T>;
|
||||||
(*userdata).window_state_lock().window_flags
|
(*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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue