RFR: 8370498: Improve how Node detects whether a layout property change requires a new layout pass
Andy Goryachev
andy.goryachev at oracle.com
Thu Oct 23 22:09:18 UTC 2025
> We will need a unit test for this.
Perhaps we could even get it a bit further than that. What would you say could be a sufficiently comprehensive set of tests/scenarios to reduce the probability of regression?
Let's say, we limit the depth of the hierarchy to 3 (node-parent-parent), then the combinatorial complexity should still be manageable.
What do you think?
-andy
From: openjfx-dev <openjfx-dev-retn at openjdk.org> on behalf of John Hendrikx <jhendrikx at openjdk.org>
Date: Thursday, October 23, 2025 at 10:47
To: openjfx-dev at openjdk.org <openjfx-dev at openjdk.org>
Subject: Re: RFR: 8370498: Improve how Node detects whether a layout property change requires a new layout pass
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
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/openjfx-dev/attachments/20251023/6bf3e529/attachment-0001.htm>
More information about the openjfx-dev
mailing list