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
31 changed files with 252 additions and 429 deletions
|
|
@ -48,7 +48,7 @@ use crate::{
|
|||
};
|
||||
|
||||
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;
|
||||
#[cfg(wayland_platform)]
|
||||
|
|
@ -832,21 +832,21 @@ impl<T: 'static> EventLoop<T> {
|
|||
|
||||
pub fn run<F>(mut self, callback: F) -> Result<(), RunLoopError>
|
||||
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)
|
||||
}
|
||||
|
||||
pub fn run_ondemand<F>(&mut self, callback: F) -> Result<(), RunLoopError>
|
||||
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))
|
||||
}
|
||||
|
||||
pub fn pump_events<F>(&mut self, timeout: Option<Duration>, callback: F) -> PumpStatus
|
||||
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))
|
||||
}
|
||||
|
|
@ -928,12 +928,12 @@ impl<T> EventLoopWindowTarget<T> {
|
|||
}
|
||||
|
||||
fn sticky_exit_callback<T, F>(
|
||||
evt: Event<'_, T>,
|
||||
evt: Event<T>,
|
||||
target: &RootELW<T>,
|
||||
control_flow: &mut ControlFlow,
|
||||
callback: &mut F,
|
||||
) 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
|
||||
// control flow reference if it is already ExitWithCode.
|
||||
|
|
|
|||
|
|
@ -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};
|
||||
|
|
@ -17,7 +18,7 @@ use sctk::reexports::client::{Connection, Proxy, QueueHandle, WaylandSource};
|
|||
|
||||
use crate::dpi::{LogicalSize, PhysicalSize};
|
||||
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::platform::pump_events::PumpStatus;
|
||||
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>
|
||||
where
|
||||
F: FnMut(Event<'_, T>, &RootEventLoopWindowTarget<T>, &mut ControlFlow),
|
||||
F: FnMut(Event<T>, &RootEventLoopWindowTarget<T>, &mut ControlFlow),
|
||||
{
|
||||
if self.loop_running {
|
||||
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
|
||||
where
|
||||
F: FnMut(Event<'_, T>, &RootEventLoopWindowTarget<T>, &mut ControlFlow),
|
||||
F: FnMut(Event<T>, &RootEventLoopWindowTarget<T>, &mut ControlFlow),
|
||||
{
|
||||
if !self.loop_running {
|
||||
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)
|
||||
where
|
||||
F: FnMut(Event<'_, T>, &RootEventLoopWindowTarget<T>, &mut ControlFlow),
|
||||
F: FnMut(Event<T>, &RootEventLoopWindowTarget<T>, &mut ControlFlow),
|
||||
{
|
||||
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)
|
||||
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
|
||||
|
||||
|
|
@ -370,7 +371,7 @@ impl<T: 'static> EventLoop<T> {
|
|||
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,15 @@ impl<T: 'static> EventLoop<T> {
|
|||
// 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,
|
||||
inner_size_writer: InnerSizeWriter::new(Arc::downgrade(
|
||||
&new_inner_size,
|
||||
)),
|
||||
},
|
||||
},
|
||||
&self.window_target,
|
||||
|
|
@ -396,6 +400,8 @@ impl<T: 'static> EventLoop<T> {
|
|||
&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.
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ use super::{DeviceId, WindowId};
|
|||
/// to the winit's user.
|
||||
#[derive(Default)]
|
||||
pub struct EventSink {
|
||||
pub window_events: Vec<Event<'static, ()>>,
|
||||
pub window_events: Vec<Event<()>>,
|
||||
}
|
||||
|
||||
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(..)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 _};
|
||||
|
|
@ -16,7 +16,6 @@ use super::{
|
|||
WindowId, XExtension,
|
||||
};
|
||||
|
||||
use crate::platform_impl::platform::x11::ime::{ImeEvent, ImeEventReceiver, ImeRequest};
|
||||
use crate::{
|
||||
dpi::{PhysicalPosition, PhysicalSize},
|
||||
event::{DeviceEvent, ElementState, Event, Ime, RawKeyEvent, TouchPhase, WindowEvent},
|
||||
|
|
@ -24,6 +23,10 @@ use crate::{
|
|||
keyboard::ModifiersState,
|
||||
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]`".
|
||||
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)
|
||||
where
|
||||
F: FnMut(Event<'_, T>),
|
||||
F: FnMut(Event<T>),
|
||||
{
|
||||
let wt = get_xtarget(&self.target);
|
||||
let atoms = wt.x_connection().atoms();
|
||||
|
|
@ -437,19 +440,25 @@ impl<T: 'static> EventProcessor<T> {
|
|||
);
|
||||
|
||||
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,
|
||||
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 {
|
||||
window.request_inner_size_physical(
|
||||
new_inner_size.width,
|
||||
|
|
@ -1308,17 +1317,22 @@ impl<T: 'static> EventProcessor<T> {
|
|||
|
||||
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,
|
||||
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 {
|
||||
let (new_width, new_height) = new_inner_size.into();
|
||||
window.request_inner_size_physical(
|
||||
|
|
@ -1400,7 +1414,7 @@ impl<T: 'static> EventProcessor<T> {
|
|||
kb_state: &mut KbdState,
|
||||
callback: &mut F,
|
||||
) where
|
||||
F: FnMut(Event<'_, T>),
|
||||
F: FnMut(Event<T>),
|
||||
{
|
||||
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>
|
||||
where
|
||||
F: FnMut(Event<'_, T>, &RootELW<T>, &mut ControlFlow),
|
||||
F: FnMut(Event<T>, &RootELW<T>, &mut ControlFlow),
|
||||
{
|
||||
if self.loop_running {
|
||||
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
|
||||
where
|
||||
F: FnMut(Event<'_, T>, &RootELW<T>, &mut ControlFlow),
|
||||
F: FnMut(Event<T>, &RootELW<T>, &mut ControlFlow),
|
||||
{
|
||||
if !self.loop_running {
|
||||
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)
|
||||
where
|
||||
F: FnMut(Event<'_, T>, &RootELW<T>, &mut ControlFlow),
|
||||
F: FnMut(Event<T>, &RootELW<T>, &mut ControlFlow),
|
||||
{
|
||||
let start = Instant::now();
|
||||
|
||||
|
|
@ -595,7 +595,7 @@ impl<T: 'static> EventLoop<T> {
|
|||
|
||||
fn single_iteration<F>(&mut self, callback: &mut F, cause: StartCause)
|
||||
where
|
||||
F: FnMut(Event<'_, T>, &RootELW<T>, &mut ControlFlow),
|
||||
F: FnMut(Event<T>, &RootELW<T>, &mut ControlFlow),
|
||||
{
|
||||
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)
|
||||
where
|
||||
F: FnMut(Event<'_, T>, &RootELW<T>, &mut ControlFlow),
|
||||
F: FnMut(Event<T>, &RootELW<T>, &mut ControlFlow),
|
||||
{
|
||||
let target = &self.target;
|
||||
let mut xev = MaybeUninit::uninit();
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue