Prevent material switch from recreating its render object when it becomes disabled#61398
Conversation
| child: Builder( | ||
| builder: (BuildContext context) { | ||
| return _SwitchRenderObjectWidget( | ||
| // FocusableActionDetector changes the shape of the tree when the |
There was a problem hiding this comment.
Should we instead fix FocusableActionDetector to not remove the Actions and Shortcuts widgets when disabled, and instead just empty out their maps? There is some performance cost to building them, but if they cause churn in the tree, that could be offset by not causing it anymore.
There was a problem hiding this comment.
It would break some tests because that introduces a 1 frame delay to descendant Focus's semantics (isFocusable) . Currently since we change the shape of the tree, a new Focus widget gets inflated so there's no delay (line 1090):
flutter/packages/flutter/lib/src/widgets/actions.dart
Lines 1081 to 1103 in 4195ad4
There was a problem hiding this comment.
(Is this expected?)
There was a problem hiding this comment.
Well, I would think that anything that cares about the focus changing shouldn't care about the 1 frame delay, since focus changes already happen in a microtask, so that already happens often. And semantics shouldn't care about a 1 frame delay either.
There was a problem hiding this comment.
I think I added that part because the focus changes were increasing a build benchmark, and I was trying to reduce the number of built items for things that were disabled.
There was a problem hiding this comment.
If a switch is disabled then isFocusable should be removed from its semantics flags in the same frame, no?
There was a problem hiding this comment.
The focus itself won't actually be removed until the microtask runs, so if the semantics removes it immediately, it might actually be early (and wrong until the task runs).
| SemanticsFlag.hasCheckedState, | ||
| SemanticsFlag.hasEnabledState, | ||
| SemanticsFlag.isInMutuallyExclusiveGroup, | ||
| SemanticsFlag.isFocusable, // This flag is delayed by 1 frame. |
There was a problem hiding this comment.
Updated. But it still seems confusing to me that when the UI is disabled the semantics is telling us the component is focusable.
There was a problem hiding this comment.
Yes, ideally it would be resolved immediately, but it causes too much of a performance hit to update focus while the tree is rebuilt, and would mean that sometimes (during the build) two things could have focus at the same time, or that nothing has focus, which complicates a lot of logic.
There was a problem hiding this comment.
Would it be possible to update the focus tree after we finalize the layout (instead of in a post-frame callback)?
|
@gspencergoog updated the PR. Could you take another look? |
| SemanticsFlag.hasCheckedState, | ||
| SemanticsFlag.hasEnabledState, | ||
| SemanticsFlag.isInMutuallyExclusiveGroup, | ||
| SemanticsFlag.isFocusable, // This flag is delayed by 1 frame. |
There was a problem hiding this comment.
Yes, ideally it would be resolved immediately, but it causes too much of a performance hit to update focus while the tree is rebuilt, and would mean that sometimes (during the build) two things could have focus at the same time, or that nothing has focus, which complicates a lot of logic.
…n it becomes disabled (flutter#61398)", reverted in flutter#64062 This reverts commit 90908b0.
…n it becomes disabled (flutter#61398)" (flutter#64062)
…n it becomes disabled (flutter#61398)", reverted in flutter#64062 (flutter#64354)
…n it becomes disabled (flutter#61398)" (flutter#64062)
…n it becomes disabled (flutter#61398)", reverted in flutter#64062 (flutter#64354)
Description
FocusableActionDetectorchanges the shape of the tree so_SwitchRenderObjectWidgetneeds aGlobalKeyto get reused. Preferred thisGlobalKeysolution over changing the implementation ofFocusableActionDetector, because that latter would change the semantics of many other widgets.Related Issues
fixes #61247
Tests
I added the following tests:
Material switch should not recreate its render object when disabled
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.