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

Fix focus management for text fields #51009

Merged
merged 30 commits into from
Jun 20, 2024
Merged

Fix focus management for text fields #51009

merged 30 commits into from
Jun 20, 2024

Conversation

tugorez
Copy link
Contributor

@tugorez tugorez commented Feb 27, 2024

Fix focus management for text fields

This PR:

  1. Refactors the DOM focus function to take options
  2. Removes the timers sorrounding the activeDomElement.focus() so that the input elements get focused as immediate as possible.
  3. Prevents the default on pointerdown in a Flutter View and schedules a requestViewFocusChange to claim focus in that view after some time. This gives 2 the opportunity to focus the right <input /> or <textarea /> element. This helps focus correctly transition from one input element to another (without jumping to a flutter view in between).
  4. Deactivating a TextField doesn't blur the focused element anymore, it insteads schedules for later a call to move the focus to the flutter view if nothing inside it claimed focus first.
  5. Prevents scroll in all the focus calls (this should help with the view jumping when focusing one text field after another).

Sample apps

  1. Full screen mode: https://tugorez.com/flutter_focus_web
  2. Embedded mode: https://tugorez.com/flutter_focus_web?embedded

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 and the C++, Objective-C, Java style guides.
  • I listed at least one issue that this PR fixes in the description above.
  • I added new tests to check the change I am making or feature I am adding, or the PR is test-exempt. See testing the engine for instructions on writing and running engine tests.
  • I updated/added relevant documentation (doc comments with ///).
  • I signed the CLA.
  • All existing and new tests are passing.

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

@github-actions github-actions bot added the platform-web Code specifically for the web engine label Feb 27, 2024
@tugorez tugorez closed this Mar 27, 2024
@tugorez tugorez reopened this Mar 28, 2024
@tugorez tugorez closed this Apr 23, 2024
@tugorez tugorez reopened this Apr 23, 2024
@tugorez tugorez requested review from mdebbar and ditman May 20, 2024 17:31
@tugorez tugorez marked this pull request as ready for review May 20, 2024 17:32
@ditman

This comment was marked as resolved.

ditman added 2 commits June 18, 2024 16:43
When Safari auto-completes a field, it synthesizes an event that quacks
like a DomKeyboardEvent, but it lacks the `shiftKey` property.

This change makes the property nullable, and adjusts its use.

(This only affects debug mode builds)
@ditman
Copy link
Member

ditman commented Jun 19, 2024

This may break autofill forms. If you look at line 1425, we used to only blur the element. But now we are also removing it.

I've re-deployed a small testing app with a form to test autocomplete, here:

I think this now works similarly across all browsers, PTAL @mdebbar.

Comment on lines +2264 to +2265
external JSBoolean? get _shiftKey;
bool? get shiftKey => _shiftKey?.toDart;
Copy link
Member

Choose a reason for hiding this comment

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

This change is unrelated to this PR, I can move it to a separate PR to keep this one small.

Comment on lines +1355 to +1359
if (this is! SafariDesktopTextEditingStrategy) {
// handleBlur causes Safari to reopen autofill dialogs after autofill,
// so we don't attach the listener there.
subscriptions.add(DomSubscription(activeDomElement, 'blur', handleBlur));
}
Copy link
Member

Choose a reason for hiding this comment

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

the handleBlur function was causing trouble with autocomplete in Safari (refocusing the field). Is this maybe not needed anymore?

Copy link
Contributor

@mdebbar mdebbar left a comment

Choose a reason for hiding this comment

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

LGTM!

@ditman ditman added the autosubmit Merge PR when tree becomes green via auto submit App label Jun 20, 2024
@auto-submit auto-submit bot merged commit 87a632b into flutter:main Jun 20, 2024
29 checks passed
engine-flutter-autoroll added a commit to engine-flutter-autoroll/flutter that referenced this pull request Jun 20, 2024
engine-flutter-autoroll added a commit to engine-flutter-autoroll/flutter that referenced this pull request Jun 20, 2024
engine-flutter-autoroll added a commit to engine-flutter-autoroll/flutter that referenced this pull request Jun 20, 2024
auto-submit bot pushed a commit to flutter/flutter that referenced this pull request Jun 20, 2024
…150582)

flutter/engine@dd37cef...dda82d9

2024-06-20 tarrinneal@gmail.com Update StandardMessageCodec.readValue to be @nullable (flutter/engine#53473)
2024-06-20 bruno.leroux@gmail.com [Web] Fix extra new line when inputAction is not newline for a multil� (flutter/engine#53453)
2024-06-20 skia-flutter-autoroll@skia.org Roll Dart SDK from 366eb1b4b308 to be6b533e07e7 (1 revision) (flutter/engine#53492)
2024-06-20 tugorez@users.noreply.github.com Fix focus management for text fields (flutter/engine#51009)
2024-06-20 skia-flutter-autoroll@skia.org Roll Dart SDK from cbd933e707e7 to 366eb1b4b308 (1 revision) (flutter/engine#53487)
2024-06-20 skia-flutter-autoroll@skia.org Roll Skia from 17626ca22729 to 4471ee07e223 (1 revision) (flutter/engine#53486)
2024-06-20 skia-flutter-autoroll@skia.org Roll Dart SDK from e403519a4436 to cbd933e707e7 (1 revision) (flutter/engine#53485)
2024-06-20 skia-flutter-autoroll@skia.org Roll Skia from 4acebac47ea5 to 17626ca22729 (1 revision) (flutter/engine#53484)
2024-06-20 skia-flutter-autoroll@skia.org Roll Skia from 199e1a49b091 to 4acebac47ea5 (1 revision) (flutter/engine#53482)

If this roll has caused a breakage, revert this CL and stop the roller
using the controls here:
https://autoroll.skia.org/r/flutter-engine-flutter-autoroll
Please CC jsimmons@google.com,rmistry@google.com,zra@google.com on the revert to ensure that a human
is aware of the problem.

To file a bug in Flutter: https://github.com/flutter/flutter/issues/new/choose

To report a problem with the AutoRoller itself, please file a bug:
https://issues.skia.org/issues/new?component=1389291&template=1850622

Documentation for the AutoRoller is here:
https://skia.googlesource.com/buildbot/+doc/main/autoroll/README.md
@jiahaog
Copy link
Member

jiahaog commented Jun 21, 2024

Reason for revert: This causes b/348598454. We're getting test failures with stack traces like the following after this PR:

Cannot get renderObject of inactive element.
In order for an element to have a valid renderObject, it must be active, which means it is part of the tree.
Instead, this element is in the _ElementLifecycle.inactive state.
If you called this method from a State object, consider guarding it with State.mounted.
The findRenderObject() method was called for the following element:
  FocusScope
package:flutter/src/widgets/framework.dart 4725:9                   <fn>
package:flutter/src/widgets/framework.dart 4737:14                  findRenderObject
package:flutter/src/widgets/focus_manager.dart 842:33               get rect
package:flutter/src/widgets/focus_traversal.dart 1108:20            new
package:flutter/src/widgets/focus_traversal.dart 1353:49            <fn>
package:flutter/src/widgets/focus_traversal.dart 1353:75            sortDescendants
package:flutter/src/widgets/focus_traversal.dart 466:55             _sortAllDescendants
package:flutter/src/widgets/focus_traversal.dart 309:82             [_findInitialFocus]
package:flutter/src/widgets/focus_traversal.dart 277:12             findFirstFocus
package:flutter/src/widgets/view.dart 216:33                        didChangeViewFocus
package:flutter/src/widgets/binding.dart 971:15                     handleViewFocusChanged
package:flutter_test/src/window.dart 194:25                         [_handleViewFocusChanged]
...

which seems related to the focus changes in this PR.

@jiahaog jiahaog added the revert Label used to revert changes in a closed and merged pull request. label Jun 21, 2024
auto-submit bot pushed a commit that referenced this pull request Jun 21, 2024
@auto-submit auto-submit bot removed the revert Label used to revert changes in a closed and merged pull request. label Jun 21, 2024
auto-submit bot added a commit that referenced this pull request Jun 21, 2024
Reverts: #51009
Initiated by: jiahaog
Reason for reverting: This causes b/348598454. We're getting test failures with stack traces like the following after this PR:

```
Cannot get renderObject of inactive element.
In order for an element to have a valid renderObject, it must be active, which means it is part of the tree.
Instead, this element is in the _ElementLifecycle.inactive state.
If you called this method from a State object, consider guarding
```

Original PR Author: tugorez

Reviewed By: {mdebbar}

This change reverts the following previous change:
Fix focus management for text fields

This PR:

1. Refactors the DOM `focus` function to take [options][1]
2. Removes the timers sorrounding the `activeDomElement.focus()` so that the input elements get focused as immediate as possible.
3. Prevents the default on pointerdown in a Flutter View and schedules a `requestViewFocusChange` to claim focus in that view after some time. This gives `2` the opportunity to focus the right `<input />` or `<textarea />` element. This helps focus correctly transition from one input element to another (without jumping to a flutter view in between).
4. Deactivating a `TextField` doesn't blur the focused element anymore, it insteads schedules for later a call to move the focus to the flutter view if nothing inside it claimed focus first.
5. Prevents scroll in all the focus calls (this should help with the view jumping when focusing one text field after another).

## Sample apps

1. Full screen mode: https://tugorez.com/flutter_focus_web
2. Embedded mode: https://tugorez.com/flutter_focus_web?embedded

[C++, Objective-C, Java style guides]: https://github.com/flutter/engine/blob/main/CONTRIBUTING.md#style
@tugorez
Copy link
Contributor Author

tugorez commented Jun 21, 2024

b/348598454.

@gspencergoog is there something we're missing on the framework?

@@ -16,7 +16,7 @@ final class ViewFocusBinding {
///
/// DO NOT rely on this bit as it will go away soon. You're warned :)!
@visibleForTesting
static bool isEnabled = false;
static bool isEnabled = true;
Copy link
Contributor Author

Choose a reason for hiding this comment

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

@ditman we might want to reland these changes but with this one set to false. Not sure what's breaking on the framework side but don't think the rest of these changes is related.

Copy link
Member

Choose a reason for hiding this comment

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

Will take a look!

Copy link
Member

Choose a reason for hiding this comment

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

Reland posted: #53537 /cc @tugorez

ditman added a commit to ditman/flutter-engine that referenced this pull request Jun 24, 2024
auto-submit bot pushed a commit that referenced this pull request Jun 24, 2024
Relands: [**Fix focus management for text fields** (#51009)](#51009) by:

* Reverting commit: cf3ac2d (#53502).
* Keeping the new `ViewFocusBinding` disabled, as [suggested](#51009 (comment)).

[C++, Objective-C, Java style guides]: https://github.com/flutter/engine/blob/main/CONTRIBUTING.md#style
sigurdm pushed a commit to sigurdm/flutter that referenced this pull request Jun 26, 2024
…lutter#150582)

flutter/engine@dd37cef...dda82d9

2024-06-20 tarrinneal@gmail.com Update StandardMessageCodec.readValue to be @nullable (flutter/engine#53473)
2024-06-20 bruno.leroux@gmail.com [Web] Fix extra new line when inputAction is not newline for a multil� (flutter/engine#53453)
2024-06-20 skia-flutter-autoroll@skia.org Roll Dart SDK from 366eb1b4b308 to be6b533e07e7 (1 revision) (flutter/engine#53492)
2024-06-20 tugorez@users.noreply.github.com Fix focus management for text fields (flutter/engine#51009)
2024-06-20 skia-flutter-autoroll@skia.org Roll Dart SDK from cbd933e707e7 to 366eb1b4b308 (1 revision) (flutter/engine#53487)
2024-06-20 skia-flutter-autoroll@skia.org Roll Skia from 17626ca22729 to 4471ee07e223 (1 revision) (flutter/engine#53486)
2024-06-20 skia-flutter-autoroll@skia.org Roll Dart SDK from e403519a4436 to cbd933e707e7 (1 revision) (flutter/engine#53485)
2024-06-20 skia-flutter-autoroll@skia.org Roll Skia from 4acebac47ea5 to 17626ca22729 (1 revision) (flutter/engine#53484)
2024-06-20 skia-flutter-autoroll@skia.org Roll Skia from 199e1a49b091 to 4acebac47ea5 (1 revision) (flutter/engine#53482)

If this roll has caused a breakage, revert this CL and stop the roller
using the controls here:
https://autoroll.skia.org/r/flutter-engine-flutter-autoroll
Please CC jsimmons@google.com,rmistry@google.com,zra@google.com on the revert to ensure that a human
is aware of the problem.

To file a bug in Flutter: https://github.com/flutter/flutter/issues/new/choose

To report a problem with the AutoRoller itself, please file a bug:
https://issues.skia.org/issues/new?component=1389291&template=1850622

Documentation for the AutoRoller is here:
https://skia.googlesource.com/buildbot/+doc/main/autoroll/README.md
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
autosubmit Merge PR when tree becomes green via auto submit App platform-web Code specifically for the web engine
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants