RawInput: fix input latching when dragging and switching between windows
This commit is contained in:
@@ -346,6 +346,10 @@ namespace FlaxEditor.GUI.Docking
|
|||||||
{
|
{
|
||||||
if (button == MouseButton.Left)
|
if (button == MouseButton.Left)
|
||||||
{
|
{
|
||||||
|
// Workaround to make sure the mouse down event which initiated dragging in moved window gets properly
|
||||||
|
// released when this window gets destroyed.
|
||||||
|
_toMove.Window.Window.Internal_OnMouseUp(ref location, button);
|
||||||
|
|
||||||
Dispose();
|
Dispose();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -112,7 +112,13 @@ namespace WindowsInputImpl
|
|||||||
bool XInputGamepads[XUSER_MAX_COUNT] = { false };
|
bool XInputGamepads[XUSER_MAX_COUNT] = { false };
|
||||||
WindowsMouse* Mouse = nullptr;
|
WindowsMouse* Mouse = nullptr;
|
||||||
WindowsKeyboard* Keyboard = nullptr;
|
WindowsKeyboard* Keyboard = nullptr;
|
||||||
bool RawInputEnabled = true;
|
}
|
||||||
|
|
||||||
|
namespace WindowsRawInputImpl
|
||||||
|
{
|
||||||
|
bool UseRawInput = true;
|
||||||
|
Window* LastLeaveWindow = nullptr;
|
||||||
|
Window* CurrentInputWindow = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void WindowsInput::Init()
|
void WindowsInput::Init()
|
||||||
@@ -120,7 +126,7 @@ void WindowsInput::Init()
|
|||||||
Input::Mouse = WindowsInputImpl::Mouse = New<WindowsMouse>();
|
Input::Mouse = WindowsInputImpl::Mouse = New<WindowsMouse>();
|
||||||
Input::Keyboard = WindowsInputImpl::Keyboard = New<WindowsKeyboard>();
|
Input::Keyboard = WindowsInputImpl::Keyboard = New<WindowsKeyboard>();
|
||||||
|
|
||||||
if (WindowsInputImpl::RawInputEnabled)
|
if (WindowsRawInputImpl::UseRawInput)
|
||||||
{
|
{
|
||||||
RAWINPUTDEVICE rid[2] = {};
|
RAWINPUTDEVICE rid[2] = {};
|
||||||
|
|
||||||
@@ -176,6 +182,8 @@ bool WindowsInput::WndProc(Window* window, Windows::UINT msg, Windows::WPARAM wP
|
|||||||
|
|
||||||
bool OnRawInput(Vector2 mousePosition, Window* window, HRAWINPUT input)
|
bool OnRawInput(Vector2 mousePosition, Window* window, HRAWINPUT input)
|
||||||
{
|
{
|
||||||
|
// TODO: use GetRawInputBuffer to avoid filling the message queue with high polling rate mice
|
||||||
|
|
||||||
static BYTE* dataBuffer = nullptr;
|
static BYTE* dataBuffer = nullptr;
|
||||||
static uint32 dataBufferSize = 0;
|
static uint32 dataBufferSize = 0;
|
||||||
|
|
||||||
@@ -191,6 +199,13 @@ bool OnRawInput(Vector2 mousePosition, Window* window, HRAWINPUT input)
|
|||||||
|
|
||||||
GetRawInputData(input, RID_INPUT, dataBuffer, &dataSize, sizeof(RAWINPUTHEADER));
|
GetRawInputData(input, RID_INPUT, dataBuffer, &dataSize, sizeof(RAWINPUTHEADER));
|
||||||
|
|
||||||
|
// Workaround to send the input to the topmost window after focusing the window from other applications.
|
||||||
|
if (WindowsRawInputImpl::LastLeaveWindow == window || WindowsRawInputImpl::LastLeaveWindow == nullptr)
|
||||||
|
{
|
||||||
|
if (WindowsRawInputImpl::CurrentInputWindow != nullptr)
|
||||||
|
window = WindowsRawInputImpl::CurrentInputWindow;
|
||||||
|
}
|
||||||
|
|
||||||
const RAWINPUT* rawInput = reinterpret_cast<RAWINPUT*>(dataBuffer);
|
const RAWINPUT* rawInput = reinterpret_cast<RAWINPUT*>(dataBuffer);
|
||||||
if (rawInput->header.dwType == RIM_TYPEKEYBOARD)
|
if (rawInput->header.dwType == RIM_TYPEKEYBOARD)
|
||||||
{
|
{
|
||||||
@@ -227,11 +242,8 @@ bool OnRawInput(Vector2 mousePosition, Window* window, HRAWINPUT input)
|
|||||||
mousePos += mouseDelta;
|
mousePos += mouseDelta;
|
||||||
|
|
||||||
if (!mouseDelta.IsZero())
|
if (!mouseDelta.IsZero())
|
||||||
{
|
|
||||||
//Input::Mouse->OnMouseMove(mousePos, window);
|
|
||||||
Input::Mouse->OnMouseMoveDelta(mouseDelta, window);
|
Input::Mouse->OnMouseMoveDelta(mouseDelta, window);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if ((rawMouse.usButtonFlags & RI_MOUSE_LEFT_BUTTON_DOWN) != 0)
|
if ((rawMouse.usButtonFlags & RI_MOUSE_LEFT_BUTTON_DOWN) != 0)
|
||||||
Input::Mouse->OnMouseDown(mousePos, MouseButton::Left, window);
|
Input::Mouse->OnMouseDown(mousePos, MouseButton::Left, window);
|
||||||
@@ -268,7 +280,7 @@ bool OnRawInput(Vector2 mousePosition, Window* window, HRAWINPUT input)
|
|||||||
|
|
||||||
bool WindowsKeyboard::WndProc(Window* window, const Windows::UINT msg, Windows::WPARAM wParam, Windows::LPARAM lParam)
|
bool WindowsKeyboard::WndProc(Window* window, const Windows::UINT msg, Windows::WPARAM wParam, Windows::LPARAM lParam)
|
||||||
{
|
{
|
||||||
if (WindowsInputImpl::RawInputEnabled && WndProcRawInput(window, msg, wParam, lParam))
|
if (WindowsRawInputImpl::UseRawInput && WndProcRawInput(window, msg, wParam, lParam))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
bool result = false;
|
bool result = false;
|
||||||
@@ -324,7 +336,7 @@ bool WindowsKeyboard::WndProcRawInput(Window* window, const Windows::UINT msg, W
|
|||||||
|
|
||||||
bool WindowsMouse::WndProc(Window* window, const UINT msg, WPARAM wParam, LPARAM lParam)
|
bool WindowsMouse::WndProc(Window* window, const UINT msg, WPARAM wParam, LPARAM lParam)
|
||||||
{
|
{
|
||||||
if (WindowsInputImpl::RawInputEnabled && WndProcRawInput(window, msg, wParam, lParam))
|
if (WindowsRawInputImpl::UseRawInput && WndProcRawInput(window, msg, wParam, lParam))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
bool result = false;
|
bool result = false;
|
||||||
@@ -341,6 +353,9 @@ bool WindowsMouse::WndProc(Window* window, const UINT msg, WPARAM wParam, LPARAM
|
|||||||
{
|
{
|
||||||
case WM_MOUSEMOVE:
|
case WM_MOUSEMOVE:
|
||||||
{
|
{
|
||||||
|
if (!WindowsRawInputImpl::UseRawInput)
|
||||||
|
{
|
||||||
|
// Calculate mouse deltas since last message
|
||||||
static Vector2 lastPos = mousePos;
|
static Vector2 lastPos = mousePos;
|
||||||
if (_state.MouseWasReset)
|
if (_state.MouseWasReset)
|
||||||
{
|
{
|
||||||
@@ -352,6 +367,7 @@ bool WindowsMouse::WndProc(Window* window, const UINT msg, WPARAM wParam, LPARAM
|
|||||||
if (!deltaPos.IsZero())
|
if (!deltaPos.IsZero())
|
||||||
OnMouseMoveDelta(deltaPos, window);
|
OnMouseMoveDelta(deltaPos, window);
|
||||||
lastPos = mousePos;
|
lastPos = mousePos;
|
||||||
|
}
|
||||||
|
|
||||||
OnMouseMove(mousePos, window);
|
OnMouseMove(mousePos, window);
|
||||||
result = true;
|
result = true;
|
||||||
@@ -475,11 +491,15 @@ bool WindowsMouse::WndProcRawInput(Window* window, const UINT msg, WPARAM wParam
|
|||||||
case WM_MOUSEWHEEL:
|
case WM_MOUSEWHEEL:
|
||||||
{
|
{
|
||||||
// Ignored with raw input
|
// Ignored with raw input
|
||||||
|
WindowsRawInputImpl::CurrentInputWindow = window;
|
||||||
result = true;
|
result = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case WM_MOUSEMOVE:
|
case WM_MOUSEMOVE:
|
||||||
case WM_MOUSELEAVE:
|
{
|
||||||
|
WindowsRawInputImpl::CurrentInputWindow = window;
|
||||||
|
break;
|
||||||
|
}
|
||||||
case WM_LBUTTONDBLCLK:
|
case WM_LBUTTONDBLCLK:
|
||||||
case WM_RBUTTONDBLCLK:
|
case WM_RBUTTONDBLCLK:
|
||||||
case WM_MBUTTONDBLCLK:
|
case WM_MBUTTONDBLCLK:
|
||||||
@@ -487,6 +507,21 @@ bool WindowsMouse::WndProcRawInput(Window* window, const UINT msg, WPARAM wParam
|
|||||||
// Might need to be handled here
|
// Might need to be handled here
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case WM_MOUSELEAVE:
|
||||||
|
{
|
||||||
|
WindowsRawInputImpl::LastLeaveWindow = window;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case WM_ACTIVATE:
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case WM_ACTIVATEAPP:
|
||||||
|
{
|
||||||
|
// Reset when switching between apps
|
||||||
|
WindowsRawInputImpl::LastLeaveWindow = nullptr;
|
||||||
|
break;
|
||||||
|
}
|
||||||
case WM_INPUT:
|
case WM_INPUT:
|
||||||
{
|
{
|
||||||
result = OnRawInput(_state.MousePosition, window, reinterpret_cast<HRAWINPUT>(lParam));
|
result = OnRawInput(_state.MousePosition, window, reinterpret_cast<HRAWINPUT>(lParam));
|
||||||
|
|||||||
Reference in New Issue
Block a user