RawKeyEvent.fromMessage constructor Null safety

RawKeyEvent.fromMessage(
  1. Map<String, Object?> message
)

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');
  }
}