On Windows, fix bug causing mouse capture to not be released. (#1797)

This commit is contained in:
Samuel 2020-12-15 03:31:13 -03:00 committed by GitHub
parent 39573d65d0
commit 932cbe40bf
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 19 additions and 10 deletions

View file

@ -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)

View file

@ -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();
}
}
@ -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);
@ -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);
@ -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);
@ -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);
@ -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);

View file

@ -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>>,
}
@ -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,
},