Windows: issue on HiDPI monitor and multiple monitors

Here is an issue and a potential fix. Maybe a better fix could be found. Here are steps to reproduce, reproduced on both master and develop branches:

  1. Setup: get a Windows machine with a High DPI main monitor (i.e. scale factor 200%) and a 100% scale factor secondary display, with secondary display “arranged” to be to the left of the primary display. Note, the first issue (A below) can likely be reproduced without the secondary display. But, I believe the second issue (B below) is caused by the same thing (and is what lead me down this road).
  2. Build and launch HelloWorldDemo.

A. Start with the window positioned towards the top of the primary (HiDPI) display. Click on the titlebar of the window. Very slowly, drag the window towards the bottom of the screen. You will see the mouse cursor “detach” from the titlebar of the window. If you drag slow enough the mouse cursor will be in the middle of the window before the window gets to the bottom of the screen. Note, I was using an Intel Macbook Pro with Bootcamp, so perhaps the trackpad contributes to the issue.

B. Second issue. When you drag the window from the primary (HiDPI) display to the secondary (100% scale factor) display the window size should adjust. If it does not then when the window is on the secondary display it will be too big. This is the main problem I’m investigating. To reproduce it drag the window slowly from the primary to the secondary display. Here’s the key: go very slowly and start dragging the titlebar just to the left of the minimize button.

Potential solution:
I believe this is all related to the position constraining code (handlePositionChanging) in the HWNDComponentPeer. It always constrains the position to even coordinates. I suppose it is scaling pixel values to points and then back and this is losing some precision. What seems to work for me is this:

-    auto getNewPositionIfNotRoundingError = [] (int posIn, float newPos)
+    auto getNewPositionIfNotRoundingError = [this] (int posIn, float newPos)
    {
-        return (std::abs ((float) posIn - newPos) >= 1.0f) ? roundToInt (newPos) : posIn;
+        return (std::abs ((float) posIn - newPos) >= scaleFactor) ? roundToInt (newPos) : posIn;
    };

Thanks for listening! Hopefully this helps reproduce and maybe figure out a better fix.

Best,
Rob