Skip to content

Conversation

@mstr2
Copy link
Collaborator

@mstr2 mstr2 commented Nov 24, 2025

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):
window-size-1

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:
window-size-2

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?).


Progress

  • Change must not contain extraneous whitespace
  • Commit message must refer to an issue
  • Change must be properly reviewed (2 reviews required, with at least 1 Reviewer, 1 Author)

Issue

  • JDK-8372415: Stage size should match visual window bounds (Bug - P4)

Reviewing

Using git

Checkout this PR locally:
$ git fetch https://git.openjdk.org/jfx.git pull/1982/head:pull/1982
$ git checkout pull/1982

Update a local copy of the PR:
$ git checkout pull/1982
$ git pull https://git.openjdk.org/jfx.git pull/1982/head

Using Skara CLI tools

Checkout this PR locally:
$ git pr checkout 1982

View PR using the GUI difftool:
$ git pr show -t 1982

Using diff file

Download this PR as a diff file:
https://git.openjdk.org/jfx/pull/1982.diff

Using Webrev

Link to Webrev Comment

@mstr2
Copy link
Collaborator Author

mstr2 commented Nov 24, 2025

/reviewers 2

@bridgekeeper
Copy link

bridgekeeper bot commented Nov 24, 2025

👋 Welcome back mstrauss! A progress list of the required criteria for merging this PR into master will be added to the body of your pull request. There are additional pull request commands available for use with this pull request.

@openjdk
Copy link

openjdk bot commented Nov 24, 2025

❗ This change is not yet ready to be integrated.
See the Progress checklist in the description for automated requirements.

@openjdk openjdk bot added the rfr Ready for review label Nov 24, 2025
@openjdk
Copy link

openjdk bot commented Nov 24, 2025

@mstr2
The total number of required reviews for this PR (including the jcheck configuration and the last /reviewers command) is now set to 2 (with at least 1 Reviewer, 1 Author).

@mlbridge
Copy link

mlbridge bot commented Nov 24, 2025

Webrevs

@beldenfox
Copy link
Contributor

I haven't uncovered any problems so far but it took me a while to get my bearings. You're working with two coordinate systems, the one used by JavaFX which doesn't include the invisible border and the one used by Windows which does. The naming convention is confusing since the "extended" rectangle is actually the smaller of the two. It would also be good to see some comments clarifying that m_insets, m_maxSize, and m_minSize are all specified in the JavaFX system.

@mstr2
Copy link
Collaborator Author

mstr2 commented Dec 2, 2025

I haven't uncovered any problems so far but it took me a while to get my bearings. You're working with two coordinate systems, the one used by JavaFX which doesn't include the invisible border and the one used by Windows which does. The naming convention is confusing since the "extended" rectangle is actually the smaller of the two. It would also be good to see some comments clarifying that m_insets, m_maxSize, and m_minSize are all specified in the JavaFX system.

I don’t think it’s quite "two coordinate systems" (JavaFX vs Windows). Stage.width/height are intended to include the normal system decorations (title bar + borders), which historically also matches what people mean by "window size": it includes the non-client area, but not purely visual effects like drop shadows. The weirdness on Windows 10+ is that GetWindowRect started including an extra invisible resize border that’s not part of the visible frame, so the window ends up being reported a few pixels larger than it looks. Using DwmGetWindowAttribute(DWMA_EXTENDED_FRAME_BOUNDS) is basically a way to get the visually perceived bounds back.

@beldenfox
Copy link
Contributor

I was thinking that JavaFX and Windows have different ideas of where the window origin (0, 0) lies; Windows thinks it's at the top left of drop shadow area and JavaFX thinks it's at the top left of the title bar (in this PR). But you're right, what's relevant is that there are two rectangles of different sizes. I still think it could be clearer that, say, m_insets applies to the smaller of the two (which is the extended one).

@mstr2
Copy link
Collaborator Author

mstr2 commented Dec 3, 2025

I've added a comment to clarify that m_minSize, m_maxSize, and m_insets are specified with respect to the extended frame bounds.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

rfr Ready for review

Development

Successfully merging this pull request may close these issues.

2 participants