@@ -459,6 +459,46 @@ void main() {
459459 expect (child2.hasPrimaryFocus, isTrue);
460460 });
461461
462+ // Regression test for https://github.com/flutter/flutter/issues/136758
463+ testWidgetsWithLeakTracking ('removing grandchildren from scope updates focusedChild' , (WidgetTester tester) async {
464+ final BuildContext context = await setupWidget (tester);
465+
466+ // Sets up this focus node tree:
467+ //
468+ // root
469+ // |
470+ // scope1
471+ // |
472+ // child1
473+ // |
474+ // child2
475+ final FocusScopeNode scope1 = FocusScopeNode (debugLabel: 'scope2' );
476+ addTearDown (scope1.dispose);
477+ final FocusAttachment scope2Attachment = scope1.attach (context);
478+ scope2Attachment.reparent (parent: tester.binding.focusManager.rootScope);
479+
480+ final FocusNode child1 = FocusNode (debugLabel: 'child2' );
481+ addTearDown (child1.dispose);
482+ final FocusAttachment child2Attachment = child1.attach (context);
483+
484+ final FocusNode child2 = FocusNode (debugLabel: 'child3' );
485+ addTearDown (child2.dispose);
486+ final FocusAttachment child3Attachment = child2.attach (context);
487+
488+ child2Attachment.reparent (parent: scope1);
489+ child3Attachment.reparent (parent: child1);
490+ expect (child1.parent, equals (scope1));
491+ expect (scope1.children.first, equals (child1));
492+ child2.requestFocus ();
493+ await tester.pump ();
494+ expect (scope1.focusedChild, equals (child2));
495+
496+ // Detach the middle child and make sure that the scope is updated so that
497+ // it no longer references child2 as the focused child.
498+ child2Attachment.detach ();
499+ expect (scope1.focusedChild, isNull);
500+ });
501+
462502 testWidgetsWithLeakTracking ('Requesting focus before adding to tree results in a request after adding' , (WidgetTester tester) async {
463503 final BuildContext context = await setupWidget (tester);
464504 final FocusScopeNode scope = FocusScopeNode ();
0 commit comments