Unverified Commit 199a7c19 authored by Greg Spencer's avatar Greg Spencer Committed by GitHub

Fix the `character` field of the `RawKeyEvent` to hold correct data on...

Fix the `character` field of the `RawKeyEvent` to hold correct data on non-Android platforms. (#65667)

This fixes a problem where the character field of the RawKeyEvent was not being set at all for non-Android platforms.

I also updated the key maps, and corrected a problem with the Windows key map where the backquote character wasn't correctly mapped.
parent b8a39c15
......@@ -79,6 +79,7 @@ class _HardwareKeyDemoState extends State<RawKeyboardDemo> {
final String modifierList = data.modifiersPressed.keys.map<String>(_getEnumName).join(', ').replaceAll('Modifier', '');
final List<Widget> dataText = <Widget>[
Text('${_event.runtimeType}'),
if (_event.character?.isNotEmpty ?? false) Text('character produced: "${_event.character}"'),
Text('modifiers set: $modifierList'),
];
if (data is RawKeyEventDataAndroid) {
......@@ -114,6 +115,10 @@ class _HardwareKeyDemoState extends State<RawKeyboardDemo> {
dataText.add(Text('scanCode: ${data.scanCode}'));
dataText.add(Text('characterCodePoint: ${data.characterCodePoint}'));
dataText.add(Text('modifiers: ${data.modifiers} (${_asHex(data.modifiers)})'));
} else if (data is RawKeyEventDataWeb) {
dataText.add(Text('key: ${data.key}'));
dataText.add(Text('code: ${data.code}'));
dataText.add(Text('metaState: ${data.metaState} (${_asHex(data.metaState)})'));
}
dataText.add(Text('logical: ${_event.logicalKey}'));
dataText.add(Text('physical: ${_event.physicalKey}'));
......
......@@ -2472,7 +2472,9 @@
"gtk": [
"quoteleft"
],
"windows": null
"windows": [
"OEM_3"
]
},
"scanCodes": {
"android": [
......@@ -2494,7 +2496,9 @@
"gtk": [
96
],
"windows": null
"windows": [
192
]
}
},
"comma": {
......@@ -6565,7 +6569,9 @@
"windows": null
},
"scanCodes": {
"android": null,
"android": [
370
],
"usb": 786529,
"linux": 370,
"xkb": 378,
......@@ -6822,7 +6828,9 @@
"windows": null
},
"scanCodes": {
"android": null,
"android": [
405
],
"usb": 786563,
"linux": 405,
"xkb": 413,
......@@ -7891,7 +7899,9 @@
"windows": null
},
"scanCodes": {
"android": null,
"android": [
583
],
"usb": 786891,
"linux": 583,
"xkb": 591,
......
......@@ -132,7 +132,7 @@
"minus": ["OEM_MINUS"],
"period": ["OEM_PERIOD"],
"slash": ["OEM_2"],
"backQuote": ["OEM_3"],
"backquote": ["OEM_3"],
"gamepadA": ["GAMEPAD_A"],
"gamepadB": ["GAMEPAD_B"],
"gamepadX": ["GAMEPAD_X"],
......
......@@ -2,8 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// @dart = 2.8
// DO NOT EDIT -- DO NOT EDIT -- DO NOT EDIT
// This file is generated by dev/tools/gen_keycodes/bin/gen_keycodes.dart and
// should not be edited directly.
......
......@@ -2,7 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// DO NOT EDIT -- DO NOT EDIT -- DO NOT EDIT
// This file is generated by dev/tools/gen_keycodes/bin/gen_keycodes.dart and
// should not be edited directly.
......@@ -349,8 +348,10 @@ const Map<int, PhysicalKeyboardKey> kAndroidToPhysicalKey = <int, PhysicalKeyboa
100: PhysicalKeyboardKey.altRight,
126: PhysicalKeyboardKey.metaRight,
358: PhysicalKeyboardKey.info,
370: PhysicalKeyboardKey.closedCaptionToggle,
225: PhysicalKeyboardKey.brightnessUp,
224: PhysicalKeyboardKey.brightnessDown,
405: PhysicalKeyboardKey.mediaLast,
174: PhysicalKeyboardKey.exit,
402: PhysicalKeyboardKey.channelUp,
403: PhysicalKeyboardKey.channelDown,
......@@ -372,6 +373,7 @@ const Map<int, PhysicalKeyboardKey> kAndroidToPhysicalKey = <int, PhysicalKeyboa
215: PhysicalKeyboardKey.launchMail,
429: PhysicalKeyboardKey.launchContacts,
397: PhysicalKeyboardKey.launchCalendar,
583: PhysicalKeyboardKey.launchAssistant,
181: PhysicalKeyboardKey.newKey,
160: PhysicalKeyboardKey.close,
206: PhysicalKeyboardKey.close,
......@@ -2290,6 +2292,7 @@ const Map<int, LogicalKeyboardKey> kWindowsToLogicalKey = <int, LogicalKeyboardK
220: LogicalKeyboardKey.backslash,
186: LogicalKeyboardKey.semicolon,
222: LogicalKeyboardKey.quote,
192: LogicalKeyboardKey.backquote,
188: LogicalKeyboardKey.comma,
190: LogicalKeyboardKey.period,
191: LogicalKeyboardKey.slash,
......
......@@ -267,6 +267,7 @@ abstract class RawKeyEvent with Diagnosticable {
/// on the [SystemChannels.keyEvent] channel.
factory RawKeyEvent.fromMessage(Map<String, dynamic> message) {
RawKeyEventData data;
String? character;
final String keymap = message['keymap'] as String;
switch (keymap) {
......@@ -284,13 +285,20 @@ abstract class RawKeyEvent with Diagnosticable {
deviceId: message['deviceId'] as int? ?? 0,
repeatCount: message['repeatCount'] as int? ?? 0,
);
if (message.containsKey('character')) {
character = message['character'] as String?;
}
break;
case 'fuchsia':
final int codePoint = message['codePoint'] as int? ?? 0;
data = RawKeyEventDataFuchsia(
hidUsage: message['hidUsage'] as int? ?? 0,
codePoint: message['codePoint'] as int? ?? 0,
codePoint: codePoint,
modifiers: message['modifiers'] as int? ?? 0,
);
if (codePoint != 0) {
character = String.fromCharCode(codePoint);
}
break;
case 'macos':
data = RawKeyEventDataMacOs(
......@@ -298,15 +306,20 @@ abstract class RawKeyEvent with Diagnosticable {
charactersIgnoringModifiers: message['charactersIgnoringModifiers'] as String? ?? '',
keyCode: message['keyCode'] as int? ?? 0,
modifiers: message['modifiers'] as int? ?? 0);
character = message['characters'] as String?;
break;
case 'linux':
final int unicodeScalarValues = message['unicodeScalarValues'] as int? ?? 0;
data = RawKeyEventDataLinux(
keyHelper: KeyHelper(message['toolkit'] as String? ?? ''),
unicodeScalarValues: message['unicodeScalarValues'] as int? ?? 0,
unicodeScalarValues: unicodeScalarValues,
keyCode: message['keyCode'] as int? ?? 0,
scanCode: message['scanCode'] as int? ?? 0,
modifiers: message['modifiers'] as int? ?? 0,
isDown: message['type'] == 'keydown');
if (unicodeScalarValues != 0) {
character = String.fromCharCode(unicodeScalarValues);
}
break;
case 'web':
data = RawKeyEventDataWeb(
......@@ -314,14 +327,19 @@ abstract class RawKeyEvent with Diagnosticable {
key: message['key'] as String? ?? '',
metaState: message['metaState'] as int? ?? 0,
);
character = message['key'] as String?;
break;
case 'windows':
final int characterCodePoint = message['characterCodePoint'] as int? ?? 0;
data = RawKeyEventDataWindows(
keyCode: message['keyCode'] as int? ?? 0,
scanCode: message['scanCode'] as int? ?? 0,
characterCodePoint: message['characterCodePoint'] as int? ?? 0,
characterCodePoint: characterCodePoint,
modifiers: message['modifiers'] as int? ?? 0,
);
if (characterCodePoint != 0) {
character = String.fromCharCode(characterCodePoint);
}
break;
default:
// Raw key events are not yet implemented on iOS or other platforms,
......@@ -333,7 +351,7 @@ abstract class RawKeyEvent with Diagnosticable {
final String type = message['type'] as String;
switch (type) {
case 'keydown':
return RawKeyDownEvent(data: data, character: message['character'] as String);
return RawKeyDownEvent(data: data, character: character);
case 'keyup':
return RawKeyUpEvent(data: data);
default:
......
......@@ -17,6 +17,30 @@ class _ModifierCheck {
void main() {
group('RawKeyboard', () {
testWidgets('The correct character is produced', (WidgetTester tester) async {
for (final String platform in <String>['linux', 'android', 'macos', 'fuchsia', 'windows']) {
String character = '';
void handleKey(RawKeyEvent event) {
expect(event.character, equals(character), reason: 'on $platform');
}
RawKeyboard.instance.addListener(handleKey);
character = 'a';
await simulateKeyDownEvent(LogicalKeyboardKey.keyA, platform: platform);
character = '`';
await simulateKeyDownEvent(LogicalKeyboardKey.backquote, platform: platform);
RawKeyboard.instance.removeListener(handleKey);
}
});
testWidgets('No character is produced for non-printables', (WidgetTester tester) async {
for (final String platform in <String>['linux', 'android', 'macos', 'fuchsia', 'windows']) {
void handleKey(RawKeyEvent event) {
expect(event.character, isNull, reason: 'on $platform');
}
RawKeyboard.instance.addListener(handleKey);
await simulateKeyDownEvent(LogicalKeyboardKey.shiftLeft, platform: platform);
RawKeyboard.instance.removeListener(handleKey);
}
});
testWidgets('keysPressed is maintained', (WidgetTester tester) async {
for (final String platform in <String>['linux', 'android', 'macos', 'fuchsia', 'windows']) {
RawKeyboard.instance.clearKeysPressed();
......
......@@ -174,7 +174,6 @@ class KeyEventSimulator {
final Map<String, dynamic> result = <String, dynamic>{
'type': isDown ? 'keydown' : 'keyup',
'keymap': platform,
'character': key.keyLabel,
};
switch (platform) {
......@@ -182,6 +181,7 @@ class KeyEventSimulator {
result['keyCode'] = keyCode;
if (key.keyLabel.isNotEmpty) {
result['codePoint'] = key.keyLabel.codeUnitAt(0);
result['character'] = key.keyLabel;
}
result['scanCode'] = scanCode;
result['metaState'] = _getAndroidModifierFlags(key, isDown);
......@@ -198,16 +198,19 @@ class KeyEventSimulator {
result['keyCode'] = keyCode;
result['scanCode'] = scanCode;
result['modifiers'] = _getGlfwModifierFlags(key, isDown);
result['unicodeScalarValues'] = key.keyLabel.isNotEmpty ? key.keyLabel.codeUnitAt(0) : 0;
break;
case 'macos':
result['keyCode'] = scanCode;
if (key.keyLabel.isNotEmpty) {
result['characters'] = key.keyLabel;
result['charactersIgnoringModifiers'] = key.keyLabel;
}
result['modifiers'] = _getMacOsModifierFlags(key, isDown);
break;
case 'web':
result['code'] = _getWebKeyCode(key);
result['key'] = '';
result['key'] = key.keyLabel;
result['metaState'] = _getWebModifierFlags(key, isDown);
break;
case 'windows':
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment