mirror of
https://github.com/flutter/flutter.git
synced 2025-06-03 00:51:18 +00:00
Add code for updating focusedChild
when removing grandchildren from scope (#136771)
## Description This adds code to make sure that grandchildren are removed from the `focusedChild` of a scope when the child is detached. ## Related Issues - Fixes https://github.com/flutter/flutter/issues/136758 ## Tests - Added regression test.
This commit is contained in:
parent
747128ff7a
commit
2492242593
@ -964,7 +964,13 @@ class FocusNode with DiagnosticableTreeMixin, ChangeNotifier {
|
||||
assert(node._manager == _manager);
|
||||
|
||||
if (removeScopeFocus) {
|
||||
node.enclosingScope?._focusedChildren.remove(node);
|
||||
final FocusScopeNode? nodeScope = node.enclosingScope;
|
||||
if (nodeScope != null) {
|
||||
nodeScope._focusedChildren.remove(node);
|
||||
node.descendants.where((FocusNode descendant) {
|
||||
return descendant.enclosingScope == nodeScope;
|
||||
}).forEach(nodeScope._focusedChildren.remove);
|
||||
}
|
||||
}
|
||||
|
||||
node._parent = null;
|
||||
|
@ -459,6 +459,46 @@ void main() {
|
||||
expect(child2.hasPrimaryFocus, isTrue);
|
||||
});
|
||||
|
||||
// Regression test for https://github.com/flutter/flutter/issues/136758
|
||||
testWidgetsWithLeakTracking('removing grandchildren from scope updates focusedChild', (WidgetTester tester) async {
|
||||
final BuildContext context = await setupWidget(tester);
|
||||
|
||||
// Sets up this focus node tree:
|
||||
//
|
||||
// root
|
||||
// |
|
||||
// scope1
|
||||
// |
|
||||
// child1
|
||||
// |
|
||||
// child2
|
||||
final FocusScopeNode scope1 = FocusScopeNode(debugLabel: 'scope2');
|
||||
addTearDown(scope1.dispose);
|
||||
final FocusAttachment scope2Attachment = scope1.attach(context);
|
||||
scope2Attachment.reparent(parent: tester.binding.focusManager.rootScope);
|
||||
|
||||
final FocusNode child1 = FocusNode(debugLabel: 'child2');
|
||||
addTearDown(child1.dispose);
|
||||
final FocusAttachment child2Attachment = child1.attach(context);
|
||||
|
||||
final FocusNode child2 = FocusNode(debugLabel: 'child3');
|
||||
addTearDown(child2.dispose);
|
||||
final FocusAttachment child3Attachment = child2.attach(context);
|
||||
|
||||
child2Attachment.reparent(parent: scope1);
|
||||
child3Attachment.reparent(parent: child1);
|
||||
expect(child1.parent, equals(scope1));
|
||||
expect(scope1.children.first, equals(child1));
|
||||
child2.requestFocus();
|
||||
await tester.pump();
|
||||
expect(scope1.focusedChild, equals(child2));
|
||||
|
||||
// Detach the middle child and make sure that the scope is updated so that
|
||||
// it no longer references child2 as the focused child.
|
||||
child2Attachment.detach();
|
||||
expect(scope1.focusedChild, isNull);
|
||||
});
|
||||
|
||||
testWidgetsWithLeakTracking('Requesting focus before adding to tree results in a request after adding', (WidgetTester tester) async {
|
||||
final BuildContext context = await setupWidget(tester);
|
||||
final FocusScopeNode scope = FocusScopeNode();
|
||||
|
Loading…
Reference in New Issue
Block a user