Skip to content

Commit

Permalink
[web] Reland "Fix focus management for text fields (#51009)" (#53537)
Browse files Browse the repository at this point in the history
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
  • Loading branch information
ditman authored Jun 24, 2024
1 parent 1fb20a2 commit 63c2403
Show file tree
Hide file tree
Showing 6 changed files with 250 additions and 253 deletions.
17 changes: 14 additions & 3 deletions lib/web_ui/lib/src/engine/dom.dart
Original file line number Diff line number Diff line change
Expand Up @@ -658,7 +658,16 @@ extension DomElementExtension on DomElement {
external JSNumber? get _tabIndex;
double? get tabIndex => _tabIndex?.toDartDouble;

external JSVoid focus();
@JS('focus')
external JSVoid _focus(JSAny options);

void focus({bool? preventScroll, bool? focusVisible}) {
final Map<String, bool> options = <String, bool>{
if (preventScroll != null) 'preventScroll': preventScroll,
if (focusVisible != null) 'focusVisible': focusVisible,
};
_focus(options.toJSAnyDeep);
}

@JS('scrollTop')
external JSNumber get _scrollTop;
Expand Down Expand Up @@ -2249,9 +2258,11 @@ extension DomKeyboardEventExtension on DomKeyboardEvent {
external JSBoolean? get _repeat;
bool? get repeat => _repeat?.toDart;

// Safari injects synthetic keyboard events after auto-complete that don't
// have a `shiftKey` attribute, so this property must be nullable.
@JS('shiftKey')
external JSBoolean get _shiftKey;
bool get shiftKey => _shiftKey.toDart;
external JSBoolean? get _shiftKey;
bool? get shiftKey => _shiftKey?.toDart;

@JS('isComposing')
external JSBoolean get _isComposing;
Expand Down
2 changes: 1 addition & 1 deletion lib/web_ui/lib/src/engine/keyboard_binding.dart
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,7 @@ class FlutterHtmlKeyboardEvent {
num? get timeStamp => _event.timeStamp;
bool get altKey => _event.altKey;
bool get ctrlKey => _event.ctrlKey;
bool get shiftKey => _event.shiftKey;
bool get shiftKey => _event.shiftKey ?? false;
bool get metaKey => _event.metaKey;
bool get isComposing => _event.isComposing;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ final class ViewFocusBinding {
if (state == ui.ViewFocusState.focused) {
// Only move the focus to the flutter view if nothing inside it is focused already.
if (viewId != _viewId(domDocument.activeElement)) {
viewElement?.focus();
viewElement?.focus(preventScroll: true);
}
} else {
viewElement?.blur();
Expand All @@ -70,7 +70,7 @@ final class ViewFocusBinding {

late final DomEventListener _handleKeyDown = createDomEventListener((DomEvent event) {
event as DomKeyboardEvent;
if (event.shiftKey) {
if (event.shiftKey ?? false) {
_viewFocusDirection = ui.ViewFocusDirection.backward;
}
});
Expand Down
16 changes: 16 additions & 0 deletions lib/web_ui/lib/src/engine/pointer_binding.dart
Original file line number Diff line number Diff line change
Expand Up @@ -982,6 +982,22 @@ class _PointerAdapter extends _BaseAdapter with _WheelEventListenerMixin {
);
_convertEventsToPointerData(data: pointerData, event: event, details: down);
_callback(event, pointerData);

if (event.target == _viewTarget) {
// Ensure smooth focus transitions between text fields within the Flutter view.
// Without preventing the default and this delay, the engine may not have fully
// rendered the next input element, leading to the focus incorrectly returning to
// the main Flutter view instead.
// A zero-length timer is sufficient in all tested browsers to achieve this.
event.preventDefault();
Timer(Duration.zero, () {
EnginePlatformDispatcher.instance.requestViewFocusChange(
viewId: _view.viewId,
state: ui.ViewFocusState.focused,
direction: ui.ViewFocusDirection.undefined,
);
});
}
});

// Why `domWindow` you ask? See this fiddle: https://jsfiddle.net/ditman/7towxaqp
Expand Down
Loading

0 comments on commit 63c2403

Please sign in to comment.