Unverified Commit 760635e6 authored by Francisco Magdaleno's avatar Francisco Magdaleno Committed by GitHub

[linux] Receives the unmodified characters obtained from GLFW (#34752)

parent 43f118ad
...@@ -105,7 +105,7 @@ class _HardwareKeyDemoState extends State<RawKeyboardDemo> { ...@@ -105,7 +105,7 @@ class _HardwareKeyDemoState extends State<RawKeyboardDemo> {
} else if (data is RawKeyEventDataLinux) { } else if (data is RawKeyEventDataLinux) {
dataText.add(Text('keyCode: ${data.keyCode} (${_asHex(data.keyCode)})')); dataText.add(Text('keyCode: ${data.keyCode} (${_asHex(data.keyCode)})'));
dataText.add(Text('scanCode: ${data.scanCode}')); dataText.add(Text('scanCode: ${data.scanCode}'));
dataText.add(Text('codePoint: ${data.codePoint}')); dataText.add(Text('unicodeScalarValues: ${data.unicodeScalarValues}'));
dataText.add(Text('modifiers: ${data.modifiers} (${_asHex(data.modifiers)})')); dataText.add(Text('modifiers: ${data.modifiers} (${_asHex(data.modifiers)})'));
} }
dataText.add(Text('logical: ${_event.logicalKey}')); dataText.add(Text('logical: ${_event.logicalKey}'));
......
...@@ -279,7 +279,7 @@ abstract class RawKeyEvent extends Diagnosticable { ...@@ -279,7 +279,7 @@ abstract class RawKeyEvent extends Diagnosticable {
case 'linux': case 'linux':
data = RawKeyEventDataLinux( data = RawKeyEventDataLinux(
keyHelper: KeyHelper(message['toolkit'] ?? ''), keyHelper: KeyHelper(message['toolkit'] ?? ''),
codePoint: message['codePoint'] ?? 0, unicodeScalarValues: message['unicodeScalarValues'] ?? 0,
keyCode: message['keyCode'] ?? 0, keyCode: message['keyCode'] ?? 0,
scanCode: message['scanCode'] ?? 0, scanCode: message['scanCode'] ?? 0,
modifiers: message['modifiers'] ?? 0); modifiers: message['modifiers'] ?? 0);
......
...@@ -19,16 +19,17 @@ import 'raw_keyboard.dart'; ...@@ -19,16 +19,17 @@ import 'raw_keyboard.dart';
class RawKeyEventDataLinux extends RawKeyEventData { class RawKeyEventDataLinux extends RawKeyEventData {
/// Creates a key event data structure specific for macOS. /// Creates a key event data structure specific for macOS.
/// ///
/// The [toolkit], [scanCode], [codePoint], [keyCode], and [modifiers], arguments /// The [toolkit], [scanCode], [unicodeScalarValues], [keyCode], and [modifiers],
/// must not be null. /// arguments must not be null.
const RawKeyEventDataLinux({ const RawKeyEventDataLinux({
@required this.keyHelper, @required this.keyHelper,
this.unicodeScalarValues = 0,
this.scanCode = 0, this.scanCode = 0,
this.codePoint = 0,
this.keyCode = 0, this.keyCode = 0,
this.modifiers = 0, this.modifiers = 0,
}) : assert(scanCode != null), }) : assert(scanCode != null),
assert(codePoint != null), assert(unicodeScalarValues != null),
assert((unicodeScalarValues & ~LogicalKeyboardKey.valueMask) == 0),
assert(keyCode != null), assert(keyCode != null),
assert(modifiers != null), assert(modifiers != null),
assert(keyHelper != null); assert(keyHelper != null);
...@@ -39,32 +40,32 @@ class RawKeyEventDataLinux extends RawKeyEventData { ...@@ -39,32 +40,32 @@ class RawKeyEventDataLinux extends RawKeyEventData {
/// (GLFW, GTK, QT, etc) may have a different key code mapping. /// (GLFW, GTK, QT, etc) may have a different key code mapping.
final KeyHelper keyHelper; final KeyHelper keyHelper;
/// An int with up to two Unicode scalar values generated by a single keystroke. An assertion
/// will fire if more than two values are encoded in a single keystroke.
///
/// This is typically the character that [keyCode] would produce without any modifier keys.
/// For dead keys, it is typically the diacritic it would add to a character. Defaults to 0,
/// asserted to be not null.
final int unicodeScalarValues;
/// The hardware scan code id corresponding to this key event. /// The hardware scan code id corresponding to this key event.
/// ///
/// These values are not reliable and vary from device to device, so this /// These values are not reliable and vary from device to device, so this
/// information is mainly useful for debugging. /// information is mainly useful for debugging.
final int scanCode; final int scanCode;
/// The Unicode code point represented by the key event, if any.
///
/// If there is no Unicode code point, this value is zero.
///
/// Dead keys are represented as Unicode combining characters.
final int codePoint;
/// The hardware key code corresponding to this key event. /// The hardware key code corresponding to this key event.
/// ///
/// This is the physical key that was pressed, not the Unicode character. /// This is the physical key that was pressed, not the Unicode character.
/// See [codePoint] for the Unicode character. This value may be different depending /// This value may be different depending on the window toolkit used. See [KeyHelper].
/// on the window toolkit used (See [toolkit]).
final int keyCode; final int keyCode;
/// A mask of the current modifiers using the values in Modifier Flags. /// A mask of the current modifiers using the values in Modifier Flags.
/// This value may be different depending on the window toolkit used (See [toolkit]). /// This value may be different depending on the window toolkit used. See [KeyHelper].
final int modifiers; final int modifiers;
@override @override
String get keyLabel => codePoint == 0 ? null : String.fromCharCode(codePoint); String get keyLabel => unicodeScalarValues == 0 ? null : String.fromCharCode(unicodeScalarValues);
@override @override
PhysicalKeyboardKey get physicalKey => kLinuxToPhysicalKey[scanCode] ?? PhysicalKeyboardKey.none; PhysicalKeyboardKey get physicalKey => kLinuxToPhysicalKey[scanCode] ?? PhysicalKeyboardKey.none;
...@@ -85,7 +86,7 @@ class RawKeyEventDataLinux extends RawKeyEventData { ...@@ -85,7 +86,7 @@ class RawKeyEventDataLinux extends RawKeyEventData {
// plane. // plane.
if (keyLabel != null && if (keyLabel != null &&
!LogicalKeyboardKey.isControlCharacter(keyLabel)) { !LogicalKeyboardKey.isControlCharacter(keyLabel)) {
final int keyId = LogicalKeyboardKey.unicodePlane | (codePoint & LogicalKeyboardKey.valueMask); final int keyId = LogicalKeyboardKey.unicodePlane | (unicodeScalarValues & LogicalKeyboardKey.valueMask);
return LogicalKeyboardKey.findKeyByKeyId(keyId) ?? LogicalKeyboardKey( return LogicalKeyboardKey.findKeyByKeyId(keyId) ?? LogicalKeyboardKey(
keyId, keyId,
keyLabel: keyLabel, keyLabel: keyLabel,
...@@ -123,7 +124,7 @@ class RawKeyEventDataLinux extends RawKeyEventData { ...@@ -123,7 +124,7 @@ class RawKeyEventDataLinux extends RawKeyEventData {
@override @override
String toString() { String toString() {
return '$runtimeType(keyLabel: $keyLabel, keyCode: $keyCode, scanCode: $scanCode,' return '$runtimeType(keyLabel: $keyLabel, keyCode: $keyCode, scanCode: $scanCode,'
' codePoint: $codePoint, modifiers: $modifiers, ' ' unicodeScalarValues: $unicodeScalarValues, modifiers: $modifiers, '
'modifiers down: $modifiersPressed)'; 'modifiers down: $modifiersPressed)';
} }
} }
......
...@@ -467,9 +467,9 @@ void main() { ...@@ -467,9 +467,9 @@ void main() {
'type': 'keydown', 'type': 'keydown',
'keymap': 'linux', 'keymap': 'linux',
'toolkit': 'glfw', 'toolkit': 'glfw',
'keyCode': 0x04, 'keyCode': 65,
'scanCode': 0x01, 'scanCode': 0x00000026,
'codePoint': 0x10, 'unicodeScalarValues': 97,
'modifiers': modifier, 'modifiers': modifier,
}); });
final RawKeyEventDataLinux data = event.data; final RawKeyEventDataLinux data = event.data;
...@@ -501,9 +501,9 @@ void main() { ...@@ -501,9 +501,9 @@ void main() {
'type': 'keydown', 'type': 'keydown',
'keymap': 'linux', 'keymap': 'linux',
'toolkit': 'glfw', 'toolkit': 'glfw',
'keyCode': 0x04, 'keyCode': 65,
'scanCode': 0x64, 'scanCode': 0x00000026,
'codePoint': 0x1, 'unicodeScalarValues': 97,
'modifiers': modifier | GLFWKeyHelper.modifierControl, 'modifiers': modifier | GLFWKeyHelper.modifierControl,
}); });
final RawKeyEventDataLinux data = event.data; final RawKeyEventDataLinux data = event.data;
...@@ -538,13 +538,44 @@ void main() { ...@@ -538,13 +538,44 @@ void main() {
'toolkit': 'glfw', 'toolkit': 'glfw',
'keyCode': 65, 'keyCode': 65,
'scanCode': 0x00000026, 'scanCode': 0x00000026,
'codePoint': 97, 'unicodeScalarValues': 113,
'modifiers': 0x0, 'modifiers': 0x0,
}); });
final RawKeyEventDataLinux data = keyAEvent.data; final RawKeyEventDataLinux data = keyAEvent.data;
expect(data.physicalKey, equals(PhysicalKeyboardKey.keyA)); expect(data.physicalKey, equals(PhysicalKeyboardKey.keyA));
expect(data.logicalKey, equals(LogicalKeyboardKey.keyA)); expect(data.logicalKey, equals(LogicalKeyboardKey.keyQ));
expect(data.keyLabel, equals('a')); expect(data.keyLabel, equals('q'));
});
test('Code points with two Unicode scalar values are allowed', () {
final RawKeyEvent keyAEvent = RawKeyEvent.fromMessage(const <String, dynamic>{
'type': 'keydown',
'keymap': 'linux',
'toolkit': 'glfw',
'keyCode': 65,
'scanCode': 0x00000026,
'unicodeScalarValues': 0x10FFFF,
'modifiers': 0x0,
});
final RawKeyEventDataLinux data = keyAEvent.data;
expect(data.physicalKey, equals(PhysicalKeyboardKey.keyA));
expect(data.logicalKey.keyId, equals(0x10FFFF));
expect(data.keyLabel, equals('􏿿'));
});
test('Code points with more than three Unicode scalar values are not allowed', () {
// |keyCode| and |scanCode| are arbitrary values. This test should fail due to an invalid |unicodeScalarValues|.
void _createFailingKey() {
RawKeyEvent.fromMessage(const <String, dynamic>{
'type': 'keydown',
'keymap': 'linux',
'toolkit': 'glfw',
'keyCode': 65,
'scanCode': 0x00000026,
'unicodeScalarValues': 0x1F00000000,
'modifiers': 0x0,
});
}
expect(() => _createFailingKey(), throwsAssertionError);
}); });
test('Control keyboard keys are correctly translated', () { test('Control keyboard keys are correctly translated', () {
final RawKeyEvent escapeKeyEvent = RawKeyEvent.fromMessage(const <String, dynamic>{ final RawKeyEvent escapeKeyEvent = RawKeyEvent.fromMessage(const <String, dynamic>{
...@@ -553,7 +584,7 @@ void main() { ...@@ -553,7 +584,7 @@ void main() {
'toolkit': 'glfw', 'toolkit': 'glfw',
'keyCode': 256, 'keyCode': 256,
'scanCode': 0x00000009, 'scanCode': 0x00000009,
'codePoint': 0, 'unicodeScalarValues': 0,
'modifiers': 0x0, 'modifiers': 0x0,
}); });
final RawKeyEventDataLinux data = escapeKeyEvent.data; final RawKeyEventDataLinux data = escapeKeyEvent.data;
...@@ -568,7 +599,7 @@ void main() { ...@@ -568,7 +599,7 @@ void main() {
'toolkit': 'glfw', 'toolkit': 'glfw',
'keyCode': 340, 'keyCode': 340,
'scanCode': 0x00000032, 'scanCode': 0x00000032,
'codePoint': 0, 'unicodeScalarValues': 0,
}); });
final RawKeyEventDataLinux data = shiftLeftKeyEvent.data; final RawKeyEventDataLinux data = shiftLeftKeyEvent.data;
expect(data.physicalKey, equals(PhysicalKeyboardKey.shiftLeft)); expect(data.physicalKey, equals(PhysicalKeyboardKey.shiftLeft));
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment