MediatedCommunications / WindowsInput

Capture and Simulate Keyboard and Mouse Input
MIT License
111 stars 17 forks source link

MoveMouseToPositionOnVirtualDesktop from one screen to another is inaccurate #18

Closed lsim closed 1 year ago

lsim commented 2 years ago

Reproducing this requires one of a number of specific arrangements of screens. Something like the following seems to do the trick:

 _________
|         |
|         |
|         |___________
-----------           |
          |           |
          |           |
          -------------

It may also help for the two monitors to be different resolutions.

What appears to happen is that when moving the cursor from one screen to another, the coordinate scaling from the source screen is used on the target screen, which causes the cursor to miss its target - by a lot or a little depending on the screen arrangement.

A somewhat reliable workaround is to simply call MoveMouseToPositionOnVirtualDesktop twice with the same arguments. The first performs the inaccurate move, but gets the cursor to the target screen - the second invocation does a move within a single screen, which works fine.

TonyValenti commented 2 years ago

Hi @lsim - I think the issue exists inside of MouseMove.cs

 var NewX = X;
            var NewY = Y;

            if(Offset == MouseOffset.Absolute || Offset == MouseOffset.AbsoluteVirtual) {
                NewX = X * SystemMetrics.Screen.ScaleFactor.Value / SystemMetrics.Screen.Primary.Width.Value;
                NewY = Y * SystemMetrics.Screen.ScaleFactor.Value / SystemMetrics.Screen.Primary.Height.Value;
            }

            yield return new RawInput(new MOUSEINPUT() {
                Point = new POINT() {
                    X = NewX,
                    Y = NewY,
                },
                Flags = Offset.ToMouseFlags(),
            });
        }

I'll have to spend some time thinking about the best way to work around this. But if you have some ideas, I'd love to hear them!