Skip to content

Commit 8c3f28d

Browse files
committed
Qt: Make mouse screen locking DPI aware
Also removed some global mouse hook stuff. Don't ever want to use that anyways.
1 parent 8fb2940 commit 8c3f28d

2 files changed

Lines changed: 36 additions & 72 deletions

File tree

common/Windows/WinMisc.cpp

Lines changed: 3 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -100,54 +100,16 @@ void Common::SetMousePosition(int x, int y)
100100
SetCursorPos(x, y);
101101
}
102102

103-
/*
104-
static HHOOK mouseHook = nullptr;
105-
static std::function<void(int, int)> fnMouseMoveCb;
106-
LRESULT CALLBACK Mousecb(int nCode, WPARAM wParam, LPARAM lParam)
107-
{
108-
if (nCode >= 0 && wParam == WM_MOUSEMOVE)
109-
{
110-
MSLLHOOKSTRUCT* mouse = (MSLLHOOKSTRUCT*)lParam;
111-
fnMouseMoveCb(mouse->pt.x, mouse->pt.y);
112-
}
113-
return CallNextHookEx(mouseHook, nCode, wParam, lParam);
114-
}
115-
*/
116-
117-
// This (and the above) works, but is not recommended on Windows and is only here for consistency.
118-
// Defer to using raw input instead.
119103
bool Common::AttachMousePositionCb(std::function<void(int, int)> cb)
120104
{
121-
/*
122-
if (mouseHook)
123-
Common::DetachMousePositionCb();
124-
125-
fnMouseMoveCb = cb;
126-
mouseHook = SetWindowsHookEx(WH_MOUSE_LL, Mousecb, GetModuleHandle(NULL), 0);
127-
if (!mouseHook)
128-
{
129-
Console.Warning("Failed to set mouse hook: %d", GetLastError());
130-
return false;
131-
}
132-
133-
#if defined(PCSX2_DEBUG) || defined(PCSX2_DEVBUILD)
134-
static bool warned = false;
135-
if (!warned)
136-
{
137-
Console.Warning("Mouse hooks are enabled, and this isn't a release build! Using a debugger, or loading symbols, _will_ stall the hook and cause global mouse lag.");
138-
warned = true;
139-
}
140-
#endif
141-
*/
105+
// We use raw input messages which are handled by the windows message loop.
106+
// The alternative is to use a low-level mouse hook, but this passes Windows all mouse messages to PCSX2.
107+
// If PCSX2 hangs, or you attach a debugger, the mouse will stop working system-wide.
142108
return true;
143109
}
144110

145111
void Common::DetachMousePositionCb()
146112
{
147-
/*
148-
UnhookWindowsHookEx(mouseHook);
149-
mouseHook = nullptr;
150-
*/
151113
}
152114

153115
bool Common::PlaySoundAsync(const char* path)

pcsx2-qt/MainWindow.cpp

Lines changed: 33 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -2320,21 +2320,27 @@ bool MainWindow::nativeEvent(const QByteArray& eventType, void* message, qintptr
23202320
return true;
23212321
}
23222322

2323+
23232324
if (msg->message == WM_INPUT)
23242325
{
2325-
UINT dwSize = 40;
2326-
static BYTE lpb[40];
2327-
if (GetRawInputData((HRAWINPUT)msg->lParam, RID_INPUT, lpb, &dwSize, sizeof(RAWINPUTHEADER)))
2326+
UINT dwSize = 0;
2327+
GetRawInputData((HRAWINPUT)msg->lParam, RID_INPUT, nullptr, &dwSize, sizeof(RAWINPUTHEADER));
2328+
2329+
if (dwSize > 0)
23282330
{
2329-
const RAWINPUT* raw = (RAWINPUT*)lpb;
2330-
if (raw->header.dwType == RIM_TYPEMOUSE)
2331+
std::vector<BYTE> lpb(dwSize);
2332+
if (GetRawInputData((HRAWINPUT)msg->lParam, RID_INPUT, lpb.data(), &dwSize, sizeof(RAWINPUTHEADER)) == dwSize)
23312333
{
2332-
const RAWMOUSE& mouse = raw->data.mouse;
2333-
if (mouse.usFlags == MOUSE_MOVE_ABSOLUTE || mouse.usFlags == MOUSE_MOVE_RELATIVE)
2334+
const RAWINPUT* raw = reinterpret_cast<const RAWINPUT*>(lpb.data());
2335+
if (raw->header.dwType == RIM_TYPEMOUSE)
23342336
{
2335-
POINT cursorPos;
2336-
GetCursorPos(&cursorPos);
2337-
checkMousePosition(cursorPos.x, cursorPos.y);
2337+
const RAWMOUSE& mouse = raw->data.mouse;
2338+
if (mouse.usFlags == MOUSE_MOVE_ABSOLUTE || mouse.usFlags == MOUSE_MOVE_RELATIVE)
2339+
{
2340+
POINT cursorPos;
2341+
if (GetCursorPos(&cursorPos))
2342+
checkMousePosition(cursorPos.x, cursorPos.y);
2343+
}
23382344
}
23392345
}
23402346
}
@@ -2638,30 +2644,26 @@ void MainWindow::checkMousePosition(int x, int y)
26382644
if (!shouldMouseLock())
26392645
return;
26402646

2641-
const QPoint globalCursorPos = {x, y};
2642-
QRect windowBounds = isRenderingFullscreen() ? screen()->geometry() : geometry();
2643-
if (windowBounds.contains(globalCursorPos))
2647+
// physical mouse position
2648+
const QPoint physicalPos(x, y);
2649+
2650+
// logical (DIP) frame rect
2651+
QRectF logicalBounds = isRenderingFullscreen() ? screen()->geometry() : frameGeometry();
2652+
2653+
// physical frame rect
2654+
const qreal scale = window()->devicePixelRatioF();
2655+
QRectF physicalBounds(
2656+
logicalBounds.x() * scale,
2657+
logicalBounds.y() * scale,
2658+
logicalBounds.width() * scale,
2659+
logicalBounds.height() * scale);
2660+
2661+
if (physicalBounds.contains(physicalPos))
26442662
return;
26452663

26462664
Common::SetMousePosition(
2647-
std::clamp(globalCursorPos.x(), windowBounds.left(), windowBounds.right()),
2648-
std::clamp(globalCursorPos.y(), windowBounds.top(), windowBounds.bottom()));
2649-
2650-
/*
2651-
Provided below is how we would handle this if we were using low level hooks (What is used in Common::AttachMouseCb)
2652-
We currently use rawmouse on Windows, so Common::SetMousePosition called directly works fine.
2653-
*/
2654-
#if 0
2655-
// We are currently in a low level hook. SetCursorPos here (what is in Common::SetMousePosition) will not work!
2656-
// Let's (a)buse Qt's event loop to dispatch the call at a later time, outside of the hook.
2657-
QMetaObject::invokeMethod(
2658-
this, [=]() {
2659-
Common::SetMousePosition(
2660-
std::clamp(globalCursorPos.x(), windowBounds.left(), windowBounds.right()),
2661-
std::clamp(globalCursorPos.y(), windowBounds.top(), windowBounds.bottom()));
2662-
},
2663-
Qt::QueuedConnection);
2664-
#endif
2665+
std::clamp(physicalPos.x(), (int)physicalBounds.left(), (int)physicalBounds.right()),
2666+
std::clamp(physicalPos.y(), (int)physicalBounds.top(), (int)physicalBounds.bottom()));
26652667
}
26662668

26672669
void MainWindow::saveDisplayWindowGeometryToConfig()

0 commit comments

Comments
 (0)