mirror of
https://github.com/rust-windowing/winit.git
synced 2026-08-31 22:00:04 -04:00
Fix thread executor not executing closure when called from non-loop thread
This commit is contained in:
@@ -140,8 +140,6 @@ impl<T> ThreadMsgTargetSubclassInput<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub struct EventLoop<T: 'static> {
|
pub struct EventLoop<T: 'static> {
|
||||||
// Id of the background thread from the Win32 API.
|
|
||||||
thread_msg_target: HWND,
|
|
||||||
thread_msg_sender: Sender<T>,
|
thread_msg_sender: Sender<T>,
|
||||||
window_target: RootELW<T>
|
window_target: RootELW<T>
|
||||||
}
|
}
|
||||||
@@ -149,6 +147,7 @@ pub struct EventLoop<T: 'static> {
|
|||||||
pub struct EventLoopWindowTarget<T> {
|
pub struct EventLoopWindowTarget<T> {
|
||||||
thread_id: DWORD,
|
thread_id: DWORD,
|
||||||
trigger_newevents_on_redraw: Arc<AtomicBool>,
|
trigger_newevents_on_redraw: Arc<AtomicBool>,
|
||||||
|
thread_msg_target: HWND,
|
||||||
pub(crate) runner_shared: EventLoopRunnerShared<T>,
|
pub(crate) runner_shared: EventLoopRunnerShared<T>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -172,11 +171,12 @@ impl<T: 'static> EventLoop<T> {
|
|||||||
let (thread_msg_target, thread_msg_sender) = thread_event_target_window(runner_shared.clone());
|
let (thread_msg_target, thread_msg_sender) = thread_event_target_window(runner_shared.clone());
|
||||||
|
|
||||||
EventLoop {
|
EventLoop {
|
||||||
thread_msg_target, thread_msg_sender,
|
thread_msg_sender,
|
||||||
window_target: RootELW {
|
window_target: RootELW {
|
||||||
p: EventLoopWindowTarget {
|
p: EventLoopWindowTarget {
|
||||||
thread_id,
|
thread_id,
|
||||||
trigger_newevents_on_redraw: Arc::new(AtomicBool::new(true)),
|
trigger_newevents_on_redraw: Arc::new(AtomicBool::new(true)),
|
||||||
|
thread_msg_target,
|
||||||
runner_shared
|
runner_shared
|
||||||
},
|
},
|
||||||
_marker: PhantomData
|
_marker: PhantomData
|
||||||
@@ -261,7 +261,7 @@ impl<T: 'static> EventLoop<T> {
|
|||||||
|
|
||||||
pub fn create_proxy(&self) -> EventLoopProxy<T> {
|
pub fn create_proxy(&self) -> EventLoopProxy<T> {
|
||||||
EventLoopProxy {
|
EventLoopProxy {
|
||||||
target_window: self.thread_msg_target,
|
target_window: self.window_target.p.thread_msg_target,
|
||||||
event_send: self.thread_msg_sender.clone()
|
event_send: self.thread_msg_sender.clone()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -272,7 +272,8 @@ impl<T> EventLoopWindowTarget<T> {
|
|||||||
pub(crate) fn create_thread_executor(&self) -> EventLoopThreadExecutor {
|
pub(crate) fn create_thread_executor(&self) -> EventLoopThreadExecutor {
|
||||||
EventLoopThreadExecutor {
|
EventLoopThreadExecutor {
|
||||||
thread_id: self.thread_id,
|
thread_id: self.thread_id,
|
||||||
trigger_newevents_on_redraw: self.trigger_newevents_on_redraw.clone()
|
trigger_newevents_on_redraw: self.trigger_newevents_on_redraw.clone(),
|
||||||
|
target_window: self.thread_msg_target
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -327,7 +328,7 @@ impl<T> EventLoopRunner<T> {
|
|||||||
control_flow: ControlFlow::default(),
|
control_flow: ControlFlow::default(),
|
||||||
runner_state: RunnerState::New,
|
runner_state: RunnerState::New,
|
||||||
in_modal_loop: false,
|
in_modal_loop: false,
|
||||||
modal_redraw_window: event_loop.thread_msg_target,
|
modal_redraw_window: event_loop.window_target.p.thread_msg_target,
|
||||||
event_handler: mem::transmute::<
|
event_handler: mem::transmute::<
|
||||||
Box<FnMut(Event<T>, &mut ControlFlow)>,
|
Box<FnMut(Event<T>, &mut ControlFlow)>,
|
||||||
Box<FnMut(Event<T>, &mut ControlFlow)>
|
Box<FnMut(Event<T>, &mut ControlFlow)>
|
||||||
@@ -558,16 +559,20 @@ fn dur2timeout(dur: Duration) -> DWORD {
|
|||||||
impl<T> Drop for EventLoop<T> {
|
impl<T> Drop for EventLoop<T> {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
unsafe {
|
unsafe {
|
||||||
winuser::DestroyWindow(self.thread_msg_target);
|
winuser::DestroyWindow(self.window_target.p.thread_msg_target);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) struct EventLoopThreadExecutor {
|
pub(crate) struct EventLoopThreadExecutor {
|
||||||
thread_id: DWORD,
|
thread_id: DWORD,
|
||||||
trigger_newevents_on_redraw: Arc<AtomicBool>
|
trigger_newevents_on_redraw: Arc<AtomicBool>,
|
||||||
|
target_window: HWND
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsafe impl Send for EventLoopThreadExecutor {}
|
||||||
|
unsafe impl Sync for EventLoopThreadExecutor {}
|
||||||
|
|
||||||
impl EventLoopThreadExecutor {
|
impl EventLoopThreadExecutor {
|
||||||
/// Check to see if we're in the parent event loop's thread.
|
/// Check to see if we're in the parent event loop's thread.
|
||||||
pub(super) fn in_event_loop_thread(&self) -> bool {
|
pub(super) fn in_event_loop_thread(&self) -> bool {
|
||||||
@@ -605,11 +610,11 @@ impl EventLoopThreadExecutor {
|
|||||||
|
|
||||||
let raw = Box::into_raw(boxed2);
|
let raw = Box::into_raw(boxed2);
|
||||||
|
|
||||||
let res = winuser::PostThreadMessageA(self.thread_id, *EXEC_MSG_ID,
|
let res = winuser::PostMessageW(
|
||||||
raw as *mut () as usize as WPARAM, 0);
|
self.target_window, *EXEC_MSG_ID,
|
||||||
// PostThreadMessage can only fail if the thread ID is invalid (which shouldn't happen
|
raw as *mut () as usize as WPARAM, 0
|
||||||
// as the events loop is still alive) or if the queue is full.
|
);
|
||||||
assert!(res != 0, "PostThreadMessage failed ; is the messages queue full?");
|
assert!(res != 0, "PostMessage failed ; is the messages queue full?");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user