Unverified Commit 041a3eaa authored by Greg Spencer's avatar Greg Spencer Committed by GitHub

Standardize the nullability of arguments to raw key data constructors. (#63523)

This standardizes the handling of nullability for the LogicalKeyboardKey.keyLabel and RawKeyEventData.keyLabel accessors so that they are non-nullable, but can be empty.

Before this change, the keyLabel could be either null or an empty string to indicate that there wasn't a label, which makes it harder to test for, since both need to be checked for. Since an empty string is sufficient, there is no need for it to be nullable.

Also, in raw_keyboard.dart, the web and Windows implementations wouldn't accept null values for parameters in the Map coming from the message, but tests were supplying null for some of them. This makes web and Windows creation of events match the other platforms, and makes the migration of tests to non-nullability easier.
parent 69fd5c50
......@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// @dart = 2.8
import 'package:flutter/foundation.dart';
// DO NOT EDIT -- DO NOT EDIT -- DO NOT EDIT
// This file is generated by dev/tools/gen_keycodes/bin/gen_keycodes.dart and
......@@ -11,8 +11,6 @@
// Edit the template dev/tools/gen_keycodes/data/keyboard_key.tmpl instead.
// See dev/tools/gen_keycodes/README.md for more information.
import 'package:flutter/foundation.dart';
/// A base class for all keyboard key types.
///
/// See also:
......@@ -138,7 +136,7 @@ class LogicalKeyboardKey extends KeyboardKey {
/// const LogicalKeyboardKey(0x0010000000a, debugName: kReleaseMode ? null : 'Special Key')
/// ```
/// {@end-tool}
const LogicalKeyboardKey(this.keyId, {this.debugName, this.keyLabel})
const LogicalKeyboardKey(this.keyId, {this.debugName, this.keyLabel = ''})
: assert(keyId != null);
/// A unique code representing this key.
......@@ -156,7 +154,7 @@ class LogicalKeyboardKey extends KeyboardKey {
/// This value is useful for describing or matching mnemonic keyboard
/// shortcuts.
///
/// This value can be null if there's no key label data for a key.
/// This value is an empty string if there's no key label data for a key.
///
/// On most platforms this is a single code point, but it could contain any
/// Unicode string. The `keyLabel` differs from [RawKeyEvent.character]
......@@ -166,7 +164,7 @@ class LogicalKeyboardKey extends KeyboardKey {
/// “o” for [keyLabel], but would return “ö” for [RawKeyEvent.character].
///
/// {@macro flutter.services.RawKeyEventData.keyLabel}
final String? keyLabel;
final String keyLabel;
@override
int get hashCode => keyId.hashCode;
......@@ -194,7 +192,7 @@ class LogicalKeyboardKey extends KeyboardKey {
///
/// Used by [RawKeyEvent] subclasses to help construct IDs.
static bool isControlCharacter(String label) {
if (label.length > 1) {
if (label.length != 1) {
return false;
}
final int codeUnit = label.codeUnitAt(0);
......
......@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'package:flutter/foundation.dart';
// DO NOT EDIT -- DO NOT EDIT -- DO NOT EDIT
// This file is generated by dev/tools/gen_keycodes/bin/gen_keycodes.dart and
......@@ -10,8 +11,6 @@
// Edit the template dev/tools/gen_keycodes/data/keyboard_key.tmpl instead.
// See dev/tools/gen_keycodes/README.md for more information.
import 'package:flutter/foundation.dart';
/// A base class for all keyboard key types.
///
/// See also:
......@@ -137,7 +136,7 @@ class LogicalKeyboardKey extends KeyboardKey {
/// const LogicalKeyboardKey(0x0010000000a, debugName: kReleaseMode ? null : 'Special Key')
/// ```
/// {@end-tool}
const LogicalKeyboardKey(this.keyId, {this.debugName, this.keyLabel})
const LogicalKeyboardKey(this.keyId, {this.debugName, this.keyLabel = ''})
: assert(keyId != null);
/// A unique code representing this key.
......@@ -155,7 +154,7 @@ class LogicalKeyboardKey extends KeyboardKey {
/// This value is useful for describing or matching mnemonic keyboard
/// shortcuts.
///
/// This value can be null if there's no key label data for a key.
/// This value is an empty string if there's no key label data for a key.
///
/// On most platforms this is a single code point, but it could contain any
/// Unicode string. The `keyLabel` differs from [RawKeyEvent.character]
......@@ -165,7 +164,7 @@ class LogicalKeyboardKey extends KeyboardKey {
/// “o” for [keyLabel], but would return “ö” for [RawKeyEvent.character].
///
/// {@macro flutter.services.RawKeyEventData.keyLabel}
final String? keyLabel;
final String keyLabel;
@override
int get hashCode => keyId.hashCode;
......@@ -193,7 +192,7 @@ class LogicalKeyboardKey extends KeyboardKey {
///
/// Used by [RawKeyEvent] subclasses to help construct IDs.
static bool isControlCharacter(String label) {
if (label.length > 1) {
if (label.length != 1) {
return false;
}
final int codeUnit = label.codeUnitAt(0);
......
......@@ -213,6 +213,8 @@ abstract class RawKeyEventData {
/// Returns the Unicode string representing the label on this key.
///
/// This value is an empty string if there's no key label data for a key.
///
/// {@template flutter.services.RawKeyEventData.keyLabel}
/// Do not use the [keyLabel] to compose a text string: it will be missing
/// special processing for Unicode strings for combining characters and other
......@@ -226,7 +228,7 @@ abstract class RawKeyEventData {
/// complexities of managing keyboard input, like showing a soft keyboard or
/// interacting with an input method editor (IME).
/// {@endtemplate}
String? get keyLabel;
String get keyLabel;
}
/// Defines the interface for raw key events.
......@@ -308,17 +310,17 @@ abstract class RawKeyEvent with Diagnosticable {
break;
case 'web':
data = RawKeyEventDataWeb(
code: message['code'] as String,
key: message['key'] as String,
metaState: message['metaState'] as int,
code: message['code'] as String? ?? '',
key: message['key'] as String? ?? '',
metaState: message['metaState'] as int? ?? 0,
);
break;
case 'windows':
data = RawKeyEventDataWindows(
keyCode: message['keyCode'] as int,
scanCode: message['scanCode'] as int,
characterCodePoint: message['characterCodePoint'] as int,
modifiers: message['modifiers'] as int,
keyCode: message['keyCode'] as int? ?? 0,
scanCode: message['scanCode'] as int? ?? 0,
characterCodePoint: message['characterCodePoint'] as int? ?? 0,
modifiers: message['modifiers'] as int? ?? 0,
);
break;
default:
......
......@@ -147,7 +147,7 @@ class RawKeyEventDataAndroid extends RawKeyEventData {
// Android only reports a single code point for the key label.
@override
String? get keyLabel => plainCodePoint == 0 ? null : String.fromCharCode(plainCodePoint & _kCombiningCharacterMask);
String get keyLabel => plainCodePoint == 0 ? '' : String.fromCharCode(plainCodePoint & _kCombiningCharacterMask);
@override
PhysicalKeyboardKey get physicalKey {
......@@ -191,13 +191,13 @@ class RawKeyEventDataAndroid extends RawKeyEventData {
// constant, or construct a new Unicode-based key from it. Don't mark it as
// autogenerated, since the label uniquely identifies an ID from the Unicode
// plane.
if (keyLabel != null && keyLabel!.isNotEmpty && !LogicalKeyboardKey.isControlCharacter(keyLabel!)) {
if (keyLabel.isNotEmpty && !LogicalKeyboardKey.isControlCharacter(keyLabel)) {
final int combinedCodePoint = plainCodePoint & _kCombiningCharacterMask;
final int keyId = LogicalKeyboardKey.unicodePlane | (combinedCodePoint & LogicalKeyboardKey.valueMask);
return LogicalKeyboardKey.findKeyByKeyId(keyId) ?? LogicalKeyboardKey(
keyId,
keyLabel: keyLabel,
debugName: kReleaseMode ? null : 'Key ${keyLabel!.toUpperCase()}',
debugName: kReleaseMode ? null : 'Key ${keyLabel.toUpperCase()}',
);
}
......
......@@ -61,7 +61,7 @@ class RawKeyEventDataFuchsia extends RawKeyEventData {
// Fuchsia only reports a single code point for the key label.
@override
String? get keyLabel => codePoint == 0 ? null : String.fromCharCode(codePoint);
String get keyLabel => codePoint == 0 ? '' : String.fromCharCode(codePoint);
@override
LogicalKeyboardKey get logicalKey {
......
......@@ -70,7 +70,7 @@ class RawKeyEventDataLinux extends RawKeyEventData {
final bool isDown;
@override
String? get keyLabel => unicodeScalarValues == 0 ? null : String.fromCharCode(unicodeScalarValues);
String get keyLabel => unicodeScalarValues == 0 ? '' : String.fromCharCode(unicodeScalarValues);
@override
PhysicalKeyboardKey get physicalKey => kLinuxToPhysicalKey[scanCode] ?? PhysicalKeyboardKey.none;
......@@ -89,13 +89,13 @@ class RawKeyEventDataLinux extends RawKeyEventData {
// constant, or construct a new Unicode-based key from it. Don't mark it as
// autogenerated, since the label uniquely identifies an ID from the Unicode
// plane.
if (keyLabel != null &&
!LogicalKeyboardKey.isControlCharacter(keyLabel!)) {
if (keyLabel.isNotEmpty &&
!LogicalKeyboardKey.isControlCharacter(keyLabel)) {
final int keyId = LogicalKeyboardKey.unicodePlane | (unicodeScalarValues & LogicalKeyboardKey.valueMask);
return LogicalKeyboardKey.findKeyByKeyId(keyId) ?? LogicalKeyboardKey(
keyId,
keyLabel: keyLabel,
debugName: kReleaseMode ? null : 'Key ${keyLabel!.toUpperCase()}',
debugName: kReleaseMode ? null : 'Key ${keyLabel.toUpperCase()}',
);
}
......
......@@ -62,7 +62,7 @@ class RawKeyEventDataMacOs extends RawKeyEventData {
final int modifiers;
@override
String? get keyLabel => charactersIgnoringModifiers.isEmpty ? null : charactersIgnoringModifiers;
String get keyLabel => charactersIgnoringModifiers;
@override
PhysicalKeyboardKey get physicalKey => kMacOsToPhysicalKey[keyCode] ?? PhysicalKeyboardKey.none;
......@@ -76,15 +76,17 @@ class RawKeyEventDataMacOs extends RawKeyEventData {
if (numPadKey != null) {
return numPadKey;
}
// If this key is printable, generate the LogicalKeyboardKey from its Unicode value.
// Control keys such as ESC, CRTL, and SHIFT are not printable. HOME, DEL, arrow keys, and function
// keys are considered modifier function keys, which generate invalid Unicode scalar values.
if (keyLabel != null &&
!LogicalKeyboardKey.isControlCharacter(keyLabel!) &&
!_isUnprintableKey(keyLabel!)) {
// Given that charactersIgnoringModifiers can contain a String of arbitrary length,
// limit to a maximum of two Unicode scalar values. It is unlikely that a keyboard would produce a code point
// bigger than 32 bits, but it is still worth defending against this case.
// If this key is printable, generate the LogicalKeyboardKey from its
// Unicode value. Control keys such as ESC, CRTL, and SHIFT are not
// printable. HOME, DEL, arrow keys, and function keys are considered
// modifier function keys, which generate invalid Unicode scalar values.
if (keyLabel.isNotEmpty &&
!LogicalKeyboardKey.isControlCharacter(keyLabel) &&
!_isUnprintableKey(keyLabel)) {
// Given that charactersIgnoringModifiers can contain a String of
// arbitrary length, limit to a maximum of two Unicode scalar values. It
// is unlikely that a keyboard would produce a code point bigger than 32
// bits, but it is still worth defending against this case.
assert(charactersIgnoringModifiers.length <= 2);
int codeUnit = charactersIgnoringModifiers.codeUnitAt(0);
if (charactersIgnoringModifiers.length == 2) {
......@@ -96,20 +98,21 @@ class RawKeyEventDataMacOs extends RawKeyEventData {
return LogicalKeyboardKey.findKeyByKeyId(keyId) ?? LogicalKeyboardKey(
keyId,
keyLabel: keyLabel,
debugName: kReleaseMode ? null : 'Key ${keyLabel!.toUpperCase()}',
debugName: kReleaseMode ? null : 'Key ${keyLabel.toUpperCase()}',
);
}
// Control keys like "backspace" and movement keys like arrow keys don't have a printable representation,
// but are present on the physical keyboard. Since there is no logical keycode map for macOS
// (macOS uses the keycode to reference physical keys), a LogicalKeyboardKey is created with
// the physical key's HID usage and debugName. This avoids duplicating the physical
// key map.
// Control keys like "backspace" and movement keys like arrow keys don't
// have a printable representation, but are present on the physical
// keyboard. Since there is no logical keycode map for macOS (macOS uses the
// keycode to reference physical keys), a LogicalKeyboardKey is created with
// the physical key's HID usage and debugName. This avoids duplicating the
// physical key map.
if (physicalKey != PhysicalKeyboardKey.none) {
final int keyId = physicalKey.usbHidUsage | LogicalKeyboardKey.hidPlane;
return LogicalKeyboardKey.findKeyByKeyId(keyId) ?? LogicalKeyboardKey(
keyId,
keyLabel: physicalKey.debugName,
keyLabel: physicalKey.debugName ?? '',
debugName: physicalKey.debugName,
);
}
......@@ -129,10 +132,9 @@ class RawKeyEventDataMacOs extends RawKeyEventData {
return false;
}
// If only the "anyMask" bit is set, then we respond true for requests of
// whether either left or right is pressed.
// Handles the case where macOS supplies just the "either" modifier flag,
// but not the left/right flag. (e.g. modifierShift but not
// modifierLeftShift).
// whether either left or right is pressed. Handles the case where macOS
// supplies just the "either" modifier flag, but not the left/right flag.
// (e.g. modifierShift but not modifierLeftShift).
final bool anyOnly = modifiers & (leftMask | rightMask | anyMask) == anyMask;
switch (side) {
case KeyboardSide.any:
......@@ -229,7 +231,7 @@ class RawKeyEventDataMacOs extends RawKeyEventData {
///
/// Used by [RawKeyEvent] subclasses to help construct IDs.
static bool _isUnprintableKey(String label) {
if (label.length > 1) {
if (label.length != 1) {
return false;
}
final int codeUnit = label.codeUnitAt(0);
......
......@@ -36,7 +36,7 @@ class RawKeyEventDataWeb extends RawKeyEventData {
///
/// See <https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/key>
/// for more information.
final String? key;
final String key;
/// The modifiers that were present when the key event occurred.
///
......@@ -56,7 +56,7 @@ class RawKeyEventDataWeb extends RawKeyEventData {
final int metaState;
@override
String? get keyLabel => key;
String get keyLabel => key == 'Unidentified' ? '' : key;
@override
PhysicalKeyboardKey get physicalKey {
......
......@@ -54,7 +54,7 @@ class RawKeyEventDataWindows extends RawKeyEventData {
final int modifiers;
@override
String? get keyLabel => characterCodePoint == 0 ? null : String.fromCharCode(characterCodePoint);
String get keyLabel => characterCodePoint == 0 ? '' : String.fromCharCode(characterCodePoint);
@override
PhysicalKeyboardKey get physicalKey => kWindowsToPhysicalKey[scanCode] ?? PhysicalKeyboardKey.none;
......@@ -73,12 +73,12 @@ class RawKeyEventDataWindows extends RawKeyEventData {
// constant, or construct a new Unicode-based key from it. Don't mark it as
// autogenerated, since the label uniquely identifies an ID from the Unicode
// plane.
if (keyLabel != null && keyLabel!.isNotEmpty && !LogicalKeyboardKey.isControlCharacter(keyLabel!)) {
if (keyLabel.isNotEmpty && !LogicalKeyboardKey.isControlCharacter(keyLabel)) {
final int keyId = LogicalKeyboardKey.unicodePlane | (characterCodePoint & LogicalKeyboardKey.valueMask);
return LogicalKeyboardKey.findKeyByKeyId(keyId) ?? LogicalKeyboardKey(
keyId,
keyLabel: keyLabel,
debugName: kReleaseMode ? null : 'Key ${keyLabel!.toUpperCase()}',
debugName: kReleaseMode ? null : 'Key ${keyLabel.toUpperCase()}',
);
}
// Look to see if the keyCode is one we know about and have a mapping for.
......@@ -104,10 +104,9 @@ class RawKeyEventDataWindows extends RawKeyEventData {
return false;
}
// If only the "anyMask" bit is set, then we respond true for requests of
// whether either left or right is pressed.
// Handles the case where Windows supplies just the "either" modifier flag,
// but not the left/right flag. (e.g. modifierShift but not
// modifierLeftShift).
// whether either left or right is pressed. Handles the case where Windows
// supplies just the "either" modifier flag, but not the left/right flag.
// (e.g. modifierShift but not modifierLeftShift).
final bool anyOnly = modifiers & (leftMask | rightMask | anyMask) == anyMask;
switch (side) {
case KeyboardSide.any:
......
......@@ -601,7 +601,6 @@ void main() {
'keymap': 'android',
'keyCode': 111,
'codePoint': 0,
'character': null,
'scanCode': 1,
'metaState': 0x0,
'source': 0x101, // Keyboard source.
......@@ -610,7 +609,7 @@ void main() {
final RawKeyEventDataAndroid data = escapeKeyEvent.data as RawKeyEventDataAndroid;
expect(data.physicalKey, equals(PhysicalKeyboardKey.escape));
expect(data.logicalKey, equals(LogicalKeyboardKey.escape));
expect(data.keyLabel, isNull);
expect(data.keyLabel, isEmpty);
});
test('Modifier keyboard keys are correctly translated', () {
final RawKeyEvent shiftLeftKeyEvent = RawKeyEvent.fromMessage(const <String, dynamic>{
......@@ -619,7 +618,6 @@ void main() {
'keyCode': 59,
'plainCodePoint': 0,
'codePoint': 0,
'character': null,
'scanCode': 42,
'metaState': RawKeyEventDataAndroid.modifierLeftShift,
'source': 0x101, // Keyboard source.
......@@ -628,7 +626,7 @@ void main() {
final RawKeyEventDataAndroid data = shiftLeftKeyEvent.data as RawKeyEventDataAndroid;
expect(data.physicalKey, equals(PhysicalKeyboardKey.shiftLeft));
expect(data.logicalKey, equals(LogicalKeyboardKey.shiftLeft));
expect(data.keyLabel, isNull);
expect(data.keyLabel, isEmpty);
});
test('DPAD keys from a joystick give physical key mappings', () {
final RawKeyEvent joystickDpadDown = RawKeyEvent.fromMessage(const <String, dynamic>{
......@@ -637,7 +635,6 @@ void main() {
'keyCode': 20,
'plainCodePoint': 0,
'codePoint': 0,
'character': null,
'scanCode': 0,
'metaState': 0,
'source': 0x1000010, // Joystick source.
......@@ -646,7 +643,7 @@ void main() {
final RawKeyEventDataAndroid data = joystickDpadDown.data as RawKeyEventDataAndroid;
expect(data.physicalKey, equals(PhysicalKeyboardKey.arrowDown));
expect(data.logicalKey, equals(LogicalKeyboardKey.arrowDown));
expect(data.keyLabel, isNull);
expect(data.keyLabel, isEmpty);
});
test('Arrow keys from a keyboard give correct physical key mappings', () {
final RawKeyEvent joystickDpadDown = RawKeyEvent.fromMessage(const <String, dynamic>{
......@@ -655,7 +652,6 @@ void main() {
'keyCode': 20,
'plainCodePoint': 0,
'codePoint': 0,
'character': null,
'scanCode': 108,
'metaState': 0,
'source': 0x101, // Keyboard source.
......@@ -663,7 +659,7 @@ void main() {
final RawKeyEventDataAndroid data = joystickDpadDown.data as RawKeyEventDataAndroid;
expect(data.physicalKey, equals(PhysicalKeyboardKey.arrowDown));
expect(data.logicalKey, equals(LogicalKeyboardKey.arrowDown));
expect(data.keyLabel, isNull);
expect(data.keyLabel, isEmpty);
});
test('DPAD center from a game pad gives physical key mappings', () {
final RawKeyEvent joystickDpadCenter = RawKeyEvent.fromMessage(const <String, dynamic>{
......@@ -672,7 +668,6 @@ void main() {
'keyCode': 23, // DPAD_CENTER code.
'plainCodePoint': 0,
'codePoint': 0,
'character': null,
'scanCode': 317, // Left side thumb joystick center click button.
'metaState': 0,
'source': 0x501, // Gamepad and keyboard source.
......@@ -681,7 +676,7 @@ void main() {
final RawKeyEventDataAndroid data = joystickDpadCenter.data as RawKeyEventDataAndroid;
expect(data.physicalKey, equals(PhysicalKeyboardKey.gameButtonThumbLeft));
expect(data.logicalKey, equals(LogicalKeyboardKey.select));
expect(data.keyLabel, isNull);
expect(data.keyLabel, isEmpty);
});
test('Device id is read from message', () {
final RawKeyEvent joystickDpadCenter = RawKeyEvent.fromMessage(const <String, dynamic>{
......@@ -690,7 +685,6 @@ void main() {
'keyCode': 23, // DPAD_CENTER code.
'plainCodePoint': 0,
'codePoint': 0,
'character': null,
'scanCode': 317, // Left side thumb joystick center click button.
'metaState': 0,
'source': 0x501, // Gamepad and keyboard source.
......@@ -853,13 +847,11 @@ void main() {
'type': 'keydown',
'keymap': 'fuchsia',
'hidUsage': 0x00070029,
'codePoint': null,
'character': null,
});
final RawKeyEventDataFuchsia data = escapeKeyEvent.data as RawKeyEventDataFuchsia;
expect(data.physicalKey, equals(PhysicalKeyboardKey.escape));
expect(data.logicalKey, equals(LogicalKeyboardKey.escape));
expect(data.keyLabel, isNull);
expect(data.keyLabel, isEmpty);
}, skip: isBrowser); // https://github.com/flutter/flutter/issues/35347
test('Modifier keyboard keys are correctly translated', () {
......@@ -867,13 +859,11 @@ void main() {
'type': 'keydown',
'keymap': 'fuchsia',
'hidUsage': 0x000700e1,
'codePoint': null,
'character': null,
});
final RawKeyEventDataFuchsia data = shiftLeftKeyEvent.data as RawKeyEventDataFuchsia;
expect(data.physicalKey, equals(PhysicalKeyboardKey.shiftLeft));
expect(data.logicalKey, equals(LogicalKeyboardKey.shiftLeft));
expect(data.keyLabel, isNull);
expect(data.keyLabel, isEmpty);
}, skip: isBrowser); // https://github.com/flutter/flutter/issues/35347
});
......@@ -985,13 +975,12 @@ void main() {
'keyCode': 0x00000035,
'characters': '',
'charactersIgnoringModifiers': '',
'character': null,
'modifiers': 0x0,
});
final RawKeyEventDataMacOs data = escapeKeyEvent.data as RawKeyEventDataMacOs;
expect(data.physicalKey, equals(PhysicalKeyboardKey.escape));
expect(data.logicalKey, equals(LogicalKeyboardKey.escape));
expect(data.keyLabel, isNull);
expect(data.keyLabel, isEmpty);
}, skip: isBrowser); // https://github.com/flutter/flutter/issues/35347
test('Modifier keyboard keys are correctly translated', () {
......@@ -1001,13 +990,12 @@ void main() {
'keyCode': 0x00000038,
'characters': '',
'charactersIgnoringModifiers': '',
'character': null,
'modifiers': RawKeyEventDataMacOs.modifierLeftShift,
});
final RawKeyEventDataMacOs data = shiftLeftKeyEvent.data as RawKeyEventDataMacOs;
expect(data.physicalKey, equals(PhysicalKeyboardKey.shiftLeft));
expect(data.logicalKey, equals(LogicalKeyboardKey.shiftLeft));
expect(data.keyLabel, isNull);
expect(data.keyLabel, isEmpty);
}, skip: isBrowser); // https://github.com/flutter/flutter/issues/35347
test('Unprintable keyboard keys are correctly translated', () {
......@@ -1017,13 +1005,12 @@ void main() {
'keyCode': 0x0000007B,
'characters': '',
'charactersIgnoringModifiers': '', // NSLeftArrowFunctionKey = 0xF702
'character': null,
'modifiers': RawKeyEventDataMacOs.modifierFunction,
});
final RawKeyEventDataMacOs data = leftArrowKey.data as RawKeyEventDataMacOs;
expect(data.physicalKey, equals(PhysicalKeyboardKey.arrowLeft));
expect(data.logicalKey, equals(LogicalKeyboardKey.arrowLeft));
expect(data.logicalKey.keyLabel, isNull);
expect(data.logicalKey.keyLabel, isEmpty);
}, skip: isBrowser); // https://github.com/flutter/flutter/issues/35347
});
......@@ -1140,7 +1127,7 @@ void main() {
final RawKeyEventDataWindows data = escapeKeyEvent.data as RawKeyEventDataWindows;
expect(data.physicalKey, equals(PhysicalKeyboardKey.escape));
expect(data.logicalKey, equals(LogicalKeyboardKey.escape));
expect(data.keyLabel, isNull);
expect(data.keyLabel, isEmpty);
});
test('Modifier keyboard keys are correctly translated', () {
final RawKeyEvent shiftLeftKeyEvent = RawKeyEvent.fromMessage(const <String, dynamic>{
......@@ -1154,7 +1141,7 @@ void main() {
final RawKeyEventDataWindows data = shiftLeftKeyEvent.data as RawKeyEventDataWindows;
expect(data.physicalKey, equals(PhysicalKeyboardKey.shiftLeft));
expect(data.logicalKey, equals(LogicalKeyboardKey.shiftLeft));
expect(data.keyLabel, isNull);
expect(data.keyLabel, isEmpty);
});
test('Unprintable keyboard keys are correctly translated', () {
final RawKeyEvent leftArrowKey = RawKeyEvent.fromMessage(const <String, dynamic>{
......@@ -1168,7 +1155,7 @@ void main() {
final RawKeyEventDataWindows data = leftArrowKey.data as RawKeyEventDataWindows;
expect(data.physicalKey, equals(PhysicalKeyboardKey.arrowLeft));
expect(data.logicalKey, equals(LogicalKeyboardKey.arrowLeft));
expect(data.logicalKey.keyLabel, isNull);
expect(data.logicalKey.keyLabel, isEmpty);
});
});
......@@ -1338,7 +1325,7 @@ void main() {
final RawKeyEventDataLinux data = escapeKeyEvent.data as RawKeyEventDataLinux;
expect(data.physicalKey, equals(PhysicalKeyboardKey.escape));
expect(data.logicalKey, equals(LogicalKeyboardKey.escape));
expect(data.keyLabel, isNull);
expect(data.keyLabel, isEmpty);
});
test('Modifier keyboard keys are correctly translated', () {
final RawKeyEvent shiftLeftKeyEvent = RawKeyEvent.fromMessage(const <String, dynamic>{
......@@ -1352,7 +1339,7 @@ void main() {
final RawKeyEventDataLinux data = shiftLeftKeyEvent.data as RawKeyEventDataLinux;
expect(data.physicalKey, equals(PhysicalKeyboardKey.shiftLeft));
expect(data.logicalKey, equals(LogicalKeyboardKey.shiftLeft));
expect(data.keyLabel, isNull);
expect(data.keyLabel, isEmpty);
});
});
......@@ -1522,7 +1509,7 @@ void main() {
final RawKeyEventDataLinux data = escapeKeyEvent.data as RawKeyEventDataLinux;
expect(data.physicalKey, equals(PhysicalKeyboardKey.escape));
expect(data.logicalKey, equals(LogicalKeyboardKey.escape));
expect(data.keyLabel, isNull);
expect(data.keyLabel, isEmpty);
});
test('Modifier keyboard keys are correctly translated', () {
final RawKeyEvent shiftLeftKeyEvent = RawKeyEvent.fromMessage(const <String, dynamic>{
......@@ -1536,7 +1523,7 @@ void main() {
final RawKeyEventDataLinux data = shiftLeftKeyEvent.data as RawKeyEventDataLinux;
expect(data.physicalKey, equals(PhysicalKeyboardKey.shiftLeft));
expect(data.logicalKey, equals(LogicalKeyboardKey.shiftLeft));
expect(data.keyLabel, isNull);
expect(data.keyLabel, isEmpty);
});
});
......@@ -1557,7 +1544,6 @@ void main() {
'type': 'keydown',
'keymap': 'web',
'code': 'RandomCode',
'key': null,
'metaState': modifier,
});
final RawKeyEventDataWeb data = event.data as RawKeyEventDataWeb;
......@@ -1588,7 +1574,6 @@ void main() {
'type': 'keydown',
'keymap': 'web',
'code': 'RandomCode',
'key': null,
'metaState': modifier | RawKeyEventDataWeb.modifierMeta,
});
final RawKeyEventDataWeb data = event.data as RawKeyEventDataWeb;
......@@ -1629,39 +1614,36 @@ void main() {
'type': 'keydown',
'keymap': 'web',
'code': 'Escape',
'key': null,
'metaState': 0x0,
});
final RawKeyEventDataWeb data = escapeKeyEvent.data as RawKeyEventDataWeb;
expect(data.physicalKey, equals(PhysicalKeyboardKey.escape));
expect(data.logicalKey, equals(LogicalKeyboardKey.escape));
expect(data.keyLabel, isNull);
expect(data.keyLabel, isEmpty);
});
test('Modifier keyboard keys are correctly translated', () {
final RawKeyEvent shiftKeyEvent = RawKeyEvent.fromMessage(const <String, dynamic>{
'type': 'keydown',
'keymap': 'web',
'code': 'ShiftLeft',
'keyLabel': null,
'metaState': RawKeyEventDataWeb.modifierShift,
});
final RawKeyEventDataWeb data = shiftKeyEvent.data as RawKeyEventDataWeb;
expect(data.physicalKey, equals(PhysicalKeyboardKey.shiftLeft));
expect(data.logicalKey, equals(LogicalKeyboardKey.shiftLeft));
expect(data.keyLabel, isNull);
expect(data.keyLabel, isEmpty);
});
test('Arrow keys from a keyboard give correct physical key mappings', () {
final RawKeyEvent arrowKeyDown = RawKeyEvent.fromMessage(const <String, dynamic>{
'type': 'keydown',
'keymap': 'web',
'code': 'ArrowDown',
'key': null,
'metaState': 0x0,
});
final RawKeyEventDataWeb data = arrowKeyDown.data as RawKeyEventDataWeb;
expect(data.physicalKey, equals(PhysicalKeyboardKey.arrowDown));
expect(data.logicalKey, equals(LogicalKeyboardKey.arrowDown));
expect(data.keyLabel, isNull);
expect(data.keyLabel, isEmpty);
});
});
}
......@@ -180,13 +180,17 @@ class KeyEventSimulator {
switch (platform) {
case 'android':
result['keyCode'] = keyCode;
result['codePoint'] = key.keyLabel?.codeUnitAt(0);
if (key.keyLabel.isNotEmpty) {
result['codePoint'] = key.keyLabel.codeUnitAt(0);
}
result['scanCode'] = scanCode;
result['metaState'] = _getAndroidModifierFlags(key, isDown);
break;
case 'fuchsia':
result['hidUsage'] = physicalKey?.usbHidUsage ?? (key.keyId & LogicalKeyboardKey.hidPlane != 0 ? key.keyId & LogicalKeyboardKey.valueMask : null);
result['codePoint'] = key.keyLabel?.codeUnitAt(0);
if (key.keyLabel.isNotEmpty) {
result['codePoint'] = key.keyLabel.codeUnitAt(0);
}
result['modifiers'] = _getFuchsiaModifierFlags(key, isDown);
break;
case 'linux':
......@@ -209,7 +213,9 @@ class KeyEventSimulator {
case 'windows':
result['keyCode'] = keyCode;
result['scanCode'] = scanCode;
result['characterCodePoint'] = key.keyLabel?.codeUnitAt(0) ?? 0;
if (key.keyLabel.isNotEmpty) {
result['characterCodePoint'] = key.keyLabel.codeUnitAt(0);
}
result['modifiers'] = _getWindowsModifierFlags(key, isDown);
}
return result;
......
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