-
Notifications
You must be signed in to change notification settings - Fork 560
8372415: Stage size should match visual window bounds #1982
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
|
/reviewers 2 |
|
👋 Welcome back mstrauss! A progress list of the required criteria for merging this PR into |
|
❗ This change is not yet ready to be integrated. |
Webrevs
|
|
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 |
I don’t think it’s quite "two coordinate systems" (JavaFX vs Windows). |
|
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, |
|
I've added a comment to clarify that |
|
With this fix applied, the problem described in JDK-8285983 disappears and the reported position and size of a full-screen window is as a sane person would expect it to be (position = 0,0 and size = visual bounds of the screen). I suggest we re-open the bug (which was closed as "not an issue") and add it to this PR. |
beldenfox
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The existing changes look fine. GitHub doesn't allow me to comment on unchanged code so I'll just have to write up my comments here.
In GlassView.cpp the _getX and _getY routines return the location of the scene relative to the upper-left corner of the window. I believe these offsets should be relative to the extended frame bounds instead of GetWindowRect.
In GlassWindow.cpp there's a call to the Java routine notifyMoving (which lives in WinWindow.java). At that call site the x and y coordinates are based on GetWindowRect and the anchor is relative to GetWindowRect but the insets are relative to the extended frame bounds. notifyMoving is also called from the setBounds routine in WinWindow.java. In that case I believe it's being called with the coordinates of the extended frame bounds, an anchor relative to GetWindowRect, and insets relative to the extended frame bounds. I think this all needs further review.
|
I've looked at every call to |
|
/issue add JDK-8285983 |
|
@mstr2 |
| pSetThreadDpiAwarenessContext = reinterpret_cast<FnSetThreadDpiAwarenessContext*>( | ||
| GetProcAddress(hModule, "SetThreadDpiAwarenessContext")); | ||
|
|
||
| // Only load GetProcessDpiAwareness if GetThreadDpiAwarenessContext is not available (pre-Win10). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What versions of Windows does JavaFX support? I just spent a half hour searching and couldn't find any statement on this for either JavaFX or the JDK.
As of October of this year the original version of Windows 10 left Microsoft's Long Term Servicing Channel. As of now the earliest version of Windows supported by Microsoft is Win10 2016 (1607), the version where the thread DPI awareness calls were first added. Is JavaFX supporting and testing earlier versions of Windows? If not you should be able to just make direct calls to the thread DPI awareness API's.
This is probably a topic for the mailing list. I'm still surprised I couldn't find this information anywhere.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Even if we didn't officially support Windows 10, I think it's a little too early to remove functionality given that this OS still has a ~40% share of Windows installations.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Definitely. We don't need to worry about Windows 8 or earlier, but it's premature to break Windows 10.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't want to stop supporting Windows 10. I'm referring specifically to Windows 10 RTM, the very first version of 10, which has fallen entirely out of Microsoft's support system. If we only need to support versions of Windows that Microsoft is supporting that would be Windows 10 2016 (1607) in which case there's no need to mess with all the DLL and function pointer retrieval in this code. You can just issue direct calls to SetThreadDpiAwarenessContext and friends.
I will add that though we might say in this thread that we don't need to worry about Windows 8 or earlier I really and truly could not find any public statement to that effect anywhere.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we removed that path, then for Windows 10 < 1607, we wouldn't be able to skip coordinate mapping for the usual (99.9%) case when the Java process is running with per-monitor DPI awareness. This wouldn't cause JavaFX to stop working, we'd just be back at the status quo where we don't account for the visible window frame.
We still need to dynamically load the function though, as it definitely won't be available on Win10 < 1607.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We still need to dynamically load the function though, as it definitely won't be available on Win10 < 1607.
Officially you're doing the right thing by writing code that works on all versions of Windows 10. But this assumes there are users out there with the original release of Windows 10 (no updates past 2015) who will want to install a JavaFX 26-based app. Are there? Can we even test this code? I don't see how this is sustainable going forward.
This is not really a question for you. I should take it to the mailing list.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I can't test this in a systematic way, as I can't be bothered to get an installation of an ancient version of Windows. However, in this particular case, I did test what would happen if the new functions can't be loaded by simply commenting out the code that loads the new functions.
On Windows, the
Stage.widthandStage.heightcorrespond to the window size as returned byGetWindowRect.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
GetWindowRectreturns the window size including these invisible borders, the location and size of aStageisn't exactly what we'd expect.For example, if we place a

StageatsetX(0)andsetY(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):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:

The implementation is quite simple: instead of
GetWindowRect, we useDwmGetWindowAttribute(DWMA_EXTENDED_FRAME_BOUNDS). This gives us the bounds of the visual window borders. If this function fails, we fall back toGetWindowRect(now, I don't know whyDwmGetWindowAttribute(DWMA_EXTENDED_FRAME_BOUNDS)would ever fail... maybe an old Windows version in a remote desktop scenario?).Progress
Issues
Reviewing
Using
gitCheckout this PR locally:
$ git fetch https://git.openjdk.org/jfx.git pull/1982/head:pull/1982$ git checkout pull/1982Update a local copy of the PR:
$ git checkout pull/1982$ git pull https://git.openjdk.org/jfx.git pull/1982/headUsing Skara CLI tools
Checkout this PR locally:
$ git pr checkout 1982View PR using the GUI difftool:
$ git pr show -t 1982Using diff file
Download this PR as a diff file:
https://git.openjdk.org/jfx/pull/1982.diff
Using Webrev
Link to Webrev Comment