From 52af1b4a7741af00bc9bb15cbc1a453d63ec88de Mon Sep 17 00:00:00 2001 From: Jasper Bekkers Date: Tue, 31 Oct 2023 16:20:34 +0100 Subject: [PATCH] On Windows, fix MT safety when starting drag --- CHANGELOG.md | 2 ++ src/platform_impl/windows/window.rs | 52 ++++++++++++++++++----------- 2 files changed, 35 insertions(+), 19 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7ec3c32d..561e24cb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,8 @@ Unreleased` header. # Unreleased +- On Windows, fix so `drag_window` and `drag_resize_window` can be called from another thread. + # 0.29.3 - On Wayland, apply correct scale to `PhysicalSize` passed in `WindowBuilder::with_inner_size` when possible. diff --git a/src/platform_impl/windows/window.rs b/src/platform_impl/windows/window.rs index 3f891d5b..7d5bc6d7 100644 --- a/src/platform_impl/windows/window.rs +++ b/src/platform_impl/windows/window.rs @@ -472,27 +472,41 @@ impl Window { } unsafe fn handle_os_dragging(&self, wparam: WPARAM) { - let points = { - let mut pos = unsafe { mem::zeroed() }; - unsafe { GetCursorPos(&mut pos) }; - pos - }; - let points = POINTS { - x: points.x as i16, - y: points.y as i16, - }; - unsafe { ReleaseCapture() }; + let window = self.window.clone(); + let window_state = self.window_state.clone(); - self.window_state_lock().dragging = true; + self.thread_executor.execute_in_thread(move || { + { + let mut guard = window_state.lock().unwrap(); + if !guard.dragging { + guard.dragging = true; + } else { + return; + } + } - unsafe { - PostMessageW( - self.hwnd(), - WM_NCLBUTTONDOWN, - wparam, - &points as *const _ as LPARAM, - ) - }; + let points = { + let mut pos = unsafe { mem::zeroed() }; + unsafe { GetCursorPos(&mut pos) }; + pos + }; + let points = POINTS { + x: points.x as i16, + y: points.y as i16, + }; + + // ReleaseCapture needs to execute on the main thread + unsafe { ReleaseCapture() }; + + unsafe { + PostMessageW( + window.0, + WM_NCLBUTTONDOWN, + wparam, + &points as *const _ as LPARAM, + ) + }; + }); } #[inline]