@@ -766,6 +766,11 @@ class KeyEventManager {
766766 // dispatchable [RawKeyEvent] is available.
767767 final List <KeyEvent > _keyEventsSinceLastMessage = < KeyEvent > [];
768768
769+ // When a RawKeyDownEvent is skipped ([RawKeyEventData.shouldDispatchEvent]
770+ // is false), its physical key will be recorded here, so that its up event
771+ // can also be properly skipped.
772+ final Set <PhysicalKeyboardKey > _skippedRawKeysPressed = < PhysicalKeyboardKey > {};
773+
769774 /// Dispatch a key data to global and leaf listeners.
770775 ///
771776 /// This method is the handler to the global `onKeyData` API.
@@ -843,21 +848,40 @@ class KeyEventManager {
843848 _rawKeyboard.addListener (_convertRawEventAndStore);
844849 }
845850 final RawKeyEvent rawEvent = RawKeyEvent .fromMessage (message as Map <String , dynamic >);
846- // The following `handleRawKeyEvent` will call `_convertRawEventAndStore`
847- // unless the event is not dispatched.
848- bool handled = _rawKeyboard.handleRawKeyEvent (rawEvent);
849851
850- for (final KeyEvent event in _keyEventsSinceLastMessage) {
851- handled = _hardwareKeyboard.handleKeyEvent (event) || handled;
852- }
853- if (_transitMode == KeyDataTransitMode .rawKeyData) {
854- assert (setEquals (_rawKeyboard.physicalKeysPressed, _hardwareKeyboard.physicalKeysPressed),
855- 'RawKeyboard reported ${_rawKeyboard .physicalKeysPressed }, '
856- 'while HardwareKeyboard reported ${_hardwareKeyboard .physicalKeysPressed }' );
852+ bool shouldDispatch = true ;
853+ if (rawEvent is RawKeyDownEvent ) {
854+ if (! rawEvent.data.shouldDispatchEvent ()) {
855+ shouldDispatch = false ;
856+ _skippedRawKeysPressed.add (rawEvent.physicalKey);
857+ } else {
858+ _skippedRawKeysPressed.remove (rawEvent.physicalKey);
859+ }
860+ } else if (rawEvent is RawKeyUpEvent ) {
861+ if (_skippedRawKeysPressed.contains (rawEvent.physicalKey)) {
862+ _skippedRawKeysPressed.remove (rawEvent.physicalKey);
863+ shouldDispatch = false ;
864+ }
857865 }
858866
859- handled = _dispatchKeyMessage (_keyEventsSinceLastMessage, rawEvent) || handled;
860- _keyEventsSinceLastMessage.clear ();
867+ bool handled = true ;
868+ if (shouldDispatch) {
869+ // The following `handleRawKeyEvent` will call `_convertRawEventAndStore`
870+ // unless the event is not dispatched.
871+ handled = _rawKeyboard.handleRawKeyEvent (rawEvent);
872+
873+ for (final KeyEvent event in _keyEventsSinceLastMessage) {
874+ handled = _hardwareKeyboard.handleKeyEvent (event) || handled;
875+ }
876+ if (_transitMode == KeyDataTransitMode .rawKeyData) {
877+ assert (setEquals (_rawKeyboard.physicalKeysPressed, _hardwareKeyboard.physicalKeysPressed),
878+ 'RawKeyboard reported ${_rawKeyboard .physicalKeysPressed }, '
879+ 'while HardwareKeyboard reported ${_hardwareKeyboard .physicalKeysPressed }' );
880+ }
881+
882+ handled = _dispatchKeyMessage (_keyEventsSinceLastMessage, rawEvent) || handled;
883+ _keyEventsSinceLastMessage.clear ();
884+ }
861885
862886 return < String , dynamic > { 'handled' : handled };
863887 }
0 commit comments