Browse Source

Prevents sending excessive value updates to the native side which cause race condition errors on android.

Anatoly Pulyaevskiy 6 years ago
parent
commit
ece9fa6564
2 changed files with 26 additions and 10 deletions
  1. 5
    5
      packages/zefyr/example/lib/main.dart
  2. 21
    5
      packages/zefyr/lib/src/widgets/input.dart

+ 5
- 5
packages/zefyr/example/lib/main.dart View File

@@ -63,11 +63,11 @@ class _MyHomePageState extends State<MyHomePage> {
63 63
   Widget build(BuildContext context) {
64 64
     final theme = new ZefyrThemeData(
65 65
       toolbarTheme: ZefyrToolbarTheme.fallback(context).copyWith(
66
-            color: Colors.grey.shade800,
67
-            toggleColor: Colors.grey.shade900,
68
-            iconColor: Colors.white,
69
-            disabledIconColor: Colors.grey.shade500,
70
-          ),
66
+        color: Colors.grey.shade800,
67
+        toggleColor: Colors.grey.shade900,
68
+        iconColor: Colors.white,
69
+        disabledIconColor: Colors.grey.shade500,
70
+      ),
71 71
     );
72 72
 
73 73
     final done = _editing

+ 21
- 5
packages/zefyr/lib/src/widgets/input.dart View File

@@ -67,13 +67,23 @@ class InputConnectionController implements TextInputClient {
67 67
   void updateRemoteValue(TextEditingValue value) {
68 68
     if (!hasConnection) return;
69 69
 
70
-    if (value == _lastKnownRemoteTextEditingValue) return;
70
+    // Since we don't keep track of composing range in value provided by
71
+    // ZefyrController we need to add it here manually before comparing
72
+    // with the last known remote value.
73
+    // It is important to prevent excessive remote updates as it can cause
74
+    // race conditions.
75
+    final actualValue = value.copyWith(
76
+      composing: _lastKnownRemoteTextEditingValue.composing,
77
+    );
78
+
79
+    if (actualValue == _lastKnownRemoteTextEditingValue) return;
80
+
71 81
     bool shouldRemember = value.text != _lastKnownRemoteTextEditingValue.text;
72
-    _lastKnownRemoteTextEditingValue = value;
73
-    _textInputConnection.setEditingState(value);
74
-    // Only keep track if text changed (selection changes are not relevant)
82
+    _lastKnownRemoteTextEditingValue = actualValue;
83
+    _textInputConnection.setEditingState(actualValue);
75 84
     if (shouldRemember) {
76
-      _sentRemoteValues.add(value);
85
+      // Only keep track if text changed (selection changes are not relevant)
86
+      _sentRemoteValues.add(actualValue);
77 87
     }
78 88
   }
79 89
 
@@ -103,6 +113,12 @@ class InputConnectionController implements TextInputClient {
103 113
       _sentRemoteValues.remove(value);
104 114
       return;
105 115
     }
116
+
117
+    if (_lastKnownRemoteTextEditingValue == value) {
118
+      // There is no difference between this value and the last known value.
119
+      return;
120
+    }
121
+
106 122
     // Note Flutter (unintentionally?) silences errors occurred during
107 123
     // text input update, so we have to report it ourselves.
108 124
     // For more details see https://github.com/flutter/flutter/issues/19191