Hello.
Please review the fix for JDK 15.

Bugs: 8231564: setMaximizedBounds is broken with large display scale and 
multiple monitors
        https://bugs.openjdk.java.net/browse/JDK-8231564
      8176359: Frame#setMaximizedbounds not working properly in multi screen 
environments
        https://bugs.openjdk.java.net/browse/JDK-8176359
Fix: http://cr.openjdk.java.net/~serb/8176359/webrev.01

Short description:
=================
  The fix changes the way on how we limit the size and position of the 
maximized window.

Long description:
=================
  On Windows supports of maximized is done by the WM_GETMINMAXINFO[1] message. 
This
message provides MINMAXINFO[2] which has two related fields: ptMaxSize and 
ptMaxPosition.
  ptMaxPosition: The position of the left side of the maximized window (x 
member) and
                 the position of the top of the maximized window (y member). 
For top-level
                 windows, this value is based on the position of the primary 
monitor.
  ptMaxSize: The maximized width (x member) and the maximized height (y member) 
of the
             window. For top-level windows, this value is based on the width of 
the primary
             monitor.
"For systems with multiple monitors, the ptMaxSize and ptMaxPosition members 
describe the
maximized size and position of the window on the primary monitor, even if the 
window
ultimately maximizes onto a secondary monitor. In that case, the window manager 
adjusts
these values to compensate for differences between the primary monitor and the 
monitor that
displays the window. Thus, if the user leaves ptMaxSize untouched, a window on 
a monitor
larger than the primary monitor maximizes to the size of the larger monitor."

My observation:
=================
  1. Description of "ptMaxPosition" in the documentation is wrong, this value 
is based on the
     actual window's monitor not a primary monitor. I have read about it 
here[3] and confirmed
     by the tests using three monitors setup.
  2. ptMaxSize will be used as-is if the size is smaller than the !!main!! 
monitor. If the size
     is larger than the main monitor then the window manager adjusts the size, 
like this:
     // result = requested.w + (current.w - main.w); =>> This results in the 
correct size if we
     want to fully maximize the window on the current monitor, but if we want 
to set a smaller
     size then we will get the wrong result.
     We can try to compensate for this adjustment like this:
     // requested = requested.w - (current.w - main.w);
     but this can result to the size smaller than the main screen, so no 
adjustment will be
     done by the window manager =>> wrong size again.
     Note that the result does not depend on the monitor on which we maximize 
the window.
  3. For example for the three monitors setup: W1=600, W2=1600, W3=1080. It is 
not possible
     to maximize the window on W3 if the current window is on W2 monitor, 
because if we
     request size=1080 which is bigger than 600 and it will be adjusted by the 
window
     manager: resulted size = 1080+(1600-600) = 2080. If we will try to 
compensate this value:
     size = 1080 - (1600-600) = 80, which is smaller than main monitor and will 
be used as-is.

Fix description:
  1. To fix JDK-8231564 we should convert all coordinates from the user's 
virtual space to
     the device space.
  2. To fix JDK-8176359 we need to translate the bounds.x/y from the global 
virtual coordinate
     system related to the main monitor to the coordinate system of the 
window's actual monitor.
  3. The current code already tried to compensate adjustment, but it missed the 
fact that the
     width and height should be adjusted separately, but even if that be fixed, 
in some situations
     this logic will be broken(see observation point 3). So instead of fixing 
that I have passed
     these values to the native as-is, and cut the adjustment in the  
WM_WINDOWPOSCHANGING event,
     just before the window is resized.


Known issue:
 - The current approach, as well as most of the API which uses user's space 
coordinates, does
   not work well if different scales are used for each screen and the coordinates 
"overlaps".
 - It looks like the user in the JDK-8231564 tried to avoid covers the taskbar 
by the maximized
   undecorated window, this is a know issue JDK-8022302.


[1] https://docs.microsoft.com/en-us/windows/win32/winmsg/wm-getminmaxinfo
[2] 
https://docs.microsoft.com/en-us/windows/win32/api/winuser/ns-winuser-minmaxinfo?redirectedfrom=MSDN
[3] https://devblogs.microsoft.com/oldnewthing/20150501-00/?p=44964

--
Best regards, Sergey.

Reply via email to