@@ -204,11 +204,18 @@ class FlutterHtmlKeyboardEvent {
204
204
// [dispatchKeyData] as given in the constructor. Some key data might be
205
205
// dispatched asynchronously.
206
206
class KeyboardConverter {
207
- KeyboardConverter (this .dispatchKeyData , {this .onMacOs = false });
207
+ KeyboardConverter (this .performDispatchKeyData , {this .onMacOs = false });
208
208
209
- final DispatchKeyData dispatchKeyData ;
209
+ final DispatchKeyData performDispatchKeyData ;
210
210
final bool onMacOs;
211
211
212
+ // The `performDispatchKeyData` wrapped with tracking logic.
213
+ //
214
+ // It is non-null only during `handleEvent`. All events during `handleEvent`
215
+ // should be dispatched with `_dispatchKeyData`, others with
216
+ // `performDispatchKeyData`.
217
+ DispatchKeyData ? _dispatchKeyData;
218
+
212
219
bool _disposed = false ;
213
220
void dispose () {
214
221
_disposed = true ;
@@ -294,7 +301,9 @@ class KeyboardConverter {
294
301
Future <void >.delayed (duration).then <void >((_) {
295
302
if (! canceled && ! _disposed) {
296
303
callback ();
297
- dispatchKeyData (getData ());
304
+ // This dispatch is performed asynchronously, therefore should not use
305
+ // `_dispatchKeyData`.
306
+ performDispatchKeyData (getData ());
298
307
}
299
308
});
300
309
return () { canceled = true ; };
@@ -335,17 +344,7 @@ class KeyboardConverter {
335
344
_keyGuards.remove (physicalKey)? .call ();
336
345
}
337
346
338
- // Parse the HTML event, update states, and dispatch Flutter key data through
339
- // [dispatchKeyData].
340
- //
341
- // * The method might dispatch some synthesized key data first to update states,
342
- // results discarded.
343
- // * Then it dispatches exactly one non-synthesized key data that corresponds
344
- // to the `event`, i.e. the primary key data. If this dispatching returns
345
- // true, then this event will be invoked `preventDefault`.
346
- // * Some key data might be synthesized to update states after the main key
347
- // data. They are always scheduled asynchronously with results discarded.
348
- void handleEvent (FlutterHtmlKeyboardEvent event) {
347
+ void _handleEvent (FlutterHtmlKeyboardEvent event) {
349
348
final Duration timeStamp = _eventTimeStampToDuration (event.timeStamp! );
350
349
351
350
final String eventKey = event.key! ;
@@ -411,7 +410,6 @@ class KeyboardConverter {
411
410
// a currently pressed one, usually indicating multiple keyboards are
412
411
// pressing keys with the same physical key, or the up event was lost
413
412
// during a loss of focus. The down event is ignored.
414
- dispatchKeyData (_emptyKeyData);
415
413
event.preventDefault ();
416
414
return ;
417
415
}
@@ -425,7 +423,6 @@ class KeyboardConverter {
425
423
if (lastLogicalRecord == null ) {
426
424
// The physical key has been released before. It indicates multiple
427
425
// keyboards pressed keys with the same physical key. Ignore the up event.
428
- dispatchKeyData (_emptyKeyData);
429
426
event.preventDefault ();
430
427
return ;
431
428
}
@@ -465,7 +462,7 @@ class KeyboardConverter {
465
462
if (logicalRecord != logicalKey)
466
463
return false ;
467
464
468
- dispatchKeyData (ui.KeyData (
465
+ _dispatchKeyData ! (ui.KeyData (
469
466
timeStamp: timeStamp,
470
467
type: ui.KeyEventType .up,
471
468
physical: physicalKey,
@@ -497,9 +494,36 @@ class KeyboardConverter {
497
494
synthesized: false ,
498
495
);
499
496
500
- final bool primaryHandled = dispatchKeyData (keyData);
497
+ final bool primaryHandled = _dispatchKeyData ! (keyData);
501
498
if (primaryHandled) {
502
499
event.preventDefault ();
503
500
}
504
501
}
502
+
503
+ // Parse the HTML event, update states, and dispatch Flutter key data through
504
+ // [performDispatchKeyData].
505
+ //
506
+ // * The method might dispatch some synthesized key data first to update states,
507
+ // results discarded.
508
+ // * Then it dispatches exactly one non-synthesized key data that corresponds
509
+ // to the `event`, i.e. the primary key data. If this dispatching returns
510
+ // true, then this event will be invoked `preventDefault`.
511
+ // * Some key data might be synthesized to update states after the main key
512
+ // data. They are always scheduled asynchronously with results discarded.
513
+ void handleEvent (FlutterHtmlKeyboardEvent event) {
514
+ assert (_dispatchKeyData == null );
515
+ bool sentAnyEvents = false ;
516
+ _dispatchKeyData = (ui.KeyData data) {
517
+ sentAnyEvents = true ;
518
+ return performDispatchKeyData (data);
519
+ };
520
+ try {
521
+ _handleEvent (event);
522
+ } finally {
523
+ if (! sentAnyEvents) {
524
+ _dispatchKeyData !(_emptyKeyData);
525
+ }
526
+ _dispatchKeyData = null ;
527
+ }
528
+ }
505
529
}
0 commit comments