From d87faf921dffabd73bc6d0a35295d717635fe3e4 Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Wed, 13 Jul 2022 15:40:06 -0700 Subject: [PATCH] [Keyboard, iOS] Generate iOS's special key mapping (#106909) --- .../data/ios_key_code_map_mm.tmpl | 5 +++ .../gen_keycodes/data/keyboard_maps.tmpl | 9 ++++++ dev/tools/gen_keycodes/lib/data.dart | 30 +++++++++++++++++ dev/tools/gen_keycodes/lib/ios_code_gen.dart | 11 +++++++ .../lib/keyboard_maps_code_gen.dart | 12 +++++++ .../lib/src/services/keyboard_maps.g.dart | 29 +++++++++++++++++ .../lib/src/services/raw_keyboard_ios.dart | 32 ++----------------- 7 files changed, 99 insertions(+), 29 deletions(-) create mode 100644 dev/tools/gen_keycodes/lib/data.dart diff --git a/dev/tools/gen_keycodes/data/ios_key_code_map_mm.tmpl b/dev/tools/gen_keycodes/data/ios_key_code_map_mm.tmpl index 9cecd01383..da621f4bc3 100644 --- a/dev/tools/gen_keycodes/data/ios_key_code_map_mm.tmpl +++ b/dev/tools/gen_keycodes/data/ios_key_code_map_mm.tmpl @@ -48,4 +48,9 @@ const std::set functionKeyCodes = { @@@IOS_FUNCTION_KEY_SET@@@ }; +API_AVAILABLE(ios(13.4)) +NSDictionary* specialKeyMapping = [[NSDictionary alloc] initWithDictionary:@{ +@@@SPECIAL_KEY_MAPPING@@@ +}]; + @@@SPECIAL_KEY_CONSTANTS@@@ diff --git a/dev/tools/gen_keycodes/data/keyboard_maps.tmpl b/dev/tools/gen_keycodes/data/keyboard_maps.tmpl index 36e4c0226a..7129959562 100644 --- a/dev/tools/gen_keycodes/data/keyboard_maps.tmpl +++ b/dev/tools/gen_keycodes/data/keyboard_maps.tmpl @@ -78,6 +78,15 @@ const Map kIosToPhysicalKey = kIosSpecialLogicalMap = { +@@@IOS_SPECIAL_MAP@@@ +}; + /// A map of iOS key codes which have printable representations, but appear /// on the number pad. Used to provide different key objects for keys like /// KEY_EQUALS and NUMPAD_EQUALS. diff --git a/dev/tools/gen_keycodes/lib/data.dart b/dev/tools/gen_keycodes/lib/data.dart new file mode 100644 index 0000000000..faaf12b0d6 --- /dev/null +++ b/dev/tools/gen_keycodes/lib/data.dart @@ -0,0 +1,30 @@ +// Copyright 2014 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +/// Maps iOS's special key labels to logical key names. +/// +/// See https://developer.apple.com/documentation/uikit/uikeycommand/input_strings_for_special_keys?language=objc +const Map kIosSpecialKeyMapping = { + 'UIKeyInputEscape': 'Escape', + 'UIKeyInputF1': 'F1', + 'UIKeyInputF2': 'F2', + 'UIKeyInputF3': 'F3', + 'UIKeyInputF4': 'F4', + 'UIKeyInputF5': 'F5', + 'UIKeyInputF6': 'F6', + 'UIKeyInputF7': 'F7', + 'UIKeyInputF8': 'F8', + 'UIKeyInputF9': 'F9', + 'UIKeyInputF10': 'F10', + 'UIKeyInputF11': 'F11', + 'UIKeyInputF12': 'F12', + 'UIKeyInputUpArrow': 'ArrowUp', + 'UIKeyInputDownArrow': 'ArrowDown', + 'UIKeyInputLeftArrow': 'ArrowLeft', + 'UIKeyInputRightArrow': 'ArrowRight', + 'UIKeyInputHome': 'Home', + 'UIKeyInputEnd': 'Enter', + 'UIKeyInputPageUp': 'PageUp', + 'UIKeyInputPageDown': 'PageDown', +}; diff --git a/dev/tools/gen_keycodes/lib/ios_code_gen.dart b/dev/tools/gen_keycodes/lib/ios_code_gen.dart index 0d9e800037..58e53c990b 100644 --- a/dev/tools/gen_keycodes/lib/ios_code_gen.dart +++ b/dev/tools/gen_keycodes/lib/ios_code_gen.dart @@ -6,6 +6,7 @@ import 'package:path/path.dart' as path; import 'base_code_gen.dart'; import 'constants.dart'; +import 'data.dart'; import 'logical_key_data.dart'; import 'physical_key_data.dart'; import 'utils.dart'; @@ -105,6 +106,15 @@ class IOSCodeGenerator extends PlatformCodeGenerator { return modifierKeyMap.toString().trimRight(); } + String get _specialKeyMapping { + final OutputLines lines = OutputLines('iOS special key mapping'); + kIosSpecialKeyMapping.forEach((String key, String logicalName) { + final int value = logicalData.entryByName(logicalName).value; + lines.add(value, ' @"$key" : @(${toHex(value)}),'); + }); + return lines.join().trimRight(); + } + /// This generates some keys that needs special attention. String get _specialKeyConstants { final StringBuffer specialKeyConstants = StringBuffer(); @@ -137,6 +147,7 @@ class IOSCodeGenerator extends PlatformCodeGenerator { 'KEYCODE_TO_MODIFIER_FLAG_MAP': _keyToModifierFlagMap, 'MODIFIER_FLAG_TO_KEYCODE_MAP': _modifierFlagToKeyMap, 'SPECIAL_KEY_CONSTANTS': _specialKeyConstants, + 'SPECIAL_KEY_MAPPING': _specialKeyMapping, }; } } diff --git a/dev/tools/gen_keycodes/lib/keyboard_maps_code_gen.dart b/dev/tools/gen_keycodes/lib/keyboard_maps_code_gen.dart index cf4e65c668..c0c793e840 100644 --- a/dev/tools/gen_keycodes/lib/keyboard_maps_code_gen.dart +++ b/dev/tools/gen_keycodes/lib/keyboard_maps_code_gen.dart @@ -7,6 +7,7 @@ import 'dart:io'; import 'package:path/path.dart' as path; import 'base_code_gen.dart'; +import 'data.dart'; import 'logical_key_data.dart'; import 'physical_key_data.dart'; import 'utils.dart'; @@ -246,6 +247,16 @@ class KeyboardMapsCodeGenerator extends BaseCodeGenerator { return lines.sortedJoin().trimRight(); } + /// This generates the map of iOS key label to logical keys for special keys. + String get _iOSSpecialMap { + final OutputLines lines = OutputLines('iOS special key mapping'); + kIosSpecialKeyMapping.forEach((String key, String logicalName) { + final LogicalKeyEntry entry = logicalData.entryByName(logicalName); + lines.add(entry.value, " '$key': LogicalKeyboardKey.${entry.constantName},"); + }); + return lines.join().trimRight(); + } + /// This generates the map of iOS number pad key codes to logical keys. String get _iOSNumpadMap { final OutputLines lines = OutputLines('iOS numpad map'); @@ -353,6 +364,7 @@ class KeyboardMapsCodeGenerator extends BaseCodeGenerator { 'MACOS_FUNCTION_KEY_MAP': _macOSFunctionKeyMap, 'MACOS_KEY_CODE_MAP': _macOSKeyCodeMap, 'IOS_SCAN_CODE_MAP': _iOSScanCodeMap, + 'IOS_SPECIAL_MAP': _iOSSpecialMap, 'IOS_NUMPAD_MAP': _iOSNumpadMap, 'IOS_KEY_CODE_MAP': _iOSKeyCodeMap, 'GLFW_KEY_CODE_MAP': _glfwKeyCodeMap, diff --git a/packages/flutter/lib/src/services/keyboard_maps.g.dart b/packages/flutter/lib/src/services/keyboard_maps.g.dart index 66abf825bf..079230c431 100644 --- a/packages/flutter/lib/src/services/keyboard_maps.g.dart +++ b/packages/flutter/lib/src/services/keyboard_maps.g.dart @@ -1468,6 +1468,35 @@ const Map kIosToPhysicalKey = kIosSpecialLogicalMap = { + 'UIKeyInputEscape': LogicalKeyboardKey.escape, + 'UIKeyInputF1': LogicalKeyboardKey.f1, + 'UIKeyInputF2': LogicalKeyboardKey.f2, + 'UIKeyInputF3': LogicalKeyboardKey.f3, + 'UIKeyInputF4': LogicalKeyboardKey.f4, + 'UIKeyInputF5': LogicalKeyboardKey.f5, + 'UIKeyInputF6': LogicalKeyboardKey.f6, + 'UIKeyInputF7': LogicalKeyboardKey.f7, + 'UIKeyInputF8': LogicalKeyboardKey.f8, + 'UIKeyInputF9': LogicalKeyboardKey.f9, + 'UIKeyInputF10': LogicalKeyboardKey.f10, + 'UIKeyInputF11': LogicalKeyboardKey.f11, + 'UIKeyInputF12': LogicalKeyboardKey.f12, + 'UIKeyInputUpArrow': LogicalKeyboardKey.arrowUp, + 'UIKeyInputDownArrow': LogicalKeyboardKey.arrowDown, + 'UIKeyInputLeftArrow': LogicalKeyboardKey.arrowLeft, + 'UIKeyInputRightArrow': LogicalKeyboardKey.arrowRight, + 'UIKeyInputHome': LogicalKeyboardKey.home, + 'UIKeyInputEnd': LogicalKeyboardKey.enter, + 'UIKeyInputPageUp': LogicalKeyboardKey.pageUp, + 'UIKeyInputPageDown': LogicalKeyboardKey.pageDown, +}; + /// A map of iOS key codes which have printable representations, but appear /// on the number pad. Used to provide different key objects for keys like /// KEY_EQUALS and NUMPAD_EQUALS. diff --git a/packages/flutter/lib/src/services/raw_keyboard_ios.dart b/packages/flutter/lib/src/services/raw_keyboard_ios.dart index f5f952cd49..4ee5f5d226 100644 --- a/packages/flutter/lib/src/services/raw_keyboard_ios.dart +++ b/packages/flutter/lib/src/services/raw_keyboard_ios.dart @@ -12,32 +12,6 @@ export 'package:flutter/foundation.dart' show DiagnosticPropertiesBuilder; export 'keyboard_key.g.dart' show LogicalKeyboardKey, PhysicalKeyboardKey; export 'raw_keyboard.dart' show KeyboardSide, ModifierKey; -/// Maps iOS specific string values of nonvisible keys to logical keys -/// -/// See: https://developer.apple.com/documentation/uikit/uikeycommand/input_strings_for_special_keys?language=objc -const Map _kIosToLogicalMap = { - 'UIKeyInputEscape': LogicalKeyboardKey.escape, - 'UIKeyInputF1': LogicalKeyboardKey.f1, - 'UIKeyInputF2': LogicalKeyboardKey.f2, - 'UIKeyInputF3': LogicalKeyboardKey.f3, - 'UIKeyInputF4': LogicalKeyboardKey.f4, - 'UIKeyInputF5': LogicalKeyboardKey.f5, - 'UIKeyInputF6': LogicalKeyboardKey.f6, - 'UIKeyInputF7': LogicalKeyboardKey.f7, - 'UIKeyInputF8': LogicalKeyboardKey.f8, - 'UIKeyInputF9': LogicalKeyboardKey.f9, - 'UIKeyInputF10': LogicalKeyboardKey.f10, - 'UIKeyInputF11': LogicalKeyboardKey.f11, - 'UIKeyInputF12': LogicalKeyboardKey.f12, - 'UIKeyInputUpArrow': LogicalKeyboardKey.arrowUp, - 'UIKeyInputDownArrow': LogicalKeyboardKey.arrowDown, - 'UIKeyInputLeftArrow': LogicalKeyboardKey.arrowLeft, - 'UIKeyInputRightArrow': LogicalKeyboardKey.arrowRight, - 'UIKeyInputHome': LogicalKeyboardKey.home, - 'UIKeyInputEnd': LogicalKeyboardKey.enter, - 'UIKeyInputPageUp': LogicalKeyboardKey.pageUp, - 'UIKeyInputPageDown': LogicalKeyboardKey.pageDown, -}; /// Platform-specific key event data for iOS. /// /// This object contains information about key events obtained from iOS' @@ -107,9 +81,9 @@ class RawKeyEventDataIos extends RawKeyEventData { } // Look to see if the [keyLabel] is one we know about and have a mapping for. - final LogicalKeyboardKey? newKey = _kIosToLogicalMap[keyLabel]; - if (newKey != null) { - return newKey; + final LogicalKeyboardKey? specialKey = kIosSpecialLogicalMap[keyLabel]; + if (specialKey != null) { + return specialKey; } // Keys that can't be derived with characterIgnoringModifiers will be