mirror of
https://github.com/rust-windowing/winit.git
synced 2026-06-27 15:13:13 -04:00
Replace &EventLoop in callback with &EventLoopWindowTarget
This commit is contained in:
@@ -11,6 +11,7 @@
|
||||
//! [send_event]: ./struct.EventLoopProxy.html#method.send_event
|
||||
use std::{fmt, error};
|
||||
use std::time::Instant;
|
||||
use std::ops::Deref;
|
||||
|
||||
use platform_impl;
|
||||
use event::Event;
|
||||
@@ -34,6 +35,11 @@ pub struct EventLoop<T: 'static> {
|
||||
pub(crate) _marker: ::std::marker::PhantomData<*mut ()> // Not Send nor Sync
|
||||
}
|
||||
|
||||
pub struct EventLoopWindowTarget<T: 'static> {
|
||||
pub(crate) p: platform_impl::EventLoopWindowTarget<T>,
|
||||
pub(crate) _marker: ::std::marker::PhantomData<*mut ()> // Not Send nor Sync
|
||||
}
|
||||
|
||||
impl<T> fmt::Debug for EventLoop<T> {
|
||||
fn fmt(&self, fmtr: &mut fmt::Formatter) -> fmt::Result {
|
||||
fmtr.pad("EventLoop { .. }")
|
||||
@@ -123,7 +129,7 @@ impl<T> EventLoop<T> {
|
||||
/// [`ControlFlow`]: ./enum.ControlFlow.html
|
||||
#[inline]
|
||||
pub fn run<F>(self, event_handler: F) -> !
|
||||
where F: 'static + FnMut(Event<T>, &EventLoop<T>, &mut ControlFlow)
|
||||
where F: 'static + FnMut(Event<T>, &EventLoopWindowTarget<T>, &mut ControlFlow)
|
||||
{
|
||||
self.event_loop.run(event_handler)
|
||||
}
|
||||
@@ -137,6 +143,13 @@ impl<T> EventLoop<T> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Deref for EventLoop<T> {
|
||||
type Target = EventLoopWindowTarget<T>;
|
||||
fn deref(&self) -> &EventLoopWindowTarget<T> {
|
||||
self.event_loop.window_target()
|
||||
}
|
||||
}
|
||||
|
||||
/// Used to send custom events to `EventLoop`.
|
||||
#[derive(Clone)]
|
||||
pub struct EventLoopProxy<T> {
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
))]
|
||||
|
||||
use event::Event;
|
||||
use event_loop::{EventLoop, ControlFlow};
|
||||
use event_loop::{EventLoop, EventLoopWindowTarget, ControlFlow};
|
||||
|
||||
/// Additional methods on `EventLoop` that are specific to desktop platforms.
|
||||
pub trait EventLoopExtDesktop {
|
||||
@@ -17,14 +17,14 @@ pub trait EventLoopExtDesktop {
|
||||
/// Unlikes `run`, this function accepts non-`'static` (i.e. non-`move`) closures and returns
|
||||
/// control flow to the caller when `control_flow` is set to `ControlFlow::Exit`.
|
||||
fn run_return<F>(&mut self, event_handler: F)
|
||||
where F: FnMut(Event<Self::UserEvent>, &EventLoop<Self::UserEvent>, &mut ControlFlow);
|
||||
where F: FnMut(Event<Self::UserEvent>, &EventLoopWindowTarget<Self::UserEvent>, &mut ControlFlow);
|
||||
}
|
||||
|
||||
impl<T> EventLoopExtDesktop for EventLoop<T> {
|
||||
type UserEvent = T;
|
||||
|
||||
fn run_return<F>(&mut self, event_handler: F)
|
||||
where F: FnMut(Event<T>, &EventLoop<T>, &mut ControlFlow)
|
||||
where F: FnMut(Event<T>, &EventLoopWindowTarget<T>, &mut ControlFlow)
|
||||
{
|
||||
self.event_loop.run_return(event_handler)
|
||||
}
|
||||
|
||||
@@ -22,6 +22,7 @@ use std::time::{Duration, Instant};
|
||||
use std::rc::Rc;
|
||||
use std::cell::RefCell;
|
||||
use std::collections::VecDeque;
|
||||
use std::marker::PhantomData;
|
||||
use parking_lot::Mutex;
|
||||
|
||||
use winapi::ctypes::c_int;
|
||||
@@ -43,7 +44,7 @@ use winapi::um::winnt::{LONG, LPCSTR, SHORT};
|
||||
|
||||
use window::WindowId as RootWindowId;
|
||||
use monitor::MonitorHandle;
|
||||
use event_loop::{ControlFlow, EventLoop as RootEventLoop, EventLoopClosed};
|
||||
use event_loop::{ControlFlow, EventLoopWindowTarget as RootELW, EventLoopClosed};
|
||||
use dpi::{LogicalPosition, LogicalSize, PhysicalSize};
|
||||
use event::{DeviceEvent, Touch, TouchPhase, StartCause, KeyboardInput, Event, WindowEvent};
|
||||
use platform_impl::platform::{event, Cursor, WindowId, DEVICE_ID, wrap_device_id, util};
|
||||
@@ -138,11 +139,15 @@ impl<T> ThreadMsgTargetSubclassInput<T> {
|
||||
}
|
||||
}
|
||||
|
||||
pub struct EventLoop<T> {
|
||||
pub struct EventLoop<T: 'static> {
|
||||
// Id of the background thread from the Win32 API.
|
||||
thread_id: DWORD,
|
||||
thread_msg_target: HWND,
|
||||
thread_msg_sender: Sender<T>,
|
||||
window_target: RootELW<T>
|
||||
}
|
||||
|
||||
pub struct EventLoopWindowTarget<T> {
|
||||
thread_id: DWORD,
|
||||
trigger_newevents_on_redraw: Arc<AtomicBool>,
|
||||
pub(crate) runner_shared: EventLoopRunnerShared<T>,
|
||||
}
|
||||
@@ -152,6 +157,10 @@ impl<T: 'static> EventLoop<T> {
|
||||
Self::with_dpi_awareness(true)
|
||||
}
|
||||
|
||||
pub fn window_target(&self) -> &RootELW<T> {
|
||||
&self.window_target
|
||||
}
|
||||
|
||||
pub fn with_dpi_awareness(dpi_aware: bool) -> EventLoop<T> {
|
||||
become_dpi_aware(dpi_aware);
|
||||
|
||||
@@ -163,37 +172,40 @@ impl<T: 'static> EventLoop<T> {
|
||||
let (thread_msg_target, thread_msg_sender) = thread_event_target_window(runner_shared.clone());
|
||||
|
||||
EventLoop {
|
||||
thread_id,
|
||||
thread_msg_target, thread_msg_sender,
|
||||
trigger_newevents_on_redraw: Arc::new(AtomicBool::new(true)),
|
||||
runner_shared
|
||||
window_target: RootELW {
|
||||
p: EventLoopWindowTarget {
|
||||
thread_id,
|
||||
trigger_newevents_on_redraw: Arc::new(AtomicBool::new(true)),
|
||||
runner_shared
|
||||
},
|
||||
_marker: PhantomData
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn run<F>(mut self, event_handler: F) -> !
|
||||
where F: 'static + FnMut(Event<T>, &RootEventLoop<T>, &mut ControlFlow)
|
||||
where F: 'static + FnMut(Event<T>, &RootELW<T>, &mut ControlFlow)
|
||||
{
|
||||
self.run_return(event_handler);
|
||||
::std::process::exit(0);
|
||||
}
|
||||
|
||||
pub fn run_return<F>(&mut self, mut event_handler: F)
|
||||
where F: FnMut(Event<T>, &RootEventLoop<T>, &mut ControlFlow)
|
||||
where F: FnMut(Event<T>, &RootELW<T>, &mut ControlFlow)
|
||||
{
|
||||
unsafe{ winuser::IsGUIThread(1); }
|
||||
|
||||
assert_eq!(mem::size_of::<RootEventLoop<T>>(), mem::size_of::<EventLoop<T>>());
|
||||
let self_ptr = self as *const EventLoop<T>;
|
||||
let event_loop_windows_ref = &self.window_target;
|
||||
|
||||
let mut runner = unsafe{ EventLoopRunner::new(
|
||||
self,
|
||||
move |event, control_flow| {
|
||||
let event_loop_ref = &*(self_ptr as *const RootEventLoop<T>);
|
||||
event_handler(event, event_loop_ref, control_flow)
|
||||
event_handler(event, event_loop_windows_ref, control_flow)
|
||||
}
|
||||
) };
|
||||
{
|
||||
let runner_shared = self.runner_shared.clone();
|
||||
let runner_shared = self.window_target.p.runner_shared.clone();
|
||||
let mut runner_ref = runner_shared.runner.borrow_mut();
|
||||
loop {
|
||||
let event = runner_shared.buffer.borrow_mut().pop_front();
|
||||
@@ -206,7 +218,7 @@ impl<T: 'static> EventLoop<T> {
|
||||
}
|
||||
|
||||
macro_rules! runner {
|
||||
() => {{ self.runner_shared.runner.borrow_mut().as_mut().unwrap() }};
|
||||
() => {{ self.window_target.p.runner_shared.runner.borrow_mut().as_mut().unwrap() }};
|
||||
}
|
||||
|
||||
unsafe {
|
||||
@@ -244,7 +256,7 @@ impl<T: 'static> EventLoop<T> {
|
||||
}
|
||||
|
||||
runner!().call_event_handler(Event::LoopDestroyed);
|
||||
*self.runner_shared.runner.borrow_mut() = None;
|
||||
*self.window_target.p.runner_shared.runner.borrow_mut() = None;
|
||||
}
|
||||
|
||||
pub fn create_proxy(&self) -> EventLoopProxy<T> {
|
||||
@@ -253,7 +265,9 @@ impl<T: 'static> EventLoop<T> {
|
||||
event_send: self.thread_msg_sender.clone()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> EventLoopWindowTarget<T> {
|
||||
#[inline(always)]
|
||||
pub(crate) fn create_thread_executor(&self) -> EventLoopThreadExecutor {
|
||||
EventLoopThreadExecutor {
|
||||
@@ -309,7 +323,7 @@ impl<T> EventLoopRunner<T> {
|
||||
where F: FnMut(Event<T>, &mut ControlFlow)
|
||||
{
|
||||
EventLoopRunner {
|
||||
trigger_newevents_on_redraw: event_loop.trigger_newevents_on_redraw.clone(),
|
||||
trigger_newevents_on_redraw: event_loop.window_target.p.trigger_newevents_on_redraw.clone(),
|
||||
control_flow: ControlFlow::default(),
|
||||
runner_state: RunnerState::New,
|
||||
in_modal_loop: false,
|
||||
@@ -545,8 +559,6 @@ impl<T> Drop for EventLoop<T> {
|
||||
fn drop(&mut self) {
|
||||
unsafe {
|
||||
winuser::DestroyWindow(self.thread_msg_target);
|
||||
// Posting `WM_QUIT` will cause `GetMessage` to stop.
|
||||
winuser::PostThreadMessageA(self.thread_id, winuser::WM_QUIT, 0, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
use winapi;
|
||||
use winapi::shared::windef::HWND;
|
||||
|
||||
pub use self::event_loop::{EventLoop, EventLoopProxy};
|
||||
pub use self::event_loop::{EventLoop, EventLoopWindowTarget, EventLoopProxy};
|
||||
pub use self::monitor::MonitorHandle;
|
||||
pub use self::window::Window;
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@ use dpi::{LogicalPosition, LogicalSize, PhysicalSize};
|
||||
use monitor::MonitorHandle as RootMonitorHandle;
|
||||
use platform_impl::platform::{Cursor, PlatformSpecificWindowBuilderAttributes, WindowId};
|
||||
use platform_impl::platform::dpi::{dpi_to_scale_factor, get_hwnd_dpi};
|
||||
use platform_impl::platform::event_loop::{self, EventLoop, DESTROY_MSG_ID, INITIAL_DPI_MSG_ID, REQUEST_REDRAW_NO_NEWEVENTS_MSG_ID};
|
||||
use platform_impl::platform::event_loop::{self, EventLoopWindowTarget, DESTROY_MSG_ID, INITIAL_DPI_MSG_ID, REQUEST_REDRAW_NO_NEWEVENTS_MSG_ID};
|
||||
use platform_impl::platform::event_loop::WindowState;
|
||||
use platform_impl::platform::icon::{self, IconType, WinIcon};
|
||||
use platform_impl::platform::monitor;
|
||||
@@ -69,7 +69,7 @@ unsafe fn unjust_window_rect(prc: &mut RECT, style: DWORD, ex_style: DWORD) -> B
|
||||
|
||||
impl Window {
|
||||
pub fn new<T: 'static>(
|
||||
event_loop: &EventLoop<T>,
|
||||
event_loop: &EventLoopWindowTarget<T>,
|
||||
w_attr: WindowAttributes,
|
||||
pl_attr: PlatformSpecificWindowBuilderAttributes,
|
||||
) -> Result<Window, CreationError> {
|
||||
@@ -857,7 +857,7 @@ pub unsafe fn adjust_size(
|
||||
unsafe fn init<T: 'static>(
|
||||
mut attributes: WindowAttributes,
|
||||
mut pl_attribs: PlatformSpecificWindowBuilderAttributes,
|
||||
event_loop: &event_loop::EventLoop<T>,
|
||||
event_loop: &EventLoopWindowTarget<T>,
|
||||
) -> Result<Window, CreationError> {
|
||||
let title = OsStr::new(&attributes.title)
|
||||
.encode_wide()
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
use std::{fmt, error};
|
||||
|
||||
use platform_impl;
|
||||
use event_loop::EventLoop;
|
||||
use event_loop::EventLoopWindowTarget;
|
||||
use monitor::{AvailableMonitorsIter, MonitorHandle};
|
||||
use dpi::{LogicalPosition, LogicalSize};
|
||||
|
||||
@@ -283,7 +283,7 @@ impl WindowBuilder {
|
||||
/// Error should be very rare and only occur in case of permission denied, incompatible system,
|
||||
/// out of memory, etc.
|
||||
#[inline]
|
||||
pub fn build<T: 'static>(mut self, event_loop: &EventLoop<T>) -> Result<Window, CreationError> {
|
||||
pub fn build<T: 'static>(mut self, window_target: &EventLoopWindowTarget<T>) -> Result<Window, CreationError> {
|
||||
self.window.dimensions = Some(self.window.dimensions.unwrap_or_else(|| {
|
||||
if let Some(ref monitor) = self.window.fullscreen {
|
||||
// resizing the window to the dimensions of the monitor when fullscreen
|
||||
@@ -296,7 +296,7 @@ impl WindowBuilder {
|
||||
|
||||
// building
|
||||
platform_impl::Window::new(
|
||||
&event_loop.event_loop,
|
||||
&window_target.p,
|
||||
self.window,
|
||||
self.platform_specific,
|
||||
).map(|window| Window { window })
|
||||
@@ -311,7 +311,7 @@ impl Window {
|
||||
/// Error should be very rare and only occur in case of permission denied, incompatible system,
|
||||
/// out of memory, etc.
|
||||
#[inline]
|
||||
pub fn new<T: 'static>(event_loop: &EventLoop<T>) -> Result<Window, CreationError> {
|
||||
pub fn new<T: 'static>(event_loop: &EventLoopWindowTarget<T>) -> Result<Window, CreationError> {
|
||||
let builder = WindowBuilder::new();
|
||||
builder.build(event_loop)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user