Skip to content

Commit

Permalink
Fixes focus traversal crash if the current node can't request focus (…
Browse files Browse the repository at this point in the history
…#134954)

fixes flutter/flutter#134854

## Pre-launch Checklist

- [ ] I read the [Contributor Guide] and followed the process outlined
there for submitting PRs.
- [ ] I read the [Tree Hygiene] wiki page, which explains my
responsibilities.
- [ ] I read and followed the [Flutter Style Guide], including [Features
we expect every widget to implement].
- [ ] I signed the [CLA].
- [ ] I listed at least one issue that this PR fixes in the description
above.
- [ ] I updated/added relevant documentation (doc comments with `///`).
- [ ] I added new tests to check the change I am making, or this PR is
[test-exempt].
- [ ] All existing and new tests are passing.

If you need help, consider asking for advice on the #hackers-new channel
on [Discord].

<!-- Links -->
[Contributor Guide]:
https://github.com/flutter/flutter/wiki/Tree-hygiene#overview
[Tree Hygiene]: https://github.com/flutter/flutter/wiki/Tree-hygiene
[test-exempt]:
https://github.com/flutter/flutter/wiki/Tree-hygiene#tests
[Flutter Style Guide]:
https://github.com/flutter/flutter/wiki/Style-guide-for-Flutter-repo
[Features we expect every widget to implement]:
https://github.com/flutter/flutter/wiki/Style-guide-for-Flutter-repo#features-we-expect-every-widget-to-implement
[CLA]: https://cla.developers.google.com/
[flutter/tests]: https://github.com/flutter/tests
[breaking change policy]:
https://github.com/flutter/flutter/wiki/Tree-hygiene#handling-breaking-changes
[Discord]: https://github.com/flutter/flutter/wiki/Chat
  • Loading branch information
chunhtai authored Sep 18, 2023
1 parent 43407cf commit f2050e8
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 1 deletion.
4 changes: 3 additions & 1 deletion packages/flutter/lib/src/widgets/focus_traversal.dart
Original file line number Diff line number Diff line change
Expand Up @@ -433,7 +433,9 @@ abstract class FocusTraversalPolicy with Diagnosticable {
// finds.
assert((){
final Set<FocusNode> difference = sortedDescendants.toSet().difference(scope.traversalDescendants.toSet());
if (currentNode.skipTraversal) {
if (currentNode.skipTraversal || !currentNode.canRequestFocus) {
// The scope.traversalDescendants will not contain currentNode if it
// skips traversal or not focusable.
assert(
difference.length == 1 && difference.contains(currentNode),
'Sorted descendants contains different nodes than FocusScopeNode.traversalDescendants would. '
Expand Down
35 changes: 35 additions & 0 deletions packages/flutter/test/widgets/focus_traversal_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -596,6 +596,41 @@ void main() {
expect(scope.hasFocus, isTrue);
});

testWidgetsWithLeakTracking('Requesting nextFocus on node focuses its descendant', (WidgetTester tester) async {
for (final bool canRequestFocus in <bool>{true, false}) {
final FocusNode node1 = FocusNode();
final FocusNode node2 = FocusNode();
addTearDown(() {
node1.dispose();
node2.dispose();
});
await tester.pumpWidget(
Directionality(
textDirection: TextDirection.ltr,
child: FocusTraversalGroup(
policy: ReadingOrderTraversalPolicy(),
child: FocusScope(
child: Focus(
focusNode: node1,
canRequestFocus: canRequestFocus,
child: Focus(
focusNode: node2,
child: Container(),
),
),
),
),
),
);

final bool didFindNode = node1.nextFocus();
await tester.pump();
expect(didFindNode, isTrue);
expect(node1.hasPrimaryFocus, isFalse);
expect(node2.hasPrimaryFocus, isTrue);
}
});

testWidgetsWithLeakTracking('Move reading focus to previous node.', (WidgetTester tester) async {
final GlobalKey key1 = GlobalKey(debugLabel: '1');
final GlobalKey key2 = GlobalKey(debugLabel: '2');
Expand Down

0 comments on commit f2050e8

Please sign in to comment.