diff --git a/dev/tools/gen_keycodes/data/keyboard_key.tmpl b/dev/tools/gen_keycodes/data/keyboard_key.tmpl index 80cf3b4d00..37da2944bf 100644 --- a/dev/tools/gen_keycodes/data/keyboard_key.tmpl +++ b/dev/tools/gen_keycodes/data/keyboard_key.tmpl @@ -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); diff --git a/packages/flutter/lib/src/services/keyboard_key.dart b/packages/flutter/lib/src/services/keyboard_key.dart index 63e560f8d6..e80f5e674b 100644 --- a/packages/flutter/lib/src/services/keyboard_key.dart +++ b/packages/flutter/lib/src/services/keyboard_key.dart @@ -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); diff --git a/packages/flutter/lib/src/services/raw_keyboard.dart b/packages/flutter/lib/src/services/raw_keyboard.dart index 7a12ea58e7..46e49dd405 100644 --- a/packages/flutter/lib/src/services/raw_keyboard.dart +++ b/packages/flutter/lib/src/services/raw_keyboard.dart @@ -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: diff --git a/packages/flutter/lib/src/services/raw_keyboard_android.dart b/packages/flutter/lib/src/services/raw_keyboard_android.dart index 12a972bf08..4d92b4485a 100644 --- a/packages/flutter/lib/src/services/raw_keyboard_android.dart +++ b/packages/flutter/lib/src/services/raw_keyboard_android.dart @@ -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()}', ); } diff --git a/packages/flutter/lib/src/services/raw_keyboard_fuchsia.dart b/packages/flutter/lib/src/services/raw_keyboard_fuchsia.dart index f8b53dcaae..fff0e91451 100644 --- a/packages/flutter/lib/src/services/raw_keyboard_fuchsia.dart +++ b/packages/flutter/lib/src/services/raw_keyboard_fuchsia.dart @@ -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 { diff --git a/packages/flutter/lib/src/services/raw_keyboard_linux.dart b/packages/flutter/lib/src/services/raw_keyboard_linux.dart index 990712cf83..7ea87d88c3 100644 --- a/packages/flutter/lib/src/services/raw_keyboard_linux.dart +++ b/packages/flutter/lib/src/services/raw_keyboard_linux.dart @@ -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()}', ); } diff --git a/packages/flutter/lib/src/services/raw_keyboard_macos.dart b/packages/flutter/lib/src/services/raw_keyboard_macos.dart index 60797b92a6..45148ed7aa 100644 --- a/packages/flutter/lib/src/services/raw_keyboard_macos.dart +++ b/packages/flutter/lib/src/services/raw_keyboard_macos.dart @@ -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); diff --git a/packages/flutter/lib/src/services/raw_keyboard_web.dart b/packages/flutter/lib/src/services/raw_keyboard_web.dart index 77b399efcd..3e0edde068 100644 --- a/packages/flutter/lib/src/services/raw_keyboard_web.dart +++ b/packages/flutter/lib/src/services/raw_keyboard_web.dart @@ -36,7 +36,7 @@ class RawKeyEventDataWeb extends RawKeyEventData { /// /// See /// 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 { diff --git a/packages/flutter/lib/src/services/raw_keyboard_windows.dart b/packages/flutter/lib/src/services/raw_keyboard_windows.dart index 1d81eddbea..a88ee17081 100644 --- a/packages/flutter/lib/src/services/raw_keyboard_windows.dart +++ b/packages/flutter/lib/src/services/raw_keyboard_windows.dart @@ -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: diff --git a/packages/flutter/test/services/raw_keyboard_test.dart b/packages/flutter/test/services/raw_keyboard_test.dart index 5b28d13ab3..a19c5bb2c6 100644 --- a/packages/flutter/test/services/raw_keyboard_test.dart +++ b/packages/flutter/test/services/raw_keyboard_test.dart @@ -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 { @@ -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 { @@ -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 { @@ -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 { @@ -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 { @@ -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 { @@ -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 { @@ -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 { @@ -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 { @@ -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 { '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 { '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); }); }); } diff --git a/packages/flutter_test/lib/src/event_simulation.dart b/packages/flutter_test/lib/src/event_simulation.dart index a38c87f048..f7a65f22a0 100644 --- a/packages/flutter_test/lib/src/event_simulation.dart +++ b/packages/flutter_test/lib/src/event_simulation.dart @@ -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;