On Thu, 21 May 2026 15:14:38 GMT, Alexander Zvegintsev <[email protected]> 
wrote:

> [JDK-8185862](https://bugs.openjdk.org/browse/JDK-8185862) introduced several 
> behavioral changes:
> 
> 1. `CountMonitors()` started counting only those `HMONITOR` from 
> `EnumDisplayMonitors` for which `CreateDC` was successful.
> 2. A new state `0 valid monitors` appeared, which did not exist before.
> 3. In `Devices::GetDevice`, the lower bound check was insufficient (`index < 
> 0` instead of `index <= 0`,  this was not introduced by 
> [JDK-8185862](https://bugs.openjdk.org/browse/JDK-8185862) though). 
> Thus, we could attempt to read the first element of a zero-length array, 
> which caused a crash in `sun.awt.Win32GraphicsDevice.initNativeScale`.
> 3. Invalidation only occurres for devices whose indices were removed from the 
> end of the array.
> In RDP scenarios, a device may be replaced at the same index without changing 
> the total number of screens, which bypassed invalidation.
> 
> ---
> 
> Changes in this fix:
> 
> 1. Combined `CountMonitors()` and `CollectMonitors()`. Monitors are now 
> collected into a dynamic array in a single pass.
> 2. The working list of devices is no longer replaced by an empty one.
> 3. `displayChanged()` is called only after a successful native update.
> 5. Added RDP transient states handling (retries by timer and by session 
> connect).
> 6. `GetDevice()` now returns `NULL` if `numDevices <= 0`.
> 7. Improved device comparison logic: comparisons are now performed using 
> display data (`dwFlags`, `szDevice`).
> Changed devices are invalidated, unchanged ones receive transferred Java 
> references to the new native device.
> 
> ---
> 
> Testing:
> 
> The fix seems to be stable over various scenarios of changing display 
> configurations, locally and over RDP.
> CI testing is also green.
> 
> 
> 
> ---------
> - [x] I confirm that I make this contribution in accordance with the [OpenJDK 
> Interim AI Policy](https://openjdk.org/legal/ai).

src/java.desktop/windows/native/libawt/windows/awt_Win32GraphicsDevice.cpp line 
628:

> 626:         }
> 627:     }
> 628: 

Is it intentional that if objPtr == NULL that we release the jni ref to the old 
java device and set javaDevice = NULL ?
It would make sense if this is the intended way to clear the javaDevice but I 
don't have the whole picture yet. If intentional an explanatory comment would 
help.

src/java.desktop/windows/native/libawt/windows/awt_Win32GraphicsDevice.cpp line 
649:

> 647:         env->DeleteWeakGlobalRef(javaDevice);
> 648:     }
> 649:     javaDevice = device->javaDevice;

Why don't we need a new JNI ref here ?

-------------

PR Review Comment: https://git.openjdk.org/jdk/pull/31238#discussion_r3320221113
PR Review Comment: https://git.openjdk.org/jdk/pull/31238#discussion_r3320254068

Reply via email to