RFR: 8345188: Support tree-structural pseudo-classes [v6]

Michael Strauß mstrauss at openjdk.org
Wed Jan 8 17:48:03 UTC 2025


On Wed, 8 Jan 2025 11:25:37 GMT, John Hendrikx <jhendrikx at openjdk.org> wrote:

>> Michael Strauß has updated the pull request with a new target base due to a merge or a rebase. The incremental webrev excludes the unrelated changes brought in by the merge/rebase. The pull request contains seven additional commits since the last revision:
>> 
>>  - Merge branch 'master' into feature/root-pseudo-class
>>  - whitespace error
>>  - add child-indexed pseudo-classes
>>  - add pseudo-class table to Parent
>>  - update cssref
>>  - Set :root pseudo-class on sub-scene root node
>>  - Set :root pseudo-class on root node
>
> modules/javafx.graphics/src/main/java/javafx/scene/Parent.java line 341:
> 
>> 339: 
>> 340:         @Override
>> 341:         protected void onChanged(Change<Node> c) {
> 
> I hate to bring this up, and it perhaps should be dealt with separately, but how safe is this code in `onProposedChange` / `onChanged` when it is re-entered due to the many potential listener callbacks?  For example, the removal of a child on `parent` can trigger list change listeners from the user that can trigger all kinds of other changes that eventually lead to more children changes on this node, triggering a nested `onChanged`; the new changes are adding more opportunities in the form of listeners on pseudo state changes.
> 
> For example, `onProposedChange` will blatantly reset `geomChanged` to `false` in all cases, even if it rejects the change later.  It doesn't check if an `onChange` is in progress higher up the call stack, effectively resetting a flag that is in active use...
> 
> I believe this may be quite a difficult problem to solve if nested calls remain allowed, and one of the easiest ways to fix it IMHO is to reject any changes (in `onProposedChange`) when a change is already in progress. For users this would effectively mean that listeners triggered during a child modification will not be allowed to make further modifications to the same children list until the first one completes.  This is not a common situation, but can happen with very dynamic UI's that construct new nodes in response to triggers; without such protection for nested changes, the errors that crop up are often of a form that seem to be multi-threading issues (where certain invariants seem to be broken), while in reality they're just re-entrant code calls that use instance fields in an unsafe manner.

One option might be to move all pseudo-class modifications to the end of the `onChange` method. This would make the code equivalent to being called after the callback has completed.

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

PR Review Comment: https://git.openjdk.org/jfx/pull/1652#discussion_r1907567157


More information about the openjfx-dev mailing list