Repository navigation
[flutter] prevent errant text field clicks from losing focus - #86041
Conversation
|
@gspencergoog @chunhtai this is an attempt to fix one of the side effects from the focus removal change; since the "focused" part of the text field is just the tiny editable text portion it is too easy to lose focus by clicking on the decorative parts. This introduces another context that can be attached to a focus node to detect this. |
| focusScopeNode.addListener(_currentFocusListener); | ||
| } | ||
|
|
||
| void _currentFocusListener() { |
There was a problem hiding this comment.
For some reason this wasn't giving up to date results when using tab navigation
There was a problem hiding this comment.
I am not so certain about why we need to remove this code. If this is indeed a bug fixes, we should have a test for this.
|
It looks like this pull request may not have tests. Please make sure to add tests before merging. If you need an exemption to this rule, contact Hixie on the #hackers channel in Chat. If you are not sure if you need tests, consider this rule of thumb: the purpose of a test is to make sure someone doesn't accidentally revert the fix. Ask yourself, is there anything in your PR that you feel it is important we not accidentally revert back to how it was before your fix? Reviewers: Read the Tree Hygiene page and make sure this patch meets those guidelines before LGTMing. |
|
ahh, need to port over my old tests |
| BuildContext? _context; | ||
|
|
||
| /// An optional parent context that determines whether or not a primary pointer | ||
| /// gesture that missed the actual [context] should remove focus from the node. |
There was a problem hiding this comment.
Can you also document on when will this focus manager will remove focus from the node? will it do it when the parent context = null or will it do it when the parent context != null?
Also where the focus will go if this happen
There was a problem hiding this comment.
expanded the comments here a bit
| _clipboardStatus?.addListener(_onChangedClipboardStatus); | ||
| widget.controller.addListener(_didChangeTextEditingValue); | ||
| _focusAttachment = widget.focusNode.attach(context); | ||
| _focusAttachment = widget.focusNode.attach(context, contextBounds: widget.parentContext); |
There was a problem hiding this comment.
It looks like the hittest prioritizes context bounds to determine hittest rect, I wonder can it directly attach to the widget.parentContext if it is not null?
There was a problem hiding this comment.
Thinking about this more, we might have some issues if editable text migrates to use a regular focus node since we won't have the attachment available.
Attaching to the parent context might work, but thinking about it more I'm not sure if we need to worry about reparenting. Surely you'd never re-parent the text field decoration apart from an editable text right?
There was a problem hiding this comment.
third party libraries does crazy thing around editable text, I wouldn't be surprised if the editabletext gets reparented. but I think we should be able to reparent the attachment in didUpdateWidget?
There was a problem hiding this comment.
Currently focus will be lost (at least according to my test cases)
There was a problem hiding this comment.
yes, focusAttachment.detach will call unfocus on the focusnode. I think this is probably fine because this will be an edgy case where people keep swapping out the parent focus. We can fix it later if that actually cause issue.
| focusScopeNode.addListener(_currentFocusListener); | ||
| } | ||
|
|
||
| void _currentFocusListener() { |
There was a problem hiding this comment.
I am not so certain about why we need to remove this code. If this is indeed a bug fixes, we should have a test for this.
| /// than 1. | ||
| final ScrollBehavior? scrollBehavior; | ||
|
|
||
| /// Optionally, the parent build context if this editable text was built as part of |
There was a problem hiding this comment.
| /// Optionally, the parent build context if this editable text was built as part of | |
| /// The optional parent build context if this editable text was built as part of |
| /// a larger text field. | ||
| /// | ||
| /// If this is provided then focus will be attached to the parent context instead of | ||
| /// the editable text. If the [parentContext] is later modified while the editable text |
There was a problem hiding this comment.
Maybe also explain what's the different consequences to attach to this context vs parent context, and why developer may want to do that
|
The overall approach looks good to me, just some nits |
|
Good point, i need to investigate a bit more. i might be working around a focus bug, so finding the root cause first is probably ideal. |
|
moved the listener change to #86141 |
|
I wasn't able to make the parent context work - it changed how actions/shortcuts were looked up in some non-obvious ways. I've gone back to tagging render objects with the focus node. |
|
This is ready for review |
| /// This area is conceptually part of the editable text, but not attached to the | ||
| /// focus context. The [FocusTrapArea] is used to inform the framework of this | ||
| /// relationship, so that primary pointer contact inside of this region but above | ||
| /// the editable text focus will not trigger loss of focus. |
There was a problem hiding this comment.
You might add a reference/description here for the focus trap and when it comes into play, etc. If I pretend that I just happened upon the API docs page for this widget, it feels like if I wasn't writing my own text widget I wouldn't quite know when to use it, or what it affects.
Since _FocusTrap isn't a public class, there's probably not much mention of it in other docs.
There was a problem hiding this comment.
I could make it public, no need to keep it private really
There was a problem hiding this comment.
that would require me to document it a bit more, but no harm there
There was a problem hiding this comment.
The other option would be to make FocusTrapArea private, if you don't think anyone will need it outside of the text field (but it seems like they might).
There was a problem hiding this comment.
probably the cupertino text field needs it as well, as would other like the macos ui package - depending on whether or not they are editable text widget based
|
I've updated the documentation and made focus trap/ focus area stuff public. ptAL @gspencergoog |

Without making dramatic adjustments to the focus system, attempts to support the text field / editable text nesting while still preventing clicks from text field decoration from removing focus from the editable text.
Fixes #86154