Clean up synonyms, key code generation. (#138192)
## Description
This cleans up how synonyms are calculated, and adds a reverse mapping from pseudo keys to the real keys they are synonyms of.
Updates the `layout_goals.json` to include the "Space" key, since that was added in the engine without updating the generation configuration.
diff --git a/dev/tools/gen_keycodes/data/keyboard_key.tmpl b/dev/tools/gen_keycodes/data/keyboard_key.tmpl
index 36390ef..c3b983f 100644
--- a/dev/tools/gen_keycodes/data/keyboard_key.tmpl
+++ b/dev/tools/gen_keycodes/data/keyboard_key.tmpl
@@ -225,35 +225,40 @@
/// Returns a set of pseudo-key synonyms for the given `key`.
///
- /// This allows finding the pseudo-keys that also represents a concrete
- /// `key` so that a class with a key map can match pseudo-keys as well as the
- /// actual generated keys.
+ /// This allows finding the pseudo-keys that also represent a concrete `key`
+ /// so that a class with a key map can match pseudo-keys as well as the actual
+ /// generated keys.
///
- /// The pseudo-keys returned in the set are typically used to represent keys
- /// which appear in multiple places on the keyboard, such as the [shift],
- /// [alt], [control], and [meta] keys. The keys in the returned set won't ever
- /// be generated directly, but if a more specific key event is received, then
+ /// Pseudo-keys returned in the set are typically used to represent keys which
+ /// appear in multiple places on the keyboard, such as the [shift], [alt],
+ /// [control], and [meta] keys. Pseudo-keys in the returned set won't ever be
+ /// generated directly, but if a more specific key event is received, then
/// this set can be used to find the more general pseudo-key. For example, if
/// this is a [shiftLeft] key, this accessor will return the set
/// `<LogicalKeyboardKey>{ shift }`.
- Set<LogicalKeyboardKey> get synonyms {
- final LogicalKeyboardKey? result = _synonyms[this];
- return result == null ? <LogicalKeyboardKey>{} : <LogicalKeyboardKey>{result};
- }
+ Set<LogicalKeyboardKey> get synonyms => _synonyms[this] ?? <LogicalKeyboardKey>{};
/// Takes a set of keys, and returns the same set, but with any keys that have
/// synonyms replaced.
///
- /// It is used, for example, to make sets of keys with members like
+ /// It is used, for example, to take sets of keys with members like
/// [controlRight] and [controlLeft] and convert that set to contain just
/// [control], so that the question "is any control key down?" can be asked.
static Set<LogicalKeyboardKey> collapseSynonyms(Set<LogicalKeyboardKey> input) {
- final Set<LogicalKeyboardKey> result = <LogicalKeyboardKey>{};
- for (final LogicalKeyboardKey key in input) {
- final LogicalKeyboardKey? synonym = _synonyms[key];
- result.add(synonym ?? key);
- }
- return result;
+ return input.expand((LogicalKeyboardKey element) {
+ return _synonyms[element] ?? <LogicalKeyboardKey>{element};
+ }).toSet();
+ }
+
+ /// Returns the given set with any pseudo-keys expanded into their synonyms.
+ ///
+ /// It is used, for example, to take sets of keys with members like [control]
+ /// and [shift] and convert that set to contain [controlLeft], [controlRight],
+ /// [shiftLeft], and [shiftRight].
+ static Set<LogicalKeyboardKey> expandSynonyms(Set<LogicalKeyboardKey> input) {
+ return input.expand((LogicalKeyboardKey element) {
+ return _reverseSynonyms[element] ?? <LogicalKeyboardKey>{element};
+ }).toSet();
}
@override
@@ -277,10 +282,14 @@
@@@LOGICAL_KEY_MAP@@@
};
- // A map of keys to the pseudo-key synonym for that key. Used by getSynonyms.
- static final Map<LogicalKeyboardKey, LogicalKeyboardKey> _synonyms = <LogicalKeyboardKey, LogicalKeyboardKey>{
+ // A map of keys to the pseudo-key synonym for that key.
+ static final Map<LogicalKeyboardKey, Set<LogicalKeyboardKey>> _synonyms = <LogicalKeyboardKey, Set<LogicalKeyboardKey>>{
@@@LOGICAL_KEY_SYNONYMS@@@ };
+ // A map of pseudo-key to the set of keys that are synonyms for that pseudo-key.
+ static final Map<LogicalKeyboardKey, Set<LogicalKeyboardKey>> _reverseSynonyms = <LogicalKeyboardKey, Set<LogicalKeyboardKey>>{
+@@@LOGICAL_KEY_REVERSE_SYNONYMS@@@ };
+
static const Map<int, String> _keyLabels = <int, String>{
@@@LOGICAL_KEY_KEY_LABELS@@@
};
diff --git a/dev/tools/gen_keycodes/data/layout_goals.json b/dev/tools/gen_keycodes/data/layout_goals.json
index 4e7942c..267a8a5 100644
--- a/dev/tools/gen_keycodes/data/layout_goals.json
+++ b/dev/tools/gen_keycodes/data/layout_goals.json
@@ -1,4 +1,21 @@
{
+ "Backquote": false,
+ "Backslash": false,
+ "BracketLeft": false,
+ "BracketRight": false,
+ "Comma": false,
+ "Digit0": true,
+ "Digit1": true,
+ "Digit2": true,
+ "Digit3": true,
+ "Digit4": true,
+ "Digit5": true,
+ "Digit6": true,
+ "Digit7": true,
+ "Digit8": true,
+ "Digit9": true,
+ "Equal": false,
+ "IntlBackslash": false,
"KeyA": true,
"KeyB": true,
"KeyC": true,
@@ -25,26 +42,10 @@
"KeyX": true,
"KeyY": true,
"KeyZ": true,
- "Digit1": true,
- "Digit2": true,
- "Digit3": true,
- "Digit4": true,
- "Digit5": true,
- "Digit6": true,
- "Digit7": true,
- "Digit8": true,
- "Digit9": true,
- "Digit0": true,
- "Quote": false,
- "Comma": false,
"Minus": false,
"Period": false,
- "Slash": false,
+ "Quote": false,
"Semicolon": false,
- "Equal": false,
- "BracketLeft": false,
- "Backslash": false,
- "BracketRight": false,
- "Backquote": false,
- "IntlBackslash": false
+ "Slash": false,
+ "Space": false
}
diff --git a/dev/tools/gen_keycodes/data/macos_key_code_map_cc.tmpl b/dev/tools/gen_keycodes/data/macos_key_code_map_cc.tmpl
index 349795e..3d4a4782 100644
--- a/dev/tools/gen_keycodes/data/macos_key_code_map_cc.tmpl
+++ b/dev/tools/gen_keycodes/data/macos_key_code_map_cc.tmpl
@@ -39,7 +39,7 @@
@@@SPECIAL_KEY_CONSTANTS@@@
-const std::vector<LayoutGoal> layoutGoals = {
+const std::vector<LayoutGoal> kLayoutGoals = {
@@@LAYOUT_GOALS@@@
};
diff --git a/dev/tools/gen_keycodes/lib/keyboard_keys_code_gen.dart b/dev/tools/gen_keycodes/lib/keyboard_keys_code_gen.dart
index 2aa39f5..b01f3cc 100644
--- a/dev/tools/gen_keycodes/lib/keyboard_keys_code_gen.dart
+++ b/dev/tools/gen_keycodes/lib/keyboard_keys_code_gen.dart
@@ -115,12 +115,22 @@
for (final SynonymKeyInfo synonymInfo in synonyms.values) {
for (final LogicalKeyEntry key in synonymInfo.keys) {
final LogicalKeyEntry synonym = logicalData.entryByName(synonymInfo.name);
- result.writeln(' ${key.constantName}: ${synonym.constantName},');
+ result.writeln(' ${key.constantName}: <LogicalKeyboardKey>{${synonym.constantName}},');
}
}
return result.toString();
}
+ String get _logicalReverseSynonyms {
+ final StringBuffer result = StringBuffer();
+ for (final SynonymKeyInfo synonymInfo in synonyms.values) {
+ final LogicalKeyEntry synonym = logicalData.entryByName(synonymInfo.name);
+ final List<String> entries = synonymInfo.keys.map<String>((LogicalKeyEntry entry) => entry.constantName).toList();
+ result.writeln(' ${synonym.constantName}: <LogicalKeyboardKey>{${entries.join(', ')}},');
+ }
+ return result.toString();
+ }
+
String get _logicalKeyLabels {
final OutputLines<int> lines = OutputLines<int>('Logical key labels', behavior: DeduplicateBehavior.kSkip);
for (final LogicalKeyEntry entry in logicalData.entries) {
@@ -169,6 +179,7 @@
'LOGICAL_KEY_MAP': _predefinedKeyCodeMap,
'LOGICAL_KEY_DEFINITIONS': _logicalDefinitions,
'LOGICAL_KEY_SYNONYMS': _logicalSynonyms,
+ 'LOGICAL_KEY_REVERSE_SYNONYMS': _logicalReverseSynonyms,
'LOGICAL_KEY_KEY_LABELS': _logicalKeyLabels,
'PHYSICAL_KEY_MAP': _predefinedHidCodeMap,
'PHYSICAL_KEY_DEFINITIONS': _physicalDefinitions,
diff --git a/dev/tools/gen_keycodes/lib/macos_code_gen.dart b/dev/tools/gen_keycodes/lib/macos_code_gen.dart
index cbd697e..75ffab6 100644
--- a/dev/tools/gen_keycodes/lib/macos_code_gen.dart
+++ b/dev/tools/gen_keycodes/lib/macos_code_gen.dart
@@ -108,7 +108,7 @@
'${mandatory ? 'true' : 'false'}'
'},';
lines.add(logicalEntry.value,
- ' ${line.padRight(39)}'
+ ' ${line.padRight(32)}'
'// ${logicalEntry.name}');
});
return lines.sortedJoin().trimRight();
diff --git a/dev/tools/gen_keycodes/test/gen_keycodes_test.dart b/dev/tools/gen_keycodes/test/gen_keycodes_test.dart
index 9c53ca7..7a22834 100644
--- a/dev/tools/gen_keycodes/test/gen_keycodes_test.dart
+++ b/dev/tools/gen_keycodes/test/gen_keycodes_test.dart
@@ -79,6 +79,7 @@
expect(output, contains('modifierFlagToKeyCode'));
expect(output, contains('kCapsLockPhysicalKey'));
expect(output, contains('kCapsLockLogicalKey'));
+ expect(output, contains('kLayoutGoals'));
checkCommonOutput(output);
});
test('Generate Keycodes for iOS', () {
diff --git a/packages/flutter/lib/src/services/keyboard_key.g.dart b/packages/flutter/lib/src/services/keyboard_key.g.dart
index a39c259..4feaa7b 100644
--- a/packages/flutter/lib/src/services/keyboard_key.g.dart
+++ b/packages/flutter/lib/src/services/keyboard_key.g.dart
@@ -225,35 +225,40 @@
/// Returns a set of pseudo-key synonyms for the given `key`.
///
- /// This allows finding the pseudo-keys that also represents a concrete
- /// `key` so that a class with a key map can match pseudo-keys as well as the
- /// actual generated keys.
+ /// This allows finding the pseudo-keys that also represent a concrete `key`
+ /// so that a class with a key map can match pseudo-keys as well as the actual
+ /// generated keys.
///
- /// The pseudo-keys returned in the set are typically used to represent keys
- /// which appear in multiple places on the keyboard, such as the [shift],
- /// [alt], [control], and [meta] keys. The keys in the returned set won't ever
- /// be generated directly, but if a more specific key event is received, then
+ /// Pseudo-keys returned in the set are typically used to represent keys which
+ /// appear in multiple places on the keyboard, such as the [shift], [alt],
+ /// [control], and [meta] keys. Pseudo-keys in the returned set won't ever be
+ /// generated directly, but if a more specific key event is received, then
/// this set can be used to find the more general pseudo-key. For example, if
/// this is a [shiftLeft] key, this accessor will return the set
/// `<LogicalKeyboardKey>{ shift }`.
- Set<LogicalKeyboardKey> get synonyms {
- final LogicalKeyboardKey? result = _synonyms[this];
- return result == null ? <LogicalKeyboardKey>{} : <LogicalKeyboardKey>{result};
- }
+ Set<LogicalKeyboardKey> get synonyms => _synonyms[this] ?? <LogicalKeyboardKey>{};
/// Takes a set of keys, and returns the same set, but with any keys that have
/// synonyms replaced.
///
- /// It is used, for example, to make sets of keys with members like
+ /// It is used, for example, to take sets of keys with members like
/// [controlRight] and [controlLeft] and convert that set to contain just
/// [control], so that the question "is any control key down?" can be asked.
static Set<LogicalKeyboardKey> collapseSynonyms(Set<LogicalKeyboardKey> input) {
- final Set<LogicalKeyboardKey> result = <LogicalKeyboardKey>{};
- for (final LogicalKeyboardKey key in input) {
- final LogicalKeyboardKey? synonym = _synonyms[key];
- result.add(synonym ?? key);
- }
- return result;
+ return input.expand((LogicalKeyboardKey element) {
+ return _synonyms[element] ?? <LogicalKeyboardKey>{element};
+ }).toSet();
+ }
+
+ /// Returns the given set with any pseudo-keys expanded into their synonyms.
+ ///
+ /// It is used, for example, to take sets of keys with members like [control]
+ /// and [shift] and convert that set to contain [controlLeft], [controlRight],
+ /// [shiftLeft], and [shiftRight].
+ static Set<LogicalKeyboardKey> expandSynonyms(Set<LogicalKeyboardKey> input) {
+ return input.expand((LogicalKeyboardKey element) {
+ return _reverseSynonyms[element] ?? <LogicalKeyboardKey>{element};
+ }).toSet();
}
@override
@@ -3017,16 +3022,24 @@
0x0020000031f: gameButtonZ,
};
- // A map of keys to the pseudo-key synonym for that key. Used by getSynonyms.
- static final Map<LogicalKeyboardKey, LogicalKeyboardKey> _synonyms = <LogicalKeyboardKey, LogicalKeyboardKey>{
- shiftLeft: shift,
- shiftRight: shift,
- metaLeft: meta,
- metaRight: meta,
- altLeft: alt,
- altRight: alt,
- controlLeft: control,
- controlRight: control,
+ // A map of keys to the pseudo-key synonym for that key.
+ static final Map<LogicalKeyboardKey, Set<LogicalKeyboardKey>> _synonyms = <LogicalKeyboardKey, Set<LogicalKeyboardKey>>{
+ shiftLeft: <LogicalKeyboardKey>{shift},
+ shiftRight: <LogicalKeyboardKey>{shift},
+ metaLeft: <LogicalKeyboardKey>{meta},
+ metaRight: <LogicalKeyboardKey>{meta},
+ altLeft: <LogicalKeyboardKey>{alt},
+ altRight: <LogicalKeyboardKey>{alt},
+ controlLeft: <LogicalKeyboardKey>{control},
+ controlRight: <LogicalKeyboardKey>{control},
+ };
+
+ // A map of pseudo-key to the set of keys that are synonyms for that pseudo-key.
+ static final Map<LogicalKeyboardKey, Set<LogicalKeyboardKey>> _reverseSynonyms = <LogicalKeyboardKey, Set<LogicalKeyboardKey>>{
+ shift: <LogicalKeyboardKey>{shiftLeft, shiftRight},
+ meta: <LogicalKeyboardKey>{metaLeft, metaRight},
+ alt: <LogicalKeyboardKey>{altLeft, altRight},
+ control: <LogicalKeyboardKey>{controlLeft, controlRight},
};
static const Map<int, String> _keyLabels = <int, String>{