Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# Unreleased

- On Windows, fix bug causing mouse capture to not be released.
- On Windows, fix fullscreen not preserving minimized/maximized state.

# 0.24.0 (2020-12-09)
Expand Down
24 changes: 16 additions & 8 deletions src/platform_impl/windows/event_loop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -619,15 +619,17 @@ fn subclass_event_target_window<T>(
/// Capture mouse input, allowing `window` to receive mouse events when the cursor is outside of
/// the window.
unsafe fn capture_mouse(window: HWND, window_state: &mut WindowState) {
window_state.mouse.buttons_down += 1;
window_state.mouse.capture_count += 1;
winuser::SetCapture(window);
}

/// Release mouse input, stopping windows on this thread from receiving mouse input when the cursor
/// is outside the window.
unsafe fn release_mouse(window_state: &mut WindowState) {
window_state.mouse.buttons_down = window_state.mouse.buttons_down.saturating_sub(1);
if window_state.mouse.buttons_down == 0 {
unsafe fn release_mouse(mut window_state: parking_lot::MutexGuard<'_, WindowState>) {
window_state.mouse.capture_count = window_state.mouse.capture_count.saturating_sub(1);
if window_state.mouse.capture_count == 0 {
// ReleaseCapture() causes a WM_CAPTURECHANGED where we lock the window_state.
drop(window_state);
winuser::ReleaseCapture();
}
}
Expand Down Expand Up @@ -1192,7 +1194,7 @@ unsafe extern "system" fn public_window_callback<T: 'static>(
ElementState::Released, MouseButton::Left, WindowEvent::MouseInput,
};

release_mouse(&mut *subclass_input.window_state.lock());
release_mouse(subclass_input.window_state.lock());

update_modifiers(window, subclass_input);

Expand Down Expand Up @@ -1234,7 +1236,7 @@ unsafe extern "system" fn public_window_callback<T: 'static>(
ElementState::Released, MouseButton::Right, WindowEvent::MouseInput,
};

release_mouse(&mut *subclass_input.window_state.lock());
release_mouse(subclass_input.window_state.lock());

update_modifiers(window, subclass_input);

Expand Down Expand Up @@ -1276,7 +1278,7 @@ unsafe extern "system" fn public_window_callback<T: 'static>(
ElementState::Released, MouseButton::Middle, WindowEvent::MouseInput,
};

release_mouse(&mut *subclass_input.window_state.lock());
release_mouse(subclass_input.window_state.lock());

update_modifiers(window, subclass_input);

Expand Down Expand Up @@ -1320,7 +1322,7 @@ unsafe extern "system" fn public_window_callback<T: 'static>(
};
let xbutton = winuser::GET_XBUTTON_WPARAM(wparam);

release_mouse(&mut *subclass_input.window_state.lock());
release_mouse(subclass_input.window_state.lock());

update_modifiers(window, subclass_input);

Expand All @@ -1336,6 +1338,12 @@ unsafe extern "system" fn public_window_callback<T: 'static>(
0
}

winuser::WM_CAPTURECHANGED => {
// window lost mouse capture
subclass_input.window_state.lock().mouse.capture_count = 0;
0
}

winuser::WM_TOUCH => {
let pcount = LOWORD(wparam as DWORD) as usize;
let mut inputs = Vec::with_capacity(pcount);
Expand Down
4 changes: 2 additions & 2 deletions src/platform_impl/windows/window_state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ pub struct SavedWindow {
#[derive(Clone)]
pub struct MouseProperties {
pub cursor: CursorIcon,
pub buttons_down: u32,
pub capture_count: u32,
cursor_flags: CursorFlags,
pub last_position: Option<PhysicalPosition<f64>>,
}
Expand Down Expand Up @@ -102,7 +102,7 @@ impl WindowState {
WindowState {
mouse: MouseProperties {
cursor: CursorIcon::default(),
buttons_down: 0,
capture_count: 0,
cursor_flags: CursorFlags::empty(),
last_position: None,
},
Expand Down