RFR: 8370498: Improve how Node detects whether a layout property change requires a new layout pass

John Hendrikx jhendrikx at openjdk.org
Thu Oct 23 17:47:36 UTC 2025


On Thu, 23 Oct 2025 15:52:55 GMT, Kevin Rushforth <kcr at openjdk.org> wrote:

> Reviewers: @johanvos @kevinrushforth @arapte
> 
> We will need a unit test for this. 

I think I can add one that confirms that no 2nd layout pass occurs when it is not needed when detected changes are part of the current pass.

> What is the risk of regression?

I think it is certainly possible that some poorly constructed `layoutChildren` methods may inadvertently be relying on a 2nd layout pass occurring whenever there is a major UI change (when a control changes sufficiently that its parent must also change size).  If that 2nd pass however did anything more than "confirming" the first layout pass, then this likely would result in an infinite layout loop (whereas now it would stop after a single pass).  Assuming that controls that create infinite layout loops are fixed before they reach a wide audience (as you'd likely notice the drain on resources) it seems to me that it is unlikely such controls are in active use.

Note that it is really easy to get the "old" behavior; just return `false` in `Parent::inLayoutChildren` -- I've been using this to test differences.  If we're really worried this may cause problems, we could turn this into a system property so people may opt out of this fix.

The benefits of this fix could be a reduction in layout passes by half when doing things like resizing windows.  This may be quite noticeable on heavy controls like TableViews.

> Are there additional tests that we could add to help detect any regressions?

Code that may not work correctly with this fix is code where a container is unable to size and position its direct children in a stable fashion in one pass.  If the container is tracking state between layout passes, is not clearing caches at the right time, etc, then a 2nd layout pass (with all else being equal) may result in its direct children being positioned differently.  It's possible some code out there has such problems; they would currently require a 2nd (and perhaps a 3rd or 4th pass) before reaching a stable set of positions and sizes for its direct children.  Note that if they never stabilize, the code before this fix would just keep running layout passes indefinitely.  The fixed code will only do so once regardless.

As soon as anything other than the container and its direct children is modified (ie. a sibling container, a grand child, or a child of a sibling container), then this code won't block another layout pass, so any regressions will be limited to containers being unable to decide how to position its children in a single pass.  If the layout children code modifies some grand child, or some other node it happens to have a reference to, then this will still result in a new layout pass.

I could write a test that will work with the old code, and fail with the new code (simple counting layout passes, or having some state that requires multiple passes would work to "detect" this fix) but am unsure what purpose that would serve.  It's not a supported or documented use of the layout system.  Layouts that need time to settle should still have a strict opinion on the positioning of a single container's direct children, but are likely being jostled by other influences (sibling containers, grand children).  Such situations should still trigger further layout passes until everything converges (hopefully).

Note that "failure" here would just mean that it shows you the result of the first pass; FX would not crash or go into infinite loops.

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

PR Comment: https://git.openjdk.org/jfx/pull/1945#issuecomment-3438319381


More information about the openjfx-dev mailing list