-
Notifications
You must be signed in to change notification settings - Fork 548
8346281: [Windows] RenderScale doesn't update to HiDPI changes #1964
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?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,5 +1,5 @@ | ||
| /* | ||
| * Copyright (c) 2010, 2024, Oracle and/or its affiliates. All rights reserved. | ||
| * Copyright (c) 2010, 2025, Oracle and/or its affiliates. All rights reserved. | ||
| * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | ||
| * | ||
| * This code is free software; you can redistribute it and/or modify it | ||
|
|
@@ -26,7 +26,9 @@ | |
|
|
||
| import java.util.Arrays; | ||
| import java.util.Collections; | ||
| import java.util.HashSet; | ||
| import java.util.List; | ||
| import java.util.Set; | ||
|
|
||
| public final class Screen { | ||
|
|
||
|
|
@@ -370,7 +372,7 @@ public static void setEventHandler(EventHandler eh) { | |
| */ | ||
| public static void notifySettingsChanged() { | ||
| // Save the old screens in order to dispose them later | ||
| List<Screen> oldScreens = screens; | ||
| Set<Screen> oldScreens = new HashSet<>(); | ||
|
|
||
| // Get the new screens | ||
| initScreens(); | ||
|
|
@@ -389,16 +391,15 @@ public static void notifySettingsChanged() { | |
| for (Screen newScreen : screens) { | ||
| if (oldScreen.getNativeScreen() == newScreen.getNativeScreen()) { | ||
| w.setScreen(newScreen); | ||
| oldScreens.add(oldScreen); | ||
| break; | ||
| } | ||
| } | ||
| } | ||
|
|
||
| // Dispose the old screens | ||
| if (oldScreens != null) { | ||
| for (Screen screen : oldScreens) { | ||
| screen.dispose(); | ||
| } | ||
| // Dispose the old screens, if any | ||
| for (Screen screen : oldScreens) { | ||
| screen.dispose(); | ||
| } | ||
|
Comment on lines
+400
to
403
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm still a little puzzled as to why a change was needed in the class at all. Even with the change you made to the native Windows glass code, it seems that calling dispose for all of the old Java screen objects is what we want. Am I missing something?
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There is a reason for it, otherwise I wouldn't have modified If you run the test in the JBS issue, on Windows with two monitors (primary with scale > 100%), with the changes from
Adding some debugging info, it can be seen that, when the application starts (without doing any external change in Windows settings), there is a DPI event, that calls When opening the This causes some unexpected issues for instance in So the change in Does that make sense?
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hmm. I see what you are saying, and can confirm the behavior. With your proposed fix, though, it seems like we will still have a situation where an in-use screen object is no longer in the list of screens. When this happens it will point to the same native screen object as one of the newly-created screens. This seems fragile. Maybe we could still dispose all old screens, but do it in a way that allows it to later be mapped to a new screen? Or, thinking out loud, maybe "put back" the screens that didn't actually change as the result of the DPI change notification? I'll want to think about this and take a closer look, but it will be a couple days before I can get to it. |
||
| } | ||
|
|
||
|
|
||

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.
Does the order matter? I don't think so, but if it does,
LinkedHashSetwould preserve the order.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.
No, it doesn't matter.
The old screens are "disposed" just by setting their native pointer to 0L, so they can't be reused, while the new screens instances are passed to the windows, to keep an updated instance.
Note that even if old screen and new screen have the very same information (nothing changed for this particular screen), since
WinWindow::notifyMovinguses the equality operator (screen 1 == screen 2), we need to keep a valid instance inWindow::screen, and thereforeScreen::disposeis just a way of invalidating old instances. Then, since they are no longer referenced by any window, they can be gc'ed.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 had exactly the same question, and looked into the implementation.
Is it likely the implementation would change and the order be important in the future?
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 think so. And I would also argue that it would be weird, if not even bad if the order of disposing a
Screenwould matterThere 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.
Agreed. In this case I don't see how it could ever matter.
I only raised the question because whenever I see an ordinary HashSet being iterated, I always ask myself whether the iteration order matters.
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 agree 100%, especially since bugs in that case are really hard to find and debug.
I remember from my personal experience tests that sometimes failed, because the test did call
iterator().next()on a Collection, which was a HashSet.😄I just saw that I forgot to quote Andy on my previous answer. Just to emphasize this: I don't see how the implementation could be changed in such a way that the order would matter in the future.