-
Notifications
You must be signed in to change notification settings - Fork 29.7k
Attach an Element's render object to a designated OverlayEntry #39104
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
Attach an Element's render object to a designated OverlayEntry #39104
Conversation
8029459 to
8ca93a6
Compare
goderbauer
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.
Some comments I noticed during the initial read-through.
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.
Why this change?
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 default implementation of redepthChild should respect AbstractNode.depth overrides so the minDepth trick in _RenderFollowerProxyBox works
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.
That will probably have painful performance implications (moves this from a simple jmp to an indirect jump).
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.
When would you call visitChildren while _offstage is still null? Should this be an assert?
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 ran into this issue #37161 when I was poking around. Probably was trying to print the overlay before it was mounted and toString() threw.
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.
let's resolve this in a separate 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.
This probably needs a better doc comment explaining when and for what this should and shouldn't be used.
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.
Move this annotation to after the 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.
This comment doesn't seem useful.
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.
Maybe: overlayChild to make it clear that this is the child that goes into the overlay?
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.
A widget that is build like a regular child, but visually appears in the [overlayEntry].
The widget is build in the build context of this widget, but its render object is attached to the overlayEntry.
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 the slot's identity is only defined by the element - can you just use the element as slot?
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.
_OverlayConduitElement used to have no render object (similar to a ComponentElement) so I added this class to differentiate the overlayChild slot and the child slot. I guess it's safe to get rid of it 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.
This is strange: The only child we can forget is the overlayItem? What about the child child? Can those not be different?
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 is the if missing a return maybe? (If so, we should add a test that fails without it)
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.
oh it's missing a return. Thanks for catching that!
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.
child = null; didn't know it was possible 👀
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 one have multiple slots? Can slot just be null?
|
@LongCatIsLooong Any chance you can merge this to tip of tree? I tried checking out the branch but I got a lot of merge conflicts. |
|
So I tried this out yesterday and by and large it seems to work as expected (which is impressive! Wow!). However, I think we need to separate out the conduit API from Overlay. Having them be tied too closely leads to all kinds of problems, for example you can't use Positioned in the overlayChild. The other weird thing about this API is that if you have multiple children you want to move to elsewhere in the tree you need one widget for each one. That took me a while to understand. Once I got the hang of it I was able to work with that easily enough. Here's the code I wrote to experiment with this: http://junkyard.damowmow.com/606 I think I need to do more experiments, but I'd like to wait to have a version that isn't tied to the Overlay before I do that. |
f36d8b6 to
6f2d077
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.
looks like the comments need updating
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.
done
2cef766 to
0db2ab9
Compare
|
any updates? Can we merge this? |
|
Oh ok, I see it's just in progress :) gtk |
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.
nit: since the class is private, the member can be public. this lets you avoid the double-underscore thing.
|
I like this new approach. I need to try playing with it. |
|
@LongCatIsLooong points out for (3) that when the Leader is pushed down, its nodes are (temporarily) removed from the tree which also removes the children from the Follower, so it actually reduces to case (1). So really all we need to do is make sizedByParent prevent the layout() call from laying out the children immediately. |
|
Looking at the test failures, this probably requires a rebase to make cirrus happy. |
1ebdede to
1c61cb4
Compare
|
@Hixie @goderbauer I tried out the "throw It seems some render objects need not only the size of their child but also the child's layout, e.g. render objects that call their child's |
|
|
|
@LongCatIsLooong Do you think there still is a path forward for this PR? Are you still working on it? |
|
Yes I'm still (not very actively) working on this. I think it may still be doable, just need to find an approach that requires less crazy framework changes. |
3e1c937 to
4b6adf1
Compare
4b6adf1 to
af596b1
Compare
|
@Hixie @goderbauer all the tests seem to be passing now. Could you take a look? I added a |
chunhtai
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.
For the depthbarrier, if i understand correctly, it is trying to prevent the attached children under conduit anchor to be laid out before the anchor. If that is the intention, have you checked out this https://github.com/rrousselGit/flutter_portal/blob/rework/lib/src/portal.dart?
This is @rrousselGit attempt to deal with this problem and i think it worth considering. The goal is the conduit widget is not responsible for laying out or paint its remote child. It merely attach its remote child to the anchor key. When the conduit anchor layout, it pick up the anchor key and see which children it has and proceed to layout and paint them. The entire discussion can be found in #50961
Besides the comment, I have a general question, It seems like the attempt here is to wrapped the overlay with conduit and conduitanchor to provide declarative overlay api. The portal is trying to achieve the same thing except it replace the overlay with an entire different system Portal. Why do we prefer one over the other?
| /// | ||
| /// The [dependent] must be [attached], has the same [PipelineOwner] as this | ||
| /// [RenderObject], and its [shouldDeferLayout] and [sizedByParent] must be true. | ||
| /// Additionally To prevent introducing circular dependencies, [dependent]'s |
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.
| /// Additionally To prevent introducing circular dependencies, [dependent]'s | |
| /// Additionally to prevent introducing circular dependencies, [dependent]'s |
| class _RenderConduit extends RenderProxyBox { | ||
| _RenderConduit([RenderBox child]) : super(child); | ||
|
|
||
| _RenderConduitAnchor _follower; |
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 was confused by the name. If i read it correctly, shouldn't the Conduit be follower and ConduitAnchor be the leader because conduit attach its child the conduitanchor?
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 anchor is named follower in the sense that it depends on its conduit. The anchor changes if its conduit changes, but not the other way around. I guess dependent/dependency sounds good here 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.
The problem with naming the anchor follower is that you then have one follower with multiple leaders which is counterintuitive. Usually there should only be one leader with multiple followers. The dependent/dependency sounds good
I can answer that question: Although if it were to be merged into Flutter, it could still be valuable to separate them, to help the migration. |
In the The conduit does the layout of the overlay entry (where the constraints are obtained with an object equivalent to Although I'm not sure if this has undesired side-effects |
|
@rrousselGit Thanks for the explanation! I think the current implementation in the rework branch will probably break |
It did, but I managed to fix it (it's in the branch) My biggest worry was about RepaintBoundary & co, wondering if there isn't an edge case where the UI doesn't refresh or something Haven't found anything so far though. |
|
Are you giving up on this?
…On Fri, Jun 19, 2020, 22:32 LongCatIsLooong ***@***.***> wrote:
Closed #39104 <#39104>.
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#39104 (comment)>, or
unsubscribe
<https://github.com/notifications/unsubscribe-auth/AEZ3I3ITSE5M6G6WT4TFIB3RXPKNHANCNFSM4IO4OPUA>
.
|
|
@rrousselGit no I'm just trying to reduce the number of open PRs since I'm currently not working on this. |
|
What remains to be done? Between Hero/package:animation issues, state restoration, and provider having difficulties, I think it's quite important and may continue it myself. |
Description
This PR adds a new widget
OverlayConduitthat manages a regular child and anoverlayItemchild. When mounted, theoverlayItemchild has the same behavior as the regular child, except that it attaches its render object to the designatedoverlayEntry. Thus theoverlayItemgets its inherited widgets from the currentBuildContext, as the regular child does. This also guarantees that when the entireOverlayConduitsubtree unmounts, the removal of listeners and invocation ofState.disposewill proceed in an orderly fashion: the deepest elements get removed/disposed of first, preventing #35555 from happening.Classes in this PR, in a typical setting
Related Issues
#36220
Tests
I added the following tests:
packages/flutter/test/widgets/overlay_conduit_test.dart
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
Does your PR require Flutter developers to manually update their apps to accommodate your change?