mirror of
https://github.com/flutter/flutter.git
synced 2025-06-03 00:51:18 +00:00
Remove keyLabel and debugName from Logical/PhysicalKeyboardKey (#78263)
- Remove `LogicalKeyboardKey.keyLabel` - Make `Physical/LogicalKeyboardKey.debugName` getters - Make `Physical/LogicalKeyboardKey()` factory constructors, which cache non-predefined instances.
This commit is contained in:
parent
2f05751973
commit
515ef91ba1
@ -18,6 +18,7 @@ import 'package:gen_keycodes/glfw_code_gen.dart';
|
||||
import 'package:gen_keycodes/gtk_code_gen.dart';
|
||||
import 'package:gen_keycodes/windows_code_gen.dart';
|
||||
import 'package:gen_keycodes/web_code_gen.dart';
|
||||
import 'package:gen_keycodes/key_labels_code_gen.dart';
|
||||
import 'package:gen_keycodes/keyboard_keys_code_gen.dart';
|
||||
import 'package:gen_keycodes/keyboard_maps_code_gen.dart';
|
||||
import 'package:gen_keycodes/key_data.dart';
|
||||
@ -253,6 +254,13 @@ Future<void> main(List<String> rawArguments) async {
|
||||
print('Writing ${'key maps'.padRight(15)}${mapsFile.absolute}');
|
||||
await mapsFile.writeAsString(KeyboardMapsCodeGenerator(data).generate());
|
||||
|
||||
final File keyLabelsFile = File(path.join(flutterRoot.path, 'packages', 'flutter_test', 'lib', 'src', 'key_labels.dart'));
|
||||
if (!keyLabelsFile.existsSync()) {
|
||||
mapsFile.createSync(recursive: true);
|
||||
}
|
||||
print('Writing ${'key labels'.padRight(15)}${mapsFile.absolute}');
|
||||
await keyLabelsFile.writeAsString(KeyLabelsCodeGenerator(data).generate());
|
||||
|
||||
for (final String platform in <String>['android', 'macos', 'ios', 'glfw', 'fuchsia', 'linux', 'windows', 'web']) {
|
||||
PlatformCodeGenerator codeGenerator;
|
||||
switch (platform) {
|
||||
|
16
dev/tools/gen_keycodes/data/key_labels.tmpl
Normal file
16
dev/tools/gen_keycodes/data/key_labels.tmpl
Normal file
@ -0,0 +1,16 @@
|
||||
// Copyright 2014 The Flutter Authors. All rights reserved.
|
||||
// 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.
|
||||
//
|
||||
// Edit the template dev/tools/gen_keycodes/data/key_labels.tmpl instead.
|
||||
// See dev/tools/gen_keycodes/README.md for more information.
|
||||
|
||||
/// The keyLabel corresponding to a logical key.
|
||||
///
|
||||
/// Used to generate simulated key events out of a logical key.
|
||||
const Map<int, String> logicalKeyLabels = <int, String>{
|
||||
@@@LOGICAL_KEY_LABELS@@@};
|
@ -76,9 +76,9 @@ abstract class KeyboardKey with Diagnosticable {
|
||||
/// _message = 'Pressed the "Q" key!';
|
||||
/// } else {
|
||||
/// if (kReleaseMode) {
|
||||
/// _message = 'Not a Q: Key label is "${event.logicalKey.keyLabel}"';
|
||||
/// _message = 'Not a Q: Pressed 0x${event.logicalKey.keyId.toRadixString(16)}';
|
||||
/// } else {
|
||||
/// // This will only print useful information in debug mode.
|
||||
/// // The debugName will only print useful information in debug mode.
|
||||
/// _message = 'Not a Q: Pressed ${event.logicalKey.debugName}';
|
||||
/// }
|
||||
/// }
|
||||
@ -124,21 +124,18 @@ abstract class KeyboardKey with Diagnosticable {
|
||||
/// keyboard events.
|
||||
@immutable
|
||||
class LogicalKeyboardKey extends KeyboardKey {
|
||||
/// Creates a LogicalKeyboardKey object with an optional key label and debug
|
||||
/// name.
|
||||
/// A LogicalKeyboardKey object for a key ID.
|
||||
///
|
||||
/// [keyId] must not be null.
|
||||
///
|
||||
/// {@tool snippet}
|
||||
/// To save executable size, it is recommended that the [debugName] be null in
|
||||
/// release mode. You can do this by using the [kReleaseMode] constant.
|
||||
///
|
||||
/// ```dart
|
||||
/// const LogicalKeyboardKey(0x0010000000a, debugName: kReleaseMode ? null : 'Special Key')
|
||||
/// ```
|
||||
/// {@end-tool}
|
||||
const LogicalKeyboardKey(this.keyId, {this.debugName, this.keyLabel = ''})
|
||||
: assert(keyId != null);
|
||||
/// This factory constructor ensures that the same `keyId` always results
|
||||
/// in the identical instance. It looks up an object from the predefined values
|
||||
/// if possible, or construct a new one and cache it.
|
||||
factory LogicalKeyboardKey(int keyId) {
|
||||
return findKeyByKeyId(keyId) ??
|
||||
_additionalKeyPool.putIfAbsent(keyId, () => LogicalKeyboardKey._(keyId));
|
||||
}
|
||||
|
||||
/// Creates a LogicalKeyboardKey object for a key ID.
|
||||
const LogicalKeyboardKey._(this.keyId);
|
||||
|
||||
/// A unique code representing this key.
|
||||
///
|
||||
@ -146,37 +143,42 @@ class LogicalKeyboardKey extends KeyboardKey {
|
||||
/// from it, as the representation of the code could change at any time.
|
||||
final int keyId;
|
||||
|
||||
// Returns the bits that are not included in [valueMask], shifted to the
|
||||
// right.
|
||||
//
|
||||
// For example, if the input is 0x12abcdabcd, then the result is 0x12.
|
||||
//
|
||||
// This could have been a trivial shifting for non-Web environment, but in
|
||||
// order to support JavaScript, which only supports bitwise operation of up to
|
||||
// 32 bits, this function extracts them using division.
|
||||
//
|
||||
// It returns 0 for release mode.
|
||||
static int _debugNonValueBits(int numOf64Bits) {
|
||||
int result = 0;
|
||||
assert(() {
|
||||
const int kDivisorForValueMask = valueMask + 1;
|
||||
result = (numOf64Bits / kDivisorForValueMask).floor();
|
||||
return true;
|
||||
}());
|
||||
return result;
|
||||
}
|
||||
|
||||
/// The debug string to print for this keyboard key, which will be null in
|
||||
/// release mode.
|
||||
final String? debugName;
|
||||
|
||||
/// The Unicode string representing the character produced by a [RawKeyEvent].
|
||||
///
|
||||
/// This value is useful for describing or matching mnemonic keyboard
|
||||
/// shortcuts.
|
||||
///
|
||||
/// 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]
|
||||
/// because `keyLabel` only takes into account the key being pressed, not any
|
||||
/// combining keys pressed before it, so, for example, an “o” that follows a
|
||||
/// combining dieresis (“¨”, COMBINING DIAERESIS (U+0308)) would just return
|
||||
/// “o” for [keyLabel], but would return “ö” for [RawKeyEvent.character].
|
||||
///
|
||||
/// {@macro flutter.services.RawKeyEventData.keyLabel}
|
||||
final String keyLabel;
|
||||
|
||||
@override
|
||||
int get hashCode => keyId.hashCode;
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
if (other.runtimeType != runtimeType) {
|
||||
return false;
|
||||
}
|
||||
return other is LogicalKeyboardKey
|
||||
&& other.keyId == keyId;
|
||||
String? get debugName {
|
||||
String? result;
|
||||
assert(() {
|
||||
result = _debugNames[keyId];
|
||||
if (result == null) {
|
||||
if (_debugNonValueBits(keyId) == 0) {
|
||||
result = 'Key ${String.fromCharCode(keyId)}';
|
||||
} else {
|
||||
result = 'Key with ID 0x${keyId.toRadixString(16).padLeft(11, '0')}';
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}());
|
||||
return result;
|
||||
}
|
||||
|
||||
/// Returns the [LogicalKeyboardKey] constant that matches the given ID, or
|
||||
@ -261,10 +263,11 @@ class LogicalKeyboardKey extends KeyboardKey {
|
||||
void debugFillProperties(DiagnosticPropertiesBuilder properties) {
|
||||
super.debugFillProperties(properties);
|
||||
properties.add(StringProperty('keyId', '0x${keyId.toRadixString(16).padLeft(8, '0')}', showName: true));
|
||||
properties.add(StringProperty('keyLabel', keyLabel, showName: true));
|
||||
properties.add(StringProperty('debugName', debugName, showName: true, defaultValue: null));
|
||||
}
|
||||
|
||||
static final Map<int, LogicalKeyboardKey> _additionalKeyPool = <int, LogicalKeyboardKey>{};
|
||||
|
||||
/// Mask for the 32-bit value portion of the key code.
|
||||
///
|
||||
/// This is used by platform-specific code to generate Flutter key codes.
|
||||
@ -313,6 +316,11 @@ class LogicalKeyboardKey extends KeyboardKey {
|
||||
// A map of keys to the pseudo-key synonym for that key. Used by getSynonyms.
|
||||
static final Map<LogicalKeyboardKey, LogicalKeyboardKey> _synonyms = <LogicalKeyboardKey, LogicalKeyboardKey>{
|
||||
@@@LOGICAL_KEY_SYNONYMS@@@ };
|
||||
|
||||
static const Map<int, String> _debugNames = kReleaseMode ?
|
||||
<int, String>{} :
|
||||
<int, String>{
|
||||
@@@LOGICAL_KEY_DEBUG_NAMES@@@ };
|
||||
}
|
||||
|
||||
/// A class with static values that describe the keys that are returned from
|
||||
@ -387,7 +395,7 @@ class LogicalKeyboardKey extends KeyboardKey {
|
||||
/// onTap: () {
|
||||
/// FocusScope.of(context).requestFocus(_focusNode);
|
||||
/// },
|
||||
/// child: Text('Tap to focus'),
|
||||
/// child: const Text('Tap to focus'),
|
||||
/// );
|
||||
/// }
|
||||
/// return Text(_message ?? 'Press a key');
|
||||
@ -408,20 +416,18 @@ class LogicalKeyboardKey extends KeyboardKey {
|
||||
/// keyboard events.
|
||||
@immutable
|
||||
class PhysicalKeyboardKey extends KeyboardKey {
|
||||
/// Creates a PhysicalKeyboardKey object with an optional debug name.
|
||||
/// A PhysicalKeyboardKey object for a USB HID usage.
|
||||
///
|
||||
/// The [usbHidUsage] must not be null.
|
||||
///
|
||||
/// {@tool snippet}
|
||||
/// To save executable size, it is recommended that the [debugName] be null in
|
||||
/// release mode. You can do this using the [kReleaseMode] constant.
|
||||
///
|
||||
/// ```dart
|
||||
/// const PhysicalKeyboardKey(0x0000ffff, debugName: kReleaseMode ? null : 'Special Key')
|
||||
/// ```
|
||||
/// {@end-tool}
|
||||
const PhysicalKeyboardKey(this.usbHidUsage, {this.debugName})
|
||||
: assert(usbHidUsage != null);
|
||||
/// This factory constructor ensures that the same `usbHidUsage` always results
|
||||
/// in the identical instance. It looks up an object from the predefined values
|
||||
/// if possible, or construct a new one and cache it.
|
||||
factory PhysicalKeyboardKey(int usbHidUsage) {
|
||||
return findKeyByCode(usbHidUsage) ??
|
||||
_additionalKeyPool.putIfAbsent(usbHidUsage, () => PhysicalKeyboardKey._(usbHidUsage));
|
||||
}
|
||||
|
||||
/// Creates a PhysicalKeyboardKey object for a USB HID usage.
|
||||
const PhysicalKeyboardKey._(this.usbHidUsage);
|
||||
|
||||
/// The unique USB HID usage ID of this physical key on the keyboard.
|
||||
///
|
||||
@ -435,24 +441,20 @@ class PhysicalKeyboardKey extends KeyboardKey {
|
||||
|
||||
/// The debug string to print for this keyboard key, which will be null in
|
||||
/// release mode.
|
||||
final String? debugName;
|
||||
String? get debugName {
|
||||
String? result;
|
||||
assert(() {
|
||||
result = _debugNames[usbHidUsage] ??
|
||||
'Key with ID 0x${usbHidUsage.toRadixString(16).padLeft(8, '0')}';
|
||||
return true;
|
||||
}());
|
||||
return result;
|
||||
}
|
||||
|
||||
/// Finds a known [PhysicalKeyboardKey] that matches the given USB HID usage
|
||||
/// code.
|
||||
static PhysicalKeyboardKey? findKeyByCode(int usageCode) => _knownPhysicalKeys[usageCode];
|
||||
|
||||
@override
|
||||
int get hashCode => usbHidUsage.hashCode;
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
if (other.runtimeType != runtimeType) {
|
||||
return false;
|
||||
}
|
||||
return other is PhysicalKeyboardKey
|
||||
&& other.usbHidUsage == usbHidUsage;
|
||||
}
|
||||
|
||||
@override
|
||||
void debugFillProperties(DiagnosticPropertiesBuilder properties) {
|
||||
super.debugFillProperties(properties);
|
||||
@ -460,6 +462,8 @@ class PhysicalKeyboardKey extends KeyboardKey {
|
||||
properties.add(StringProperty('debugName', debugName, showName: true, defaultValue: null));
|
||||
}
|
||||
|
||||
static final Map<int, PhysicalKeyboardKey> _additionalKeyPool = <int, PhysicalKeyboardKey>{};
|
||||
|
||||
// Key constants for all keyboard keys in the USB HID specification at the
|
||||
// time Flutter was built.
|
||||
@@@PHYSICAL_KEY_DEFINITIONS@@@
|
||||
@ -468,4 +472,9 @@ class PhysicalKeyboardKey extends KeyboardKey {
|
||||
static const Map<int, PhysicalKeyboardKey> _knownPhysicalKeys = <int, PhysicalKeyboardKey>{
|
||||
@@@PHYSICAL_KEY_MAP@@@
|
||||
};
|
||||
|
||||
static const Map<int, String> _debugNames = kReleaseMode ?
|
||||
<int, String>{} :
|
||||
<int, String>{
|
||||
@@@PHYSICAL_KEY_DEBUG_NAMES@@@ };
|
||||
}
|
||||
|
49
dev/tools/gen_keycodes/lib/key_labels_code_gen.dart
Normal file
49
dev/tools/gen_keycodes/lib/key_labels_code_gen.dart
Normal file
@ -0,0 +1,49 @@
|
||||
// Copyright 2014 The Flutter Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
import 'package:path/path.dart' as path;
|
||||
|
||||
import 'base_code_gen.dart';
|
||||
import 'key_data.dart';
|
||||
import 'utils.dart';
|
||||
|
||||
/// Generates the event_simulation_keylabels.dart based on the information in the
|
||||
/// key data structure given to it.
|
||||
class KeyLabelsCodeGenerator extends BaseCodeGenerator {
|
||||
KeyLabelsCodeGenerator(KeyData keyData) : super(keyData);
|
||||
|
||||
/// Gets the generated definitions of logicalKeyLabels.
|
||||
String get _logicalKeyLabels {
|
||||
String escapeLabel(String label) => label.contains("'") ? 'r"$label"' : "r'$label'";
|
||||
final StringBuffer result = StringBuffer();
|
||||
void printKey(int flutterId, String keyLabel) {
|
||||
if (keyLabel != null)
|
||||
result.write('''
|
||||
${toHex(flutterId, digits: 11)}: ${escapeLabel(keyLabel)},
|
||||
''');
|
||||
}
|
||||
|
||||
for (final Key entry in keyData.data) {
|
||||
printKey(entry.flutterId, entry.keyLabel);
|
||||
}
|
||||
for (final String name in Key.synonyms.keys) {
|
||||
// Use the first item in the synonyms as a template for the ID to use.
|
||||
// It won't end up being the same value because it'll be in the pseudo-key
|
||||
// plane.
|
||||
final Key entry = keyData.data.firstWhere((Key item) => item.name == Key.synonyms[name][0]);
|
||||
printKey(Key.synonymPlane | entry.flutterId, entry.keyLabel);
|
||||
}
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
@override
|
||||
String get templatePath => path.join(flutterRoot.path, 'dev', 'tools', 'gen_keycodes', 'data', 'key_labels.tmpl');
|
||||
|
||||
@override
|
||||
Map<String, String> mappings() {
|
||||
return <String, String>{
|
||||
'LOGICAL_KEY_LABELS': _logicalKeyLabels,
|
||||
};
|
||||
}
|
||||
}
|
@ -45,38 +45,38 @@ class KeyboardKeysCodeGenerator extends BaseCodeGenerator {
|
||||
definitions.write('''
|
||||
|
||||
$firstComment ///
|
||||
$otherComments static const PhysicalKeyboardKey ${entry.constantName} = PhysicalKeyboardKey(${toHex(entry.usbHidCode, digits: 8)}, debugName: kReleaseMode ? null : '${entry.commentName}');
|
||||
$otherComments static const PhysicalKeyboardKey ${entry.constantName} = PhysicalKeyboardKey._(${toHex(entry.usbHidCode, digits: 8)});
|
||||
''');
|
||||
}
|
||||
return definitions.toString();
|
||||
}
|
||||
|
||||
String get _physicalDebugNames {
|
||||
final StringBuffer result = StringBuffer();
|
||||
for (final Key entry in keyData.data) {
|
||||
result.write('''
|
||||
${toHex(entry.usbHidCode, digits: 8)}: '${entry.commentName}',
|
||||
''');
|
||||
}
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
/// Gets the generated definitions of LogicalKeyboardKeys.
|
||||
String get _logicalDefinitions {
|
||||
String escapeLabel(String label) => label.contains("'") ? 'r"$label"' : "r'$label'";
|
||||
final StringBuffer definitions = StringBuffer();
|
||||
void printKey(int flutterId, String keyLabel, String constantName, String commentName, {String otherComments}) {
|
||||
void printKey(int flutterId, String constantName, String commentName, {String otherComments}) {
|
||||
final String firstComment = _wrapString('Represents the logical "$commentName" key on the keyboard.');
|
||||
otherComments ??= _wrapString('See the function [RawKeyEvent.logicalKey] for more information.');
|
||||
if (keyLabel == null) {
|
||||
definitions.write('''
|
||||
definitions.write('''
|
||||
|
||||
$firstComment ///
|
||||
$otherComments static const LogicalKeyboardKey $constantName = LogicalKeyboardKey(${toHex(flutterId, digits: 11)}, debugName: kReleaseMode ? null : '$commentName');
|
||||
$otherComments static const LogicalKeyboardKey $constantName = LogicalKeyboardKey._(${toHex(flutterId, digits: 11)});
|
||||
''');
|
||||
} else {
|
||||
definitions.write('''
|
||||
|
||||
$firstComment ///
|
||||
$otherComments static const LogicalKeyboardKey $constantName = LogicalKeyboardKey(${toHex(flutterId, digits: 11)}, keyLabel: ${escapeLabel(keyLabel)}, debugName: kReleaseMode ? null : '$commentName');
|
||||
''');
|
||||
}
|
||||
}
|
||||
|
||||
for (final Key entry in keyData.data) {
|
||||
printKey(
|
||||
entry.flutterId,
|
||||
entry.keyLabel,
|
||||
entry.constantName,
|
||||
entry.commentName,
|
||||
);
|
||||
@ -89,7 +89,7 @@ $otherComments static const LogicalKeyboardKey $constantName = LogicalKeyboardK
|
||||
final Set<String> unionNames = Key.synonyms[name].map<String>((dynamic name) {
|
||||
return upperCamelToLowerCamel(name as String);
|
||||
}).toSet();
|
||||
printKey(Key.synonymPlane | entry.flutterId, entry.keyLabel, name, Key.getCommentName(name),
|
||||
printKey(Key.synonymPlane | entry.flutterId, name, Key.getCommentName(name),
|
||||
otherComments: _wrapString('This key represents the union of the keys '
|
||||
'$unionNames when comparing keys. This key will never be generated '
|
||||
'directly, its main use is in defining key maps.'));
|
||||
@ -108,6 +108,25 @@ $otherComments static const LogicalKeyboardKey $constantName = LogicalKeyboardK
|
||||
return synonyms.toString();
|
||||
}
|
||||
|
||||
String get _logicalDebugNames {
|
||||
final StringBuffer result = StringBuffer();
|
||||
for (final Key entry in keyData.data) {
|
||||
result.write('''
|
||||
${toHex(entry.flutterId, digits: 11)}: '${entry.commentName}',
|
||||
''');
|
||||
}
|
||||
for (final String name in Key.synonyms.keys) {
|
||||
// Use the first item in the synonyms as a template for the ID to use.
|
||||
// It won't end up being the same value because it'll be in the pseudo-key
|
||||
// plane.
|
||||
final Key entry = keyData.data.firstWhere((Key item) => item.name == Key.synonyms[name][0]);
|
||||
result.write('''
|
||||
${toHex(Key.synonymPlane | entry.flutterId, digits: 11)}: '${Key.getCommentName(name)}',
|
||||
''');
|
||||
}
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
/// This generates the map of USB HID codes to physical keys.
|
||||
String get _predefinedHidCodeMap {
|
||||
final StringBuffer scanCodeMap = StringBuffer();
|
||||
@ -146,7 +165,9 @@ $otherComments static const LogicalKeyboardKey $constantName = LogicalKeyboardK
|
||||
'LOGICAL_KEY_MAP': _predefinedKeyCodeMap,
|
||||
'LOGICAL_KEY_DEFINITIONS': _logicalDefinitions,
|
||||
'LOGICAL_KEY_SYNONYMS': _logicalSynonyms,
|
||||
'LOGICAL_KEY_DEBUG_NAMES': _logicalDebugNames,
|
||||
'PHYSICAL_KEY_DEFINITIONS': _physicalDefinitions,
|
||||
'PHYSICAL_KEY_DEBUG_NAMES': _physicalDebugNames,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -194,11 +194,7 @@ class RawKeyEventDataAndroid extends RawKeyEventData {
|
||||
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()}',
|
||||
);
|
||||
return LogicalKeyboardKey.findKeyByKeyId(keyId) ?? LogicalKeyboardKey(keyId);
|
||||
}
|
||||
|
||||
// Look to see if the keyCode is one we know about and have a mapping for.
|
||||
@ -210,10 +206,7 @@ class RawKeyEventDataAndroid extends RawKeyEventData {
|
||||
// This is a non-printable key that we don't know about, so we mint a new
|
||||
// code with the autogenerated bit set.
|
||||
const int androidKeyIdPlane = 0x00200000000;
|
||||
newKey ??= LogicalKeyboardKey(
|
||||
androidKeyIdPlane | keyCode | LogicalKeyboardKey.autogeneratedMask,
|
||||
debugName: kReleaseMode ? null : 'Unknown Android key code $keyCode',
|
||||
);
|
||||
newKey ??= LogicalKeyboardKey(androidKeyIdPlane | keyCode | LogicalKeyboardKey.autogeneratedMask);
|
||||
return newKey;
|
||||
}
|
||||
|
||||
|
@ -68,11 +68,8 @@ class RawKeyEventDataFuchsia extends RawKeyEventData {
|
||||
// If the key has a printable representation, then make a logical key based
|
||||
// on that.
|
||||
if (codePoint != 0) {
|
||||
return LogicalKeyboardKey(
|
||||
LogicalKeyboardKey.unicodePlane | codePoint & LogicalKeyboardKey.valueMask,
|
||||
keyLabel: keyLabel,
|
||||
debugName: kReleaseMode ? null : 'Key $keyLabel',
|
||||
);
|
||||
final int flutterId = LogicalKeyboardKey.unicodePlane | codePoint & LogicalKeyboardKey.valueMask;
|
||||
return kFuchsiaToLogicalKey[flutterId] ?? LogicalKeyboardKey(LogicalKeyboardKey.unicodePlane | codePoint & LogicalKeyboardKey.valueMask);
|
||||
}
|
||||
|
||||
// Look to see if the hidUsage is one we know about and have a mapping for.
|
||||
@ -84,10 +81,7 @@ class RawKeyEventDataFuchsia extends RawKeyEventData {
|
||||
// This is a non-printable key that we don't know about, so we mint a new
|
||||
// code with the autogenerated bit set.
|
||||
const int fuchsiaKeyIdPlane = 0x00300000000;
|
||||
newKey ??= LogicalKeyboardKey(
|
||||
fuchsiaKeyIdPlane | hidUsage | LogicalKeyboardKey.autogeneratedMask,
|
||||
debugName: kReleaseMode ? null : 'Ephemeral Fuchsia key code $hidUsage',
|
||||
);
|
||||
newKey ??= LogicalKeyboardKey(fuchsiaKeyIdPlane | hidUsage | LogicalKeyboardKey.autogeneratedMask);
|
||||
return newKey;
|
||||
}
|
||||
|
||||
|
@ -92,7 +92,6 @@ class RawKeyEventDataIos extends RawKeyEventData {
|
||||
@override
|
||||
PhysicalKeyboardKey get physicalKey => kIosToPhysicalKey[keyCode] ?? PhysicalKeyboardKey.none;
|
||||
|
||||
|
||||
@override
|
||||
LogicalKeyboardKey get logicalKey {
|
||||
// Look to see if the keyCode is a printable number pad key, so that a
|
||||
@ -126,11 +125,7 @@ class RawKeyEventDataIos extends RawKeyEventData {
|
||||
}
|
||||
|
||||
final int keyId = LogicalKeyboardKey.unicodePlane | (codeUnit & LogicalKeyboardKey.valueMask);
|
||||
return LogicalKeyboardKey.findKeyByKeyId(keyId) ?? LogicalKeyboardKey(
|
||||
keyId,
|
||||
keyLabel: keyLabel,
|
||||
debugName: kReleaseMode ? null : 'Key ${keyLabel.toUpperCase()}',
|
||||
);
|
||||
return LogicalKeyboardKey.findKeyByKeyId(keyId) ?? LogicalKeyboardKey(keyId);
|
||||
}
|
||||
|
||||
// Control keys like "backspace" and movement keys like arrow keys don't
|
||||
@ -141,21 +136,14 @@ class RawKeyEventDataIos extends RawKeyEventData {
|
||||
// physical key map.
|
||||
if (physicalKey != PhysicalKeyboardKey.none) {
|
||||
final int keyId = physicalKey.usbHidUsage | LogicalKeyboardKey.hidPlane;
|
||||
return LogicalKeyboardKey.findKeyByKeyId(keyId) ?? LogicalKeyboardKey(
|
||||
keyId,
|
||||
keyLabel: physicalKey.debugName ?? '',
|
||||
debugName: physicalKey.debugName,
|
||||
);
|
||||
return LogicalKeyboardKey.findKeyByKeyId(keyId) ?? LogicalKeyboardKey(keyId);
|
||||
}
|
||||
|
||||
// This is a non-printable key that is unrecognized, so a new code is minted
|
||||
// with the autogenerated bit set.
|
||||
const int iosKeyIdPlane = 0x00400000000;
|
||||
|
||||
return LogicalKeyboardKey(
|
||||
iosKeyIdPlane | keyCode | LogicalKeyboardKey.autogeneratedMask,
|
||||
debugName: kReleaseMode ? null : 'Unknown iOS key code $keyCode',
|
||||
);
|
||||
return LogicalKeyboardKey(iosKeyIdPlane | keyCode | LogicalKeyboardKey.autogeneratedMask);
|
||||
}
|
||||
|
||||
bool _isLeftRightModifierPressed(KeyboardSide side, int anyMask, int leftMask, int rightMask) {
|
||||
|
@ -92,11 +92,7 @@ class RawKeyEventDataLinux extends RawKeyEventData {
|
||||
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()}',
|
||||
);
|
||||
return LogicalKeyboardKey.findKeyByKeyId(keyId) ?? LogicalKeyboardKey(keyId);
|
||||
}
|
||||
|
||||
// Look to see if the keyCode is one we know about and have a mapping for.
|
||||
@ -109,10 +105,7 @@ class RawKeyEventDataLinux extends RawKeyEventData {
|
||||
|
||||
// This is a non-printable key that we don't know about, so we mint a new
|
||||
// code with the autogenerated bit set.
|
||||
newKey ??= LogicalKeyboardKey(
|
||||
linuxKeyIdPlane | keyCode | LogicalKeyboardKey.autogeneratedMask,
|
||||
debugName: kReleaseMode ? null : 'Unknown key code $keyCode',
|
||||
);
|
||||
newKey ??= LogicalKeyboardKey(linuxKeyIdPlane | keyCode | LogicalKeyboardKey.autogeneratedMask);
|
||||
return newKey;
|
||||
}
|
||||
|
||||
|
@ -95,11 +95,7 @@ class RawKeyEventDataMacOs extends RawKeyEventData {
|
||||
}
|
||||
|
||||
final int keyId = LogicalKeyboardKey.unicodePlane | (codeUnit & LogicalKeyboardKey.valueMask);
|
||||
return LogicalKeyboardKey.findKeyByKeyId(keyId) ?? LogicalKeyboardKey(
|
||||
keyId,
|
||||
keyLabel: keyLabel,
|
||||
debugName: kReleaseMode ? null : 'Key ${keyLabel.toUpperCase()}',
|
||||
);
|
||||
return LogicalKeyboardKey.findKeyByKeyId(keyId) ?? LogicalKeyboardKey(keyId);
|
||||
}
|
||||
|
||||
// Control keys like "backspace" and movement keys like arrow keys don't
|
||||
@ -110,21 +106,14 @@ class RawKeyEventDataMacOs extends RawKeyEventData {
|
||||
// physical key map.
|
||||
if (physicalKey != PhysicalKeyboardKey.none) {
|
||||
final int keyId = physicalKey.usbHidUsage | LogicalKeyboardKey.hidPlane;
|
||||
return LogicalKeyboardKey.findKeyByKeyId(keyId) ?? LogicalKeyboardKey(
|
||||
keyId,
|
||||
keyLabel: physicalKey.debugName ?? '',
|
||||
debugName: physicalKey.debugName,
|
||||
);
|
||||
return LogicalKeyboardKey.findKeyByKeyId(keyId) ?? LogicalKeyboardKey(keyId);
|
||||
}
|
||||
|
||||
// This is a non-printable key that is unrecognized, so a new code is minted
|
||||
// with the autogenerated bit set.
|
||||
const int macOsKeyIdPlane = 0x00500000000;
|
||||
|
||||
return LogicalKeyboardKey(
|
||||
macOsKeyIdPlane | keyCode | LogicalKeyboardKey.autogeneratedMask,
|
||||
debugName: kReleaseMode ? null : 'Unknown macOS key code $keyCode',
|
||||
);
|
||||
return LogicalKeyboardKey(macOsKeyIdPlane | keyCode | LogicalKeyboardKey.autogeneratedMask);
|
||||
}
|
||||
|
||||
bool _isLeftRightModifierPressed(KeyboardSide side, int anyMask, int leftMask, int rightMask) {
|
||||
|
@ -82,10 +82,7 @@ class RawKeyEventDataWeb extends RawKeyEventData {
|
||||
// This is a non-printable key that we don't know about, so we mint a new
|
||||
// code with the autogenerated bit set.
|
||||
const int webKeyIdPlane = 0x00800000000;
|
||||
return LogicalKeyboardKey(
|
||||
webKeyIdPlane | code.hashCode | LogicalKeyboardKey.autogeneratedMask,
|
||||
debugName: kReleaseMode ? null : 'Unknown Web code "$code"',
|
||||
);
|
||||
return LogicalKeyboardKey(webKeyIdPlane | code.hashCode | LogicalKeyboardKey.autogeneratedMask);
|
||||
}
|
||||
|
||||
@override
|
||||
|
@ -3,8 +3,6 @@
|
||||
// found in the LICENSE file.
|
||||
|
||||
|
||||
import 'package:flutter/foundation.dart';
|
||||
|
||||
import 'keyboard_key.dart';
|
||||
import 'keyboard_maps.dart';
|
||||
import 'raw_keyboard.dart';
|
||||
@ -80,11 +78,7 @@ class RawKeyEventDataWindows extends RawKeyEventData {
|
||||
// plane.
|
||||
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()}',
|
||||
);
|
||||
return LogicalKeyboardKey.findKeyByKeyId(keyId) ?? LogicalKeyboardKey(keyId);
|
||||
}
|
||||
// Look to see if the keyCode is one we know about and have a mapping for.
|
||||
LogicalKeyboardKey? newKey = kWindowsToLogicalKey[keyCode];
|
||||
@ -95,10 +89,7 @@ class RawKeyEventDataWindows extends RawKeyEventData {
|
||||
// This is a non-printable key that we don't know about, so we mint a new
|
||||
// code with the autogenerated bit set.
|
||||
const int windowsKeyIdPlane = 0x00700000000;
|
||||
newKey ??= LogicalKeyboardKey(
|
||||
windowsKeyIdPlane | keyCode | LogicalKeyboardKey.autogeneratedMask,
|
||||
debugName: kReleaseMode ? null : 'Unknown Windows key code $keyCode',
|
||||
);
|
||||
newKey ??= LogicalKeyboardKey(windowsKeyIdPlane | keyCode | LogicalKeyboardKey.autogeneratedMask);
|
||||
return newKey;
|
||||
}
|
||||
|
||||
|
@ -15,11 +15,14 @@ void main() {
|
||||
// Check a modifier key
|
||||
expect(PhysicalKeyboardKey.findKeyByCode(0x000700e1), equals(PhysicalKeyboardKey.shiftLeft));
|
||||
});
|
||||
test('Equality is only based on HID code.', () async {
|
||||
const PhysicalKeyboardKey key1 = PhysicalKeyboardKey(0x01, debugName: 'key1');
|
||||
const PhysicalKeyboardKey key2 = PhysicalKeyboardKey(0x01, debugName: 'key2');
|
||||
expect(key1, equals(key1));
|
||||
expect(key1, equals(key2));
|
||||
test('Values are cached', () async {
|
||||
expect(identical(PhysicalKeyboardKey.keyA, PhysicalKeyboardKey(PhysicalKeyboardKey.keyA.usbHidUsage)), true);
|
||||
expect(identical(PhysicalKeyboardKey(0x12345), PhysicalKeyboardKey(0x12345)), true);
|
||||
});
|
||||
test('debugNames', () async {
|
||||
expect(PhysicalKeyboardKey.keyA.debugName, 'Key A');
|
||||
expect(PhysicalKeyboardKey.backslash.debugName, 'Backslash');
|
||||
expect(PhysicalKeyboardKey(0x12345).debugName, 'Key with ID 0x00012345');
|
||||
});
|
||||
});
|
||||
group(LogicalKeyboardKey, () {
|
||||
@ -44,12 +47,6 @@ void main() {
|
||||
expect(LogicalKeyboardKey.isControlCharacter('~'), isFalse);
|
||||
expect(LogicalKeyboardKey.isControlCharacter('\xa0'), isFalse); // NO-BREAK SPACE
|
||||
});
|
||||
test('Equality is only based on ID.', () async {
|
||||
const LogicalKeyboardKey key1 = LogicalKeyboardKey(0x01, keyLabel: 'label1', debugName: 'key1');
|
||||
const LogicalKeyboardKey key2 = LogicalKeyboardKey(0x01, keyLabel: 'label2', debugName: 'key2');
|
||||
expect(key1, equals(key1));
|
||||
expect(key1, equals(key2));
|
||||
});
|
||||
test('Basic synonyms can be looked up.', () async {
|
||||
expect(LogicalKeyboardKey.shiftLeft.synonyms.first, equals(LogicalKeyboardKey.shift));
|
||||
expect(LogicalKeyboardKey.controlLeft.synonyms.first, equals(LogicalKeyboardKey.control));
|
||||
@ -106,5 +103,16 @@ void main() {
|
||||
LogicalKeyboardKey.meta,
|
||||
}));
|
||||
});
|
||||
test('Values are cached', () async {
|
||||
expect(identical(LogicalKeyboardKey.keyA, LogicalKeyboardKey(LogicalKeyboardKey.keyA.keyId)), true);
|
||||
expect(identical(LogicalKeyboardKey(0x12345), LogicalKeyboardKey(0x12345)), true);
|
||||
});
|
||||
test('debugNames', () async {
|
||||
expect(LogicalKeyboardKey.keyA.debugName, 'Key A');
|
||||
expect(LogicalKeyboardKey.backslash.debugName, 'Backslash');
|
||||
expect(LogicalKeyboardKey(0xD9).debugName, 'Key Ù');
|
||||
expect(LogicalKeyboardKey.mediaPlay.debugName, 'Media Play');
|
||||
expect(LogicalKeyboardKey(0x100012345).debugName, 'Key with ID 0x00100012345');
|
||||
});
|
||||
});
|
||||
}
|
||||
|
@ -1178,7 +1178,6 @@ void main() {
|
||||
final RawKeyEventDataMacOs data = leftArrowKey.data as RawKeyEventDataMacOs;
|
||||
expect(data.physicalKey, equals(PhysicalKeyboardKey.arrowLeft));
|
||||
expect(data.logicalKey, equals(LogicalKeyboardKey.arrowLeft));
|
||||
expect(data.logicalKey.keyLabel, isEmpty);
|
||||
}, skip: isBrowser); // https://github.com/flutter/flutter/issues/35347
|
||||
}, skip: isBrowser); // This is a macOS-specific group.
|
||||
|
||||
@ -1324,7 +1323,6 @@ void main() {
|
||||
final RawKeyEventDataIos data = leftArrowKey.data as RawKeyEventDataIos;
|
||||
expect(data.physicalKey, equals(PhysicalKeyboardKey.arrowLeft));
|
||||
expect(data.logicalKey, equals(LogicalKeyboardKey.arrowLeft));
|
||||
expect(data.logicalKey.keyLabel, isEmpty);
|
||||
}, skip: isBrowser); // https://github.com/flutter/flutter/issues/35347
|
||||
}, skip: isBrowser); // This is an iOS-specific group.
|
||||
|
||||
@ -1469,7 +1467,6 @@ 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, isEmpty);
|
||||
});
|
||||
testWidgets('Win32 VK_PROCESSKEY events are skipped', (WidgetTester tester) async {
|
||||
const String platform = 'windows';
|
||||
|
@ -68,8 +68,7 @@ void main() {
|
||||
LogicalKeyboardKey.keyC,
|
||||
LogicalKeyboardKey.keyD,
|
||||
);
|
||||
// ignore: prefer_const_literals_to_create_immutables, https://github.com/dart-lang/linter/issues/2026
|
||||
final LogicalKeySet setFromSet = LogicalKeySet.fromSet(<LogicalKeyboardKey>{
|
||||
final LogicalKeySet setFromSet = LogicalKeySet.fromSet(const <LogicalKeyboardKey>{
|
||||
LogicalKeyboardKey.keyA,
|
||||
LogicalKeyboardKey.keyB,
|
||||
LogicalKeyboardKey.keyC,
|
||||
@ -124,8 +123,7 @@ void main() {
|
||||
LogicalKeyboardKey.keyB,
|
||||
LogicalKeyboardKey.keyA,
|
||||
);
|
||||
// ignore: prefer_const_literals_to_create_immutables, https://github.com/dart-lang/linter/issues/2026
|
||||
final LogicalKeySet set4 = LogicalKeySet.fromSet(<LogicalKeyboardKey>{
|
||||
final LogicalKeySet set4 = LogicalKeySet.fromSet(const <LogicalKeyboardKey>{
|
||||
LogicalKeyboardKey.keyD,
|
||||
LogicalKeyboardKey.keyC,
|
||||
LogicalKeyboardKey.keyB,
|
||||
@ -140,8 +138,7 @@ void main() {
|
||||
expect(map.containsKey(LogicalKeySet(LogicalKeyboardKey.keyA)), isTrue);
|
||||
expect(
|
||||
set2,
|
||||
// ignore: prefer_const_literals_to_create_immutables, https://github.com/dart-lang/linter/issues/2026
|
||||
equals(LogicalKeySet.fromSet(<LogicalKeyboardKey>{
|
||||
equals(LogicalKeySet.fromSet(const <LogicalKeyboardKey>{
|
||||
LogicalKeyboardKey.keyA,
|
||||
LogicalKeyboardKey.keyB,
|
||||
LogicalKeyboardKey.keyC,
|
||||
|
@ -6,6 +6,7 @@ import 'dart:io';
|
||||
|
||||
import 'package:flutter/foundation.dart' show kIsWeb;
|
||||
import 'package:flutter/services.dart';
|
||||
import 'key_labels.dart';
|
||||
import 'test_async_utils.dart';
|
||||
|
||||
// TODO(gspencergoog): Replace this with more robust key simulation code once
|
||||
@ -13,6 +14,10 @@ import 'test_async_utils.dart';
|
||||
// https://github.com/flutter/flutter/issues/33521
|
||||
// This code can only simulate keys which appear in the key maps.
|
||||
|
||||
String _keyLabel(LogicalKeyboardKey key) {
|
||||
return logicalKeyLabels[key.keyId] ?? '';
|
||||
}
|
||||
|
||||
/// A class that serves as a namespace for a bunch of keyboard-key generation
|
||||
/// utilities.
|
||||
class KeyEventSimulator {
|
||||
@ -206,7 +211,7 @@ class KeyEventSimulator {
|
||||
|
||||
if (kIsWeb) {
|
||||
result['code'] = _getWebKeyCode(key);
|
||||
result['key'] = key.keyLabel;
|
||||
result['key'] = _keyLabel(key);
|
||||
result['metaState'] = _getWebModifierFlags(key, isDown);
|
||||
return result;
|
||||
}
|
||||
@ -214,17 +219,17 @@ class KeyEventSimulator {
|
||||
switch (platform) {
|
||||
case 'android':
|
||||
result['keyCode'] = keyCode;
|
||||
if (key.keyLabel.isNotEmpty) {
|
||||
result['codePoint'] = key.keyLabel.codeUnitAt(0);
|
||||
result['character'] = key.keyLabel;
|
||||
if (_keyLabel(key).isNotEmpty) {
|
||||
result['codePoint'] = _keyLabel(key).codeUnitAt(0);
|
||||
result['character'] = _keyLabel(key);
|
||||
}
|
||||
result['scanCode'] = scanCode;
|
||||
result['metaState'] = _getAndroidModifierFlags(key, isDown);
|
||||
break;
|
||||
case 'fuchsia':
|
||||
result['hidUsage'] = physicalKey.usbHidUsage;
|
||||
if (key.keyLabel.isNotEmpty) {
|
||||
result['codePoint'] = key.keyLabel.codeUnitAt(0);
|
||||
if (_keyLabel(key).isNotEmpty) {
|
||||
result['codePoint'] = _keyLabel(key).codeUnitAt(0);
|
||||
}
|
||||
result['modifiers'] = _getFuchsiaModifierFlags(key, isDown);
|
||||
break;
|
||||
@ -233,32 +238,32 @@ class KeyEventSimulator {
|
||||
result['keyCode'] = keyCode;
|
||||
result['scanCode'] = scanCode;
|
||||
result['modifiers'] = _getGlfwModifierFlags(key, isDown);
|
||||
result['unicodeScalarValues'] = key.keyLabel.isNotEmpty ? key.keyLabel.codeUnitAt(0) : 0;
|
||||
result['unicodeScalarValues'] = _keyLabel(key).isNotEmpty ? _keyLabel(key).codeUnitAt(0) : 0;
|
||||
break;
|
||||
case 'macos':
|
||||
result['keyCode'] = scanCode;
|
||||
if (key.keyLabel.isNotEmpty) {
|
||||
result['characters'] = key.keyLabel;
|
||||
result['charactersIgnoringModifiers'] = key.keyLabel;
|
||||
if (_keyLabel(key).isNotEmpty) {
|
||||
result['characters'] = _keyLabel(key);
|
||||
result['charactersIgnoringModifiers'] = _keyLabel(key);
|
||||
}
|
||||
result['modifiers'] = _getMacOsModifierFlags(key, isDown);
|
||||
break;
|
||||
case 'ios':
|
||||
result['keyCode'] = scanCode;
|
||||
result['characters'] = key.keyLabel;
|
||||
result['charactersIgnoringModifiers'] = key.keyLabel;
|
||||
result['characters'] = _keyLabel(key);
|
||||
result['charactersIgnoringModifiers'] = _keyLabel(key);
|
||||
result['modifiers'] = _getIOSModifierFlags(key, isDown);
|
||||
break;
|
||||
case 'web':
|
||||
result['code'] = _getWebKeyCode(key);
|
||||
result['key'] = key.keyLabel;
|
||||
result['key'] = _keyLabel(key);
|
||||
result['metaState'] = _getWebModifierFlags(key, isDown);
|
||||
break;
|
||||
case 'windows':
|
||||
result['keyCode'] = keyCode;
|
||||
result['scanCode'] = scanCode;
|
||||
if (key.keyLabel.isNotEmpty) {
|
||||
result['characterCodePoint'] = key.keyLabel.codeUnitAt(0);
|
||||
if (_keyLabel(key).isNotEmpty) {
|
||||
result['characterCodePoint'] = _keyLabel(key).codeUnitAt(0);
|
||||
}
|
||||
result['modifiers'] = _getWindowsModifierFlags(key, isDown);
|
||||
}
|
||||
|
83
packages/flutter_test/lib/src/key_labels.dart
Normal file
83
packages/flutter_test/lib/src/key_labels.dart
Normal file
@ -0,0 +1,83 @@
|
||||
// Copyright 2014 The Flutter Authors. All rights reserved.
|
||||
// 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.
|
||||
//
|
||||
// Edit the template dev/tools/gen_keycodes/data/key_labels.tmpl instead.
|
||||
// See dev/tools/gen_keycodes/README.md for more information.
|
||||
|
||||
/// The keyLabel corresponding to a logical key.
|
||||
///
|
||||
/// Used to generate simulated key events out of a logical key.
|
||||
const Map<int, String> logicalKeyLabels = <int, String>{
|
||||
0x00000000061: r'a',
|
||||
0x00000000062: r'b',
|
||||
0x00000000063: r'c',
|
||||
0x00000000064: r'd',
|
||||
0x00000000065: r'e',
|
||||
0x00000000066: r'f',
|
||||
0x00000000067: r'g',
|
||||
0x00000000068: r'h',
|
||||
0x00000000069: r'i',
|
||||
0x0000000006a: r'j',
|
||||
0x0000000006b: r'k',
|
||||
0x0000000006c: r'l',
|
||||
0x0000000006d: r'm',
|
||||
0x0000000006e: r'n',
|
||||
0x0000000006f: r'o',
|
||||
0x00000000070: r'p',
|
||||
0x00000000071: r'q',
|
||||
0x00000000072: r'r',
|
||||
0x00000000073: r's',
|
||||
0x00000000074: r't',
|
||||
0x00000000075: r'u',
|
||||
0x00000000076: r'v',
|
||||
0x00000000077: r'w',
|
||||
0x00000000078: r'x',
|
||||
0x00000000079: r'y',
|
||||
0x0000000007a: r'z',
|
||||
0x00000000031: r'1',
|
||||
0x00000000032: r'2',
|
||||
0x00000000033: r'3',
|
||||
0x00000000034: r'4',
|
||||
0x00000000035: r'5',
|
||||
0x00000000036: r'6',
|
||||
0x00000000037: r'7',
|
||||
0x00000000038: r'8',
|
||||
0x00000000039: r'9',
|
||||
0x00000000030: r'0',
|
||||
0x00000000020: r' ',
|
||||
0x0000000002d: r'-',
|
||||
0x0000000003d: r'=',
|
||||
0x0000000005b: r'[',
|
||||
0x0000000005d: r']',
|
||||
0x0000000005c: r'\',
|
||||
0x0000000003b: r';',
|
||||
0x00000000027: r"'",
|
||||
0x00000000060: r'`',
|
||||
0x0000000002c: r',',
|
||||
0x0000000002e: r'.',
|
||||
0x0000000002f: r'/',
|
||||
0x00100070054: r'/',
|
||||
0x00100070055: r'*',
|
||||
0x00100070056: r'-',
|
||||
0x00100070057: r'+',
|
||||
0x00100070059: r'1',
|
||||
0x0010007005a: r'2',
|
||||
0x0010007005b: r'3',
|
||||
0x0010007005c: r'4',
|
||||
0x0010007005d: r'5',
|
||||
0x0010007005e: r'6',
|
||||
0x0010007005f: r'7',
|
||||
0x00100070060: r'8',
|
||||
0x00100070061: r'9',
|
||||
0x00100070062: r'0',
|
||||
0x00100070063: r'.',
|
||||
0x00100070067: r'=',
|
||||
0x00100070085: r',',
|
||||
0x001000700b6: r'(',
|
||||
0x001000700b7: r')',
|
||||
};
|
Loading…
Reference in New Issue
Block a user