Windows: kiosk component under taskbar

Here is a tweaky HiDPI scaling issue related to kiosk mode and some display settings.
To reproduce:

  1. Display width must not be divisible by the scale factor. For example, I have a screen that is 3456 pixels wide with a scale factor of 250%.
  2. Exercise JUCE code that calls setKioskModeComponent, causing the Component to go full screen on the above mentioned display.
  3. Observe that the window fails to cover the taskbar.

If you repeat the above with a scale factor of 200% then it properly covers the taskbar.

The problem is that the taskbar on windows knows how to get out of the way, but only does so if the window is truly full screen. In the above example the screen width is 3456 pixels so the logical width of the screen is 3456 / 2.5 which is 1382.4 which gets truncated to 1382. When Desktop::setKioskComponent() calls setBounds with the logical “totalArea” of the display of 1382 then we end up in the setWindowPos() static method in juce_Windowing_windows.cpp which scales this back up before calling the win32 SetWindowPos() function but ends up with a width of 3455 instead of 3456. Hacking this function to add one to the width fixes this specific example.

I tried to reproduce with the more common display resolution of 3840 pixels wide. However, the way the rounding works for all display scale factors the round trip conversion does not end up losing the pixel so all is good. I’m not sure how common a display width of 3456 is, but that’s what my Dell XPS 15 display has.

I can’t really think of a satisfying fix for this. Any ideas? Might just need to change the path that sets fullscreen to go a different route and avoid the conversions between logical and physical, but I do wonder if other code paths could suffer similar issues due to this “lossy” round trip conversion. I suppose if logical coordinates were fractional that could possibly help, but that’s likely a whole other can of worms.

Thanks for any thoughts!