Skip to content

Commit c5e3e1c

Browse files
authored
RawKeyboardMacos accepts a new field "specifiedLogicalKey" (#100803)
1 parent 08e467d commit c5e3e1c

File tree

6 files changed

+63
-3
lines changed

6 files changed

+63
-3
lines changed

dev/tools/gen_keycodes/data/keyboard_key.tmpl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -83,9 +83,9 @@ class LogicalKeyboardKey extends KeyboardKey {
8383
const int valueMaskWidth = 32;
8484

8585
// Equivalent to assert(divisorForValueMask == (1 << valueMaskWidth)).
86-
const int _firstDivisorWidth = 28;
86+
const int firstDivisorWidth = 28;
8787
assert(divisorForValueMask ==
88-
(1 << _firstDivisorWidth) * (1 << (valueMaskWidth - _firstDivisorWidth)));
88+
(1 << firstDivisorWidth) * (1 << (valueMaskWidth - firstDivisorWidth)));
8989

9090
// JS only supports up to 2^53 - 1, therefore non-value bits can only
9191
// contain (maxSafeIntegerWidth - valueMaskWidth) bits.

dev/tools/gen_keycodes/data/macos_key_code_map_cc.tmpl

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
#import <Cocoa/Cocoa.h>
66
#import <Foundation/Foundation.h>
7-
#include "./KeyCodeMap_internal.h"
7+
#include "./KeyCodeMap_Internal.h"
88

99
// DO NOT EDIT -- DO NOT EDIT -- DO NOT EDIT
1010
// This file is generated by
@@ -17,6 +17,8 @@
1717
//
1818
// See flutter/flutter:dev/tools/gen_keycodes/README.md for more information.
1919

20+
namespace flutter {
21+
2022
@@@MASK_CONSTANTS@@@
2123

2224
const NSDictionary* keyCodeToPhysicalKey = @{
@@ -36,3 +38,9 @@ const NSDictionary* modifierFlagToKeyCode = @{
3638
};
3739

3840
@@@SPECIAL_KEY_CONSTANTS@@@
41+
42+
const std::vector<LayoutGoal> layoutGoals = {
43+
@@@LAYOUT_GOALS@@@
44+
};
45+
46+
} // namespace flutter

dev/tools/gen_keycodes/lib/macos_code_gen.dart

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,27 @@ class MacOSCodeGenerator extends PlatformCodeGenerator {
9696
return specialKeyConstants.toString().trimRight();
9797
}
9898

99+
String get _layoutGoals {
100+
final OutputLines<int> lines = OutputLines<int>('macOS layout goals');
101+
final Iterable<LogicalKeyEntry> asciiEntries = logicalData.entries.where(
102+
(LogicalKeyEntry entry) => entry.value <= 128);
103+
for (final LogicalKeyEntry logicalEntry in asciiEntries) {
104+
final int value = logicalEntry.value;
105+
final PhysicalKeyEntry? physicalEntry = keyData.tryEntryByName(logicalEntry.name);
106+
if (physicalEntry == null) {
107+
continue;
108+
}
109+
final bool mandatory = (value >= '0'.codeUnitAt(0) && value <= '9'.codeUnitAt(0))
110+
|| (value >= 'a'.codeUnitAt(0) && value <= 'z'.codeUnitAt(0));
111+
lines.add(value,
112+
' LayoutGoal{${toHex(physicalEntry.macOSScanCode, digits: 2)}, '
113+
'${toHex(value, digits: 2)}, '
114+
'${mandatory ? 'true}, ' : 'false},'}'
115+
' // ${logicalEntry.name}');
116+
}
117+
return lines.sortedJoin().trimRight();
118+
}
119+
99120
@override
100121
String get templatePath => path.join(dataRoot, 'macos_key_code_map_cc.tmpl');
101122

@@ -115,6 +136,7 @@ class MacOSCodeGenerator extends PlatformCodeGenerator {
115136
'KEYCODE_TO_MODIFIER_FLAG_MAP': _keyToModifierFlagMap,
116137
'MODIFIER_FLAG_TO_KEYCODE_MAP': _modifierFlagToKeyMap,
117138
'SPECIAL_KEY_CONSTANTS': _specialKeyConstants,
139+
'LAYOUT_GOALS': _layoutGoals,
118140
};
119141
}
120142
}

packages/flutter/lib/src/services/raw_keyboard.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -343,6 +343,7 @@ abstract class RawKeyEvent with Diagnosticable {
343343
charactersIgnoringModifiers: message['charactersIgnoringModifiers'] as String? ?? '',
344344
keyCode: message['keyCode'] as int? ?? 0,
345345
modifiers: message['modifiers'] as int? ?? 0,
346+
specifiedLogicalKey: message['specifiedLogicalKey'] as int?,
346347
);
347348
character = message['characters'] as String?;
348349
break;

packages/flutter/lib/src/services/raw_keyboard_macos.dart

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ class RawKeyEventDataMacOs extends RawKeyEventData {
3636
this.charactersIgnoringModifiers = '',
3737
this.keyCode = 0,
3838
this.modifiers = 0,
39+
this.specifiedLogicalKey,
3940
}) : assert(characters != null),
4041
assert(charactersIgnoringModifiers != null),
4142
assert(keyCode != null),
@@ -70,6 +71,15 @@ class RawKeyEventDataMacOs extends RawKeyEventData {
7071
/// * [Apple's NSEvent documentation](https://developer.apple.com/documentation/appkit/nsevent/1535211-modifierflags?language=objc)
7172
final int modifiers;
7273

74+
/// A logical key specified by the embedding that should be used instead of
75+
/// deriving from raw data.
76+
///
77+
/// The macOS embedding detects the keyboard layout and maps some keys to
78+
/// logical keys in a way that can not be derived from per-key information.
79+
///
80+
/// This is not part of the native macOS key event.
81+
final int? specifiedLogicalKey;
82+
7383
@override
7484
String get keyLabel => charactersIgnoringModifiers;
7585

@@ -78,6 +88,10 @@ class RawKeyEventDataMacOs extends RawKeyEventData {
7888

7989
@override
8090
LogicalKeyboardKey get logicalKey {
91+
if (specifiedLogicalKey != null) {
92+
final int key = specifiedLogicalKey!;
93+
return LogicalKeyboardKey.findKeyByKeyId(key) ?? LogicalKeyboardKey(key);
94+
}
8195
// Look to see if the keyCode is a printable number pad key, so that a
8296
// difference between regular keys (e.g. "=") and the number pad version
8397
// (e.g. the "=" on the number pad) can be determined.

packages/flutter/test/services/raw_keyboard_test.dart

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1546,6 +1546,21 @@ void main() {
15461546
expect(data.logicalKey, equals(const LogicalKeyboardKey(0x1400000000)));
15471547
});
15481548

1549+
test('Prioritize logical key from specifiedLogicalKey', () {
1550+
final RawKeyEvent digit1FromFrench = RawKeyEvent.fromMessage(const <String, dynamic>{
1551+
'type': 'keydown',
1552+
'keymap': 'macos',
1553+
'keyCode': 0x00000012,
1554+
'characters': '&',
1555+
'charactersIgnoringModifiers': '&',
1556+
'specifiedLogicalKey': 0x000000031,
1557+
'modifiers': 0,
1558+
});
1559+
final RawKeyEventDataMacOs data = digit1FromFrench.data as RawKeyEventDataMacOs;
1560+
expect(data.physicalKey, equals(PhysicalKeyboardKey.digit1));
1561+
expect(data.logicalKey, equals(LogicalKeyboardKey.digit1));
1562+
});
1563+
15491564
test('data.toString', () {
15501565
expect(RawKeyEvent.fromMessage(const <String, dynamic>{
15511566
'type': 'keydown',

0 commit comments

Comments
 (0)