Skip to content

Commit

Permalink
Add logging when WM_CAPTURECHANGED is dropped (#822)
Browse files Browse the repository at this point in the history
WM_CAPTURECHANGED now logs when the message is dropped because of reentrancy. Make sure not to call ReleaseCapture while a mutable reference exists to the window state.
  • Loading branch information
teddemunnik authored Apr 9, 2020
1 parent 22fe008 commit 3b3d7a0
Showing 1 changed file with 21 additions and 12 deletions.
33 changes: 21 additions & 12 deletions druid-shell/src/platform/windows/window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -273,18 +273,9 @@ impl WndState {
self.captured_mouse_buttons |= 1 << (button as u32);
}

fn exit_mouse_capture(&mut self, button: MouseButton) {
fn exit_mouse_capture(&mut self, button: MouseButton) -> bool {
self.captured_mouse_buttons &= !(1 << (button as u32));
if self.captured_mouse_buttons == 0 {
unsafe {
if ReleaseCapture() == FALSE {
warn!(
"failed to release mouse capture: {}",
Error::Hr(HRESULT_FROM_WIN32(GetLastError()))
);
}
}
}
self.captured_mouse_buttons == 0
}
}

Expand Down Expand Up @@ -626,6 +617,7 @@ impl WndProc for MyWndProc {
WM_LBUTTONDBLCLK | WM_LBUTTONDOWN | WM_LBUTTONUP | WM_MBUTTONDBLCLK
| WM_MBUTTONDOWN | WM_MBUTTONUP | WM_RBUTTONDBLCLK | WM_RBUTTONDOWN | WM_RBUTTONUP
| WM_XBUTTONDBLCLK | WM_XBUTTONDOWN | WM_XBUTTONUP => {
let mut should_release_capture = false;
if let Ok(mut s) = self.state.try_borrow_mut() {
let s = s.as_mut().unwrap();
let button = match msg {
Expand Down Expand Up @@ -667,11 +659,26 @@ impl WndProc for MyWndProc {
s.handler.mouse_down(&event);
} else {
s.handler.mouse_up(&event);
s.exit_mouse_capture(button);
should_release_capture = s.exit_mouse_capture(button);
}
} else {
self.log_dropped_msg(hwnd, msg, wparam, lparam);
}

// ReleaseCapture() is deferred: it needs to be called without having a mutable
// reference to the window state, because it will generate a reentrant
// WM_CAPTURECHANGED event.
if should_release_capture {
unsafe {
if ReleaseCapture() == FALSE {
warn!(
"failed to release mouse capture: {}",
Error::Hr(HRESULT_FROM_WIN32(GetLastError()))
);
}
}
}

Some(0)
}
XI_REQUEST_DESTROY => {
Expand Down Expand Up @@ -706,6 +713,8 @@ impl WndProc for MyWndProc {
if let Ok(mut s) = self.state.try_borrow_mut() {
let s = s.as_mut().unwrap();
s.captured_mouse_buttons = 0;
} else {
self.log_dropped_msg(hwnd, msg, wparam, lparam);
}
Some(0)
}
Expand Down

0 comments on commit 3b3d7a0

Please # to comment.