[Keyboard] Accept empty events (#87152)
This commit is contained in:
@@ -787,8 +787,15 @@ class KeyEventManager {
|
||||
assert(false, 'Should never encounter KeyData when transitMode is rawKeyData.');
|
||||
return false;
|
||||
case KeyDataTransitMode.keyDataThenRawKeyData:
|
||||
assert((data.physical == 0 && data.logical == 0) ||
|
||||
(data.physical != 0 && data.logical != 0));
|
||||
// Postpone key event dispatching until the handleRawKeyMessage.
|
||||
_keyEventsSinceLastMessage.add(_eventFromData(data));
|
||||
//
|
||||
// Having 0 as the physical or logical ID indicates an empty key data,
|
||||
// transmitted to ensure that the transit mode is correctly inferred.
|
||||
if (data.physical != 0 && data.logical != 0) {
|
||||
_keyEventsSinceLastMessage.add(_eventFromData(data));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
import 'dart:ui' as ui;
|
||||
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
@@ -162,4 +164,60 @@ void main() {
|
||||
expect(logs, <int>[3, 2, 1]);
|
||||
logs.clear();
|
||||
}, variant: KeySimulatorTransitModeVariant.all());
|
||||
|
||||
// The first key data received from the engine might be an empty key data.
|
||||
// In that case, the key data should not be converted to any [KeyEvent]s,
|
||||
// but is only used so that *a* key data comes before the raw key message
|
||||
// and makes [KeyEventManager] infer [KeyDataTransitMode.keyDataThenRawKeyData].
|
||||
testWidgets('Empty keyData yields no event but triggers inferrence', (WidgetTester tester) async {
|
||||
final List<KeyEvent> events = <KeyEvent>[];
|
||||
final List<RawKeyEvent> rawEvents = <RawKeyEvent>[];
|
||||
tester.binding.keyboard.addHandler((KeyEvent event) {
|
||||
events.add(event);
|
||||
return true;
|
||||
});
|
||||
RawKeyboard.instance.addListener((RawKeyEvent event) {
|
||||
rawEvents.add(event);
|
||||
});
|
||||
tester.binding.keyEventManager.handleKeyData(const ui.KeyData(
|
||||
type: ui.KeyEventType.down,
|
||||
timeStamp: Duration.zero,
|
||||
logical: 0,
|
||||
physical: 0,
|
||||
character: 'a',
|
||||
synthesized: false,
|
||||
));
|
||||
tester.binding.keyEventManager.handleRawKeyMessage(<String, dynamic>{
|
||||
'type': 'keydown',
|
||||
'keymap': 'windows',
|
||||
'keyCode': 0x04,
|
||||
'scanCode': 0x04,
|
||||
'characterCodePoint': 0,
|
||||
'modifiers': 0,
|
||||
});
|
||||
expect(events.length, 0);
|
||||
expect(rawEvents.length, 1);
|
||||
|
||||
// Dispatch another key data to ensure it's in
|
||||
// [KeyDataTransitMode.keyDataThenRawKeyData] mode (otherwise assertion
|
||||
// will be thrown upon a KeyData).
|
||||
tester.binding.keyEventManager.handleKeyData(const ui.KeyData(
|
||||
type: ui.KeyEventType.down,
|
||||
timeStamp: Duration.zero,
|
||||
logical: 0x22,
|
||||
physical: 0x70034,
|
||||
character: '"',
|
||||
synthesized: false,
|
||||
));
|
||||
tester.binding.keyEventManager.handleRawKeyMessage(<String, dynamic>{
|
||||
'type': 'keydown',
|
||||
'keymap': 'windows',
|
||||
'keyCode': 0x04,
|
||||
'scanCode': 0x04,
|
||||
'characterCodePoint': 0,
|
||||
'modifiers': 0,
|
||||
});
|
||||
expect(events.length, 1);
|
||||
expect(rawEvents.length, 2);
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user