未验证 提交 426f774b 编写于 作者: T Tong Mu 提交者: GitHub

Update key mapping to the latest logical key values (#25883)

This PR updates the key mapping tables of every platform according to the change to keycode_gen.
上级 a4fcd2ef
......@@ -1309,6 +1309,7 @@ FILE: ../../../flutter/shell/platform/embedder/fixtures/verifyb143464703.png
FILE: ../../../flutter/shell/platform/embedder/fixtures/verifyb143464703_soft_noxform.png
FILE: ../../../flutter/shell/platform/embedder/platform_view_embedder.cc
FILE: ../../../flutter/shell/platform/embedder/platform_view_embedder.h
FILE: ../../../flutter/shell/platform/embedder/test_utils/key_codes.h
FILE: ../../../flutter/shell/platform/embedder/test_utils/proc_table_replacement.h
FILE: ../../../flutter/shell/platform/embedder/vsync_waiter_embedder.cc
FILE: ../../../flutter/shell/platform/embedder/vsync_waiter_embedder.h
......
......@@ -19,14 +19,17 @@ typedef _ModifierGetter = bool Function(FlutterHtmlKeyboardEvent event);
// Set this flag to true to see all the fired events in the console.
const bool _debugLogKeyEvents = false;
const int _kLogicalAltLeft = 0x0300000102;
const int _kLogicalAltRight = 0x0400000102;
const int _kLogicalControlLeft = 0x0300000105;
const int _kLogicalControlRight = 0x0400000105;
const int _kLogicalShiftLeft = 0x030000010d;
const int _kLogicalShiftRight = 0x040000010d;
const int _kLogicalMetaLeft = 0x0300000109;
const int _kLogicalMetaRight = 0x0400000109;
const int _kLocationLeft = 1;
const int _kLocationRight = 2;
final int _kLogicalAltLeft = kWebLogicalLocationMap['Alt']![_kLocationLeft]!;
final int _kLogicalAltRight = kWebLogicalLocationMap['Alt']![_kLocationRight]!;
final int _kLogicalControlLeft = kWebLogicalLocationMap['Control']![_kLocationLeft]!;
final int _kLogicalControlRight = kWebLogicalLocationMap['Control']![_kLocationRight]!;
final int _kLogicalShiftLeft = kWebLogicalLocationMap['Shift']![_kLocationLeft]!;
final int _kLogicalShiftRight = kWebLogicalLocationMap['Shift']![_kLocationRight]!;
final int _kLogicalMetaLeft = kWebLogicalLocationMap['Meta']![_kLocationLeft]!;
final int _kLogicalMetaRight = kWebLogicalLocationMap['Meta']![_kLocationRight]!;
// Map logical keys for modifier keys to the functions that can get their
// modifier flag out of an event.
final Map<int, _ModifierGetter> _kLogicalKeyToModifierGetter = <int, _ModifierGetter>{
......@@ -62,17 +65,16 @@ const String _kPhysicalCapsLock = 'CapsLock';
const String _kLogicalDead = 'Dead';
const int _kWebKeyIdPlane = 0x00800000000;
const int _kAutogeneratedMask = 0x10000000000;
const int _kWebKeyIdPlane = 0x1700000000;
// Bits in a Flutter logical event to generate the logical key for dead keys.
//
// Logical keys for dead keys are generated by annotating physical keys with
// modifiers (see `_getLogicalCode`).
const int _kDeadKeyCtrl = 0x100000000000;
const int _kDeadKeyShift = 0x200000000000;
const int _kDeadKeyAlt = 0x400000000000;
const int _kDeadKeyMeta = 0x800000000000;
const int _kDeadKeyCtrl = 0x10000000;
const int _kDeadKeyShift = 0x20000000;
const int _kDeadKeyAlt = 0x40000000;
const int _kDeadKeyMeta = 0x80000000;
typedef DispatchKeyData = bool Function(ui.KeyData data);
......@@ -213,7 +215,7 @@ class KeyboardConverter {
Duration get _keydownCancelDuration => onMacOs ? _kKeydownCancelDurationMacOs : _kKeydownCancelDurationNormal;
static int _getPhysicalCode(String code) {
return kWebToPhysicalKey[code] ?? (code.hashCode + _kWebKeyIdPlane + _kAutogeneratedMask);
return kWebToPhysicalKey[code] ?? (code.hashCode + _kWebKeyIdPlane);
}
static int _getModifierMask(FlutterHtmlKeyboardEvent event) {
......@@ -258,11 +260,11 @@ class KeyboardConverter {
//
// Assume they can be told apart with the physical key and the modifiers
// pressed.
return physicalKey + _getModifierMask(event) + _kWebKeyIdPlane + _kAutogeneratedMask;
return physicalKey + _getModifierMask(event) + _kWebKeyIdPlane;
}
static int _otherLogicalKey(String key) {
return kWebToLogicalKey[key] ?? (key.hashCode + _kWebKeyIdPlane + _kAutogeneratedMask);
return kWebToLogicalKey[key] ?? (key.hashCode + _kWebKeyIdPlane);
}
// Map from pressed physical key to corresponding pressed logical key.
......
......@@ -5,7 +5,7 @@
import 'package:quiver/testing/async.dart';
import 'package:test/bootstrap/browser.dart';
import 'package:test/test.dart';
import 'package:ui/src/engine/keyboard_binding.dart';
import 'package:ui/src/engine.dart';
import 'package:ui/ui.dart' as ui;
import 'package:meta/meta.dart' show isTest;
......@@ -13,28 +13,28 @@ const int kLocationLeft = 1;
const int kLocationRight = 2;
const int kLocationNumpad = 3;
const int kPhysicalKeyA = 0x00070004;
const int kPhysicalKeyE = 0x00070008;
const int kPhysicalKeyU = 0x00070018;
const int kPhysicalDigit1 = 0x0007001e;
const int kPhysicalNumpad1 = 0x00070059;
const int kPhysicalShiftLeft = 0x000700e1;
const int kPhysicalShiftRight = 0x000700e5;
const int kPhysicalMetaLeft = 0x000700e3;
const int kPhysicalTab = 0x0007002b;
const int kPhysicalCapsLock = 0x00070039;
const int kPhysicalScrollLock = 0x00070047;
const int kLogicalKeyA = 0x00000000061;
const int kLogicalKeyU = 0x00000000075;
const int kLogicalDigit1 = 0x00000000031;
const int kLogicalNumpad1 = 0x00200000031;
const int kLogicalShiftLeft = 0x030000010d;
const int kLogicalShiftRight = 0x040000010d;
const int kLogicalMetaLeft = 0x0300000109;
const int kLogicalTab = 0x0000000009;
const int kLogicalCapsLock = 0x00000000104;
const int kLogicalScrollLock = 0x0000000010c;
final int kPhysicalKeyA = kWebToPhysicalKey['KeyA']!;
final int kPhysicalKeyE = kWebToPhysicalKey['KeyE']!;
final int kPhysicalKeyU = kWebToPhysicalKey['KeyU']!;
final int kPhysicalDigit1 = kWebToPhysicalKey['Digit1']!;
final int kPhysicalNumpad1 = kWebToPhysicalKey['Numpad1']!;
final int kPhysicalShiftLeft = kWebToPhysicalKey['ShiftLeft']!;
final int kPhysicalShiftRight = kWebToPhysicalKey['ShiftRight']!;
final int kPhysicalMetaLeft = kWebToPhysicalKey['MetaLeft']!;
final int kPhysicalTab = kWebToPhysicalKey['Tab']!;
final int kPhysicalCapsLock = kWebToPhysicalKey['CapsLock']!;
final int kPhysicalScrollLock = kWebToPhysicalKey['ScrollLock']!;
final int kLogicalKeyA = 0x00000000061;
final int kLogicalKeyU = 0x00000000075;
final int kLogicalDigit1 = 0x00000000031;
final int kLogicalNumpad1 = kWebLogicalLocationMap['1']![kLocationNumpad]!;
final int kLogicalShiftLeft = kWebLogicalLocationMap['Shift']![kLocationLeft]!;
final int kLogicalShiftRight = kWebLogicalLocationMap['Shift']![kLocationRight]!;
final int kLogicalMetaLeft = kWebLogicalLocationMap['Meta']![kLocationLeft]!;
final int kLogicalTab = 0x0000000009;
final int kLogicalCapsLock = kWebToLogicalKey['CapsLock']!;
final int kLogicalScrollLock = kWebToLogicalKey['ScrollLock']!;
typedef VoidCallback = void Function();
......@@ -283,9 +283,9 @@ void testMain() {
});
// The absolute values of the following logical keys are not guaranteed.
const int kLogicalAltE = 0x410800070008;
const int kLogicalAltU = 0x410800070018;
const int kLogicalAltShiftE = 0x610800070008;
const int kLogicalAltE = 0x1740070008;
const int kLogicalAltU = 0x1740070018;
const int kLogicalAltShiftE = 0x1760070008;
// The values must be distinguishable.
expect(kLogicalAltE, isNot(equals(kLogicalAltU)));
expect(kLogicalAltE, isNot(equals(kLogicalAltShiftE)));
......
......@@ -258,6 +258,7 @@ shared_library("ios_test_flutter") {
"//flutter/lib/ui:ui",
"//flutter/shell/platform/darwin/common:framework_shared",
"//flutter/shell/platform/embedder:embedder_as_internal_library",
"//flutter/shell/platform/embedder:embedder_test_utils",
"//flutter/third_party/tonic",
"//flutter/third_party/txt",
"//third_party/ocmock:ocmock_shared",
......
......@@ -83,7 +83,7 @@ static uint64_t GetLogicalKeyForModifier(UInt32 keyCode, uint64_t hidCode) {
if (fromKeyCode != keyCodeToLogicalKey.end()) {
return fromKeyCode->second;
}
return KeyOfPlane(hidCode, kHidPlane);
return KeyOfPlane(hidCode, kIosPlane);
}
/**
......@@ -180,19 +180,9 @@ static uint64_t GetLogicalKeyForEvent(FlutterUIPressProxy* press, uint64_t physi
return KeyOfPlane(toLower(codeUnit), kUnicodePlane);
}
// Control keys like "backspace" and movement keys like arrow keys don't have
// a printable representation, but are present on the physical keyboard. Since
// there is no logical keycode map for iOS (iOS uses the keycode to
// reference physical keys), a LogicalKeyboardKey is created with the physical
// key's HID usage and debugName. This avoids duplicating the physical key
// map.
if (physicalKey != 0) {
return KeyOfPlane(physicalKey, kHidPlane);
}
// This is a non-printable key that is unrecognized, so a new code is minted
// with the autogenerated bit set.
return KeyOfPlane(press.key.keyCode, kIOSPlane | kAutogeneratedMask);
return KeyOfPlane(press.key.keyCode, kIosPlane);
}
/**
......
......@@ -12,6 +12,9 @@
#import "flutter/shell/platform/darwin/ios/framework/Source/FlutterFakeKeyEvents.h"
#import "flutter/shell/platform/darwin/ios/framework/Source/KeyCodeMap_Internal.h"
#include "flutter/shell/platform/embedder/embedder.h"
#include "flutter/shell/platform/embedder/test_utils/key_codes.h"
using namespace flutter::testing::keycodes;
FLUTTER_ASSERT_ARC;
......@@ -87,24 +90,8 @@ API_AVAILABLE(ios(13.4))
constexpr UIKeyboardHIDUsage kKeyCodeAltRight = (UIKeyboardHIDUsage)0xe6;
constexpr uint64_t kPhysicalKeyUndefined = 0x00070003;
constexpr uint64_t kPhysicalKeyA = 0x00070004;
constexpr uint64_t kPhysicalKeyW = 0x0007001a;
constexpr uint64_t kPhysicalShiftLeft = 0x000700e1;
constexpr uint64_t kPhysicalShiftRight = 0x000700e5;
constexpr uint64_t kPhysicalCapsLock = 0x00070039;
constexpr uint64_t kPhysicalNumpad1 = 0x00070059;
constexpr uint64_t kPhysicalF1 = 0x0007003a;
constexpr uint64_t kPhysicalAltRight = 0x000700e6;
constexpr uint64_t kLogicalKeyUndefined = 0x0100070003;
constexpr uint64_t kLogicalKeyA = 0x0000000061;
constexpr uint64_t kLogicalKeyW = 0x0000000077;
constexpr uint64_t kLogicalShiftLeft = 0x3000000010d;
constexpr uint64_t kLogicalShiftRight = 0x4000000010d;
constexpr uint64_t kLogicalCapsLock = 0x01000000104;
constexpr uint64_t kLogicalNumpad1 = 0x50000000031;
constexpr uint64_t kLogicalF1 = 0x01000000801;
constexpr uint64_t kLogicalAltRight = 0x40000000102;
constexpr uint64_t kLogicalKeyUndefined = 0x1300000003;
constexpr uint64_t kModifierFlagNone = 0x0;
......
......@@ -12,60 +12,24 @@
// be edited directly.
//
// Edit the template
// flutter/flutter:dev/tools/gen_keycodes/data/ios_key_code_map_cc.tmpl instead.
// flutter/flutter:dev/tools/gen_keycodes/data/ios_key_code_map_mm.tmpl instead.
//
// See flutter/flutter:dev/tools/gen_keycodes/README.md for more information.
/**
* Mask for the 32-bit value portion of the key code.
*
* This is used by platform-specific code to generate Flutter key codes.
*/
const uint64_t kValueMask = 0x000ffffffff;
/**
* Mask for the platform prefix portion of the key code.
*
* This is used by platform-specific code to generate Flutter key codes.
*/
const uint64_t kPlatformMask = 0x0ff00000000;
/**
* The code prefix for keys which have a Unicode representation.
*
* This is used by platform-specific code to generate Flutter key codes.
* The plane value for keys which have a Unicode representation.
*/
const uint64_t kUnicodePlane = 0x00000000000;
/**
* Mask for the auto-generated bit portion of the key code.
*
* This is used by platform-specific code to generate new Flutter key codes for
* keys which are not recognized.
* The plane value for the private keys defined by the iOS embedding.
*/
const uint64_t kAutogeneratedMask = 0x10000000000;
/**
* Mask for the synonym pseudo-keys generated for keys which appear in more than
* one place on the keyboard.
*
* IDs in this range are used to represent keys which appear in multiple places
* on the keyboard, such as the SHIFT, ALT, CTRL, and numeric keypad keys. These
* key codes will never be generated by the key event system, but may be used in
* key maps to represent the union of all the keys of each type in order to
* match them.
*
* To look up the synonyms that are defined, look in the [synonyms] map.
*/
const uint64_t kSynonymMask = 0x20000000000;
/**
* The code prefix for keys which do not have a Unicode representation.
*
* This is used by platform-specific code to generate Flutter key codes using
* HID Usage codes.
*/
const uint64_t kHidPlane = 0x00100000000;
const uint64_t kIosPlane = 0x01300000000;
// Maps iOS-specific key code values representing PhysicalKeyboardKey.
//
......@@ -235,114 +199,104 @@ const std::map<uint32_t, uint64_t> keyCodeToPhysicalKey = {
// Maps iOS-specific virtual key code values to logical keys representing
// LogicalKeyboardKey
const std::map<uint32_t, uint64_t> keyCodeToLogicalKey = {
{0x0000002a, 0x01000000008}, // Backspace
{0x0000002b, 0x01000000009}, // Tab
{0x00000028, 0x0100000000d}, // Enter
{0x00000029, 0x0100000001b}, // Escape
{0x0000004c, 0x0100000007f}, // Delete
{0x00000039, 0x01000000104}, // CapsLock
{0x00000053, 0x0100000010a}, // NumLock
{0x00000051, 0x01000000301}, // ArrowDown
{0x00000050, 0x01000000302}, // ArrowLeft
{0x0000004f, 0x01000000303}, // ArrowRight
{0x00000052, 0x01000000304}, // ArrowUp
{0x0000004d, 0x01000000305}, // End
{0x0000004a, 0x01000000306}, // Home
{0x0000004e, 0x01000000307}, // PageDown
{0x0000004b, 0x01000000308}, // PageUp
{0x00000049, 0x01000000407}, // Insert
{0x00000065, 0x01000000505}, // ContextMenu
{0x0000003a, 0x01000000801}, // F1
{0x0000003b, 0x01000000802}, // F2
{0x0000003c, 0x01000000803}, // F3
{0x0000003d, 0x01000000804}, // F4
{0x0000003e, 0x01000000805}, // F5
{0x0000003f, 0x01000000806}, // F6
{0x00000040, 0x01000000807}, // F7
{0x00000041, 0x01000000808}, // F8
{0x00000042, 0x01000000809}, // F9
{0x00000043, 0x0100000080a}, // F10
{0x00000044, 0x0100000080b}, // F11
{0x00000045, 0x0100000080c}, // F12
{0x00000068, 0x0100000080d}, // F13
{0x00000069, 0x0100000080e}, // F14
{0x0000006a, 0x0100000080f}, // F15
{0x0000006b, 0x01000000810}, // F16
{0x0000006c, 0x01000000811}, // F17
{0x0000006d, 0x01000000812}, // F18
{0x0000006e, 0x01000000813}, // F19
{0x0000006f, 0x01000000814}, // F20
{0x00000081, 0x01000000a0f}, // AudioVolumeDown
{0x00000080, 0x01000000a10}, // AudioVolumeUp
{0x0000007f, 0x01000000a11}, // AudioVolumeMute
{0x00000087, 0x01100070087}, // IntlRo
{0x00000089, 0x01100070089}, // IntlYen
{0x00000090, 0x01100070090}, // Lang1
{0x00000091, 0x01100070091}, // Lang2
{0x00000092, 0x01100070092}, // Lang3
{0x00000093, 0x01100070093}, // Lang4
{0x00000094, 0x01100070094}, // Lang5
{0x000000e2, 0x30000000102}, // AltLeft
{0x000000e0, 0x30000000105}, // ControlLeft
{0x000000e3, 0x30000000109}, // MetaLeft
{0x000000e1, 0x3000000010d}, // ShiftLeft
{0x000000e6, 0x40000000102}, // AltRight
{0x000000e4, 0x40000000105}, // ControlRight
{0x000000e7, 0x40000000109}, // MetaRight
{0x000000e5, 0x4000000010d}, // ShiftRight
{0x00000058, 0x5000000000d}, // NumpadEnter
{0x00000055, 0x5000000002a}, // NumpadMultiply
{0x00000057, 0x5000000002b}, // NumpadAdd
{0x00000085, 0x5000000002c}, // NumpadComma
{0x00000056, 0x5000000002d}, // NumpadSubtract
{0x00000063, 0x5000000002e}, // NumpadDecimal
{0x00000054, 0x5000000002f}, // NumpadDivide
{0x00000062, 0x50000000030}, // Numpad0
{0x00000059, 0x50000000031}, // Numpad1
{0x0000005a, 0x50000000032}, // Numpad2
{0x0000005b, 0x50000000033}, // Numpad3
{0x0000005c, 0x50000000034}, // Numpad4
{0x0000005d, 0x50000000035}, // Numpad5
{0x0000005e, 0x50000000036}, // Numpad6
{0x0000005f, 0x50000000037}, // Numpad7
{0x00000060, 0x50000000038}, // Numpad8
{0x00000061, 0x50000000039}, // Numpad9
{0x00000067, 0x5000000003d}, // NumpadEqual
{0x00000028, 0x0010000000d}, // Enter
{0x00000029, 0x0010000001b}, // Escape
{0x0000002a, 0x00100000008}, // Backspace
{0x0000002b, 0x00100000009}, // Tab
{0x00000039, 0x00100000104}, // CapsLock
{0x0000003a, 0x00100000801}, // F1
{0x0000003b, 0x00100000802}, // F2
{0x0000003c, 0x00100000803}, // F3
{0x0000003d, 0x00100000804}, // F4
{0x0000003e, 0x00100000805}, // F5
{0x0000003f, 0x00100000806}, // F6
{0x00000040, 0x00100000807}, // F7
{0x00000041, 0x00100000808}, // F8
{0x00000042, 0x00100000809}, // F9
{0x00000043, 0x0010000080a}, // F10
{0x00000044, 0x0010000080b}, // F11
{0x00000045, 0x0010000080c}, // F12
{0x00000049, 0x00100000407}, // Insert
{0x0000004a, 0x00100000306}, // Home
{0x0000004b, 0x00100000308}, // PageUp
{0x0000004c, 0x0010000007f}, // Delete
{0x0000004d, 0x00100000305}, // End
{0x0000004e, 0x00100000307}, // PageDown
{0x0000004f, 0x00100000303}, // ArrowRight
{0x00000050, 0x00100000302}, // ArrowLeft
{0x00000051, 0x00100000301}, // ArrowDown
{0x00000052, 0x00100000304}, // ArrowUp
{0x00000053, 0x0010000010a}, // NumLock
{0x00000054, 0x0020000022f}, // NumpadDivide
{0x00000055, 0x0020000022a}, // NumpadMultiply
{0x00000056, 0x0020000022d}, // NumpadSubtract
{0x00000057, 0x0020000022b}, // NumpadAdd
{0x00000058, 0x0020000020d}, // NumpadEnter
{0x00000059, 0x00200000231}, // Numpad1
{0x0000005a, 0x00200000232}, // Numpad2
{0x0000005b, 0x00200000233}, // Numpad3
{0x0000005c, 0x00200000234}, // Numpad4
{0x0000005d, 0x00200000235}, // Numpad5
{0x0000005e, 0x00200000236}, // Numpad6
{0x0000005f, 0x00200000237}, // Numpad7
{0x00000060, 0x00200000238}, // Numpad8
{0x00000061, 0x00200000239}, // Numpad9
{0x00000062, 0x00200000230}, // Numpad0
{0x00000063, 0x0020000022e}, // NumpadDecimal
{0x00000065, 0x00100000505}, // ContextMenu
{0x00000067, 0x0020000023d}, // NumpadEqual
{0x00000068, 0x0010000080d}, // F13
{0x00000069, 0x0010000080e}, // F14
{0x0000006a, 0x0010000080f}, // F15
{0x0000006b, 0x00100000810}, // F16
{0x0000006c, 0x00100000811}, // F17
{0x0000006d, 0x00100000812}, // F18
{0x0000006e, 0x00100000813}, // F19
{0x0000006f, 0x00100000814}, // F20
{0x0000007f, 0x00100000a11}, // AudioVolumeMute
{0x00000080, 0x00100000a10}, // AudioVolumeUp
{0x00000081, 0x00100000a0f}, // AudioVolumeDown
{0x00000085, 0x0020000022c}, // NumpadComma
{0x00000087, 0x00200000021}, // IntlRo
{0x00000089, 0x00200000022}, // IntlYen
{0x00000090, 0x00200000010}, // Lang1
{0x00000091, 0x00200000011}, // Lang2
{0x00000092, 0x00200000012}, // Lang3
{0x00000093, 0x00200000013}, // Lang4
{0x00000094, 0x00200000014}, // Lang5
{0x000000e0, 0x00200000100}, // ControlLeft
{0x000000e1, 0x00200000102}, // ShiftLeft
{0x000000e2, 0x00200000104}, // AltLeft
{0x000000e3, 0x00200000106}, // MetaLeft
{0x000000e4, 0x00200000101}, // ControlRight
{0x000000e5, 0x00200000103}, // ShiftRight
{0x000000e6, 0x00200000105}, // AltRight
{0x000000e7, 0x00200000107}, // MetaRight
};
// Maps iOS-specific virtual key codes to an equivalent modifier flag enum
// value.
const std::map<uint32_t, ModifierFlag> keyCodeToModifierFlag = {
{0x000000e1, kModifierFlagShiftLeft}, {0x000000e5, kModifierFlagShiftRight},
{0x000000e0, kModifierFlagControlLeft}, {0x000000e4, kModifierFlagControlRight},
{0x000000e2, kModifierFlagAltLeft}, {0x000000e6, kModifierFlagAltRight},
{0x000000e3, kModifierFlagMetaLeft}, {0x000000e7, kModifierFlagMetaRight},
{0x000000e1, kModifierFlagShiftLeft}, // ShiftLeft
{0x000000e5, kModifierFlagShiftRight}, // ShiftRight
{0x000000e0, kModifierFlagControlLeft}, // ControlLeft
{0x000000e4, kModifierFlagControlRight}, // ControlRight
{0x000000e2, kModifierFlagAltLeft}, // AltLeft
{0x000000e6, kModifierFlagAltRight}, // AltRight
{0x000000e3, kModifierFlagMetaLeft}, // MetaLeft
{0x000000e7, kModifierFlagMetaRight}, // MetaRight
};
// Maps modifier flag enum values to an iOS-specific virtual key code.
const std::map<ModifierFlag, uint32_t> modifierFlagToKeyCode = {
{kModifierFlagShiftLeft, 0x000000e1}, {kModifierFlagShiftRight, 0x000000e5},
{kModifierFlagControlLeft, 0x000000e0}, {kModifierFlagControlRight, 0x000000e4},
{kModifierFlagAltLeft, 0x000000e2}, {kModifierFlagAltRight, 0x000000e6},
{kModifierFlagMetaLeft, 0x000000e3}, {kModifierFlagMetaRight, 0x000000e7},
};
const std::map<ModifierFlag, ModifierFlag> sidedModifierToAny = {
{kModifierFlagShiftLeft, kModifierFlagShiftAny},
{kModifierFlagShiftRight, kModifierFlagShiftAny},
{kModifierFlagControlLeft, kModifierFlagControlAny},
{kModifierFlagControlRight, kModifierFlagControlAny},
{kModifierFlagAltLeft, kModifierFlagAltAny},
{kModifierFlagAltRight, kModifierFlagAltAny},
{kModifierFlagMetaLeft, kModifierFlagMetaAny},
{kModifierFlagMetaRight, kModifierFlagMetaAny},
};
const std::map<ModifierFlag, ModifierFlag> anyModifierToLeft = {
{kModifierFlagShiftAny, kModifierFlagShiftLeft},
{kModifierFlagControlAny, kModifierFlagControlLeft},
{kModifierFlagAltAny, kModifierFlagAltLeft},
{kModifierFlagMetaAny, kModifierFlagMetaLeft},
{kModifierFlagShiftLeft, 0x000000e1}, // ShiftLeft
{kModifierFlagShiftRight, 0x000000e5}, // ShiftRight
{kModifierFlagControlLeft, 0x000000e0}, // ControlLeft
{kModifierFlagControlRight, 0x000000e4}, // ControlRight
{kModifierFlagAltLeft, 0x000000e2}, // AltLeft
{kModifierFlagAltRight, 0x000000e6}, // AltRight
{kModifierFlagMetaLeft, 0x000000e3}, // MetaLeft
{kModifierFlagMetaRight, 0x000000e7}, // MetaRight
};
// A set of virtual key codes mapping to function keys, so that may be
......@@ -375,4 +329,4 @@ const std::set<uint32_t> functionKeyCodes = {
};
const uint64_t kCapsLockPhysicalKey = 0x00070039;
const uint64_t kCapsLockLogicalKey = 0x1000000104;
const uint64_t kCapsLockLogicalKey = 0x100000104;
......@@ -28,17 +28,8 @@ extern const std::map<uint32_t, uint64_t> keyCodeToLogicalKey;
// Several mask constants. See KeyCodeMap.mm for their descriptions.
extern const uint64_t kValueMask;
extern const uint64_t kPlatformMask;
extern const uint64_t kUnicodePlane;
extern const uint64_t kHidPlane;
extern const uint64_t kAutogeneratedMask;
extern const uint64_t kSynonymMask;
/**
* The code prefix for keys from iOS which do not have a Unicode
* representation.
*/
static const uint64_t kIOSPlane = 0x00400000000;
extern const uint64_t kIosPlane;
/**
* The physical key for CapsLock, which needs special handling.
......
......@@ -67,8 +67,9 @@ static uint64_t KeyOfPlane(uint64_t baseKey, uint64_t plane) {
*/
static uint64_t GetPhysicalKeyForKeyCode(unsigned short keyCode) {
NSNumber* physicalKey = [keyCodeToPhysicalKey objectForKey:@(keyCode)];
if (physicalKey == nil)
return 0;
if (physicalKey == nil) {
return KeyOfPlane(keyCode, kMacosPlane);
}
return physicalKey.unsignedLongLongValue;
}
......@@ -79,7 +80,7 @@ static uint64_t GetLogicalKeyForModifier(unsigned short keyCode, uint64_t hidCod
NSNumber* fromKeyCode = [keyCodeToLogicalKey objectForKey:@(keyCode)];
if (fromKeyCode != nil)
return fromKeyCode.unsignedLongLongValue;
return KeyOfPlane(hidCode, kHidPlane);
return KeyOfPlane(hidCode, kMacosPlane);
}
/**
......@@ -88,13 +89,27 @@ static uint64_t GetLogicalKeyForModifier(unsigned short keyCode, uint64_t hidCod
*
* Independent of locale.
*/
static uint64_t toLower(uint64_t ch) {
const uint64_t lowerA = 0x61;
const uint64_t upperA = 0x41;
const uint64_t upperZ = 0x5a;
if (ch >= upperA && ch <= upperZ)
return ch + (lowerA - upperA);
return ch;
static uint64_t toLower(uint64_t n) {
constexpr uint64_t lowerA = 0x61;
constexpr uint64_t upperA = 0x41;
constexpr uint64_t upperZ = 0x5a;
constexpr uint64_t lowerAGrave = 0xe0;
constexpr uint64_t upperAGrave = 0xc0;
constexpr uint64_t upperThorn = 0xde;
constexpr uint64_t division = 0xf7;
// ASCII range.
if (n >= upperA && n <= upperZ) {
return n - upperA + lowerA;
}
// EASCII range.
if (n >= upperAGrave && n <= upperThorn && n != division) {
return n - upperAGrave + lowerAGrave;
}
return n;
}
/**
......@@ -130,19 +145,9 @@ static uint64_t GetLogicalKeyForEvent(NSEvent* event, uint64_t physicalKey) {
return KeyOfPlane(toLower(codeUnit), kUnicodePlane);
}
// Control keys like "backspace" and movement keys like arrow keys don't have
// a printable representation, but are present on the physical keyboard. Since
// there is no logical keycode map for macOS (macOS uses the keycode to
// reference physical keys), a LogicalKeyboardKey is created with the physical
// key's HID usage and debugName. This avoids duplicating the physical key
// map.
if (physicalKey != 0) {
return KeyOfPlane(physicalKey, kHidPlane);
}
// This is a non-printable key that is unrecognized, so a new code is minted
// with the autogenerated bit set.
return KeyOfPlane(event.keyCode, kMacosPlane | kAutogeneratedMask);
// to the macOS plane.
return KeyOfPlane(event.keyCode, kMacosPlane);
}
/**
......
......@@ -6,6 +6,7 @@
#import <OCMock/OCMock.h>
#import "flutter/shell/platform/darwin/macos/framework/Source/FlutterEmbedderKeyResponder.h"
#include "flutter/shell/platform/embedder/test_utils/key_codes.h"
#import "flutter/testing/testing.h"
#include "third_party/googletest/googletest/include/gtest/gtest.h"
......@@ -68,23 +69,7 @@ constexpr uint64_t kKeyCodeNumpad1 = 0x53;
constexpr uint64_t kKeyCodeF1 = 0x7a;
constexpr uint64_t kKeyCodeAltRight = 0x3d;
constexpr uint64_t kPhysicalKeyA = 0x00070004;
constexpr uint64_t kPhysicalKeyW = 0x0007001a;
constexpr uint64_t kPhysicalShiftLeft = 0x000700e1;
constexpr uint64_t kPhysicalShiftRight = 0x000700e5;
constexpr uint64_t kPhysicalCapsLock = 0x00070039;
constexpr uint64_t kPhysicalNumpad1 = 0x00070059;
constexpr uint64_t kPhysicalF1 = 0x0007003a;
constexpr uint64_t kPhysicalAltRight = 0x000700e6;
constexpr uint64_t kLogicalKeyA = 0x00000061;
constexpr uint64_t kLogicalKeyW = 0x00000077;
constexpr uint64_t kLogicalShiftLeft = 0x0030000010d;
constexpr uint64_t kLogicalShiftRight = 0x0040000010d;
constexpr uint64_t kLogicalCapsLock = 0x00000000104;
constexpr uint64_t kLogicalNumpad1 = 0x00200000031;
constexpr uint64_t kLogicalF1 = 0x00000000801;
constexpr uint64_t kLogicalAltRight = 0x00400000102;
using namespace ::flutter::testing::keycodes;
typedef void (^ResponseCallback)(bool handled);
......
......@@ -7,256 +7,215 @@
#include "./KeyCodeMap_Internal.h"
// DO NOT EDIT -- DO NOT EDIT -- DO NOT EDIT
// This file is generated by flutter/flutter@dev/tools/gen_keycodes/bin/gen_keycodes.dart and
// should not be edited directly.
// This file is generated by
// flutter/flutter:dev/tools/gen_keycodes/bin/gen_keycodes.dart and should not
// be edited directly.
//
// Edit the template dev/tools/gen_keycodes/data/keyboard_map_macos_cc.tmpl instead.
// See dev/tools/gen_keycodes/README.md for more information.
/**
* Mask for the 32-bit value portion of the key code.
*
* This is used by platform-specific code to generate Flutter key codes.
*/
const uint64_t kValueMask = 0x000FFFFFFFF;
/**
* Mask for the platform prefix portion of the key code.
*
* This is used by platform-specific code to generate Flutter key codes.
*/
const uint64_t kPlatformMask = 0x0FF00000000;
// Edit the template
// flutter/flutter:dev/tools/gen_keycodes/data/keyboard_map_macos_cc.tmpl
// instead.
//
// See flutter/flutter:dev/tools/gen_keycodes/README.md for more information.
/**
* The code prefix for keys which have a Unicode representation.
*
* This is used by platform-specific code to generate Flutter key codes.
*/
const uint64_t kValueMask = 0x000ffffffff;
const uint64_t kUnicodePlane = 0x00000000000;
/**
* Mask for the auto-generated bit portion of the key code.
*
* This is used by platform-specific code to generate new Flutter key codes for
* keys which are not recognized.
*/
const uint64_t kAutogeneratedMask = 0x10000000000;
/**
* Mask for the synonym pseudo-keys generated for keys which appear in more than
* one place on the keyboard.
*
* IDs in this range are used to represent keys which appear in multiple places
* on the keyboard, such as the SHIFT, ALT, CTRL, and numeric keypad keys. These
* key codes will never be generated by the key event system, but may be used in
* key maps to represent the union of all the keys of each type in order to
* match them.
*
* To look up the synonyms that are defined, look in the [synonyms] map.
*/
const uint64_t kSynonymMask = 0x20000000000;
/**
* The code prefix for keys which do not have a Unicode representation.
*
* This is used by platform-specific code to generate Flutter key codes using
* HID Usage codes.
*/
const uint64_t kHidPlane = 0x00100000000;
const uint64_t kMacosPlane = 0x01400000000;
const NSDictionary* keyCodeToPhysicalKey = @{
@0x00000000 : @0x00070004, // keyA
@0x0000000b : @0x00070005, // keyB
@0x00000008 : @0x00070006, // keyC
@0x00000001 : @0x00070016, // keyS
@0x00000002 : @0x00070007, // keyD
@0x0000000e : @0x00070008, // keyE
@0x00000003 : @0x00070009, // keyF
@0x00000005 : @0x0007000a, // keyG
@0x00000004 : @0x0007000b, // keyH
@0x00000022 : @0x0007000c, // keyI
@0x00000026 : @0x0007000d, // keyJ
@0x00000028 : @0x0007000e, // keyK
@0x00000025 : @0x0007000f, // keyL
@0x0000002e : @0x00070010, // keyM
@0x0000002d : @0x00070011, // keyN
@0x0000001f : @0x00070012, // keyO
@0x00000023 : @0x00070013, // keyP
@0x0000000c : @0x00070014, // keyQ
@0x0000000f : @0x00070015, // keyR
@0x00000001 : @0x00070016, // keyS
@0x00000011 : @0x00070017, // keyT
@0x00000020 : @0x00070018, // keyU
@0x00000005 : @0x0007000a, // keyG
@0x00000006 : @0x0007001d, // keyZ
@0x00000007 : @0x0007001b, // keyX
@0x00000008 : @0x00070006, // keyC
@0x00000009 : @0x00070019, // keyV
@0x0000000a : @0x00070064, // intlBackslash
@0x0000000b : @0x00070005, // keyB
@0x0000000c : @0x00070014, // keyQ
@0x0000000d : @0x0007001a, // keyW
@0x00000007 : @0x0007001b, // keyX
@0x0000000e : @0x00070008, // keyE
@0x0000000f : @0x00070015, // keyR
@0x00000010 : @0x0007001c, // keyY
@0x00000006 : @0x0007001d, // keyZ
@0x00000011 : @0x00070017, // keyT
@0x00000012 : @0x0007001e, // digit1
@0x00000013 : @0x0007001f, // digit2
@0x00000014 : @0x00070020, // digit3
@0x00000015 : @0x00070021, // digit4
@0x00000017 : @0x00070022, // digit5
@0x00000016 : @0x00070023, // digit6
@0x00000017 : @0x00070022, // digit5
@0x00000018 : @0x0007002e, // equal
@0x00000019 : @0x00070026, // digit9
@0x0000001a : @0x00070024, // digit7
@0x0000001b : @0x0007002d, // minus
@0x0000001c : @0x00070025, // digit8
@0x00000019 : @0x00070026, // digit9
@0x0000001d : @0x00070027, // digit0
@0x00000024 : @0x00070028, // enter
@0x00000035 : @0x00070029, // escape
@0x00000033 : @0x0007002a, // backspace
@0x00000030 : @0x0007002b, // tab
@0x00000031 : @0x0007002c, // space
@0x0000001b : @0x0007002d, // minus
@0x00000018 : @0x0007002e, // equal
@0x00000021 : @0x0007002f, // bracketLeft
@0x0000001e : @0x00070030, // bracketRight
@0x0000002a : @0x00070031, // backslash
@0x00000029 : @0x00070033, // semicolon
@0x0000001f : @0x00070012, // keyO
@0x00000020 : @0x00070018, // keyU
@0x00000021 : @0x0007002f, // bracketLeft
@0x00000022 : @0x0007000c, // keyI
@0x00000023 : @0x00070013, // keyP
@0x00000024 : @0x00070028, // enter
@0x00000025 : @0x0007000f, // keyL
@0x00000026 : @0x0007000d, // keyJ
@0x00000027 : @0x00070034, // quote
@0x00000032 : @0x00070035, // backquote
@0x00000028 : @0x0007000e, // keyK
@0x00000029 : @0x00070033, // semicolon
@0x0000002a : @0x00070031, // backslash
@0x0000002b : @0x00070036, // comma
@0x0000002f : @0x00070037, // period
@0x0000002c : @0x00070038, // slash
@0x0000002d : @0x00070011, // keyN
@0x0000002e : @0x00070010, // keyM
@0x0000002f : @0x00070037, // period
@0x00000030 : @0x0007002b, // tab
@0x00000031 : @0x0007002c, // space
@0x00000032 : @0x00070035, // backquote
@0x00000033 : @0x0007002a, // backspace
@0x00000035 : @0x00070029, // escape
@0x00000036 : @0x000700e7, // metaRight
@0x00000037 : @0x000700e3, // metaLeft
@0x00000038 : @0x000700e1, // shiftLeft
@0x00000039 : @0x00070039, // capsLock
@0x0000007a : @0x0007003a, // f1
@0x00000078 : @0x0007003b, // f2
@0x00000063 : @0x0007003c, // f3
@0x00000076 : @0x0007003d, // f4
@0x0000003a : @0x000700e2, // altLeft
@0x0000003b : @0x000700e0, // controlLeft
@0x0000003c : @0x000700e5, // shiftRight
@0x0000003d : @0x000700e6, // altRight
@0x0000003e : @0x000700e4, // controlRight
@0x0000003f : @0x00000012, // fn
@0x00000040 : @0x0007006c, // f17
@0x00000041 : @0x00070063, // numpadDecimal
@0x00000043 : @0x00070055, // numpadMultiply
@0x00000045 : @0x00070057, // numpadAdd
@0x00000047 : @0x00070053, // numLock
@0x00000048 : @0x00070080, // audioVolumeUp
@0x00000049 : @0x00070081, // audioVolumeDown
@0x0000004a : @0x0007007f, // audioVolumeMute
@0x0000004b : @0x00070054, // numpadDivide
@0x0000004c : @0x00070058, // numpadEnter
@0x0000004e : @0x00070056, // numpadSubtract
@0x0000004f : @0x0007006d, // f18
@0x00000050 : @0x0007006e, // f19
@0x00000051 : @0x00070067, // numpadEqual
@0x00000052 : @0x00070062, // numpad0
@0x00000053 : @0x00070059, // numpad1
@0x00000054 : @0x0007005a, // numpad2
@0x00000055 : @0x0007005b, // numpad3
@0x00000056 : @0x0007005c, // numpad4
@0x00000057 : @0x0007005d, // numpad5
@0x00000058 : @0x0007005e, // numpad6
@0x00000059 : @0x0007005f, // numpad7
@0x0000005a : @0x0007006f, // f20
@0x0000005b : @0x00070060, // numpad8
@0x0000005c : @0x00070061, // numpad9
@0x0000005d : @0x00070089, // intlYen
@0x0000005e : @0x00070087, // intlRo
@0x0000005f : @0x00070085, // numpadComma
@0x00000060 : @0x0007003e, // f5
@0x00000061 : @0x0007003f, // f6
@0x00000062 : @0x00070040, // f7
@0x00000063 : @0x0007003c, // f3
@0x00000064 : @0x00070041, // f8
@0x00000065 : @0x00070042, // f9
@0x0000006d : @0x00070043, // f10
@0x00000066 : @0x00070091, // lang2
@0x00000067 : @0x00070044, // f11
@0x00000068 : @0x00070090, // lang1
@0x00000069 : @0x00070068, // f13
@0x0000006a : @0x0007006b, // f16
@0x0000006b : @0x00070069, // f14
@0x0000006d : @0x00070043, // f10
@0x0000006e : @0x00070065, // contextMenu
@0x0000006f : @0x00070045, // f12
@0x00000071 : @0x0007006a, // f15
@0x00000072 : @0x00070049, // insert
@0x00000073 : @0x0007004a, // home
@0x00000074 : @0x0007004b, // pageUp
@0x00000075 : @0x0007004c, // delete
@0x00000076 : @0x0007003d, // f4
@0x00000077 : @0x0007004d, // end
@0x00000078 : @0x0007003b, // f2
@0x00000079 : @0x0007004e, // pageDown
@0x0000007c : @0x0007004f, // arrowRight
@0x0000007a : @0x0007003a, // f1
@0x0000007b : @0x00070050, // arrowLeft
@0x0000007c : @0x0007004f, // arrowRight
@0x0000007d : @0x00070051, // arrowDown
@0x0000007e : @0x00070052, // arrowUp
@0x00000047 : @0x00070053, // numLock
@0x0000004b : @0x00070054, // numpadDivide
@0x00000043 : @0x00070055, // numpadMultiply
@0x0000004e : @0x00070056, // numpadSubtract
@0x00000045 : @0x00070057, // numpadAdd
@0x0000004c : @0x00070058, // numpadEnter
@0x00000053 : @0x00070059, // numpad1
@0x00000054 : @0x0007005a, // numpad2
@0x00000055 : @0x0007005b, // numpad3
@0x00000056 : @0x0007005c, // numpad4
@0x00000057 : @0x0007005d, // numpad5
@0x00000058 : @0x0007005e, // numpad6
@0x00000059 : @0x0007005f, // numpad7
@0x0000005b : @0x00070060, // numpad8
@0x0000005c : @0x00070061, // numpad9
@0x00000052 : @0x00070062, // numpad0
@0x00000041 : @0x00070063, // numpadDecimal
@0x0000000a : @0x00070064, // intlBackslash
@0x0000006e : @0x00070065, // contextMenu
@0x00000051 : @0x00070067, // numpadEqual
@0x00000069 : @0x00070068, // f13
@0x0000006b : @0x00070069, // f14
@0x00000071 : @0x0007006a, // f15
@0x0000006a : @0x0007006b, // f16
@0x00000040 : @0x0007006c, // f17
@0x0000004f : @0x0007006d, // f18
@0x00000050 : @0x0007006e, // f19
@0x0000005a : @0x0007006f, // f20
@0x0000004a : @0x0007007f, // audioVolumeMute
@0x00000048 : @0x00070080, // audioVolumeUp
@0x00000049 : @0x00070081, // audioVolumeDown
@0x0000005f : @0x00070085, // numpadComma
@0x0000005e : @0x00070087, // intlRo
@0x0000005d : @0x00070089, // intlYen
@0x00000068 : @0x00070090, // lang1
@0x00000066 : @0x00070091, // lang2
@0x0000003b : @0x000700e0, // controlLeft
@0x00000038 : @0x000700e1, // shiftLeft
@0x0000003a : @0x000700e2, // altLeft
@0x00000037 : @0x000700e3, // metaLeft
@0x0000003e : @0x000700e4, // controlRight
@0x0000003c : @0x000700e5, // shiftRight
@0x0000003d : @0x000700e6, // altRight
@0x00000036 : @0x000700e7, // metaRight
@0x0000003f : @0x00000012, // fn
};
const NSDictionary* keyCodeToLogicalKey = @{
@0x00000033 : @0x0000000008, // Backspace
@0x00000035 : @0x000000001b, // Escape
@0x00000075 : @0x000000007f, // Delete
@0x00000039 : @0x0000000104, // CapsLock
@0x0000003f : @0x0000000106, // Fn
@0x00000047 : @0x000000010a, // NumLock
@0x0000007d : @0x0000000301, // ArrowDown
@0x0000007b : @0x0000000302, // ArrowLeft
@0x0000007c : @0x0000000303, // ArrowRight
@0x0000007e : @0x0000000304, // ArrowUp
@0x00000077 : @0x0000000305, // End
@0x00000073 : @0x0000000306, // Home
@0x00000079 : @0x0000000307, // PageDown
@0x00000074 : @0x0000000308, // PageUp
@0x00000072 : @0x0000000407, // Insert
@0x0000006e : @0x0000000505, // ContextMenu
@0x0000007a : @0x0000000801, // F1
@0x00000078 : @0x0000000802, // F2
@0x00000063 : @0x0000000803, // F3
@0x00000076 : @0x0000000804, // F4
@0x00000060 : @0x0000000805, // F5
@0x00000061 : @0x0000000806, // F6
@0x00000062 : @0x0000000807, // F7
@0x00000064 : @0x0000000808, // F8
@0x00000065 : @0x0000000809, // F9
@0x0000006d : @0x000000080a, // F10
@0x00000067 : @0x000000080b, // F11
@0x0000006f : @0x000000080c, // F12
@0x00000069 : @0x000000080d, // F13
@0x0000006b : @0x000000080e, // F14
@0x00000071 : @0x000000080f, // F15
@0x0000006a : @0x0000000810, // F16
@0x00000040 : @0x0000000811, // F17
@0x0000004f : @0x0000000812, // F18
@0x00000050 : @0x0000000813, // F19
@0x0000005a : @0x0000000814, // F20
@0x00000049 : @0x0000000a0f, // AudioVolumeDown
@0x00000048 : @0x0000000a10, // AudioVolumeUp
@0x0000004a : @0x0000000a11, // AudioVolumeMute
@0x0000005e : @0x0100070087, // IntlRo
@0x0000005d : @0x0100070089, // IntlYen
@0x00000068 : @0x0100070090, // Lang1
@0x00000066 : @0x0100070091, // Lang2
@0x0000004c : @0x020000000d, // NumpadEnter
@0x00000043 : @0x020000002a, // NumpadMultiply
@0x00000045 : @0x020000002b, // NumpadAdd
@0x0000005f : @0x020000002c, // NumpadComma
@0x0000004e : @0x020000002d, // NumpadSubtract
@0x00000041 : @0x020000002e, // NumpadDecimal
@0x0000004b : @0x020000002f, // NumpadDivide
@0x00000052 : @0x0200000030, // Numpad0
@0x00000053 : @0x0200000031, // Numpad1
@0x00000054 : @0x0200000032, // Numpad2
@0x00000055 : @0x0200000033, // Numpad3
@0x00000056 : @0x0200000034, // Numpad4
@0x00000057 : @0x0200000035, // Numpad5
@0x00000058 : @0x0200000036, // Numpad6
@0x00000059 : @0x0200000037, // Numpad7
@0x0000005b : @0x0200000038, // Numpad8
@0x0000005c : @0x0200000039, // Numpad9
@0x00000051 : @0x020000003d, // NumpadEqual
@0x0000003a : @0x0300000102, // AltLeft
@0x0000003b : @0x0300000105, // ControlLeft
@0x00000037 : @0x0300000109, // MetaLeft
@0x00000038 : @0x030000010d, // ShiftLeft
@0x0000003d : @0x0400000102, // AltRight
@0x0000003e : @0x0400000105, // ControlRight
@0x00000036 : @0x0400000109, // MetaRight
@0x0000003c : @0x040000010d, // ShiftRight
@0x00000024 : @0x0010000000d, // Enter -> enter
@0x00000030 : @0x00100000009, // Tab -> tab
@0x00000033 : @0x00100000008, // Backspace -> backspace
@0x00000035 : @0x0010000001b, // Escape -> escape
@0x00000036 : @0x00200000107, // MetaRight -> metaRight
@0x00000037 : @0x00200000106, // MetaLeft -> metaLeft
@0x00000038 : @0x00200000102, // ShiftLeft -> shiftLeft
@0x00000039 : @0x00100000104, // CapsLock -> capsLock
@0x0000003a : @0x00200000104, // AltLeft -> altLeft
@0x0000003b : @0x00200000100, // ControlLeft -> controlLeft
@0x0000003c : @0x00200000103, // ShiftRight -> shiftRight
@0x0000003d : @0x00200000105, // AltRight -> altRight
@0x0000003e : @0x00200000101, // ControlRight -> controlRight
@0x0000003f : @0x00100000106, // Fn -> fn
@0x00000040 : @0x00100000811, // F17 -> f17
@0x00000041 : @0x0020000022e, // NumpadDecimal -> numpadDecimal
@0x00000043 : @0x0020000022a, // NumpadMultiply -> numpadMultiply
@0x00000045 : @0x0020000022b, // NumpadAdd -> numpadAdd
@0x00000047 : @0x0010000010a, // NumLock -> numLock
@0x00000048 : @0x00100000a10, // AudioVolumeUp -> audioVolumeUp
@0x00000049 : @0x00100000a0f, // AudioVolumeDown -> audioVolumeDown
@0x0000004a : @0x00100000a11, // AudioVolumeMute -> audioVolumeMute
@0x0000004b : @0x0020000022f, // NumpadDivide -> numpadDivide
@0x0000004c : @0x0020000020d, // NumpadEnter -> numpadEnter
@0x0000004e : @0x0020000022d, // NumpadSubtract -> numpadSubtract
@0x0000004f : @0x00100000812, // F18 -> f18
@0x00000050 : @0x00100000813, // F19 -> f19
@0x00000051 : @0x0020000023d, // NumpadEqual -> numpadEqual
@0x00000052 : @0x00200000230, // Numpad0 -> numpad0
@0x00000053 : @0x00200000231, // Numpad1 -> numpad1
@0x00000054 : @0x00200000232, // Numpad2 -> numpad2
@0x00000055 : @0x00200000233, // Numpad3 -> numpad3
@0x00000056 : @0x00200000234, // Numpad4 -> numpad4
@0x00000057 : @0x00200000235, // Numpad5 -> numpad5
@0x00000058 : @0x00200000236, // Numpad6 -> numpad6
@0x00000059 : @0x00200000237, // Numpad7 -> numpad7
@0x0000005a : @0x00100000814, // F20 -> f20
@0x0000005b : @0x00200000238, // Numpad8 -> numpad8
@0x0000005c : @0x00200000239, // Numpad9 -> numpad9
@0x0000005d : @0x00200000022, // IntlYen -> intlYen
@0x0000005e : @0x00200000021, // IntlRo -> intlRo
@0x0000005f : @0x0020000022c, // NumpadComma -> numpadComma
@0x00000060 : @0x00100000805, // F5 -> f5
@0x00000061 : @0x00100000806, // F6 -> f6
@0x00000062 : @0x00100000807, // F7 -> f7
@0x00000063 : @0x00100000803, // F3 -> f3
@0x00000064 : @0x00100000808, // F8 -> f8
@0x00000065 : @0x00100000809, // F9 -> f9
@0x00000066 : @0x00200000011, // Lang2 -> lang2
@0x00000067 : @0x0010000080b, // F11 -> f11
@0x00000068 : @0x00200000010, // Lang1 -> lang1
@0x00000069 : @0x0010000080d, // F13 -> f13
@0x0000006a : @0x00100000810, // F16 -> f16
@0x0000006b : @0x0010000080e, // F14 -> f14
@0x0000006d : @0x0010000080a, // F10 -> f10
@0x0000006e : @0x00100000505, // ContextMenu -> contextMenu
@0x0000006f : @0x0010000080c, // F12 -> f12
@0x00000071 : @0x0010000080f, // F15 -> f15
@0x00000072 : @0x00100000407, // Insert -> insert
@0x00000073 : @0x00100000306, // Home -> home
@0x00000074 : @0x00100000308, // PageUp -> pageUp
@0x00000075 : @0x0010000007f, // Delete -> delete
@0x00000076 : @0x00100000804, // F4 -> f4
@0x00000077 : @0x00100000305, // End -> end
@0x00000078 : @0x00100000802, // F2 -> f2
@0x00000079 : @0x00100000307, // PageDown -> pageDown
@0x0000007a : @0x00100000801, // F1 -> f1
@0x0000007b : @0x00100000302, // ArrowLeft -> arrowLeft
@0x0000007c : @0x00100000303, // ArrowRight -> arrowRight
@0x0000007d : @0x00100000301, // ArrowDown -> arrowDown
@0x0000007e : @0x00100000304, // ArrowUp -> arrowUp
};
const NSDictionary* keyCodeToModifierFlag = @{
......@@ -282,4 +241,4 @@ const NSDictionary* modifierFlagToKeyCode = @{
};
const uint64_t kCapsLockPhysicalKey = 0x00070039;
const uint64_t kCapsLockLogicalKey = 0x00000104;
const uint64_t kCapsLockLogicalKey = 0x100000104;
......@@ -2,6 +2,9 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#import <Cocoa/Cocoa.h>
#include <cinttypes>
/**
* Maps macOS-specific key code values representing |PhysicalKeyboardKey|.
*
......@@ -19,18 +22,20 @@ extern const NSDictionary* keyCodeToLogicalKey;
// Several mask constants. See KeyCodeMap.mm for their descriptions.
/**
* Mask for the 32-bit value portion of the key code.
*/
extern const uint64_t kValueMask;
extern const uint64_t kPlatformMask;
/**
* The plane value for keys which have a Unicode representation.
*/
extern const uint64_t kUnicodePlane;
extern const uint64_t kHidPlane;
extern const uint64_t kAutogeneratedMask;
extern const uint64_t kSynonymMask;
/**
* The code prefix for keys from macOS which do not have a Unicode
* representation.
* The plane value for the private keys defined by the macOS embedding.
*/
static const uint64_t kMacosPlane = 0x00500000000;
extern const uint64_t kMacosPlane;
/**
* Map |NSEvent.keyCode| to its corresponding bitmask of NSEventModifierFlags.
......
......@@ -128,7 +128,10 @@ source_set("embedder_headers") {
}
source_set("embedder_test_utils") {
public = [ "test_utils/proc_table_replacement.h" ]
public = [
"test_utils/key_codes.h",
"test_utils/proc_table_replacement.h",
]
deps = [ ":embedder_headers" ]
......
此差异已折叠。
......@@ -12,10 +12,6 @@
#include "flutter/shell/platform/linux/fl_key_embedder_responder_private.h"
#include "flutter/shell/platform/linux/key_mapping.h"
// The code prefix for unrecognized keys that are unique to Gtk, generated from
// platform-specific codes.
constexpr uint64_t kGtkKeyIdPlane = 0x00600000000;
constexpr uint64_t kMicrosecondsPerMillisecond = 1000;
// Look up a hash table that maps a uint64_t to a uint64_t.
......@@ -269,12 +265,16 @@ FlKeyEmbedderResponder* fl_key_embedder_responder_new(FlEngine* engine) {
/* Implement FlKeyEmbedderUserData */
static uint64_t apply_id_plane(uint64_t logical_id, uint64_t plane) {
return (logical_id & kValueMask) | plane;
}
static uint64_t event_to_physical_key(const FlKeyEvent* event) {
auto found = xkb_to_physical_key_map.find(event->keycode);
if (found != xkb_to_physical_key_map.end()) {
return found->second;
}
return kGtkKeyIdPlane | event->keycode;
return apply_id_plane(event->keycode, kGtkPlane);
}
static uint64_t event_to_logical_key(const FlKeyEvent* event) {
......@@ -285,10 +285,10 @@ static uint64_t event_to_logical_key(const FlKeyEvent* event) {
}
// EASCII range
if (keyval < 256) {
return to_lower(keyval);
return apply_id_plane(to_lower(keyval), kUnicodePlane);
}
// Auto-generate key
return kGtkKeyIdPlane | keyval;
return apply_id_plane(keyval, kGtkPlane);
}
static uint64_t event_to_timestamp(const FlKeyEvent* event) {
......
......@@ -6,6 +6,7 @@
#include "gtest/gtest.h"
#include "flutter/shell/platform/embedder/test_utils/key_codes.h"
#include "flutter/shell/platform/embedder/test_utils/proc_table_replacement.h"
#include "flutter/shell/platform/linux/fl_binary_messenger_private.h"
#include "flutter/shell/platform/linux/fl_engine_private.h"
......@@ -26,20 +27,7 @@ constexpr guint16 kKeyCodeCapsLock = 0x42u;
constexpr guint16 kKeyCodeControlLeft = 0x25u;
constexpr guint16 kKeyCodeControlRight = 0x69u;
constexpr uint64_t kPhysicalKeyA = 0x00070004;
constexpr uint64_t kPhysicalControlLeft = 0x000700e0;
constexpr uint64_t kPhysicalShiftRight = 0x000700E5;
constexpr uint64_t kPhysicalNumpad1 = 0x00070059;
constexpr uint64_t kPhysicalNumLock = 0x00070053;
constexpr uint64_t kPhysicalCapsLock = 0x00070039;
constexpr uint64_t kLogicalKeyA = 0x00000061;
constexpr uint64_t kLogicalKeyQ = 0x00000071;
constexpr uint64_t kLogicalControlLeft = 0x30000000105;
constexpr uint64_t kLogicalShiftRight = 0x4000000010D;
constexpr uint64_t kLogicalNumpad1 = 0x50000000031;
constexpr uint64_t kLogicalNumLock = 0x100000010A;
constexpr uint64_t kLogicalCapsLock = 0x1000000104;
using namespace ::flutter::testing::keycodes;
} // namespace
static void g_ptr_array_clear(GPtrArray* array) {
......
......@@ -237,177 +237,177 @@ std::map<uint64_t, uint64_t> xkb_to_physical_key_map = {
};
std::map<uint64_t, uint64_t> gtk_keyval_to_logical_key_map = {
{0x000000a5, 0x01100070089}, // yen
{0x0000fd06, 0x01000000405}, // 3270_EraseEOF
{0x0000fd0e, 0x01000000503}, // 3270_Attn
{0x0000fd15, 0x01000000402}, // 3270_Copy
{0x0000fd16, 0x01000000d2f}, // 3270_Play
{0x0000fd1b, 0x01000000406}, // 3270_ExSelect
{0x0000fd1d, 0x01000000608}, // 3270_PrintScreen
{0x0000fd1e, 0x0100000000d}, // 3270_Enter
{0x0000fe03, 0x40000000102}, // ISO_Level3_Shift
{0x0000fe08, 0x01000000709}, // ISO_Next_Group
{0x0000fe0a, 0x0100000070a}, // ISO_Prev_Group
{0x0000fe0c, 0x01000000707}, // ISO_First_Group
{0x0000fe0e, 0x01000000708}, // ISO_Last_Group
{0x0000fe20, 0x01000000009}, // ISO_Left_Tab
{0x0000fe34, 0x0100000000d}, // ISO_Enter
{0x0000ff08, 0x01000000008}, // BackSpace
{0x0000ff09, 0x01000000009}, // Tab
{0x0000ff0b, 0x01000000401}, // Clear
{0x0000ff0d, 0x0100000000d}, // Return
{0x0000ff13, 0x01000000509}, // Pause
{0x0000ff14, 0x0100000010c}, // Scroll_Lock
{0x0000ff1b, 0x0100000001b}, // Escape
{0x0000ff21, 0x01000000719}, // Kanji
{0x0000ff24, 0x0100000071b}, // Romaji
{0x0000ff25, 0x01000000716}, // Hiragana
{0x0000ff26, 0x0100000071a}, // Katakana
{0x0000ff27, 0x01000000717}, // Hiragana_Katakana
{0x0000ff28, 0x0100000071c}, // Zenkaku
{0x0000ff29, 0x01000000715}, // Hankaku
{0x0000ff2a, 0x0100000071d}, // Zenkaku_Hankaku
{0x0000ff2f, 0x01000000714}, // Eisu_Shift
{0x0000ff31, 0x01000000711}, // Hangul
{0x0000ff34, 0x01000000712}, // Hangul_Hanja
{0x0000ff37, 0x01000000703}, // Codeinput
{0x0000ff3c, 0x01000000710}, // SingleCandidate
{0x0000ff3e, 0x0100000070e}, // PreviousCandidate
{0x0000ff50, 0x01000000306}, // Home
{0x0000ff51, 0x01000000302}, // Left
{0x0000ff52, 0x01000000304}, // Up
{0x0000ff53, 0x01000000303}, // Right
{0x0000ff54, 0x01000000301}, // Down
{0x0000ff55, 0x01000000308}, // Page_Up
{0x0000ff56, 0x01000000307}, // Page_Down
{0x0000ff57, 0x01000000305}, // End
{0x0000ff60, 0x0100000050c}, // Select
{0x0000ff61, 0x01000000a0c}, // Print
{0x0000ff62, 0x01000000506}, // Execute
{0x0000ff63, 0x01000000407}, // Insert
{0x0000ff65, 0x0100000040a}, // Undo
{0x0000ff66, 0x01000000409}, // Redo
{0x0000ff67, 0x01000000505}, // Menu
{0x0000ff68, 0x01000000507}, // Find
{0x0000ff69, 0x01000000504}, // Cancel
{0x0000ff6a, 0x01000000508}, // Help
{0x0000ff7e, 0x0100000070b}, // Mode_switch
{0x0000ff7f, 0x0100000010a}, // Num_Lock
{0x000000a5, 0x00200000022}, // yen
{0x0000fd06, 0x00100000405}, // 3270_EraseEOF
{0x0000fd0e, 0x00100000503}, // 3270_Attn
{0x0000fd15, 0x00100000402}, // 3270_Copy
{0x0000fd16, 0x00100000d2f}, // 3270_Play
{0x0000fd1b, 0x00100000406}, // 3270_ExSelect
{0x0000fd1d, 0x00100000608}, // 3270_PrintScreen
{0x0000fd1e, 0x0010000000d}, // 3270_Enter
{0x0000fe03, 0x00200000105}, // ISO_Level3_Shift
{0x0000fe08, 0x00100000709}, // ISO_Next_Group
{0x0000fe0a, 0x0010000070a}, // ISO_Prev_Group
{0x0000fe0c, 0x00100000707}, // ISO_First_Group
{0x0000fe0e, 0x00100000708}, // ISO_Last_Group
{0x0000fe20, 0x00100000009}, // ISO_Left_Tab
{0x0000fe34, 0x0010000000d}, // ISO_Enter
{0x0000ff08, 0x00100000008}, // BackSpace
{0x0000ff09, 0x00100000009}, // Tab
{0x0000ff0b, 0x00100000401}, // Clear
{0x0000ff0d, 0x0010000000d}, // Return
{0x0000ff13, 0x00100000509}, // Pause
{0x0000ff14, 0x0010000010c}, // Scroll_Lock
{0x0000ff1b, 0x0010000001b}, // Escape
{0x0000ff21, 0x00100000719}, // Kanji
{0x0000ff24, 0x0010000071b}, // Romaji
{0x0000ff25, 0x00100000716}, // Hiragana
{0x0000ff26, 0x0010000071a}, // Katakana
{0x0000ff27, 0x00100000717}, // Hiragana_Katakana
{0x0000ff28, 0x0010000071c}, // Zenkaku
{0x0000ff29, 0x00100000715}, // Hankaku
{0x0000ff2a, 0x0010000071d}, // Zenkaku_Hankaku
{0x0000ff2f, 0x00100000714}, // Eisu_Shift
{0x0000ff31, 0x00100000711}, // Hangul
{0x0000ff34, 0x00100000712}, // Hangul_Hanja
{0x0000ff37, 0x00100000703}, // Codeinput
{0x0000ff3c, 0x00100000710}, // SingleCandidate
{0x0000ff3e, 0x0010000070e}, // PreviousCandidate
{0x0000ff50, 0x00100000306}, // Home
{0x0000ff51, 0x00100000302}, // Left
{0x0000ff52, 0x00100000304}, // Up
{0x0000ff53, 0x00100000303}, // Right
{0x0000ff54, 0x00100000301}, // Down
{0x0000ff55, 0x00100000308}, // Page_Up
{0x0000ff56, 0x00100000307}, // Page_Down
{0x0000ff57, 0x00100000305}, // End
{0x0000ff60, 0x0010000050c}, // Select
{0x0000ff61, 0x00100000a0c}, // Print
{0x0000ff62, 0x00100000506}, // Execute
{0x0000ff63, 0x00100000407}, // Insert
{0x0000ff65, 0x0010000040a}, // Undo
{0x0000ff66, 0x00100000409}, // Redo
{0x0000ff67, 0x00100000505}, // Menu
{0x0000ff68, 0x00100000507}, // Find
{0x0000ff69, 0x00100000504}, // Cancel
{0x0000ff6a, 0x00100000508}, // Help
{0x0000ff7e, 0x0010000070b}, // Mode_switch
{0x0000ff7f, 0x0010000010a}, // Num_Lock
{0x0000ff80, 0x00000000020}, // KP_Space
{0x0000ff89, 0x01000000009}, // KP_Tab
{0x0000ff8d, 0x5000000000d}, // KP_Enter
{0x0000ff91, 0x01000000801}, // KP_F1
{0x0000ff92, 0x01000000802}, // KP_F2
{0x0000ff93, 0x01000000803}, // KP_F3
{0x0000ff94, 0x01000000804}, // KP_F4
{0x0000ff95, 0x50000000037}, // KP_Home
{0x0000ff96, 0x50000000034}, // KP_Left
{0x0000ff97, 0x50000000038}, // KP_Up
{0x0000ff98, 0x50000000036}, // KP_Right
{0x0000ff99, 0x50000000032}, // KP_Down
{0x0000ff9a, 0x50000000039}, // KP_Page_Up
{0x0000ff9b, 0x50000000033}, // KP_Page_Down
{0x0000ff9c, 0x50000000031}, // KP_End
{0x0000ff9e, 0x50000000030}, // KP_Insert
{0x0000ff9f, 0x5000000002e}, // KP_Delete
{0x0000ffaa, 0x5000000002a}, // KP_Multiply
{0x0000ffab, 0x5000000002b}, // KP_Add
{0x0000ffad, 0x5000000002d}, // KP_Subtract
{0x0000ff89, 0x00100000009}, // KP_Tab
{0x0000ff8d, 0x0020000020d}, // KP_Enter
{0x0000ff91, 0x00100000801}, // KP_F1
{0x0000ff92, 0x00100000802}, // KP_F2
{0x0000ff93, 0x00100000803}, // KP_F3
{0x0000ff94, 0x00100000804}, // KP_F4
{0x0000ff95, 0x00200000237}, // KP_Home
{0x0000ff96, 0x00200000234}, // KP_Left
{0x0000ff97, 0x00200000238}, // KP_Up
{0x0000ff98, 0x00200000236}, // KP_Right
{0x0000ff99, 0x00200000232}, // KP_Down
{0x0000ff9a, 0x00200000239}, // KP_Page_Up
{0x0000ff9b, 0x00200000233}, // KP_Page_Down
{0x0000ff9c, 0x00200000231}, // KP_End
{0x0000ff9e, 0x00200000230}, // KP_Insert
{0x0000ff9f, 0x0020000022e}, // KP_Delete
{0x0000ffaa, 0x0020000022a}, // KP_Multiply
{0x0000ffab, 0x0020000022b}, // KP_Add
{0x0000ffad, 0x0020000022d}, // KP_Subtract
{0x0000ffae, 0x0000000002e}, // KP_Decimal
{0x0000ffaf, 0x5000000002f}, // KP_Divide
{0x0000ffb0, 0x50000000030}, // KP_0
{0x0000ffb1, 0x50000000031}, // KP_1
{0x0000ffb2, 0x50000000032}, // KP_2
{0x0000ffb3, 0x50000000033}, // KP_3
{0x0000ffb4, 0x50000000034}, // KP_4
{0x0000ffb5, 0x50000000035}, // KP_5
{0x0000ffb6, 0x50000000036}, // KP_6
{0x0000ffb7, 0x50000000037}, // KP_7
{0x0000ffb8, 0x50000000038}, // KP_8
{0x0000ffb9, 0x50000000039}, // KP_9
{0x0000ffbd, 0x5000000003d}, // KP_Equal
{0x0000ffbe, 0x01000000801}, // F1
{0x0000ffbf, 0x01000000802}, // F2
{0x0000ffc0, 0x01000000803}, // F3
{0x0000ffc1, 0x01000000804}, // F4
{0x0000ffc2, 0x01000000805}, // F5
{0x0000ffc3, 0x01000000806}, // F6
{0x0000ffc4, 0x01000000807}, // F7
{0x0000ffc5, 0x01000000808}, // F8
{0x0000ffc6, 0x01000000809}, // F9
{0x0000ffc7, 0x0100000080a}, // F10
{0x0000ffc8, 0x0100000080b}, // F11
{0x0000ffc9, 0x0100000080c}, // F12
{0x0000ffca, 0x0100000080d}, // F13
{0x0000ffcb, 0x0100000080e}, // F14
{0x0000ffcc, 0x0100000080f}, // F15
{0x0000ffcd, 0x01000000810}, // F16
{0x0000ffce, 0x01000000811}, // F17
{0x0000ffcf, 0x01000000812}, // F18
{0x0000ffd0, 0x01000000813}, // F19
{0x0000ffd1, 0x01000000814}, // F20
{0x0000ffd2, 0x01000000815}, // F21
{0x0000ffd3, 0x01000000816}, // F22
{0x0000ffd4, 0x01000000817}, // F23
{0x0000ffd5, 0x01000000818}, // F24
{0x0000ffe1, 0x3000000010d}, // Shift_L
{0x0000ffe2, 0x4000000010d}, // Shift_R
{0x0000ffe3, 0x30000000105}, // Control_L
{0x0000ffe4, 0x40000000105}, // Control_R
{0x0000ffe5, 0x01000000104}, // Caps_Lock
{0x0000ffe7, 0x30000000109}, // Meta_L
{0x0000ffe8, 0x40000000109}, // Meta_R
{0x0000ffe9, 0x30000000102}, // Alt_L
{0x0000ffea, 0x40000000102}, // Alt_R
{0x0000ffeb, 0x0100000010e}, // Super_L
{0x0000ffec, 0x0100000010e}, // Super_R
{0x0000ffed, 0x01000000108}, // Hyper_L
{0x0000ffee, 0x01000000108}, // Hyper_R
{0x0000ffff, 0x0100000007f}, // Delete
{0x1008ff02, 0x01000000602}, // MonBrightnessUp
{0x1008ff03, 0x01000000601}, // MonBrightnessDown
{0x1008ff10, 0x0100000060a}, // Standby
{0x1008ff11, 0x01000000a0f}, // AudioLowerVolume
{0x1008ff12, 0x01000000a11}, // AudioMute
{0x1008ff13, 0x01000000a10}, // AudioRaiseVolume
{0x1008ff14, 0x01000000d2f}, // AudioPlay
{0x1008ff15, 0x01000000a07}, // AudioStop
{0x1008ff16, 0x01000000a09}, // AudioPrev
{0x1008ff17, 0x01000000a08}, // AudioNext
{0x1008ff18, 0x01000000c04}, // HomePage
{0x1008ff19, 0x01000000b03}, // Mail
{0x1008ff1b, 0x01000000c06}, // Search
{0x1008ff1c, 0x01000000d30}, // AudioRecord
{0x1008ff20, 0x01000000b02}, // Calendar
{0x1008ff26, 0x01000000c01}, // Back
{0x1008ff27, 0x01000000c03}, // Forward
{0x1008ff28, 0x01000000c07}, // Stop
{0x1008ff29, 0x01000000c05}, // Refresh
{0x1008ff2a, 0x01000000607}, // PowerOff
{0x1008ff2b, 0x0100000060b}, // WakeUp
{0x1008ff2c, 0x01000000604}, // Eject
{0x1008ff2d, 0x01000000b07}, // ScreenSaver
{0x1008ff2f, 0x01100010082}, // Sleep
{0x1008ff30, 0x01000000c02}, // Favorites
{0x1008ff31, 0x01000000d2e}, // AudioPause
{0x1008ff3e, 0x01000000d31}, // AudioRewind
{0x1008ff56, 0x01000000a01}, // Close
{0x1008ff57, 0x01000000402}, // Copy
{0x1008ff58, 0x01000000404}, // Cut
{0x1008ff61, 0x01000000605}, // LogOff
{0x1008ff68, 0x01000000a0a}, // New
{0x1008ff6b, 0x01000000a0b}, // Open
{0x1008ff6d, 0x01000000408}, // Paste
{0x1008ff6e, 0x01000000b0d}, // Phone
{0x1008ff72, 0x01000000a03}, // Reply
{0x1008ff77, 0x01000000a0d}, // Save
{0x1008ff7b, 0x01000000a04}, // Send
{0x1008ff7c, 0x01000000a0e}, // Spell
{0x1008ff8b, 0x0100000050d}, // ZoomIn
{0x1008ff8c, 0x0100000050e}, // ZoomOut
{0x1008ff90, 0x01000000a02}, // MailForward
{0x1008ff97, 0x01000000d2c}, // AudioForward
{0x1008ffa7, 0x01100000014}, // Suspend
{0x0000ffaf, 0x0020000022f}, // KP_Divide
{0x0000ffb0, 0x00200000230}, // KP_0
{0x0000ffb1, 0x00200000231}, // KP_1
{0x0000ffb2, 0x00200000232}, // KP_2
{0x0000ffb3, 0x00200000233}, // KP_3
{0x0000ffb4, 0x00200000234}, // KP_4
{0x0000ffb5, 0x00200000235}, // KP_5
{0x0000ffb6, 0x00200000236}, // KP_6
{0x0000ffb7, 0x00200000237}, // KP_7
{0x0000ffb8, 0x00200000238}, // KP_8
{0x0000ffb9, 0x00200000239}, // KP_9
{0x0000ffbd, 0x0020000023d}, // KP_Equal
{0x0000ffbe, 0x00100000801}, // F1
{0x0000ffbf, 0x00100000802}, // F2
{0x0000ffc0, 0x00100000803}, // F3
{0x0000ffc1, 0x00100000804}, // F4
{0x0000ffc2, 0x00100000805}, // F5
{0x0000ffc3, 0x00100000806}, // F6
{0x0000ffc4, 0x00100000807}, // F7
{0x0000ffc5, 0x00100000808}, // F8
{0x0000ffc6, 0x00100000809}, // F9
{0x0000ffc7, 0x0010000080a}, // F10
{0x0000ffc8, 0x0010000080b}, // F11
{0x0000ffc9, 0x0010000080c}, // F12
{0x0000ffca, 0x0010000080d}, // F13
{0x0000ffcb, 0x0010000080e}, // F14
{0x0000ffcc, 0x0010000080f}, // F15
{0x0000ffcd, 0x00100000810}, // F16
{0x0000ffce, 0x00100000811}, // F17
{0x0000ffcf, 0x00100000812}, // F18
{0x0000ffd0, 0x00100000813}, // F19
{0x0000ffd1, 0x00100000814}, // F20
{0x0000ffd2, 0x00100000815}, // F21
{0x0000ffd3, 0x00100000816}, // F22
{0x0000ffd4, 0x00100000817}, // F23
{0x0000ffd5, 0x00100000818}, // F24
{0x0000ffe1, 0x00200000102}, // Shift_L
{0x0000ffe2, 0x00200000103}, // Shift_R
{0x0000ffe3, 0x00200000100}, // Control_L
{0x0000ffe4, 0x00200000101}, // Control_R
{0x0000ffe5, 0x00100000104}, // Caps_Lock
{0x0000ffe7, 0x00200000106}, // Meta_L
{0x0000ffe8, 0x00200000107}, // Meta_R
{0x0000ffe9, 0x00200000104}, // Alt_L
{0x0000ffea, 0x00200000105}, // Alt_R
{0x0000ffeb, 0x0010000010e}, // Super_L
{0x0000ffec, 0x0010000010e}, // Super_R
{0x0000ffed, 0x00100000108}, // Hyper_L
{0x0000ffee, 0x00100000108}, // Hyper_R
{0x0000ffff, 0x0010000007f}, // Delete
{0x1008ff02, 0x00100000602}, // MonBrightnessUp
{0x1008ff03, 0x00100000601}, // MonBrightnessDown
{0x1008ff10, 0x0010000060a}, // Standby
{0x1008ff11, 0x00100000a0f}, // AudioLowerVolume
{0x1008ff12, 0x00100000a11}, // AudioMute
{0x1008ff13, 0x00100000a10}, // AudioRaiseVolume
{0x1008ff14, 0x00100000d2f}, // AudioPlay
{0x1008ff15, 0x00100000a07}, // AudioStop
{0x1008ff16, 0x00100000a09}, // AudioPrev
{0x1008ff17, 0x00100000a08}, // AudioNext
{0x1008ff18, 0x00100000c04}, // HomePage
{0x1008ff19, 0x00100000b03}, // Mail
{0x1008ff1b, 0x00100000c06}, // Search
{0x1008ff1c, 0x00100000d30}, // AudioRecord
{0x1008ff20, 0x00100000b02}, // Calendar
{0x1008ff26, 0x00100000c01}, // Back
{0x1008ff27, 0x00100000c03}, // Forward
{0x1008ff28, 0x00100000c07}, // Stop
{0x1008ff29, 0x00100000c05}, // Refresh
{0x1008ff2a, 0x00100000607}, // PowerOff
{0x1008ff2b, 0x0010000060b}, // WakeUp
{0x1008ff2c, 0x00100000604}, // Eject
{0x1008ff2d, 0x00100000b07}, // ScreenSaver
{0x1008ff2f, 0x00200000002}, // Sleep
{0x1008ff30, 0x00100000c02}, // Favorites
{0x1008ff31, 0x00100000d2e}, // AudioPause
{0x1008ff3e, 0x00100000d31}, // AudioRewind
{0x1008ff56, 0x00100000a01}, // Close
{0x1008ff57, 0x00100000402}, // Copy
{0x1008ff58, 0x00100000404}, // Cut
{0x1008ff61, 0x00100000605}, // LogOff
{0x1008ff68, 0x00100000a0a}, // New
{0x1008ff6b, 0x00100000a0b}, // Open
{0x1008ff6d, 0x00100000408}, // Paste
{0x1008ff6e, 0x00100000b0d}, // Phone
{0x1008ff72, 0x00100000a03}, // Reply
{0x1008ff77, 0x00100000a0d}, // Save
{0x1008ff7b, 0x00100000a04}, // Send
{0x1008ff7c, 0x00100000a0e}, // Spell
{0x1008ff8b, 0x0010000050d}, // ZoomIn
{0x1008ff8c, 0x0010000050e}, // ZoomOut
{0x1008ff90, 0x00100000a02}, // MailForward
{0x1008ff97, 0x00100000d2c}, // AudioForward
{0x1008ffa7, 0x00200000000}, // Suspend
};
void initialize_modifier_bit_to_checked_keys(GHashTable* table) {
......@@ -417,29 +417,29 @@ void initialize_modifier_bit_to_checked_keys(GHashTable* table) {
g_hash_table_insert(table, GUINT_TO_POINTER(GDK_SHIFT_MASK), data);
data->is_caps_lock = false;
data->primary_physical_key = 0x0000700e1; // shiftLeft
data->primary_logical_key = 0x3000000010d; // shiftLeft
data->secondary_logical_key = 0x4000000010d; // shiftRight
data->primary_logical_key = 0x00200000102; // shiftLeft
data->secondary_logical_key = 0x00200000103; // shiftRight
data = g_new(FlKeyEmbedderCheckedKey, 1);
g_hash_table_insert(table, GUINT_TO_POINTER(GDK_CONTROL_MASK), data);
data->is_caps_lock = false;
data->primary_physical_key = 0x0000700e0; // controlLeft
data->primary_logical_key = 0x30000000105; // controlLeft
data->secondary_logical_key = 0x40000000105; // controlRight
data->primary_logical_key = 0x00200000100; // controlLeft
data->secondary_logical_key = 0x00200000101; // controlRight
data = g_new(FlKeyEmbedderCheckedKey, 1);
g_hash_table_insert(table, GUINT_TO_POINTER(GDK_MOD1_MASK), data);
data->is_caps_lock = false;
data->primary_physical_key = 0x0000700e2; // altLeft
data->primary_logical_key = 0x30000000102; // altLeft
data->secondary_logical_key = 0x40000000102; // altRight
data->primary_logical_key = 0x00200000104; // altLeft
data->secondary_logical_key = 0x00200000105; // altRight
data = g_new(FlKeyEmbedderCheckedKey, 1);
g_hash_table_insert(table, GUINT_TO_POINTER(GDK_META_MASK), data);
data->is_caps_lock = false;
data->primary_physical_key = 0x0000700e3; // metaLeft
data->primary_logical_key = 0x30000000109; // metaLeft
data->secondary_logical_key = 0x40000000109; // metaRight
data->primary_logical_key = 0x00200000106; // metaLeft
data->secondary_logical_key = 0x00200000107; // metaRight
}
void initialize_lock_bit_to_checked_keys(GHashTable* table) {
......@@ -449,11 +449,15 @@ void initialize_lock_bit_to_checked_keys(GHashTable* table) {
g_hash_table_insert(table, GUINT_TO_POINTER(GDK_LOCK_MASK), data);
data->is_caps_lock = true;
data->primary_physical_key = 0x000070039; // capsLock
data->primary_logical_key = 0x01000000104; // capsLock
data->primary_logical_key = 0x00100000104; // capsLock
data = g_new(FlKeyEmbedderCheckedKey, 1);
g_hash_table_insert(table, GUINT_TO_POINTER(GDK_MOD2_MASK), data);
data->is_caps_lock = false;
data->primary_physical_key = 0x000070053; // numLock
data->primary_logical_key = 0x0100000010a; // numLock
data->primary_logical_key = 0x0010000010a; // numLock
}
const uint64_t kValueMask = 0x000ffffffff;
const uint64_t kUnicodePlane = 0x00000000000;
const uint64_t kGtkPlane = 0x01500000000;
......@@ -27,4 +27,13 @@ void initialize_modifier_bit_to_checked_keys(GHashTable* table);
void initialize_lock_bit_to_checked_keys(GHashTable* table);
// Mask for the 32-bit value portion of the key code.
extern const uint64_t kValueMask;
// The plane value for keys which have a Unicode representation.
extern const uint64_t kUnicodePlane;
// The plane value for the private keys defined by the GTK embedding.
extern const uint64_t kGtkPlane;
#endif // KEYBOARD_MAP_H_
......@@ -23,35 +23,6 @@ namespace {
// '\0'.
constexpr size_t kCharacterCacheSize = 8;
/**
* The code prefix for keys which do not have a Unicode representation.
*
* This is used by platform-specific code to generate Flutter key codes using
* HID Usage codes.
*/
constexpr uint64_t kHidPlane = 0x00100000000;
/**
* The code prefix for keys which have a Unicode representation.
*
* This is used by platform-specific code to generate Flutter key codes.
*/
constexpr uint64_t kUnicodePlane = 0x00000000000;
/**
* The code prefix for keys from Windows which do not have a Unicode
* representation.
*/
constexpr uint64_t kWindowsKeyIdPlane = 0x00700000000;
/**
* Mask for the auto-generated bit portion of the key code.
*
* This is used by platform-specific code to generate new Flutter key codes
* for keys which are not recognized.
*/
constexpr uint64_t kAutogeneratedMask = 0x10000000000;
constexpr SHORT kStateMaskToggled = 0x01;
constexpr SHORT kStateMaskPressed = 0x80;
......@@ -66,13 +37,36 @@ KeyboardKeyEmbedderHandler::KeyboardKeyEmbedderHandler(
KeyboardKeyEmbedderHandler::~KeyboardKeyEmbedderHandler() = default;
static bool isAsciiPrintable(int codeUnit) {
return codeUnit <= 0x7f && codeUnit >= 0x20;
static bool isEasciiPrintable(int codeUnit) {
return (codeUnit <= 0x7f && codeUnit >= 0x20) ||
(codeUnit <= 0xff && codeUnit >= 0x80);
}
static bool isControlCharacter(int codeUnit) {
return (codeUnit <= 0x1f && codeUnit >= 0x00) ||
(codeUnit >= 0x7f && codeUnit <= 0x9f);
// Converts upper letters to lower letters in ASCII and extended ASCII, and
// returns as-is otherwise.
//
// Independent of locale.
static uint64_t toLower(uint64_t n) {
constexpr uint64_t lower_a = 0x61;
constexpr uint64_t upper_a = 0x41;
constexpr uint64_t upper_z = 0x5a;
constexpr uint64_t lower_a_grave = 0xe0;
constexpr uint64_t upper_a_grave = 0xc0;
constexpr uint64_t upper_thorn = 0xde;
constexpr uint64_t division = 0xf7;
// ASCII range.
if (n >= upper_a && n <= upper_z) {
return n - upper_a + lower_a;
}
// EASCII range.
if (n >= upper_a_grave && n <= upper_thorn && n != division) {
return n - upper_a_grave + lower_a_grave;
}
return n;
}
// Transform scancodes sent by windows to scancodes written in Chromium spec.
......@@ -82,16 +76,21 @@ static uint16_t normalizeScancode(int windowsScanCode, bool extended) {
return (windowsScanCode & 0xff) | (extended ? 0xe000 : 0);
}
uint64_t KeyboardKeyEmbedderHandler::getPhysicalKey(int scancode,
uint64_t KeyboardKeyEmbedderHandler::ApplyPlaneToId(uint64_t id,
uint64_t plane) {
return (id & valueMask) | plane;
}
uint64_t KeyboardKeyEmbedderHandler::GetPhysicalKey(int scancode,
bool extended) {
int chromiumScancode = normalizeScancode(scancode, extended);
auto resultIt = windowsToPhysicalMap_.find(chromiumScancode);
if (resultIt != windowsToPhysicalMap_.end())
return resultIt->second;
return scancode | kHidPlane;
return ApplyPlaneToId(scancode, windowsPlane);
}
uint64_t KeyboardKeyEmbedderHandler::getLogicalKey(int key,
uint64_t KeyboardKeyEmbedderHandler::GetLogicalKey(int key,
bool extended,
int scancode) {
// Normally logical keys should only be derived from key codes, but since some
......@@ -108,24 +107,11 @@ uint64_t KeyboardKeyEmbedderHandler::getLogicalKey(int key,
return logicalIt->second;
// Upper case letters should be normalized into lower case letters.
if (isAsciiPrintable(key)) {
if (isupper(key)) {
return tolower(key);
}
return key;
if (isEasciiPrintable(key)) {
return ApplyPlaneToId(toLower(key), unicodePlane);
}
// For keys that do not exist in the map, if it has a non-control-character
// label, then construct a new Unicode-based key from it. Don't mark it as
// autogenerated, since the label uniquely identifies an ID from the Unicode
// plane.
if (!isControlCharacter(key)) {
return key | kUnicodePlane;
} else {
// This is a non-printable key that we don't know about, so we mint a new
// code with the autogenerated bit set.
return key | kWindowsKeyIdPlane | kAutogeneratedMask;
}
return ApplyPlaneToId(toLower(key), windowsPlane);
}
void KeyboardKeyEmbedderHandler::KeyboardHook(
......@@ -136,8 +122,8 @@ void KeyboardKeyEmbedderHandler::KeyboardHook(
bool extended,
bool was_down,
std::function<void(bool)> callback) {
const uint64_t physical_key = getPhysicalKey(scancode, extended);
const uint64_t logical_key = getLogicalKey(key, extended, scancode);
const uint64_t physical_key = GetPhysicalKey(scancode, extended);
const uint64_t logical_key = GetLogicalKey(key, extended, scancode);
assert(action == WM_KEYDOWN || action == WM_KEYUP);
const bool is_physical_down = action == WM_KEYDOWN;
......@@ -364,8 +350,8 @@ void KeyboardKeyEmbedderHandler::InitCriticalKeys() {
bool check_toggled) -> CriticalKey {
UINT scan_code = MapVirtualKey(virtual_key, MAPVK_VK_TO_VSC);
return CriticalKey{
.physical_key = getPhysicalKey(scan_code, extended),
.logical_key = getLogicalKey(virtual_key, extended, scan_code),
.physical_key = GetPhysicalKey(scan_code, extended),
.logical_key = GetLogicalKey(virtual_key, extended, scan_code),
.check_pressed = check_pressed || check_toggled,
.check_toggled = check_toggled,
.toggled_on = check_toggled
......
......@@ -113,18 +113,28 @@ class KeyboardKeyEmbedderHandler
// key they're last seen.
std::map<UINT, CriticalKey> critical_keys_;
static uint64_t getPhysicalKey(int scancode, bool extended);
static uint64_t getLogicalKey(int key, bool extended, int scancode);
static uint64_t GetPhysicalKey(int scancode, bool extended);
static uint64_t GetLogicalKey(int key, bool extended, int scancode);
static void HandleResponse(bool handled, void* user_data);
static void ConvertUtf32ToUtf8_(char* out, char32_t ch);
static FlutterKeyEvent SynthesizeSimpleEvent(FlutterKeyEventType type,
uint64_t physical,
uint64_t logical,
const char* character);
static uint64_t ApplyPlaneToId(uint64_t id, uint64_t plane);
static std::map<uint64_t, uint64_t> windowsToPhysicalMap_;
static std::map<uint64_t, uint64_t> windowsToLogicalMap_;
static std::map<uint64_t, uint64_t> scanCodeToLogicalMap_;
// Mask for the 32-bit value portion of the key code.
static const uint64_t valueMask;
// The plane value for keys which have a Unicode representation.
static const uint64_t unicodePlane;
// The plane value for the private keys defined by the GTK embedding.
static const uint64_t windowsPlane;
};
} // namespace flutter
......
......@@ -8,6 +8,7 @@
#include <vector>
#include "flutter/shell/platform/embedder/embedder.h"
#include "flutter/shell/platform/embedder/test_utils/key_codes.h"
#include "flutter/shell/platform/embedder/test_utils/proc_table_replacement.h"
#include "flutter/shell/platform/windows/testing/engine_modifier.h"
#include "gtest/gtest.h"
......@@ -79,19 +80,7 @@ constexpr uint64_t kScanCodeShiftRight = 0x36;
constexpr uint64_t kVirtualKeyA = 0x41;
constexpr uint64_t kPhysicalKeyA = 0x00070004;
constexpr uint64_t kPhysicalControlLeft = 0x000700e0;
constexpr uint64_t kPhysicalControlRight = 0x000700e4;
constexpr uint64_t kPhysicalShiftLeft = 0x000700e1;
constexpr uint64_t kPhysicalShiftRight = 0x000700e5;
constexpr uint64_t kPhysicalKeyNumLock = 0x00070053;
constexpr uint64_t kLogicalKeyA = 0x00000061;
constexpr uint64_t kLogicalControlLeft = 0x00300000105;
constexpr uint64_t kLogicalControlRight = 0x00400000105;
constexpr uint64_t kLogicalShiftLeft = 0x0030000010d;
constexpr uint64_t kLogicalShiftRight = 0x0040000010d;
constexpr uint64_t kLogicalKeyNumLock = 0x0000000010a;
using namespace ::flutter::testing::keycodes;
} // namespace
// Test the most basic key events.
......@@ -187,8 +176,8 @@ TEST(KeyboardKeyEmbedderHandlerTest, ToggleNumLockDuringNumpadPress) {
EXPECT_EQ(results.size(), 1);
event = &results[0];
EXPECT_EQ(event->type, kFlutterKeyEventTypeDown);
EXPECT_EQ(event->physical, 0x00070059);
EXPECT_EQ(event->logical, 0x00200000031);
EXPECT_EQ(event->physical, kPhysicalNumpad1);
EXPECT_EQ(event->logical, kLogicalNumpad1);
// EXPECT_STREQ(event->character, "1"); // TODO
EXPECT_EQ(event->synthesized, false);
results.clear();
......@@ -201,8 +190,8 @@ TEST(KeyboardKeyEmbedderHandlerTest, ToggleNumLockDuringNumpadPress) {
EXPECT_EQ(results.size(), 1);
event = &results[0];
EXPECT_EQ(event->type, kFlutterKeyEventTypeDown);
EXPECT_EQ(event->physical, 0x00070053);
EXPECT_EQ(event->logical, 0x0000010a);
EXPECT_EQ(event->physical, kPhysicalNumLock);
EXPECT_EQ(event->logical, kLogicalNumLock);
EXPECT_STREQ(event->character, "");
EXPECT_EQ(event->synthesized, false);
results.clear();
......@@ -215,8 +204,8 @@ TEST(KeyboardKeyEmbedderHandlerTest, ToggleNumLockDuringNumpadPress) {
EXPECT_EQ(results.size(), 1);
event = &results[0];
EXPECT_EQ(event->type, kFlutterKeyEventTypeUp);
EXPECT_EQ(event->physical, 0x00070053);
EXPECT_EQ(event->logical, 0x0000010a);
EXPECT_EQ(event->physical, kPhysicalNumLock);
EXPECT_EQ(event->logical, kLogicalNumLock);
EXPECT_STREQ(event->character, "");
EXPECT_EQ(event->synthesized, false);
results.clear();
......@@ -228,8 +217,8 @@ TEST(KeyboardKeyEmbedderHandlerTest, ToggleNumLockDuringNumpadPress) {
EXPECT_EQ(results.size(), 1);
event = &results[0];
EXPECT_EQ(event->type, kFlutterKeyEventTypeUp);
EXPECT_EQ(event->physical, 0x00070059);
EXPECT_EQ(event->logical, 0x00200000031);
EXPECT_EQ(event->physical, kPhysicalNumpad1);
EXPECT_EQ(event->logical, kLogicalNumpad1);
EXPECT_STREQ(event->character, "");
EXPECT_EQ(event->synthesized, false);
results.clear();
......@@ -648,15 +637,15 @@ TEST(KeyboardKeyEmbedderHandlerTest, SynthesizeForDesyncToggledState) {
EXPECT_EQ(results.size(), 3);
event = &results[0];
EXPECT_EQ(event->type, kFlutterKeyEventTypeDown);
EXPECT_EQ(event->physical, kPhysicalKeyNumLock);
EXPECT_EQ(event->logical, kLogicalKeyNumLock);
EXPECT_EQ(event->physical, kPhysicalNumLock);
EXPECT_EQ(event->logical, kLogicalNumLock);
EXPECT_STREQ(event->character, "");
EXPECT_EQ(event->synthesized, true);
event = &results[1];
EXPECT_EQ(event->type, kFlutterKeyEventTypeUp);
EXPECT_EQ(event->physical, kPhysicalKeyNumLock);
EXPECT_EQ(event->logical, kLogicalKeyNumLock);
EXPECT_EQ(event->physical, kPhysicalNumLock);
EXPECT_EQ(event->logical, kLogicalNumLock);
EXPECT_STREQ(event->character, "");
EXPECT_EQ(event->synthesized, true);
......@@ -682,8 +671,8 @@ TEST(KeyboardKeyEmbedderHandlerTest, SynthesizeForDesyncToggledState) {
EXPECT_EQ(results.size(), 2);
event = &results[0];
EXPECT_EQ(event->type, kFlutterKeyEventTypeDown);
EXPECT_EQ(event->physical, kPhysicalKeyNumLock);
EXPECT_EQ(event->logical, kLogicalKeyNumLock);
EXPECT_EQ(event->physical, kPhysicalNumLock);
EXPECT_EQ(event->logical, kLogicalNumLock);
EXPECT_STREQ(event->character, "");
EXPECT_EQ(event->synthesized, true);
......@@ -711,24 +700,24 @@ TEST(KeyboardKeyEmbedderHandlerTest, SynthesizeForDesyncToggledState) {
EXPECT_EQ(results.size(), 4);
event = &results[0];
EXPECT_EQ(event->type, kFlutterKeyEventTypeUp);
EXPECT_EQ(event->physical, kPhysicalKeyNumLock);
EXPECT_EQ(event->logical, kLogicalKeyNumLock);
EXPECT_EQ(event->physical, kPhysicalNumLock);
EXPECT_EQ(event->logical, kLogicalNumLock);
EXPECT_STREQ(event->character, "");
EXPECT_EQ(event->synthesized, true);
EXPECT_EQ(event->callback, nullptr);
event = &results[1];
EXPECT_EQ(event->type, kFlutterKeyEventTypeDown);
EXPECT_EQ(event->physical, kPhysicalKeyNumLock);
EXPECT_EQ(event->logical, kLogicalKeyNumLock);
EXPECT_EQ(event->physical, kPhysicalNumLock);
EXPECT_EQ(event->logical, kLogicalNumLock);
EXPECT_STREQ(event->character, "");
EXPECT_EQ(event->synthesized, true);
EXPECT_EQ(event->callback, nullptr);
event = &results[2];
EXPECT_EQ(event->type, kFlutterKeyEventTypeUp);
EXPECT_EQ(event->physical, kPhysicalKeyNumLock);
EXPECT_EQ(event->logical, kLogicalKeyNumLock);
EXPECT_EQ(event->physical, kPhysicalNumLock);
EXPECT_EQ(event->logical, kLogicalNumLock);
EXPECT_STREQ(event->character, "");
EXPECT_EQ(event->synthesized, true);
EXPECT_EQ(event->callback, nullptr);
......@@ -775,24 +764,24 @@ TEST(KeyboardKeyEmbedderHandlerTest, SynthesizeForDesyncToggledStateByItself) {
EXPECT_EQ(results.size(), 3);
event = &results[0];
EXPECT_EQ(event->type, kFlutterKeyEventTypeUp);
EXPECT_EQ(event->physical, kPhysicalKeyNumLock);
EXPECT_EQ(event->logical, kLogicalKeyNumLock);
EXPECT_EQ(event->physical, kPhysicalNumLock);
EXPECT_EQ(event->logical, kLogicalNumLock);
EXPECT_STREQ(event->character, "");
EXPECT_EQ(event->synthesized, true);
EXPECT_EQ(event->callback, nullptr);
event = &results[1];
EXPECT_EQ(event->type, kFlutterKeyEventTypeDown);
EXPECT_EQ(event->physical, kPhysicalKeyNumLock);
EXPECT_EQ(event->logical, kLogicalKeyNumLock);
EXPECT_EQ(event->physical, kPhysicalNumLock);
EXPECT_EQ(event->logical, kLogicalNumLock);
EXPECT_STREQ(event->character, "");
EXPECT_EQ(event->synthesized, true);
EXPECT_EQ(event->callback, nullptr);
event = &results[2];
EXPECT_EQ(event->type, kFlutterKeyEventTypeUp);
EXPECT_EQ(event->physical, kPhysicalKeyNumLock);
EXPECT_EQ(event->logical, kLogicalKeyNumLock);
EXPECT_EQ(event->physical, kPhysicalNumLock);
EXPECT_EQ(event->logical, kLogicalNumLock);
EXPECT_STREQ(event->character, "");
EXPECT_EQ(event->synthesized, false);
......@@ -827,8 +816,8 @@ TEST(KeyboardKeyEmbedderHandlerTest, SynthesizeWithInitialTogglingState) {
EXPECT_EQ(results.size(), 1);
event = &results[0];
EXPECT_EQ(event->type, kFlutterKeyEventTypeDown);
EXPECT_EQ(event->physical, kPhysicalKeyNumLock);
EXPECT_EQ(event->logical, kLogicalKeyNumLock);
EXPECT_EQ(event->physical, kPhysicalNumLock);
EXPECT_EQ(event->logical, kLogicalNumLock);
EXPECT_STREQ(event->character, "");
EXPECT_EQ(event->synthesized, false);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册