On Fri, 20 Feb 2026 00:40:36 GMT, Michael Strauß <[email protected]> wrote:

>> On Windows, the `Stage.width` and `Stage.height` correspond to the window 
>> size as returned by `GetWindowRect`.
>> 
>> Up until Windows 10, the size of a window was identical to its visual 
>> borders. However, since Windows 10 has introduced thin visual window 
>> borders, the window manager adds an invisible border of a few pixels around 
>> the window to make it easier to resize the window. Since `GetWindowRect` 
>> returns the window size _including_ these invisible borders, the location 
>> and size of a `Stage` isn't exactly what we'd expect.
>> 
>> For example, if we place a `Stage` at `setX(0)` and `setY(0)`, the window 
>> appears with a small distance from the screen edge, and the window size 
>> extends a few pixels beyond its visual borders (in the following images, the 
>> screenshot size corresponds to the window size; note the invisible padding 
>> around the edges):
>> <img width="300" alt="window-size-1" 
>> src="https://github.com/user-attachments/assets/76ea6861-885f-4bea-aeb7-e8e6464b7199";
>>  />
>> 
>> What we actually want is to have the visual borders line up with the edges 
>> of the screen, and have the window size correspond to the visual borders:
>> <img width="295" alt="window-size-2" 
>> src="https://github.com/user-attachments/assets/ca6bed73-e4e7-4df6-9491-d82792bb0866";
>>  />
>> 
>> The implementation is quite simple: instead of `GetWindowRect`, we use 
>> `DwmGetWindowAttribute(DWMA_EXTENDED_FRAME_BOUNDS)`. This gives us the 
>> bounds of the visual window borders. If this function fails, we fall back to 
>> `GetWindowRect` (now, I don't know why 
>> `DwmGetWindowAttribute(DWMA_EXTENDED_FRAME_BOUNDS)` would ever fail... maybe 
>> an old Windows version in a remote desktop scenario?).
>
> Michael Strauß has updated the pull request with a new target base due to a 
> merge or a rebase. The pull request now contains nine commits:
> 
>  - review comments
>  - Merge branch 'master' into fixes/window-size
>  - fix merge
>  - Merge branch 'master' into fixes/window-size
>    
>    # Conflicts:
>    #  modules/javafx.graphics/src/main/native-glass/win/GlassWindow.cpp
>    #  modules/javafx.graphics/src/main/native-glass/win/GlassWindow.h
>  - Merge branch 'master' into fixes/window-size
>  - return earlier
>  - handle edge cases
>  - add comments
>  - Stage size should match extended frame bounds

modules/javafx.graphics/src/main/native-glass/win/Utils.cpp line 120:

> 118:  * DPI-virtualize the returned coordinates.
> 119:  *
> 120:  * It is possible (though uncommon) for the JVM to run in a DPI-unaware 
> or system-DPI-aware context.

Do you have a recommended way of testing JavaFX as DPI unaware? This is hard to 
do these days presumably due to the manifest you mention.

modules/javafx.graphics/src/main/native-glass/win/Utils.cpp line 182:

> 180:                 DPI_AWARENESS_CONTEXT currentAwareness = 
> pGetThreadDpiAwarenessContext();
> 181: 
> 182:                 return currentAwareness == 
> DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE ||

On my system canSkipMapping always returns false. I think to compare 
DPI_AWARENESS_CONTEXT values you have to use AreDpiAwarenessContextsEqual. The 
documentation for DPI_AWARENESS_CONTEXT sure makes it look like an enum or some 
other type of simple scalar but apparently it's not.

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

PR Review Comment: https://git.openjdk.org/jfx/pull/1982#discussion_r2985408159
PR Review Comment: https://git.openjdk.org/jfx/pull/1982#discussion_r2985641504

Reply via email to