RawKeyEvent.fromMessage constructor Null safety
Creates a concrete RawKeyEvent class from a message in the form received on the SystemChannels.keyEvent channel.
RawKeyEvent.repeat will be derived from the current keyboard state, instead of using the message information.
Implementation
factory RawKeyEvent.fromMessage(Map<String, Object?> message) {
String? character;
RawKeyEventData dataFromWeb() {
final String? key = message['key'] as String?;
if (key != null && key.isNotEmpty && key.length == 1) {
character = key;
}
return RawKeyEventDataWeb(
code: message['code'] as String? ?? '',
key: key ?? '',
location: message['location'] as int? ?? 0,
metaState: message['metaState'] as int? ?? 0,
keyCode: message['keyCode'] as int? ?? 0,
);
}
final RawKeyEventData data;
if (kIsWeb) {
data = dataFromWeb();
} else {
final String keymap = message['keymap']! as String;
switch (keymap) {
case 'android':
data = RawKeyEventDataAndroid(
flags: message['flags'] as int? ?? 0,
codePoint: message['codePoint'] as int? ?? 0,
keyCode: message['keyCode'] as int? ?? 0,
plainCodePoint: message['plainCodePoint'] as int? ?? 0,
scanCode: message['scanCode'] as int? ?? 0,
metaState: message['metaState'] as int? ?? 0,
eventSource: message['source'] as int? ?? 0,
vendorId: message['vendorId'] as int? ?? 0,
productId: message['productId'] as int? ?? 0,
deviceId: message['deviceId'] as int? ?? 0,
repeatCount: message['repeatCount'] as int? ?? 0,
);
if (message.containsKey('character')) {
character = message['character'] as String?;
}
break;
case 'fuchsia':
final int codePoint = message['codePoint'] as int? ?? 0;
data = RawKeyEventDataFuchsia(
hidUsage: message['hidUsage'] as int? ?? 0,
codePoint: codePoint,
modifiers: message['modifiers'] as int? ?? 0,
);
if (codePoint != 0) {
character = String.fromCharCode(codePoint);
}
break;
case 'macos':
data = RawKeyEventDataMacOs(
characters: message['characters'] as String? ?? '',
charactersIgnoringModifiers: message['charactersIgnoringModifiers'] as String? ?? '',
keyCode: message['keyCode'] as int? ?? 0,
modifiers: message['modifiers'] as int? ?? 0,
specifiedLogicalKey: message['specifiedLogicalKey'] as int?,
);
character = message['characters'] as String?;
break;
case 'ios':
data = RawKeyEventDataIos(
characters: message['characters'] as String? ?? '',
charactersIgnoringModifiers: message['charactersIgnoringModifiers'] as String? ?? '',
keyCode: message['keyCode'] as int? ?? 0,
modifiers: message['modifiers'] as int? ?? 0,
);
break;
case 'linux':
final int unicodeScalarValues = message['unicodeScalarValues'] as int? ?? 0;
data = RawKeyEventDataLinux(
keyHelper: KeyHelper(message['toolkit'] as String? ?? ''),
unicodeScalarValues: unicodeScalarValues,
keyCode: message['keyCode'] as int? ?? 0,
scanCode: message['scanCode'] as int? ?? 0,
modifiers: message['modifiers'] as int? ?? 0,
isDown: message['type'] == 'keydown',
specifiedLogicalKey: message['specifiedLogicalKey'] as int?,
);
if (unicodeScalarValues != 0) {
character = String.fromCharCode(unicodeScalarValues);
}
break;
case 'windows':
final int characterCodePoint = message['characterCodePoint'] as int? ?? 0;
data = RawKeyEventDataWindows(
keyCode: message['keyCode'] as int? ?? 0,
scanCode: message['scanCode'] as int? ?? 0,
characterCodePoint: characterCodePoint,
modifiers: message['modifiers'] as int? ?? 0,
);
if (characterCodePoint != 0) {
character = String.fromCharCode(characterCodePoint);
}
break;
case 'web':
data = dataFromWeb();
break;
default:
/// This exception would only be hit on platforms that haven't yet
/// implemented raw key events, but will only be triggered if the
/// engine for those platforms sends raw key event messages in the
/// first place.
throw FlutterError('Unknown keymap for key events: $keymap');
}
}
final bool repeat = RawKeyboard.instance.physicalKeysPressed.contains(data.physicalKey);
final String type = message['type']! as String;
switch (type) {
case 'keydown':
return RawKeyDownEvent(data: data, character: character, repeat: repeat);
case 'keyup':
return RawKeyUpEvent(data: data);
default:
throw FlutterError('Unknown key event type: $type');
}
}