Unverified Commit f2050e8a authored by chunhtai's avatar chunhtai Committed by GitHub

Fixes focus traversal crash if the current node can't request focus (#134954)

fixes https://github.com/flutter/flutter/issues/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
parent 43407cf1
......@@ -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. '
......
......@@ -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');
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment