[PATCH v2 0/1] MR8669: Draft: Map low level hooks coordinates correctly in win32u
Coordinates from mouse low level hook messages are not mapped the same way than WM_MOUSEMOVE or GetCursorPos. This causes problems on programs that make use of both values to calculate mouse movement, like the wine DirectInput implementation. I'm marking this as a draft since I was not able to find a way to write a test for this. I'm able to easily reproduce it on Proton, because it creates a scaled full screen window, on Wine this doesn't happen so the coordinates are not required to be mapped to a scaled window. Edit: I didn't realize that modesetting emulation was an experimental option! So, I was able to reproduce the bug by enabling it. -- v2: win32u: Map raw coordinates to virtual screen in low-level hooks. https://gitlab.winehq.org/wine/wine/-/merge_requests/8669
From: Santino Mazza <smazza(a)codeweavers.com> --- dlls/win32u/message.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/dlls/win32u/message.c b/dlls/win32u/message.c index 2a824dbdab3..7cdec243189 100644 --- a/dlls/win32u/message.c +++ b/dlls/win32u/message.c @@ -2948,8 +2948,13 @@ int peek_message( MSG *msg, const struct peek_message_filter *filter ) } else if (info.msg.message == WH_MOUSE_LL && size >= sizeof(msg_data->hardware)) { + RECT rect = {info.msg.pt.x, info.msg.pt.y, info.msg.pt.x, info.msg.pt.y}; MSLLHOOKSTRUCT hook; + rect = map_rect_raw_to_virt( rect, 0 ); + info.msg.pt.x = rect.left; + info.msg.pt.y = rect.top; + hook.pt = info.msg.pt; hook.mouseData = info.msg.lParam; hook.flags = msg_data->hardware.flags; -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/8669
On Thu Aug 14 14:53:57 2025 +0000, Santino Mazza wrote:
I did more testing on Windows, WH_MOUSE_LL messages are not DPI scaled. So I suppose, instead of `get_thread_dpi`, I should just put 0 so it doesn't do any DPI scaling? Also, because WH_MOUSE_LL is not DPI scaled, I think there are still going to be issues on the way mouse movement is currently calculated by DirectInput. How would we write a test for this? On Windows I can just increase the scaling of the display in the settings, but I'm not sure how to do it programmatically. Yeah I don't think we have tests that change DPI dynamically. Maybe it's just a matter of setting the LogPixels registry setting, but it's probably a whole can of worms.
This seems to match what MSDN says at least. The dinput worker thread will need to be made per-monitor aware too for it to work correctly. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/8669#note_113831
participants (3)
-
Rémi Bernon -
Santino Mazza -
Santino Mazza (@tati)