Fixes Intrinsics for RenderParagraph and RenderWrap#70656
Fixes Intrinsics for RenderParagraph and RenderWrap#70656goderbauer merged 12 commits intoflutter:masterfrom
Conversation
There was a problem hiding this comment.
also when the layout is lazy, right? e.g. SliverList?
There was a problem hiding this comment.
I don't think "Reason given:" really adds anything.
There was a problem hiding this comment.
(yes i know this is in an assert but we have a lint now)
There was a problem hiding this comment.
(also affects other places in the pr)
There was a problem hiding this comment.
should this mention debugCheckingIntrinsics? It seems to be the real reason this function exists...
f84ef65 to
9c234b6
Compare
There was a problem hiding this comment.
"(which is used by [getDryLayout] behind the scenes)" sounds mysterious, maybe "(the backend implementation of getDryLayout)" or something?
|
I'm worried about the amount of duplicate code that this involves. Is there any way we can use this to simplify matters? Maybe find places where the intrinsics can defer to the dry layout? Or ways the dry and wet layouts can be implemented as one method? |
There was a problem hiding this comment.
if this is correct, it definitely deserves a comment. :-)
There was a problem hiding this comment.
might be worth mentioning that these all implement ChildLayouter?
There was a problem hiding this comment.
can this use ChildLayoutHelper?
There was a problem hiding this comment.
can this use ChildLayoutHelper?
There was a problem hiding this comment.
might be worth adding something about RenderBox here
I guess it's not all that bad. You do end up reusing a bunch of code. Where does the previous intrinsic/layout logic now defer to the new API to solve the bug? |
b5d6d2f to
56a8f06
Compare
It's used in three places:
|
|
I was able to simplify the RenderWrap code a little more by implementing its other intrinsics methods in terms of dryLayout. The new API is now used in the following places:
|
|
Nice. |
1796776 to
9a9e9b7
Compare
|
I updated this PR with the drayLayout implementations for the remaining RenderBoxes. |
There was a problem hiding this comment.
The other intrinsics in this file are still incorrect.
I removed the legacy mode from here and closed the other PR since SliverFillRemaining seems to require intrinsics. |
There was a problem hiding this comment.
The name feels a little odd: If I was someone seeing it for the first time, I might wonder if there was a wet layout too, and what dry refers to.
Maybe computeDryRunLayout? computeDesiredLayout? computeAPrioriLayout?
There was a problem hiding this comment.
I am not really happy about any of these names... I added a paragraph to the docs explaining why this is dry and the other layout is wet.
There was a problem hiding this comment.
Instead of the paragraph, why not change the name to computeDryRunLayout? Seems more self-documenting.
eb3572c to
548b602
Compare
| /// significant optimizations. Classes that use this approach should override | ||
| /// [sizedByParent] to return true, and then override [performResize] to set the | ||
| /// [size] using nothing but the constraints, e.g.: | ||
| /// [sizedByParent] to return true, and then override [computeDryLayout] to |
There was a problem hiding this comment.
We should update the docs in sizedByParent to point the user in the right direction too
There was a problem hiding this comment.
Will open a PR to add a note to sizedByParent.
| void performResize() { | ||
| // default behavior for subclasses that have sizedByParent = true | ||
| size = constraints.smallest; | ||
| size = computeDryLayout(constraints); |
There was a problem hiding this comment.
This seems like a hugely breaking change. Many (if not most) render objects that set sizedByParent to true were likely relying on the old default behavior in performResize, and now they'll get assertion errors in the default implementation of computeDryLayout.
I know this is listed as a breaking change, but was it intentional for it to break so many places?
There was a problem hiding this comment.
In the framework there appear to be a total of 16 RenderObject subclasses that set sizedByParent to true. Of those, only 2 used to rely on the default of performResize (constraints.smallest) and the remaining 14 had custom implementations. If I recall correctly, there also wasn't any customer_test that relied on the old default of performResize. With that, I wouldn't really call this "hugely breaking"...
I considered making the default computeDryLayout return constraints.smallest if sizedByParent was set, but ultimately decided against making that method more complicated (and harder to reason about) since the impact of the change seemed so low.
Having said all that, is there something I missed that makes this change more breaking?
There was a problem hiding this comment.
Interesting. When I ran across this, it's because I hit the error in my app; I had three render objects in which I had overridden sizedByParent to return true, and in all three cases, I was relying on the old default performResize behavior.
But based on your data, it seems I may be an outlier.
There was a problem hiding this comment.
Side-note: once my app's done (and I write tests), I plan to add them to the customer tests 🙂
| /// Computes the value returned by [getDryLayout]. Do not call this | ||
| /// function directly, instead, call [getDryLayout]. | ||
| /// | ||
| /// Override in subclasses that implement [performLayout] or [performResize]. |
There was a problem hiding this comment.
... or subclasses of RenderBox that set sizedByParent to true but didn't override performResize (see comment below).
There was a problem hiding this comment.
Will open a PR to add this.

For google3 rollers: This change requires dnfield/flutter_svg#450 and cl/343539658.
Description
Fixes #48679 by implementing the solution outlined in #48679 (comment). Going forward, authors of RenderBox subclasses will have to implement a new
computeDryLayoutmethod, which calculates nondestructively the Size that the RenderBox would like to be under the given set of constraints.Furthermore, performResize is now implemented by calling the new computeDryLayout method and does not have to be overridden in subclasses anymore.
Last, but not least, this change adds a
computeSizeForNoChildmethod toRenderProxyBoxMixin, which is called from performLayout and computeDryLayout when the RenderProxy has no child to determine its size based on the current constraints (previously this was done by calling performResize, which was a little odd since performResize is documented to only be called when sizedByParent is true (which it often isn't in these cases)). The default implementation just returnsconstraints.smallest(which is whatperformResizeused to set the size as as well).Related Issues
Fixes #48679
Tests
I added the following tests:
Checklist
Before you create this PR, confirm that it meets all requirements listed below by checking the relevant checkboxes (
[x]). This will ensure a smooth and quick review process.///).flutter analyze --flutter-repo) does not report any problems on my PR.Breaking Change
Did any tests fail when you ran them? Please read Handling breaking changes.