-
Notifications
You must be signed in to change notification settings - Fork 29.7k
Stand-alone widget tree with multiple render trees to enable multi-view rendering #125003
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
Merged
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
b53331d to
b4f9996
Compare
8993887 to
c6dd65f
Compare
478a36b to
43a9a19
Compare
9b1458e to
7c92446
Compare
engine-flutter-autoroll
added a commit
to engine-flutter-autoroll/packages
that referenced
this pull request
Jul 18, 2023
…multi-view rendering (flutter/flutter#125003)
engine-flutter-autoroll
added a commit
to engine-flutter-autoroll/packages
that referenced
this pull request
Jul 18, 2023
…multi-view rendering (flutter/flutter#125003)
engine-flutter-autoroll
added a commit
to engine-flutter-autoroll/packages
that referenced
this pull request
Jul 18, 2023
…multi-view rendering (flutter/flutter#125003)
engine-flutter-autoroll
added a commit
to engine-flutter-autoroll/packages
that referenced
this pull request
Jul 18, 2023
…multi-view rendering (flutter/flutter#125003)
engine-flutter-autoroll
added a commit
to engine-flutter-autoroll/packages
that referenced
this pull request
Jul 18, 2023
…multi-view rendering (flutter/flutter#125003)
engine-flutter-autoroll
added a commit
to engine-flutter-autoroll/packages
that referenced
this pull request
Jul 18, 2023
…multi-view rendering (flutter/flutter#125003)
engine-flutter-autoroll
added a commit
to engine-flutter-autoroll/packages
that referenced
this pull request
Jul 18, 2023
…multi-view rendering (flutter/flutter#125003)
stuartmorgan-g
added a commit
to stuartmorgan-g/packages
that referenced
this pull request
Jul 18, 2023
As of flutter/flutter#125003 the current method these tests use to get the screen width throws an exception, since it assumes that the first widget in the tree has certain properties. To make the test more robust, this get the width of the outmost Column, which is part of the test setup, rather than whatever the first widget is. Unblocks the flutter->packgaes roller.
auto-submit bot
pushed a commit
to flutter/packages
that referenced
this pull request
Jul 19, 2023
As of flutter/flutter#125003 the current method these tests use to get the screen width throws an exception, since it assumes that the first widget in the tree has certain properties. To make the test more robust, this get the width of the outmost Column, which is part of the test setup, rather than whatever the first widget is. Unblocks the flutter->packgaes roller.
engine-flutter-autoroll
added a commit
to engine-flutter-autoroll/packages
that referenced
this pull request
Jul 19, 2023
…multi-view rendering (flutter/flutter#125003)
auto-submit bot
pushed a commit
to flutter/packages
that referenced
this pull request
Jul 19, 2023
Manual roll requested by [email protected] flutter/flutter@f842ed9...6f09064 2023-07-17 [email protected] Stand-alone widget tree with multiple render trees to enable multi-view rendering (flutter/flutter#125003) 2023-07-17 [email protected] Update to valid build tools variant and update lockfiles (flutter/flutter#125825) 2023-07-17 [email protected] Roll Packages from 369ee7e to 6889cca (5 revisions) (flutter/flutter#130721) 2023-07-17 [email protected] [Reland] - Update `DialogTheme` tests for M2/M3 (flutter/flutter#130711) 2023-07-17 [email protected] Roll Flutter Engine from 683087731feb to e4cae43c9c7a (9 revisions) (flutter/flutter#130716) 2023-07-17 [email protected] [flutter_tools] Support coverage collection for dependencies (flutter/flutter#129513) 2023-07-17 [email protected] Fix `DatePicker` uses incorrect overlay color from `DatePickerTheme` and add missing tests (flutter/flutter#130584) 2023-07-17 [email protected] Update `DropdownMenu`, `SnackBarTheme` and `Stepper` tests for M2/M3 (flutter/flutter#130464) 2023-07-17 [email protected] Clarify the whole "CustomPainters default to Size.zero" thing. (flutter/flutter#130624) 2023-07-16 [email protected] Update list of CoC contacts. (flutter/flutter#130630) 2023-07-15 [email protected] Manual roll Flutter Engine from 403866d16137 to 683087731feb (16 revisions) (flutter/flutter#130666) If this roll has caused a breakage, revert this CL and stop the roller using the controls here: https://autoroll.skia.org/r/flutter-packages Please CC [email protected],[email protected] on the revert to ensure that a human is aware of the problem. To file a bug in Packages: https://github.com/flutter/flutter/issues/new/choose To report a problem with the AutoRoller itself, please file a bug: https://bugs.chromium.org/p/skia/issues/entry?template=Autoroller+Bug Documentation for the AutoRoller is here: https://skia.googlesource.com/buildbot/+doc/main/autoroll/README.md
4 tasks
LouiseHsu
pushed a commit
to LouiseHsu/flutter
that referenced
this pull request
Jul 31, 2023
…ew rendering (flutter#125003) This change enables Flutter to generate multiple Scenes to be rendered into separate FlutterViews from a single widget tree. Each Scene is described by a separate render tree, which are all associated with the single widget tree. This PR implements the framework-side mechanisms to describe the content to be rendered into multiple views. Separate engine-side changes are necessary to provide these views to the framework and to draw the framework-generated Scene into them. ## Summary of changes The details of this change are described in [flutter.dev/go/multiple-views](https://flutter.dev/go/multiple-views). Below is a high-level summary organized by layers. ### Rendering layer changes * The `RendererBinding` no longer owns a single `renderView`. In fact, it doesn't OWN any `RenderView`s at all anymore. Instead, it offers an API (`addRenderView`/`removeRenderView`) to add and remove `RenderView`s that then will be MANAGED by the binding. The `RenderView` itself is now owned by a higher-level abstraction (e.g. the `RawView` Element of the widgets layer, see below), who is also in charge of adding it to the binding. When added, the binding will interact with the `RenderView` to produce a frame (e.g. by calling `compositeFrame` on it) and to perform hit tests for incoming pointer events. Multiple `RenderView`s can be added to the binding (typically one per `FlutterView`) to produce multiple Scenes. * Instead of owning a single `pipelineOwner`, the `RendererBinding` now owns the root of the `PipelineOwner` tree (exposed as `rootPipelineOwner` on the binding). Each `PipelineOwner` in that tree (except for the root) typically manages its own render tree typically rooted in one of the `RenderView`s mentioned in the previous bullet. During frame production, the binding will instruct each `PipelineOwner` of that tree to flush layout, paint, semantics etc. A higher-level abstraction (e.g. the widgets layer, see below) is in charge of adding `PipelineOwner`s to this tree. * Backwards compatibility: The old `renderView` and `pipelineOwner` properties of the `RendererBinding` are retained, but marked as deprecated. Care has been taken to keep their original behavior for the deprecation period, i.e. if you just call `runApp`, the render tree bootstrapped by this call is rooted in the deprecated `RendererBinding.renderView` and managed by the deprecated `RendererBinding.pipelineOwner`. ### Widgets layer changes * The `WidgetsBinding` no longer attaches the widget tree to an existing render tree. Instead, it bootstraps a stand-alone widget tree that is not backed by a render tree. For this, `RenderObjectToWidgetAdapter` has been replaced by `RootWidget`. * Multiple render trees can be bootstrapped and attached to the widget tree with the help of the `View` widget, which internally is backed by a `RawView` widget. Configured with a `FlutterView` to render into, the `RawView` creates a new `PipelineOwner` and a new `RenderView` for the new render tree. It adds the new `RenderView` to the `RendererBinding` and its `PipelineOwner` to the pipeline owner tree. * The `View` widget can only appear in certain well-defined locations in the widget tree since it bootstraps a new render tree and does not insert a `RenderObject` into an ancestor. However, almost all Elements expect that their children insert `RenderObject`s, otherwise they will not function properly. To produce a good error message when the `View` widget is used in an illegal location, the `debugMustInsertRenderObjectIntoSlot` method has been added to Element, where a child can ask whether a given slot must insert a RenderObject into its ancestor or not. In practice, the `View` widget can be used as a child of the `RootWidget`, inside the `view` slot of the `ViewAnchor` (see below) and inside a `ViewCollection` (see below). In those locations, the `View` widget may be wrapped in other non-RenderObjectWidgets (e.g. InheritedWidgets). * The new `ViewAnchor` can be used to create a side-view inside a parent `View`. The `child` of the `ViewAnchor` widget renders into the parent `View` as usual, but the `view` slot can take on another `View` widget, which has access to all inherited widgets above the `ViewAnchor`. Metaphorically speaking, the view is anchored to the location of the `ViewAnchor` in the widget tree. * The new `ViewCollection` widget allows for multiple sibling views as it takes a list of `View`s as children. It can be used in all the places that accept a `View` widget. ## Google3 As of July 5, 2023 this change passed a TAP global presubmit (TGP) in google3: tap/OCL:544707016:BASE:545809771:1688597935864:e43dd651 ## Note to reviewers This change is big (sorry). I suggest focusing the initial review on the changes inside of `packages/flutter` first. The majority of the changes describe above are implemented in (listed in suggested review order): * `rendering/binding.dart` * `widgets/binding.dart` * `widgets/view.dart` * `widgets/framework.dart` All other changes included in the PR are basically the fallout of what's implemented in those files. Also note that a lot of the lines added in this PR are documentation and tests. I am also very happy to walk reviewers through the code in person or via video call, if that is helpful. I appreciate any feedback. ## Feedback to address before submitting ("TODO")
2 tasks
auto-submit bot
pushed a commit
that referenced
this pull request
Aug 29, 2024
So, uhm, 2 years ago in #116429 we introduced this concept of a lookup boundary to hide certain InheritedWidgets in widget subtrees who belong to a different render tree than the InheritedWidget itself. This is for example needed for the Material widget: Buttons reach out to their Material ancestor to draw ink splashes on its associated render object. This only produces the desired effect if the button render object is a descendant of the Material render object (the two need to be in the same render tree). Overlay widgets have a similar problem. Lookup boundaries were specifically designed for multi view support, where a sub view would be powered by a separate and independent render tree. Ergo, widgets in the sub view shouldn't see these InheritedWidgets if they are part of the parent view. After all, it would be strange if clicking on a button in a subview draws the ink splash effect into the parent view. Unfortunately, we (and by that I really mean I) forgot to put a LayoutBoundary into the relevant multi view widgets when those were introduced in #125003. This PR addresses that by wrapping the `ViewAnchor.view` child in a LookupBoundary so that its subtree (which bootstraps a separate render tree) cannot see these InheritedWidgets in the parent view.
Buchimi
pushed a commit
to Buchimi/flutter
that referenced
this pull request
Sep 2, 2024
So, uhm, 2 years ago in flutter#116429 we introduced this concept of a lookup boundary to hide certain InheritedWidgets in widget subtrees who belong to a different render tree than the InheritedWidget itself. This is for example needed for the Material widget: Buttons reach out to their Material ancestor to draw ink splashes on its associated render object. This only produces the desired effect if the button render object is a descendant of the Material render object (the two need to be in the same render tree). Overlay widgets have a similar problem. Lookup boundaries were specifically designed for multi view support, where a sub view would be powered by a separate and independent render tree. Ergo, widgets in the sub view shouldn't see these InheritedWidgets if they are part of the parent view. After all, it would be strange if clicking on a button in a subview draws the ink splash effect into the parent view. Unfortunately, we (and by that I really mean I) forgot to put a LayoutBoundary into the relevant multi view widgets when those were introduced in flutter#125003. This PR addresses that by wrapping the `ViewAnchor.view` child in a LookupBoundary so that its subtree (which bootstraps a separate render tree) cannot see these InheritedWidgets in the parent view.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Labels
a: accessibility
Accessibility, e.g. VoiceOver or TalkBack. (aka a11y)
a: tests
"flutter test", flutter_test, or one of our tests
autosubmit
Merge PR when tree becomes green via auto submit App
c: contributor-productivity
Team-specific productivity, code health, technical debt.
d: examples
Sample code and demos
f: focus
Focus traversal, gaining or losing focus
f: integration_test
The flutter/packages/integration_test plugin
framework
flutter/packages/flutter repository. See also f: labels.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Part of #121573.
This change enables Flutter to generate multiple Scenes to be rendered into separate FlutterViews from a single widget tree. Each Scene is described by a separate render tree, which are all associated with the single widget tree.
This PR implements the framework-side mechanisms to describe the content to be rendered into multiple views. Separate engine-side changes are necessary to provide these views to the framework and to draw the framework-generated Scene into them.
Summary of changes
The details of this change are described in flutter.dev/go/multiple-views. Below is a high-level summary organized by layers.
Rendering layer changes
RendererBindingno longer owns a singlerenderView. In fact, it doesn't OWN anyRenderViews at all anymore. Instead, it offers an API (addRenderView/removeRenderView) to add and removeRenderViews that then will be MANAGED by the binding. TheRenderViewitself is now owned by a higher-level abstraction (e.g. theRawViewElement of the widgets layer, see below), who is also in charge of adding it to the binding. When added, the binding will interact with theRenderViewto produce a frame (e.g. by callingcompositeFrameon it) and to perform hit tests for incoming pointer events. MultipleRenderViews can be added to the binding (typically one perFlutterView) to produce multiple Scenes.pipelineOwner, theRendererBindingnow owns the root of thePipelineOwnertree (exposed asrootPipelineOwneron the binding). EachPipelineOwnerin that tree (except for the root) typically manages its own render tree typically rooted in one of theRenderViews mentioned in the previous bullet. During frame production, the binding will instruct eachPipelineOwnerof that tree to flush layout, paint, semantics etc. A higher-level abstraction (e.g. the widgets layer, see below) is in charge of addingPipelineOwners to this tree.renderViewandpipelineOwnerproperties of theRendererBindingare retained, but marked as deprecated. Care has been taken to keep their original behavior for the deprecation period, i.e. if you just callrunApp, the render tree bootstrapped by this call is rooted in the deprecatedRendererBinding.renderViewand managed by the deprecatedRendererBinding.pipelineOwner.Widgets layer changes
WidgetsBindingno longer attaches the widget tree to an existing render tree. Instead, it bootstraps a stand-alone widget tree that is not backed by a render tree. For this,RenderObjectToWidgetAdapterhas been replaced byRootWidget.Viewwidget, which internally is backed by aRawViewwidget. Configured with aFlutterViewto render into, theRawViewcreates a newPipelineOwnerand a newRenderViewfor the new render tree. It adds the newRenderViewto theRendererBindingand itsPipelineOwnerto the pipeline owner tree.Viewwidget can only appear in certain well-defined locations in the widget tree since it bootstraps a new render tree and does not insert aRenderObjectinto an ancestor. However, almost all Elements expect that their children insertRenderObjects, otherwise they will not function properly. To produce a good error message when theViewwidget is used in an illegal location, thedebugMustInsertRenderObjectIntoSlotmethod has been added to Element, where a child can ask whether a given slot must insert a RenderObject into its ancestor or not. In practice, theViewwidget can be used as a child of theRootWidget, inside theviewslot of theViewAnchor(see below) and inside aViewCollection(see below). In those locations, theViewwidget may be wrapped in other non-RenderObjectWidgets (e.g. InheritedWidgets).ViewAnchorcan be used to create a side-view inside a parentView. Thechildof theViewAnchorwidget renders into the parentViewas usual, but theviewslot can take on anotherViewwidget, which has access to all inherited widgets above theViewAnchor. Metaphorically speaking, the view is anchored to the location of theViewAnchorin the widget tree.ViewCollectionwidget allows for multiple sibling views as it takes a list ofViews as children. It can be used in all the places that accept aViewwidget.Google3
As of July 5, 2023 this change passed a TAP global presubmit (TGP) in google3: tap/OCL:544707016:BASE:545809771:1688597935864:e43dd651
Note to reviewers
This change is big (sorry). I suggest focusing the initial review on the changes inside of
packages/flutterfirst. The majority of the changes describe above are implemented in (listed in suggested review order):rendering/binding.dartwidgets/binding.dartwidgets/view.dartwidgets/framework.dartAll other changes included in the PR are basically the fallout of what's implemented in those files. Also note that a lot of the lines added in this PR are documentation and tests.
I am also very happy to walk reviewers through the code in person or via video call, if that is helpful.
I appreciate any feedback.
Feedback to address before submitting ("TODO")
DiagnosticableTree