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> {
} else if (data is RawKeyEventDataLinux) {
dataText.add(Text('keyCode: ${data.keyCode} (${_asHex(data.keyCode)})'));
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('logical: ${_event.logicalKey}'));
......
......@@ -279,7 +279,7 @@ abstract class RawKeyEvent extends Diagnosticable {
case 'linux':
data = RawKeyEventDataLinux(
keyHelper: KeyHelper(message['toolkit'] ?? ''),
codePoint: message['codePoint'] ?? 0,
unicodeScalarValues: message['unicodeScalarValues'] ?? 0,
keyCode: message['keyCode'] ?? 0,
scanCode: message['scanCode'] ?? 0,
modifiers: message['modifiers'] ?? 0);
......
......@@ -19,16 +19,17 @@ import 'raw_keyboard.dart';
class RawKeyEventDataLinux extends RawKeyEventData {
/// Creates a key event data structure specific for macOS.
///
/// The [toolkit], [scanCode], [codePoint], [keyCode], and [modifiers], arguments
/// must not be null.
/// The [toolkit], [scanCode], [unicodeScalarValues], [keyCode], and [modifiers],
/// arguments must not be null.
const RawKeyEventDataLinux({
@required this.keyHelper,
this.unicodeScalarValues = 0,
this.scanCode = 0,
this.codePoint = 0,
this.keyCode = 0,
this.modifiers = 0,
}) : assert(scanCode != null),
assert(codePoint != null),
assert(unicodeScalarValues != null),
assert((unicodeScalarValues & ~LogicalKeyboardKey.valueMask) == 0),
assert(keyCode != null),
assert(modifiers != null),
assert(keyHelper != null);
......@@ -39,32 +40,32 @@ class RawKeyEventDataLinux extends RawKeyEventData {
/// (GLFW, GTK, QT, etc) may have a different key code mapping.
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.
///
/// These values are not reliable and vary from device to device, so this
/// information is mainly useful for debugging.
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.
///
/// This is the physical key that was pressed, not the Unicode character.
/// See [codePoint] for the Unicode character. 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 keyCode;
/// 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;
@override
String get keyLabel => codePoint == 0 ? null : String.fromCharCode(codePoint);
String get keyLabel => unicodeScalarValues == 0 ? null : String.fromCharCode(unicodeScalarValues);
@override
PhysicalKeyboardKey get physicalKey => kLinuxToPhysicalKey[scanCode] ?? PhysicalKeyboardKey.none;
......@@ -85,7 +86,7 @@ class RawKeyEventDataLinux extends RawKeyEventData {
// plane.
if (keyLabel != null &&
!LogicalKeyboardKey.isControlCharacter(keyLabel)) {
final int keyId = LogicalKeyboardKey.unicodePlane | (codePoint & LogicalKeyboardKey.valueMask);
final int keyId = LogicalKeyboardKey.unicodePlane | (unicodeScalarValues & LogicalKeyboardKey.valueMask);
return LogicalKeyboardKey.findKeyByKeyId(keyId) ?? LogicalKeyboardKey(
keyId,
keyLabel: keyLabel,
......@@ -123,7 +124,7 @@ class RawKeyEventDataLinux extends RawKeyEventData {
@override
String toString() {
return '$runtimeType(keyLabel: $keyLabel, keyCode: $keyCode, scanCode: $scanCode,'
' codePoint: $codePoint, modifiers: $modifiers, '
' unicodeScalarValues: $unicodeScalarValues, modifiers: $modifiers, '
'modifiers down: $modifiersPressed)';
}
}
......
......@@ -467,9 +467,9 @@ void main() {
'type': 'keydown',
'keymap': 'linux',
'toolkit': 'glfw',
'keyCode': 0x04,
'scanCode': 0x01,
'codePoint': 0x10,
'keyCode': 65,
'scanCode': 0x00000026,
'unicodeScalarValues': 97,
'modifiers': modifier,
});
final RawKeyEventDataLinux data = event.data;
......@@ -501,9 +501,9 @@ void main() {
'type': 'keydown',
'keymap': 'linux',
'toolkit': 'glfw',
'keyCode': 0x04,
'scanCode': 0x64,
'codePoint': 0x1,
'keyCode': 65,
'scanCode': 0x00000026,
'unicodeScalarValues': 97,
'modifiers': modifier | GLFWKeyHelper.modifierControl,
});
final RawKeyEventDataLinux data = event.data;
......@@ -538,13 +538,44 @@ void main() {
'toolkit': 'glfw',
'keyCode': 65,
'scanCode': 0x00000026,
'codePoint': 97,
'unicodeScalarValues': 113,
'modifiers': 0x0,
});
final RawKeyEventDataLinux data = keyAEvent.data;
expect(data.physicalKey, equals(PhysicalKeyboardKey.keyA));
expect(data.logicalKey, equals(LogicalKeyboardKey.keyA));
expect(data.keyLabel, equals('a'));
expect(data.logicalKey, equals(LogicalKeyboardKey.keyQ));
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', () {
final RawKeyEvent escapeKeyEvent = RawKeyEvent.fromMessage(const <String, dynamic>{
......@@ -553,7 +584,7 @@ void main() {
'toolkit': 'glfw',
'keyCode': 256,
'scanCode': 0x00000009,
'codePoint': 0,
'unicodeScalarValues': 0,
'modifiers': 0x0,
});
final RawKeyEventDataLinux data = escapeKeyEvent.data;
......@@ -568,7 +599,7 @@ void main() {
'toolkit': 'glfw',
'keyCode': 340,
'scanCode': 0x00000032,
'codePoint': 0,
'unicodeScalarValues': 0,
});
final RawKeyEventDataLinux data = shiftLeftKeyEvent.data;
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