Merge pull request #23622 from RandomShaper/fix-windows-mouse-capture

Fix mouse mode restoration on Windows
This commit is contained in:
Rémi Verschelde 2018-11-10 21:55:30 +01:00 committed by GitHub
commit 9f4d89dffd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 27 additions and 25 deletions

View File

@ -300,19 +300,17 @@ LRESULT OS_Windows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{ {
case WM_SETFOCUS: { case WM_SETFOCUS: {
window_has_focus = true; window_has_focus = true;
// Re-capture cursor if we're in one of the capture modes
if (mouse_mode == MOUSE_MODE_CAPTURED || mouse_mode == MOUSE_MODE_CONFINED) { // Restore mouse mode
SetCapture(hWnd); _set_mouse_mode_impl(mouse_mode);
}
break; break;
} }
case WM_KILLFOCUS: { case WM_KILLFOCUS: {
window_has_focus = false; window_has_focus = false;
// Release capture if we're in one of the capture modes // Release capture unconditionally because it can be set due to dragging, in addition to captured mode
if (mouse_mode == MOUSE_MODE_CAPTURED || mouse_mode == MOUSE_MODE_CONFINED) { ReleaseCapture();
ReleaseCapture();
}
// Release every touch to avoid sticky points // Release every touch to avoid sticky points
for (Map<int, Vector2>::Element *E = touch_state.front(); E; E = E->next()) { for (Map<int, Vector2>::Element *E = touch_state.front(); E; E = E->next()) {
@ -334,15 +332,7 @@ LRESULT OS_Windows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
alt_mem = false; alt_mem = false;
control_mem = false; control_mem = false;
shift_mem = false; shift_mem = false;
if (mouse_mode == MOUSE_MODE_CAPTURED || mouse_mode == MOUSE_MODE_CONFINED) { } else { // WM_INACTIVE
RECT clipRect;
GetClientRect(hWnd, &clipRect);
ClientToScreen(hWnd, (POINT *)&clipRect.left);
ClientToScreen(hWnd, (POINT *)&clipRect.right);
ClipCursor(&clipRect);
SetCapture(hWnd);
}
} else {
main_loop->notification(MainLoop::NOTIFICATION_WM_FOCUS_OUT); main_loop->notification(MainLoop::NOTIFICATION_WM_FOCUS_OUT);
alt_mem = false; alt_mem = false;
}; };
@ -702,12 +692,14 @@ LRESULT OS_Windows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
if (uMsg != WM_MOUSEWHEEL && uMsg != WM_MOUSEHWHEEL) { if (uMsg != WM_MOUSEWHEEL && uMsg != WM_MOUSEHWHEEL) {
if (mb->is_pressed()) { if (mb->is_pressed()) {
if (++pressrc > 0) if (++pressrc > 0 && mouse_mode != MOUSE_MODE_CAPTURED)
SetCapture(hWnd); SetCapture(hWnd);
} else { } else {
if (--pressrc <= 0) { if (--pressrc <= 0) {
ReleaseCapture(); if (mouse_mode != MOUSE_MODE_CAPTURED) {
ReleaseCapture();
}
pressrc = 0; pressrc = 0;
} }
} }
@ -1516,18 +1508,27 @@ void OS_Windows::set_mouse_mode(MouseMode p_mode) {
if (mouse_mode == p_mode) if (mouse_mode == p_mode)
return; return;
_set_mouse_mode_impl(p_mode);
mouse_mode = p_mode; mouse_mode = p_mode;
if (mouse_mode == MOUSE_MODE_CAPTURED || mouse_mode == MOUSE_MODE_CONFINED) { }
void OS_Windows::_set_mouse_mode_impl(MouseMode p_mode) {
if (p_mode == MOUSE_MODE_CAPTURED || p_mode == MOUSE_MODE_CONFINED) {
RECT clipRect; RECT clipRect;
GetClientRect(hWnd, &clipRect); GetClientRect(hWnd, &clipRect);
ClientToScreen(hWnd, (POINT *)&clipRect.left); ClientToScreen(hWnd, (POINT *)&clipRect.left);
ClientToScreen(hWnd, (POINT *)&clipRect.right); ClientToScreen(hWnd, (POINT *)&clipRect.right);
ClipCursor(&clipRect); ClipCursor(&clipRect);
center = Point2i(video_mode.width / 2, video_mode.height / 2); if (p_mode == MOUSE_MODE_CAPTURED) {
POINT pos = { (int)center.x, (int)center.y }; center = Point2i(video_mode.width / 2, video_mode.height / 2);
ClientToScreen(hWnd, &pos); POINT pos = { (int)center.x, (int)center.y };
if (mouse_mode == MOUSE_MODE_CAPTURED) ClientToScreen(hWnd, &pos);
SetCursorPos(pos.x, pos.y); SetCursorPos(pos.x, pos.y);
SetCapture(hWnd);
}
} else { } else {
ReleaseCapture(); ReleaseCapture();
ClipCursor(NULL); ClipCursor(NULL);
@ -1541,7 +1542,6 @@ void OS_Windows::set_mouse_mode(MouseMode p_mode) {
set_cursor_shape(c); set_cursor_shape(c);
} }
} }
OS_Windows::MouseMode OS_Windows::get_mouse_mode() const { OS_Windows::MouseMode OS_Windows::get_mouse_mode() const {
return mouse_mode; return mouse_mode;

View File

@ -157,6 +157,8 @@ class OS_Windows : public OS {
void _update_window_style(bool repaint = true); void _update_window_style(bool repaint = true);
void _set_mouse_mode_impl(MouseMode p_mode);
// functions used by main to initialize/deinitialize the OS // functions used by main to initialize/deinitialize the OS
protected: protected:
virtual int get_current_video_driver() const; virtual int get_current_video_driver() const;