Skip to content

Commit 8aba4de

Browse files
rajamahmrserb
authored andcommitted
8249592: Robot.mouseMove moves cursor to incorrect location when display scale varies and Java runs in DPI Unaware mode
Reviewed-by: serb, aivanov
1 parent ff76620 commit 8aba4de

File tree

1 file changed

+21
-8
lines changed

1 file changed

+21
-8
lines changed

src/java.desktop/windows/native/libawt/windows/awt_Robot.cpp

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -28,20 +28,33 @@
2828
#include "awt_Component.h"
2929
#include <winuser.h>
3030

31-
static int signum(int i) {
32-
// special version of signum which returns 1 when value is 0
33-
return i >= 0 ? 1 : -1;
34-
}
35-
3631
static void MouseMove(jint x, jint y)
3732
{
3833
INPUT mouseInput = {0};
3934
mouseInput.type = INPUT_MOUSE;
4035
mouseInput.mi.time = 0;
41-
mouseInput.mi.dwFlags = MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_MOVE;
42-
mouseInput.mi.dx = (x * 65536 /::GetSystemMetrics(SM_CXSCREEN)) + signum(x);
43-
mouseInput.mi.dy = (y * 65536 /::GetSystemMetrics(SM_CYSCREEN)) + signum(y);
36+
37+
// The following calculations take into account a multi-monitor setup using
38+
// a virtual screen for all monitors combined.
39+
// More details from Microsoft are here --
40+
// https://docs.microsoft.com/en-us/windows/win32/gdi/the-virtual-screen
41+
42+
x -= ::GetSystemMetrics(SM_XVIRTUALSCREEN);
43+
y -= ::GetSystemMetrics(SM_YVIRTUALSCREEN);
44+
45+
mouseInput.mi.dwFlags = MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_MOVE |
46+
MOUSEEVENTF_VIRTUALDESK;
47+
48+
int scW = ::GetSystemMetrics(SM_CXVIRTUALSCREEN);
49+
int scH = ::GetSystemMetrics(SM_CYVIRTUALSCREEN);
50+
51+
// The following calculation to deduce mouse coordinates is based on
52+
// empirical data
53+
mouseInput.mi.dx = (x * 65536 + scW - 1) / scW;
54+
mouseInput.mi.dy = (y * 65536 + scH - 1) / scH;
55+
4456
::SendInput(1, &mouseInput, sizeof(mouseInput));
57+
4558
}
4659

4760
static void MousePress(jint buttonMask)

0 commit comments

Comments
 (0)