On Wed, 1 Oct 2025 16:42:42 GMT, John Hendrikx <[email protected]> wrote:

>> That's exactly what this old PR does.
>
>> When a situation like this happens in reality, we might see a momentary 
>> flicker due to the layout spanning several pulses, correct?
> 
> Well, if layout runs (due to a significant change), you'll see components be 
> re-arranged, and if a 2nd pulse is needed, you would probably not notice as 
> things were moved around a lot anyway.  But on top of that, there is a good 
> chance the 2nd pass is just recalculating everything without actually 
> changing anything because it is often triggered without a good reason.  For 
> example:
> 
> Take an HBox for example.  During layoutChildren, it will position its 
> children.  If this involves moving a child to the right or left because an 
> earlier child has shrunk/grown then layout X is changed and triggers the 
> logic in Node (without good reason I might add).  This is in part because 
> HBox does not update or set the "current layout child" at all (none of the 
> containers do this, except Parent's layoutChildren which is almost always 
> overridden).  So this code below in Node will trigger and force another 
> layout pass:
> 
>                     if (p != null && !p.isCurrentLayoutChild(Node.this)) {
>                         if (isManaged()) {
>                             // Force its parent to fix the layout since it is 
> a managed child.
>                             p.requestLayout(true);
>                         } else {
>                             // Parent size changed, parent's parent might 
> need to re-layout
>                             p.clearSizeCache();
>                             p.requestParentLayout();
>                         }
>                     }
>                     
> All the ingredients match:
> - LayoutX was modified on a child
> - Its parent is not `null` (it's the HBox)
> - It is not the current layout child (HBox doesn't update this before 
> modifying a position on a child)
> - The child in question is managed (all children in an HBox generally are)
> 
> End result: schedule another layout pass
> 
> Now, if in the 2nd pass none of the X (or Y) positions change again, then 
> this 2nd pass will end up doing nothing.  Quite wasteful.
> 
>> The platform itself can't really do anything, except for the application 
>> code to call the layout() explicitly to avoid flicker, right?
> 
> Calling `layout` won't do much when the flags are bad, as layout basically 
> operates based on those flags.  So if you call layout at the root, and the 
> flags say that it is `CLEAN` then it stops right there.  
> 
> However there are many things that will "fix" the situation; this can be a 
> nearby Node t...

> Or maybe even make it more generic: detect when (a small number of) 
> additional layout passes are needed and do them right away instead of waiting 
> for another pulse?

But also avoid passes that are not needed... I mean HBox almost always 
triggering a redundant 2nd pass makes the logic in `Node` suspect IMHO.

I get why the logic is **really** there; a user may modify layoutX randomly on 
some managed control outside a layout pass; in that case you do want the Parent 
that is managing those nodes to take control and "fix" what the user broke, but 
it is triggering much more often than needed.

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

PR Review Comment: https://git.openjdk.org/jfx/pull/1879#discussion_r2395250606

Reply via email to