diff --git a/crates/gpui_windows/src/events.rs b/crates/gpui_windows/src/events.rs index efefc375ac..f8eeea76f9 100644 --- a/crates/gpui_windows/src/events.rs +++ b/crates/gpui_windows/src/events.rs @@ -255,6 +255,13 @@ impl WindowsWindowInner { } fn handle_size_move_loop_exit(&self, handle: HWND) -> Option { + // emulating winit to support dragging a window + // https://github.com/rust-windowing/winit/blob/9674d8ceef6976326fe9583a81f2e684daac05d6/winit-win32/src/event_loop.rs#L1234-L1243 + if self.state.dragging.get() { + self.state.dragging.set(false); + let _ = unsafe { PostMessageW(Some(handle), WM_LBUTTONUP, WPARAM(0), LPARAM(0)) }; + } + unsafe { KillTimer(Some(handle), SIZE_MOVE_LOOP_TIMER_ID).log_err(); } diff --git a/crates/gpui_windows/src/window.rs b/crates/gpui_windows/src/window.rs index 2ea69ddac3..47633773f6 100644 --- a/crates/gpui_windows/src/window.rs +++ b/crates/gpui_windows/src/window.rs @@ -81,6 +81,7 @@ pub struct WindowsWindowState { /// Shared with [`WindowsPlatformState::cursor_visible`]. pub cursor_visible: Arc, pub nc_button_pressed: Cell>, + pub dragging: Cell, pub display: Cell, /// Flag to instruct the `VSyncProvider` thread to invalidate the directx devices @@ -189,6 +190,7 @@ impl WindowsWindowState { current_cursor: Cell::new(current_cursor), cursor_visible, nc_button_pressed: Cell::new(nc_button_pressed), + dragging: Cell::new(false), display: Cell::new(display), fullscreen: Cell::new(fullscreen), initial_placement: Cell::new(initial_placement), @@ -956,6 +958,33 @@ impl PlatformWindow for WindowsWindow { self.state.is_fullscreen() } + fn start_window_move(&self) { + // winit does this by tracking whether the user is mouse-dragging + // https://github.com/rust-windowing/winit/blob/9674d8ceef6976326fe9583a81f2e684daac05d6/winit-win32/src/window.rs#L241-L269 + // https://github.com/rust-windowing/winit/blob/9674d8ceef6976326fe9583a81f2e684daac05d6/winit-win32/src/event_loop.rs#L1234-L1243 + self.state.dragging.set(true); + + let cursor_pos = { + let mut pos = unsafe { std::mem::zeroed() }; + let _ = unsafe { GetCursorPos(&mut pos) }; + pos + }; + let points = POINTS { + x: cursor_pos.x as i16, + y: cursor_pos.y as i16, + }; + + let _ = unsafe { ReleaseCapture() }; + let _ = unsafe { + PostMessageW( + Some(self.0.hwnd), + WM_NCLBUTTONDOWN, + WPARAM(HTCAPTION as usize), + LPARAM(&points as *const _ as isize), + ) + }; + } + fn on_request_frame(&self, callback: Box) { self.state.callbacks.request_frame.set(Some(callback)); }