-
Notifications
You must be signed in to change notification settings - Fork 29.8k
Fixes Intrinsics for RenderParagraph and RenderWrap #70656
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
also when the layout is lazy, right? e.g. SliverList?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think "Reason given:" really adds anything.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
objectRuntimeType
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(yes i know this is in an assert but we have a lint now)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(also affects other places in the pr)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"(which is used by [getDryLayout] behind the scenes)" sounds mysterious, maybe "(the backend implementation of getDryLayout)" or something?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is a weird condition
|
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if this is correct, it definitely deserves a comment. :-)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
layouted -> laid out
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
might be worth mentioning that these all implement ChildLayouter?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can this use ChildLayoutHelper?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can this use ChildLayoutHelper?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
might be worth adding something about RenderBox here
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
dry
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. |
Piinks
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this have implications for the solution we're exploring in #70855?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can this TODO be removed?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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. |
gspencergoog
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should update the docs in sizedByParent to point the user in the right direction too
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
... or subclasses of RenderBox that set sizedByParent to true but didn't override performResize (see comment below).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.