Skip to content
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

Update 1.17 breaks FocusScope.of(context).unfocus(); #56560

Closed
n00bm0nkey opened this issue May 7, 2020 · 7 comments
Closed

Update 1.17 breaks FocusScope.of(context).unfocus(); #56560

n00bm0nkey opened this issue May 7, 2020 · 7 comments
Labels
c: regression It was better in the past than it is now f: focus Focus traversal, gaining or losing focus framework flutter/packages/flutter repository. See also f: labels.

Comments

@n00bm0nkey
Copy link

n00bm0nkey commented May 7, 2020

Had a working GestureDetector, upgraded to Flutter 1.17 and it stopped working!

Widget build(BuildContext context) {
      return GestureDetector(
        onTap: () {//fixes keyboard not closing
          FocusScopeNode currentFocus = FocusScope.of(context);
          if (!currentFocus.hasPrimaryFocus) {
            currentFocus.unfocus();
          }
        },
      child: MaterialApp(...),
   );
}
@HansMuller HansMuller added f: focus Focus traversal, gaining or losing focus framework flutter/packages/flutter repository. See also f: labels. c: regression It was better in the past than it is now labels May 7, 2020
@HansMuller
Copy link
Contributor

CC @gspencergoog - is this a regression?

@gspencergoog
Copy link
Contributor

Perhaps, but I need to understand what the goal of the code above is. It looks like this code was relying on the behavior that unfocusing a scope node which had focus would transfer focus to the root focus node, which was incorrect behavior, since it broke focus traversal whenever it happened.

If that's the case, then a fix here would be to call FocusManager.instance.rootScope.requestFocus() instead of currentFocus.unfocus().

However, I question that this code does what you actually want. I'm guessing that you have had to also put in places where you explicitly focus things that happen after a tap on the application in order for focus traversal to work properly, since once the root scope node gets focus, focus traversal has no context in which to evaluate which node should come next (since there isn't any FocusTraversalPolicy to look for above the root node).

The unfocus code was changed in #50831 to take a disposition (where to place the focus when the node loses focus). You might also try currentFocus.unfocus(disposition: UnfocusDisposition.previouslyFocusedChild) and see if that helps, since that's closer to the original algorithm.

@n00bm0nkey
Copy link
Author

@gspencergoog Resolved with #50831.
"If you want to remove the focus from the primary focus instead of the scope, that's easy enough to do: just call primaryFocus.unfocus()."

The provided code was supposed to remove primaryFocus from a child widget in the context. This issue was simply a lack of my understanding of the focus() function. My apologies and thanks for the hasty reply!

@oemdaro
Copy link

oemdaro commented May 22, 2020

I have the same issue. My goal is to unfocus when user tap anywhere on the screen.

I resolve the issue by change it to:

Widget build(BuildContext context) {
  return GestureDetector(
    onTap: () {
      FocusScopeNode currentFocus = FocusScope.of(context);
      if (currentFocus.canRequestFocus) {
        FocusScope.of(context).requestFocus(new FocusNode());
      }
    },
    child: MaterialApp(...),
  );
}

I'm not sure, if I use the right way. But it solve my problem. Lets me know, if I'm using the wrong way.

@gspencergoog
Copy link
Contributor

@oemdaro I think, with the code you have now, if you tap on the screen and then hit TAB, then it won't move to the correct next node. You could accomplish the same thing with:

onTap: () {
 FocusManager.instance.primaryFocus.unfocus();
}

and it would move to the correct next node when you hit TAB.

You definitely don't need to check to see if it can request focus: the requestFocus function already does that internally.

@oemdaro
Copy link

oemdaro commented Jun 12, 2020

@oemdaro I think, with the code you have now, if you tap on the screen and then hit TAB, then it won't move to the correct next node. You could accomplish the same thing with:

onTap: () {
 FocusManager.instance.primaryFocus.unfocus();
}

and it would move to the correct next node when you hit TAB.

You definitely don't need to check to see if it can request focus: the requestFocus function already does that internally.

Thank @gspencergoog , It's working.

@github-actions
Copy link

github-actions bot commented Aug 7, 2021

This thread has been automatically locked since there has not been any recent activity after it was closed. If you are still experiencing a similar issue, please open a new bug, including the output of flutter doctor -v and a minimal reproduction of the issue.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Aug 7, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
c: regression It was better in the past than it is now f: focus Focus traversal, gaining or losing focus framework flutter/packages/flutter repository. See also f: labels.
Projects
None yet
Development

No branches or pull requests

4 participants