[macOS] RawKeyboardDataMacos properly handles multi-char characters (#94432)
* Impl * Macos
This commit is contained in:
parent
e4a1d3e1d3
commit
3af6b2f604
@ -85,25 +85,25 @@ class RawKeyEventDataMacOs extends RawKeyEventData {
|
|||||||
return knownKey;
|
return knownKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If this key is printable, generate the LogicalKeyboardKey from its
|
// If this key is a single printable character, generate the
|
||||||
// Unicode value. Control keys such as ESC, CTRL, and SHIFT are not
|
// LogicalKeyboardKey from its Unicode value. Control keys such as ESC,
|
||||||
// printable. HOME, DEL, arrow keys, and function keys are considered
|
// CTRL, and SHIFT are not printable. HOME, DEL, arrow keys, and function
|
||||||
// modifier function keys, which generate invalid Unicode scalar values.
|
// keys are considered modifier function keys, which generate invalid
|
||||||
if (keyLabel.isNotEmpty &&
|
// Unicode scalar values. Multi-char characters are also discarded.
|
||||||
!LogicalKeyboardKey.isControlCharacter(keyLabel) &&
|
int? character;
|
||||||
!_isUnprintableKey(keyLabel)) {
|
if (keyLabel.isNotEmpty) {
|
||||||
// Given that charactersIgnoringModifiers can contain a String of
|
final List<int> codePoints = keyLabel.runes.toList();
|
||||||
// arbitrary length, limit to a maximum of two Unicode scalar values. It
|
if (codePoints.length == 1 &&
|
||||||
// is unlikely that a keyboard would produce a code point bigger than 32
|
// Ideally we should test whether `codePoints[0]` is in the range.
|
||||||
// bits, but it is still worth defending against this case.
|
// Since LogicalKeyboardKey.isControlCharacter and _isUnprintableKey
|
||||||
assert(charactersIgnoringModifiers.length <= 2);
|
// only tests BMP, it is fine to test keyLabel instead.
|
||||||
int codeUnit = charactersIgnoringModifiers.codeUnitAt(0);
|
!LogicalKeyboardKey.isControlCharacter(keyLabel) &&
|
||||||
if (charactersIgnoringModifiers.length == 2) {
|
!_isUnprintableKey(keyLabel)) {
|
||||||
final int secondCode = charactersIgnoringModifiers.codeUnitAt(1);
|
character = codePoints[0];
|
||||||
codeUnit = (codeUnit << 16) | secondCode;
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
final int keyId = LogicalKeyboardKey.unicodePlane | (codeUnit & LogicalKeyboardKey.valueMask);
|
if (character != null) {
|
||||||
|
final int keyId = LogicalKeyboardKey.unicodePlane | (character & LogicalKeyboardKey.valueMask);
|
||||||
return LogicalKeyboardKey.findKeyByKeyId(keyId) ?? LogicalKeyboardKey(keyId);
|
return LogicalKeyboardKey.findKeyByKeyId(keyId) ?? LogicalKeyboardKey(keyId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1475,6 +1475,20 @@ void main() {
|
|||||||
expect(data.logicalKey, equals(LogicalKeyboardKey.arrowLeft));
|
expect(data.logicalKey, equals(LogicalKeyboardKey.arrowLeft));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('Multi-char keyboard keys are correctly translated', () {
|
||||||
|
final RawKeyEvent leftArrowKey = RawKeyEvent.fromMessage(const <String, dynamic>{
|
||||||
|
'type': 'keydown',
|
||||||
|
'keymap': 'macos',
|
||||||
|
'keyCode': 0x00000000,
|
||||||
|
'characters': 'án',
|
||||||
|
'charactersIgnoringModifiers': 'án',
|
||||||
|
'modifiers': 0,
|
||||||
|
});
|
||||||
|
final RawKeyEventDataMacOs data = leftArrowKey.data as RawKeyEventDataMacOs;
|
||||||
|
expect(data.physicalKey, equals(PhysicalKeyboardKey.keyA));
|
||||||
|
expect(data.logicalKey, equals(const LogicalKeyboardKey(0x1400000000)));
|
||||||
|
});
|
||||||
|
|
||||||
test('data.toString', () {
|
test('data.toString', () {
|
||||||
expect(RawKeyEvent.fromMessage(const <String, dynamic>{
|
expect(RawKeyEvent.fromMessage(const <String, dynamic>{
|
||||||
'type': 'keydown',
|
'type': 'keydown',
|
||||||
|
Loading…
x
Reference in New Issue
Block a user