|
|
@ -10,7 +10,6 @@ import '../editor.dart'; |
|
|
|
|
|
|
|
|
|
|
|
mixin RawEditorStateTextInputClientMixin on EditorState |
|
|
|
mixin RawEditorStateTextInputClientMixin on EditorState |
|
|
|
implements TextInputClient { |
|
|
|
implements TextInputClient { |
|
|
|
final List<TextEditingValue> _sentRemoteValues = []; |
|
|
|
|
|
|
|
TextInputConnection? _textInputConnection; |
|
|
|
TextInputConnection? _textInputConnection; |
|
|
|
TextEditingValue? _lastKnownRemoteTextEditingValue; |
|
|
|
TextEditingValue? _lastKnownRemoteTextEditingValue; |
|
|
|
|
|
|
|
|
|
|
@ -77,7 +76,6 @@ mixin RawEditorStateTextInputClientMixin on EditorState |
|
|
|
_textInputConnection!.close(); |
|
|
|
_textInputConnection!.close(); |
|
|
|
_textInputConnection = null; |
|
|
|
_textInputConnection = null; |
|
|
|
_lastKnownRemoteTextEditingValue = null; |
|
|
|
_lastKnownRemoteTextEditingValue = null; |
|
|
|
_sentRemoteValues.clear(); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/// Updates remote value based on current state of [document] and |
|
|
|
/// Updates remote value based on current state of [document] and |
|
|
@ -105,17 +103,12 @@ mixin RawEditorStateTextInputClientMixin on EditorState |
|
|
|
return; |
|
|
|
return; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
final shouldRemember = value.text != _lastKnownRemoteTextEditingValue!.text; |
|
|
|
|
|
|
|
_lastKnownRemoteTextEditingValue = actualValue; |
|
|
|
_lastKnownRemoteTextEditingValue = actualValue; |
|
|
|
_textInputConnection!.setEditingState( |
|
|
|
_textInputConnection!.setEditingState( |
|
|
|
// Set composing to (-1, -1), otherwise an exception will be thrown if |
|
|
|
// Set composing to (-1, -1), otherwise an exception will be thrown if |
|
|
|
// the values are different. |
|
|
|
// the values are different. |
|
|
|
actualValue.copyWith(composing: const TextRange(start: -1, end: -1)), |
|
|
|
actualValue.copyWith(composing: const TextRange(start: -1, end: -1)), |
|
|
|
); |
|
|
|
); |
|
|
|
if (shouldRemember) { |
|
|
|
|
|
|
|
// Only keep track if text changed (selection changes are not relevant) |
|
|
|
|
|
|
|
_sentRemoteValues.add(actualValue); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@override |
|
|
|
@override |
|
|
@ -132,22 +125,6 @@ mixin RawEditorStateTextInputClientMixin on EditorState |
|
|
|
return; |
|
|
|
return; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (_sentRemoteValues.contains(value)) { |
|
|
|
|
|
|
|
/// There is a race condition in Flutter text input plugin where sending |
|
|
|
|
|
|
|
/// updates to native side too often results in broken behavior. |
|
|
|
|
|
|
|
/// TextInputConnection.setEditingValue is an async call to native side. |
|
|
|
|
|
|
|
/// For each such call native side _always_ sends an update which triggers |
|
|
|
|
|
|
|
/// this method (updateEditingValue) with the same value we've sent it. |
|
|
|
|
|
|
|
/// If multiple calls to setEditingValue happen too fast and we only |
|
|
|
|
|
|
|
/// track the last sent value then there is no way for us to filter out |
|
|
|
|
|
|
|
/// automatic callbacks from native side. |
|
|
|
|
|
|
|
/// Therefore we have to keep track of all values we send to the native |
|
|
|
|
|
|
|
/// side and when we see this same value appear here we skip it. |
|
|
|
|
|
|
|
/// This is fragile but it's probably the only available option. |
|
|
|
|
|
|
|
_sentRemoteValues.remove(value); |
|
|
|
|
|
|
|
return; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (_lastKnownRemoteTextEditingValue == value) { |
|
|
|
if (_lastKnownRemoteTextEditingValue == value) { |
|
|
|
// There is no difference between this value and the last known value. |
|
|
|
// There is no difference between this value and the last known value. |
|
|
|
return; |
|
|
|
return; |
|
|
@ -317,6 +294,5 @@ mixin RawEditorStateTextInputClientMixin on EditorState |
|
|
|
_textInputConnection!.connectionClosedReceived(); |
|
|
|
_textInputConnection!.connectionClosedReceived(); |
|
|
|
_textInputConnection = null; |
|
|
|
_textInputConnection = null; |
|
|
|
_lastKnownRemoteTextEditingValue = null; |
|
|
|
_lastKnownRemoteTextEditingValue = null; |
|
|
|
_sentRemoteValues.clear(); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|