-
Notifications
You must be signed in to change notification settings - Fork 513
8357067: Platform preference change can emit multiple notifications #1810
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
👋 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
|
/reviewers 2 |
@@ -84,7 +84,7 @@ public void handleOpenFilesAction(Application app, long time, String files[]) { | |||
// currently used only on Mac OS X | |||
public void handleQuitAction(Application app, long time) { | |||
} | |||
public void handlePreferencesChanged(Map<String, Object> preferences) { | |||
public void handlePreferencesChanged(Map<String, Object> preferences, int suggestedDelayMillis) { |
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 wonder if we should always debounce the changes with a short delay?
A delay of 100-150 ms will be acceptable from the user perspective.
What do you think?
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.
Most changed settings are not correlated with other settings, so no waiting is necessary (for example, we wouldn't wait after a reducedMotion
change). We only need to wait a bit when a single user-facing setting can affect several correlated preferences. This only seems to be the case on Windows, and only when changing high-contrast themes.
/** | ||
* Suggested aggregation delay for changes that come in over a period of time. | ||
*/ | ||
static constexpr int SUGGESTED_DELAY_MILLIS = 1000; |
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.
1 second seems too long.
What is the typical range for the high contrast train of changes?
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.
Quite a lot, Windows takes around 1-2 seconds to change to and from a high-contrast theme (there's even a full-frame wait screen that pops up). The suggested delay of 1 second works reliably on my machine.
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 it takes that long to update all the colors, maybe we should not add complexity to this subsystem and just send the events as they come?
What exactly is the problem the user experiences right now?
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.
A single user-facing setting change should only result in a single change notification in JavaFX, as that's what developers would intuitively expect. I'm planning to add support for CSS system colors soon, which basically exposes platform colors to stylesheet authors. When the color palette changes, I want all changes to be applied at the same time and not piece by piece.
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.
Are you sure a delay is a good way to solve this? It won't guarantee that no inconsistent states will be observed (what if Windows is slower, or a change is reverted within the delay period -- you may still see "half" changes).
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 that there's a perfect way to solve this. Yes, this can theoretically happen, and then you'll see a visual glitch. I can imagine that this might also be the reason why Windows shows a full-screen popup when you switch to and from a high-contrast theme: to hide glitchy applications during the transition period.
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.
Alright, just making sure, as you mentioned in another thread seeing inconsistent transient states isn't an acceptable trade-off. They can still occur, and so users can't rely on them. In that respect the situation is similar to before this change, other than it being less likely to occur (and perhaps never or rarely in practice).
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.
Yes, I think having inconsistent transient states is not an acceptable trade-off, that's why I think reducing them by 99,9% (from guaranteed to happen, to almost hever happening) is sensible. If it does happen anyway, it shouldn't crash your application but show up as a visual glitch (I mean, we're talking about colors). In that sense, you can "rely" on it.
I am not comfortable with this change, as it falls under application requirements. The function of the JavaFX platform is to communicate the OS events as faithfully as it can, in my opinion. If the application requirements call for some debouncing, especially that with a one second delay, then the application is free to implement that. If, however, the application requirements call for no delay, this change makes it impossible. |
The platform preferences API is an abstraction, and nowhere do we specify that it replicates the exact stream of OS events. What we do (implicitly) specify, however, is that the observable state of platform preferences accurately reflects the OS settings. Do you really think that it is okay for an application to be able to observe inconsistent transient states? In this example, applications can observe inconsistent
An application can require all it wants, but "inconsistent transient states are okay" is not an acceptable trade-off. There's no delay for uncorrelated changes, which is as good as it gets. |
I'm in favor of abstracting this away as good as possible, i.e. trying to aggregate such events if some sufficiently universal timing parameters (or something better than time-based logic) can be found. As an application developer I often choose javafx especially because it keeps OS-implementation dependent behavior to a minimum and reduces the likelihood of me "using things the wrong way", like having inconsistent states that might need to be handled. And who knows what the next version of windows will do... |
The function of JavaFX is to abstract the platform it runs on, preferably in such a way that one can't distinguish between platforms at all, just like about every other API the JDK offers (ie. NIO, Threads, Swing, etc). This is one of the reasons we don't expose window handles or DirectX/GL API's to users. |
Some platform preference changes can trigger the emission of multiple notifications. For example, when switching from a high-contrast theme on Windows to the regular theme, the following notifications are emitted (log can be viewed in
PlatformPreferencesChangedTest
):Notably, the values for Windows.UIColor.Foreground/Background are inconsistent between the notifications (although they are eventually correct). In general, only a single notification should be emitted that includes all of the changed preferences.
This artifact is only visible on Windows. The reason is that changing some system settings (like high-contrast theme) causes a number of different window messages to be sent to the application. We should wait for all window messages to come in, and then aggregate all of the changed preferences into a single notification.
In order to minimize the delay between changing a system setting and sending out the notification in JavaFX, the implementation only waits when instructed to do so by the native toolkit. This allows us to instantly send out notifications for most changes, but selectively wait a bit for changes where the native toolkit knows that more changes might be coming in.
Progress
Issue
Reviewing
Using
git
Checkout this PR locally:
$ git fetch https://git.openjdk.org/jfx.git pull/1810/head:pull/1810
$ git checkout pull/1810
Update a local copy of the PR:
$ git checkout pull/1810
$ git pull https://git.openjdk.org/jfx.git pull/1810/head
Using Skara CLI tools
Checkout this PR locally:
$ git pr checkout 1810
View PR using the GUI difftool:
$ git pr show -t 1810
Using diff file
Download this PR as a diff file:
https://git.openjdk.org/jfx/pull/1810.diff
Using Webrev
Link to Webrev Comment