Skip to content

Fix ExcludeFocus so it won't refocus a sibling of the focused node. #61756

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jul 23, 2020

Conversation

gspencergoog
Copy link
Contributor

@gspencergoog gspencergoog commented Jul 17, 2020

Description

This changes FocusNode.descendantsAreFocusable so that it doesn't allow the enclosing scope to re-focus a node that is a descendant of the node with descendantsAreFocusable set to false.

Because of the order in which the internal state for descendantsAreFocusable was being set, setting it to false was causing a sibling node to be focused when descendantsAreFocusable of the parent was set to false, even though it shouldn't have been focusable, because the enclosing scope would search for a candidate to be focused before the internal state was set to false.

Instead of looping over the children and telling them all to unfocus (and select the previously focused node), this unfocuses the node that has descendantsAreFocusable set to false, with the disposition UnfocusDisposition.previouslyFocusedChild, so that its enclosing scope will look for a previously focused child that isn't part of the subtree being excluded.

This affects how the ExcludeFocus widget behaves when turning on exclude.

Related Issues

Tests

  • Added a regression test.

Breaking Change

  • No, no existing tests failed, so this is not a breaking change.

@fluttergithubbot fluttergithubbot added the framework flutter/packages/flutter repository. See also f: labels. label Jul 17, 2020
@gspencergoog gspencergoog force-pushed the fix_exclude_focus branch 2 times, most recently from 88e40d3 to 4eb0037 Compare July 17, 2020 20:27
@gspencergoog gspencergoog changed the title Fix ExcludeFocus so it uses a different unfocus disposition Fix ExcludeFocus so it won't refocus a sibling of the focused node. Jul 17, 2020
@gspencergoog gspencergoog requested review from goderbauer and darrenaustin and removed request for goderbauer July 17, 2020 20:35
Copy link
Contributor

@darrenaustin darrenaustin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM.

@@ -864,19 +867,19 @@ class FocusNode with DiagnosticableTreeMixin, ChangeNotifier {
while (!scope.canRequestFocus) {
scope = scope.enclosingScope ?? _manager?.rootScope;
}
scope?._doRequestFocus(findFirstFocus: false);
scope._doRequestFocus(findFirstFocus: false);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are these changes here related to the fix, or just cleaning up something? I assume scope can no longer be null when it might have before?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, I made those changes thinking that these couldn't ever be null, because the rootScope can't be null, but if the _manager is null, it still could be. I reverted these.

@Piinks Piinks added the f: focus Focus traversal, gaining or losing focus label Jul 21, 2020
@gspencergoog gspencergoog merged commit cac22cd into flutter:master Jul 23, 2020
@gspencergoog gspencergoog deleted the fix_exclude_focus branch July 23, 2020 15:27
Pragya007 pushed a commit to Pragya007/flutter that referenced this pull request Aug 11, 2020
…flutter#61756)

This changes FocusNode.descendantsAreFocusable so that it doesn't allow the enclosing scope to re-focus a node that is a descendant of the node with descendantsAreFocusable set to false.

Because of the order in which the internal state for descendantsAreFocusable was being set, setting it to false was causing a sibling node to be focused when descendantsAreFocusable of the parent was set to false, even though it shouldn't have been focusable, because the enclosing scope would search for a candidate to be focused before the internal state was set to false.

Instead of looping over the children and telling them all to unfocus (and select the previously focused node), this unfocuses the node that has descendantsAreFocusable set to false, with the disposition UnfocusDisposition.previouslyFocusedChild, so that its enclosing scope will look for a previously focused child that isn't part of the subtree being excluded.

This affects how the ExcludeFocus widget behaves when turning on exclude.
mingwandroid pushed a commit to mingwandroid/flutter that referenced this pull request Sep 6, 2020
…flutter#61756)

This changes FocusNode.descendantsAreFocusable so that it doesn't allow the enclosing scope to re-focus a node that is a descendant of the node with descendantsAreFocusable set to false.

Because of the order in which the internal state for descendantsAreFocusable was being set, setting it to false was causing a sibling node to be focused when descendantsAreFocusable of the parent was set to false, even though it shouldn't have been focusable, because the enclosing scope would search for a candidate to be focused before the internal state was set to false.

Instead of looping over the children and telling them all to unfocus (and select the previously focused node), this unfocuses the node that has descendantsAreFocusable set to false, with the disposition UnfocusDisposition.previouslyFocusedChild, so that its enclosing scope will look for a previously focused child that isn't part of the subtree being excluded.

This affects how the ExcludeFocus widget behaves when turning on exclude.
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Jul 30, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
f: focus Focus traversal, gaining or losing focus framework flutter/packages/flutter repository. See also f: labels.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

ExcludeFocus can still allow focus
5 participants