Skip to content

Commit 75190be

Browse files
LongCatIsLooongclocksmith
authored andcommitted
EditableText does not request focus on autofill (flutter#97846)
1 parent 3e1bc4a commit 75190be

File tree

2 files changed

+72
-18
lines changed

2 files changed

+72
-18
lines changed

packages/flutter/lib/src/widgets/editable_text.dart

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2391,8 +2391,27 @@ class EditableTextState extends State<EditableText> with AutomaticKeepAliveClien
23912391
widget.controller.selection = selection;
23922392

23932393
// This will show the keyboard for all selection changes on the
2394-
// EditableWidget, not just changes triggered by user gestures.
2395-
requestKeyboard();
2394+
// EditableText except for those triggered by a keyboard input.
2395+
// Typically EditableText shouldn't take user keyboard input if
2396+
// it's not focused already. If the EditableText is being
2397+
// autofilled it shouldn't request focus.
2398+
switch (cause) {
2399+
case null:
2400+
case SelectionChangedCause.doubleTap:
2401+
case SelectionChangedCause.drag:
2402+
case SelectionChangedCause.forcePress:
2403+
case SelectionChangedCause.longPress:
2404+
case SelectionChangedCause.scribble:
2405+
case SelectionChangedCause.tap:
2406+
case SelectionChangedCause.toolbar:
2407+
requestKeyboard();
2408+
break;
2409+
case SelectionChangedCause.keyboard:
2410+
if (_hasFocus) {
2411+
requestKeyboard();
2412+
}
2413+
break;
2414+
}
23962415
if (widget.selectionControls == null) {
23972416
_selectionOverlay?.dispose();
23982417
_selectionOverlay = null;

packages/flutter/test/widgets/editable_text_test.dart

Lines changed: 51 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -3013,8 +3013,6 @@ void main() {
30133013
SemanticsAction.moveCursorForwardByCharacter,
30143014
SemanticsAction.moveCursorBackwardByWord,
30153015
SemanticsAction.moveCursorForwardByWord,
3016-
SemanticsAction.setSelection,
3017-
SemanticsAction.setText,
30183016
],
30193017
),
30203018
);
@@ -3049,8 +3047,6 @@ void main() {
30493047
actions: <SemanticsAction>[
30503048
SemanticsAction.moveCursorForwardByCharacter,
30513049
SemanticsAction.moveCursorForwardByWord,
3052-
SemanticsAction.setSelection,
3053-
SemanticsAction.setText,
30543050
],
30553051
),
30563052
);
@@ -3122,8 +3118,6 @@ void main() {
31223118
SemanticsAction.moveCursorForwardByCharacter,
31233119
SemanticsAction.moveCursorBackwardByWord,
31243120
SemanticsAction.moveCursorForwardByWord,
3125-
SemanticsAction.setSelection,
3126-
SemanticsAction.setText,
31273121
],
31283122
),
31293123
);
@@ -3156,8 +3150,6 @@ void main() {
31563150
actions: <SemanticsAction>[
31573151
SemanticsAction.moveCursorForwardByCharacter,
31583152
SemanticsAction.moveCursorForwardByWord,
3159-
SemanticsAction.setSelection,
3160-
SemanticsAction.setText,
31613153
],
31623154
),
31633155
);
@@ -3240,8 +3232,6 @@ void main() {
32403232
SemanticsAction.moveCursorForwardByCharacter,
32413233
SemanticsAction.moveCursorBackwardByWord,
32423234
SemanticsAction.moveCursorForwardByWord,
3243-
SemanticsAction.setSelection,
3244-
SemanticsAction.setText,
32453235
],
32463236
),
32473237
);
@@ -3276,8 +3266,6 @@ void main() {
32763266
actions: <SemanticsAction>[
32773267
SemanticsAction.moveCursorForwardByCharacter,
32783268
SemanticsAction.moveCursorForwardByWord,
3279-
SemanticsAction.setSelection,
3280-
SemanticsAction.setText,
32813269
],
32823270
),
32833271
);
@@ -3360,8 +3348,6 @@ void main() {
33603348
SemanticsAction.moveCursorForwardByCharacter,
33613349
SemanticsAction.moveCursorBackwardByWord,
33623350
SemanticsAction.moveCursorForwardByWord,
3363-
SemanticsAction.setSelection,
3364-
SemanticsAction.setText,
33653351
],
33663352
),
33673353
);
@@ -3394,8 +3380,6 @@ void main() {
33943380
actions: <SemanticsAction>[
33953381
SemanticsAction.moveCursorForwardByCharacter,
33963382
SemanticsAction.moveCursorForwardByWord,
3397-
SemanticsAction.setSelection,
3398-
SemanticsAction.setText,
33993383
],
34003384
),
34013385
);
@@ -8137,6 +8121,57 @@ void main() {
81378121
);
81388122
});
81398123

8124+
testWidgets(
8125+
'Autofill does not request focus',
8126+
(WidgetTester tester) async {
8127+
// Regression test for https://github.com/flutter/flutter/issues/91354 .
8128+
final FocusNode focusNode1 = FocusNode();
8129+
final EditableText editableText1 = EditableText(
8130+
showSelectionHandles: true,
8131+
maxLines: 2,
8132+
controller: TextEditingController(),
8133+
focusNode: focusNode1,
8134+
cursorColor: Colors.red,
8135+
backgroundCursorColor: Colors.blue,
8136+
style: Typography.material2018().black.subtitle1!.copyWith(fontFamily: 'Roboto'),
8137+
keyboardType: TextInputType.text,
8138+
);
8139+
8140+
final FocusNode focusNode2 = FocusNode();
8141+
final EditableText editableText2 = EditableText(
8142+
showSelectionHandles: true,
8143+
maxLines: 2,
8144+
controller: TextEditingController(),
8145+
focusNode: focusNode2,
8146+
cursorColor: Colors.red,
8147+
backgroundCursorColor: Colors.blue,
8148+
style: Typography.material2018().black.subtitle1!.copyWith(fontFamily: 'Roboto'),
8149+
keyboardType: TextInputType.text,
8150+
);
8151+
8152+
await tester.pumpWidget(MaterialApp(
8153+
home: Center(
8154+
child: Column(
8155+
children: <Widget>[editableText1, editableText2],
8156+
),
8157+
),
8158+
));
8159+
8160+
// editableText1 has the focus.
8161+
await tester.tap(find.byWidget(editableText1));
8162+
await tester.pumpAndSettle();
8163+
8164+
final EditableTextState state2 = tester.state<EditableTextState>(find.byWidget(editableText2));
8165+
// Update editableText2 when it's not focused. It should not request focus.
8166+
state2.updateEditingValue(
8167+
const TextEditingValue(text: 'password', selection: TextSelection.collapsed(offset: 8)),
8168+
);
8169+
await tester.pumpAndSettle();
8170+
8171+
expect(focusNode1.hasFocus, isTrue);
8172+
expect(focusNode2.hasFocus, isFalse);
8173+
});
8174+
81408175
testWidgets('setEditingState is not called when text changes', (WidgetTester tester) async {
81418176
// We shouldn't get a message here because this change is owned by the platform side.
81428177
const String testText = 'flutter is the best!';

0 commit comments

Comments
 (0)