diff --git a/packages/zefyr/CHANGELOG.md b/packages/zefyr/CHANGELOG.md index 83be16f29..d9fd78de4 100644 --- a/packages/zefyr/CHANGELOG.md +++ b/packages/zefyr/CHANGELOG.md @@ -1,3 +1,8 @@ +## 0.1.1 + +* Fixed: Prevent sending excessive value updates to the native side + which cause race conditions (#12). + ## 0.1.0 * Initial release. diff --git a/packages/zefyr/example/lib/main.dart b/packages/zefyr/example/lib/main.dart index 433645a8e..738124923 100644 --- a/packages/zefyr/example/lib/main.dart +++ b/packages/zefyr/example/lib/main.dart @@ -63,11 +63,11 @@ class _MyHomePageState extends State { Widget build(BuildContext context) { final theme = new ZefyrThemeData( toolbarTheme: ZefyrToolbarTheme.fallback(context).copyWith( - color: Colors.grey.shade800, - toggleColor: Colors.grey.shade900, - iconColor: Colors.white, - disabledIconColor: Colors.grey.shade500, - ), + color: Colors.grey.shade800, + toggleColor: Colors.grey.shade900, + iconColor: Colors.white, + disabledIconColor: Colors.grey.shade500, + ), ); final done = _editing diff --git a/packages/zefyr/lib/src/widgets/input.dart b/packages/zefyr/lib/src/widgets/input.dart index b5617d468..7fa846b1b 100644 --- a/packages/zefyr/lib/src/widgets/input.dart +++ b/packages/zefyr/lib/src/widgets/input.dart @@ -67,13 +67,23 @@ class InputConnectionController implements TextInputClient { void updateRemoteValue(TextEditingValue value) { if (!hasConnection) return; - if (value == _lastKnownRemoteTextEditingValue) return; + // Since we don't keep track of composing range in value provided by + // ZefyrController we need to add it here manually before comparing + // with the last known remote value. + // It is important to prevent excessive remote updates as it can cause + // race conditions. + final actualValue = value.copyWith( + composing: _lastKnownRemoteTextEditingValue.composing, + ); + + if (actualValue == _lastKnownRemoteTextEditingValue) return; + bool shouldRemember = value.text != _lastKnownRemoteTextEditingValue.text; - _lastKnownRemoteTextEditingValue = value; - _textInputConnection.setEditingState(value); - // Only keep track if text changed (selection changes are not relevant) + _lastKnownRemoteTextEditingValue = actualValue; + _textInputConnection.setEditingState(actualValue); if (shouldRemember) { - _sentRemoteValues.add(value); + // Only keep track if text changed (selection changes are not relevant) + _sentRemoteValues.add(actualValue); } } @@ -103,6 +113,12 @@ class InputConnectionController implements TextInputClient { _sentRemoteValues.remove(value); return; } + + if (_lastKnownRemoteTextEditingValue == value) { + // There is no difference between this value and the last known value. + return; + } + // Note Flutter (unintentionally?) silences errors occurred during // text input update, so we have to report it ourselves. // For more details see https://github.com/flutter/flutter/issues/19191 diff --git a/packages/zefyr/pubspec.yaml b/packages/zefyr/pubspec.yaml index 9a6fa3ad9..ac2148088 100644 --- a/packages/zefyr/pubspec.yaml +++ b/packages/zefyr/pubspec.yaml @@ -1,6 +1,6 @@ name: zefyr description: Rich text editor for Flutter. -version: 0.1.0 +version: 0.1.1 author: Anatoly Pulyaevskiy homepage: https://github.com/pulyaevskiy/zefyr