Unverified Commit 23c20d70 authored by LongCatIsLooong's avatar LongCatIsLooong Committed by GitHub

[TextInput] send `setEditingState` before `show` to the text input plugin when...

[TextInput] send `setEditingState` before `show` to the text input plugin when switching input clients (#92945)
parent a1115b8b
......@@ -2207,16 +2207,9 @@ class EditableTextState extends State<EditableText> with AutomaticKeepAliveClien
_textInputConnection = _needsAutofill && currentAutofillScope != null
? currentAutofillScope!.attach(this, _effectiveAutofillClient.textInputConfiguration)
: TextInput.attach(this, _effectiveAutofillClient.textInputConfiguration);
_textInputConnection!.show();
_updateSizeAndTransform();
_updateComposingRectIfNeeded();
_updateCaretRectIfNeeded();
if (_needsAutofill) {
// Request autofill AFTER the size and the transform have been sent to
// the platform text input plugin.
_textInputConnection!.requestAutofill();
}
final TextStyle style = widget.style;
_textInputConnection!
..setStyle(
......@@ -2226,8 +2219,14 @@ class EditableTextState extends State<EditableText> with AutomaticKeepAliveClien
textDirection: _textDirection,
textAlign: widget.textAlign,
)
..setEditingState(localValue);
_lastKnownRemoteTextEditingValue = localValue;
..setEditingState(localValue)
..show();
if (_needsAutofill) {
// Request autofill AFTER the size and the transform have been sent to
// the platform text input plugin.
_textInputConnection!.requestAutofill();
}
_lastKnownRemoteTextEditingValue = localValue;
} else {
_textInputConnection!.show();
}
......
......@@ -6619,14 +6619,18 @@ void main() {
));
await tester.showKeyboard(find.byType(EditableText));
// TextInput.show should be before TextInput.setEditingState
// TextInput.show should be after TextInput.setEditingState.
// On Android setEditingState triggers an IME restart which may prevent
// the keyboard from showing if the show keyboard request comes before the
// restart.
// See: https://github.com/flutter/flutter/issues/68571.
final List<String> logOrder = <String>[
'TextInput.setClient',
'TextInput.show',
'TextInput.setEditableSizeAndTransform',
'TextInput.setMarkedTextRect',
'TextInput.setStyle',
'TextInput.setEditingState',
'TextInput.show',
'TextInput.setEditingState',
'TextInput.show',
'TextInput.setCaretRect',
......@@ -6637,6 +6641,67 @@ void main() {
);
});
testWidgets(
'keyboard is requested after setEditingState after switching to a new text field',
(WidgetTester tester) async {
// Regression test for https://github.com/flutter/flutter/issues/68571.
final EditableText editableText1 = EditableText(
showSelectionHandles: true,
maxLines: 2,
controller: TextEditingController(),
focusNode: FocusNode(),
cursorColor: Colors.red,
backgroundCursorColor: Colors.blue,
style: Typography.material2018().black.subtitle1!.copyWith(fontFamily: 'Roboto'),
keyboardType: TextInputType.text,
);
final EditableText editableText2 = EditableText(
showSelectionHandles: true,
maxLines: 2,
controller: TextEditingController(),
focusNode: FocusNode(),
cursorColor: Colors.red,
backgroundCursorColor: Colors.blue,
style: Typography.material2018().black.subtitle1!.copyWith(fontFamily: 'Roboto'),
keyboardType: TextInputType.text,
);
await tester.pumpWidget(MaterialApp(
home: Center(
child: Column(
children: <Widget>[editableText1, editableText2],
),
),
));
await tester.tap(find.byWidget(editableText1));
await tester.pumpAndSettle();
tester.testTextInput.log.clear();
await tester.tap(find.byWidget(editableText2));
await tester.pumpAndSettle();
// Send TextInput.show after TextInput.setEditingState. Otherwise
// some Android keyboards ignore the "show keyboard" request, as the
// Android text input plugin restarts the input method when setEditingState
// is sent by the framework.
final List<String> logOrder = <String>[
'TextInput.clearClient',
'TextInput.setClient',
'TextInput.setEditableSizeAndTransform',
'TextInput.setMarkedTextRect',
'TextInput.setStyle',
'TextInput.setEditingState',
'TextInput.show',
'TextInput.setCaretRect',
];
expect(
tester.testTextInput.log.map((MethodCall m) => m.method),
logOrder,
);
});
testWidgets('setEditingState is not called when text changes', (WidgetTester tester) async {
// We shouldn't get a message here because this change is owned by the platform side.
const String testText = 'flutter is the best!';
......@@ -6666,11 +6731,11 @@ void main() {
final List<String> logOrder = <String>[
'TextInput.setClient',
'TextInput.show',
'TextInput.setEditableSizeAndTransform',
'TextInput.setMarkedTextRect',
'TextInput.setStyle',
'TextInput.setEditingState',
'TextInput.show',
'TextInput.setEditingState',
'TextInput.show',
'TextInput.setCaretRect',
......@@ -6716,11 +6781,11 @@ void main() {
final List<String> logOrder = <String>[
'TextInput.setClient',
'TextInput.show',
'TextInput.setEditableSizeAndTransform',
'TextInput.setMarkedTextRect',
'TextInput.setStyle',
'TextInput.setEditingState',
'TextInput.show',
'TextInput.setEditingState',
'TextInput.show',
'TextInput.setCaretRect',
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment