On Mon, 30 May 2022 05:55:38 GMT, Dmitry Kulikov <d...@openjdk.java.net> wrote:
>> Hello, >> Please review this fix for JDK-8282863. >> >> The failing >> `java/awt/FullScreen/FullscreenWindowProps/FullscreenWindowProps.java` test >> basically checks that full-screen window remains full-screen when a display >> mode change occurs. It has been introduced in JDK-8211999, which also >> contains numerous fixes for HiDPI displays. In particular, JDK-8211999 >> changed the code of `Win32GraphicsDevice.setDisplayMode()` so that it uses >> screen dimensions in user space instead of device space, which is correct. >> However, if the display mode change incurs display scaling change, as it has >> been observed on Windows 10 laptop with HiDPI screen, the method used for >> obtaining screen bounds in user space returns incorrect values under certain >> conditions. >> >> The issue is reproducible on Windows 10, when resolution of the primary >> screen is higher than 1024x768 with scaling greater than 100%. Resolution >> and scaling of secondary screen(s) is irrelevant. I used a laptop with >> 2160x1350 display resolution and scaling set to 150%. When the >> `java/awt/FullScreen/FullscreenWindowProps/FullscreenWindowProps.java` test >> is run with these initial conditions, roughly the following happens: >> >> 1. `java.awt.Frame` is created and set as full-screen. >> 2. `Win32GraphicsDevice.setDisplayMode()` is called to change screen >> resolution from 2160x1350 to 1024x768. >> 3. `Win32GraphicsDevice.configDisplayMode()` call immediately changes the >> display resolution to 1024x768, which also incurs the immediate display >> scaling change from 150% to 100%. >> 4. Inside the `Win32GraphicsDevice.setDisplayMode()` screen bounds in user >> space are obtained via `Win32GraphicsConfig.getBounds()`: >> 5. In the native code of `Win32GraphicsConfig.getBounds()` new screen bounds >> in device space (1024x768) are correctly obtained via `MonitorBounds()`. >> 6. Then screen bounds are converted to user space by applying **scaling >> factors, which are not yet updated and correspond to previous display >> mode**. In our case, 1024x768 is scaled down by 150% and becomes 683x512. >> 7. Back in `Win32GraphicsDevice.setDisplayMode()` full-screen window bounds >> are set to incorrectly scaled 683x512 instead of 1024x768. >> 8. After returning from `Win32GraphicsDevice.setDisplayMode()` the test >> waits 4 seconds. >> 9. `WM_DISPLAYCHANGE` message is received and processed, followed by >> `WM_DPICHANGED`, which updates the scaling factors used by >> `Win32GraphicsConfig.getBounds()` to the correct value of 100%. >> 10. After 4 seconds test wakes up and obtains screen bounds in user space by >> calling `Win32GraphicsConfig.getBounds()`, which now correctly returns >> 1024x768. >> 11. Test compares full-screen window bounds with screen bounds, and fails >> with `java.lang.RuntimeException: width is wrong` as 683 is not equal to >> 1024 ± 30 pixels. >> >> Proposed fix adds a `Win32GraphicsDevice.initScaleFactors()` call to >> `Win32GraphicsDevice.setDisplayMode()` code, between calling >> `Win32GraphicsDevice.configDisplayMode()` and >> `Win32GraphicsConfig.getBounds()`. This updates the scaling factors without >> waiting for `WM_DISPLAYCHANGE` or `WM_DPICHANGED`, >> `Win32GraphicsConfig.getBounds()` returns correctly scaled screen bounds in >> user space, and full-screen window remains correctly sized after display >> mode change. >> >> I've run tests from `jdk_awt` group on Windows 10 using a laptop with the >> same settings that caused the issue (primary screen with 2160x1350 >> resolution and 150% scaling), and applying the fix did not introduce any new >> test failures. > > Dmitry Kulikov has updated the pull request incrementally with one additional > commit since the last revision: > > Update src/java.desktop/windows/classes/sun/awt/Win32GraphicsDevice.java > > Comments clean-up > > Co-authored-by: Alexey Ivanov > <70774172+aivanov-...@users.noreply.github.com> Marked as reviewed by aivanov (Reviewer). ------------- PR: https://git.openjdk.java.net/jdk/pull/7835