[gen_keycodes] Remove nonexistent Web keys and improve their emulation (#87098)
diff --git a/dev/tools/gen_keycodes/data/logical_key_data.json b/dev/tools/gen_keycodes/data/logical_key_data.json
index fab6a3c..1143b52 100644
--- a/dev/tools/gen_keycodes/data/logical_key_data.json
+++ b/dev/tools/gen_keycodes/data/logical_key_data.json
@@ -4,9 +4,6 @@
"value": 32,
"keyLabel": " ",
"names": {
- "web": [
- "Space"
- ],
"gtk": [
"KP_Space"
],
@@ -41,21 +38,13 @@
"Exclamation": {
"name": "Exclamation",
"value": 33,
- "keyLabel": "!",
- "names": {
- "web": [
- "Exclamation"
- ]
- }
+ "keyLabel": "!"
},
"Quote": {
"name": "Quote",
"value": 34,
"keyLabel": "\"",
"names": {
- "web": [
- "Quote"
- ],
"windows": [
"OEM_7"
],
@@ -86,9 +75,6 @@
"value": 35,
"keyLabel": "#",
"names": {
- "web": [
- "NumberSign"
- ],
"android": [
"POUND"
]
@@ -102,71 +88,38 @@
"Dollar": {
"name": "Dollar",
"value": 36,
- "keyLabel": "$",
- "names": {
- "web": [
- "Dollar"
- ]
- }
+ "keyLabel": "$"
},
"Percent": {
"name": "Percent",
"value": 37,
- "keyLabel": "%",
- "names": {
- "web": [
- "Percent"
- ]
- }
+ "keyLabel": "%"
},
"Ampersand": {
"name": "Ampersand",
"value": 38,
- "keyLabel": "&",
- "names": {
- "web": [
- "Ampersand"
- ]
- }
+ "keyLabel": "&"
},
"QuoteSingle": {
"name": "QuoteSingle",
"value": 39,
- "keyLabel": "'",
- "names": {
- "web": [
- "QuoteSingle"
- ]
- }
+ "keyLabel": "'"
},
"ParenthesisLeft": {
"name": "ParenthesisLeft",
"value": 40,
- "keyLabel": "(",
- "names": {
- "web": [
- "ParenthesisLeft"
- ]
- }
+ "keyLabel": "("
},
"ParenthesisRight": {
"name": "ParenthesisRight",
"value": 41,
- "keyLabel": ")",
- "names": {
- "web": [
- "ParenthesisRight"
- ]
- }
+ "keyLabel": ")"
},
"Asterisk": {
"name": "Asterisk",
"value": 42,
"keyLabel": "*",
"names": {
- "web": [
- "Asterisk"
- ],
"android": [
"STAR"
]
@@ -182,9 +135,6 @@
"value": 43,
"keyLabel": "+",
"names": {
- "web": [
- "Add"
- ],
"android": [
"PLUS"
]
@@ -200,9 +150,6 @@
"value": 44,
"keyLabel": ",",
"names": {
- "web": [
- "Comma"
- ],
"windows": [
"OEM_COMMA"
],
@@ -233,9 +180,6 @@
"value": 45,
"keyLabel": "-",
"names": {
- "web": [
- "Minus"
- ],
"windows": [
"OEM_MINUS"
],
@@ -266,9 +210,6 @@
"value": 46,
"keyLabel": ".",
"names": {
- "web": [
- "Period"
- ],
"gtk": [
"KP_Decimal"
],
@@ -305,9 +246,6 @@
"value": 47,
"keyLabel": "/",
"names": {
- "web": [
- "Slash"
- ],
"windows": [
"OEM_2"
],
@@ -338,9 +276,6 @@
"value": 48,
"keyLabel": "0",
"names": {
- "web": [
- "Digit0"
- ],
"android": [
"0"
],
@@ -365,9 +300,6 @@
"value": 49,
"keyLabel": "1",
"names": {
- "web": [
- "Digit1"
- ],
"android": [
"1"
],
@@ -392,9 +324,6 @@
"value": 50,
"keyLabel": "2",
"names": {
- "web": [
- "Digit2"
- ],
"android": [
"2"
],
@@ -419,9 +348,6 @@
"value": 51,
"keyLabel": "3",
"names": {
- "web": [
- "Digit3"
- ],
"android": [
"3"
],
@@ -446,9 +372,6 @@
"value": 52,
"keyLabel": "4",
"names": {
- "web": [
- "Digit4"
- ],
"android": [
"4"
],
@@ -473,9 +396,6 @@
"value": 53,
"keyLabel": "5",
"names": {
- "web": [
- "Digit5"
- ],
"android": [
"5"
],
@@ -500,9 +420,6 @@
"value": 54,
"keyLabel": "6",
"names": {
- "web": [
- "Digit6"
- ],
"android": [
"6"
],
@@ -527,9 +444,6 @@
"value": 55,
"keyLabel": "7",
"names": {
- "web": [
- "Digit7"
- ],
"android": [
"7"
],
@@ -554,9 +468,6 @@
"value": 56,
"keyLabel": "8",
"names": {
- "web": [
- "Digit8"
- ],
"android": [
"8"
],
@@ -581,9 +492,6 @@
"value": 57,
"keyLabel": "9",
"names": {
- "web": [
- "Digit9"
- ],
"android": [
"9"
],
@@ -606,21 +514,13 @@
"Colon": {
"name": "Colon",
"value": 58,
- "keyLabel": ":",
- "names": {
- "web": [
- "Colon"
- ]
- }
+ "keyLabel": ":"
},
"Semicolon": {
"name": "Semicolon",
"value": 59,
"keyLabel": ";",
"names": {
- "web": [
- "Semicolon"
- ],
"windows": [
"OEM_1"
],
@@ -649,21 +549,13 @@
"Less": {
"name": "Less",
"value": 60,
- "keyLabel": "<",
- "names": {
- "web": [
- "Less"
- ]
- }
+ "keyLabel": "<"
},
"Equal": {
"name": "Equal",
"value": 61,
"keyLabel": "=",
"names": {
- "web": [
- "Equal"
- ],
"windows": [
"OEM_PLUS"
],
@@ -692,31 +584,18 @@
"Greater": {
"name": "Greater",
"value": 62,
- "keyLabel": ">",
- "names": {
- "web": [
- "Greater"
- ]
- }
+ "keyLabel": ">"
},
"Question": {
"name": "Question",
"value": 63,
- "keyLabel": "?",
- "names": {
- "web": [
- "Question"
- ]
- }
+ "keyLabel": "?"
},
"At": {
"name": "At",
"value": 64,
"keyLabel": "@",
"names": {
- "web": [
- "At"
- ],
"android": [
"AT"
]
@@ -732,9 +611,6 @@
"value": 91,
"keyLabel": "[",
"names": {
- "web": [
- "BracketLeft"
- ],
"windows": [
"OEM_4"
],
@@ -765,9 +641,6 @@
"value": 92,
"keyLabel": "\\",
"names": {
- "web": [
- "Backslash"
- ],
"windows": [
"OEM_5"
],
@@ -798,9 +671,6 @@
"value": 93,
"keyLabel": "]",
"names": {
- "web": [
- "BracketRight"
- ],
"windows": [
"OEM_6"
],
@@ -829,31 +699,18 @@
"Caret": {
"name": "Caret",
"value": 94,
- "keyLabel": "^",
- "names": {
- "web": [
- "Caret"
- ]
- }
+ "keyLabel": "^"
},
"Underscore": {
"name": "Underscore",
"value": 95,
- "keyLabel": "_",
- "names": {
- "web": [
- "Underscore"
- ]
- }
+ "keyLabel": "_"
},
"Backquote": {
"name": "Backquote",
"value": 96,
"keyLabel": "`",
"names": {
- "web": [
- "Backquote"
- ],
"windows": [
"OEM_3"
],
@@ -884,9 +741,6 @@
"value": 97,
"keyLabel": "a",
"names": {
- "web": [
- "KeyA"
- ],
"android": [
"A"
],
@@ -911,9 +765,6 @@
"value": 98,
"keyLabel": "b",
"names": {
- "web": [
- "KeyB"
- ],
"android": [
"B"
],
@@ -938,9 +789,6 @@
"value": 99,
"keyLabel": "c",
"names": {
- "web": [
- "KeyC"
- ],
"android": [
"C"
],
@@ -965,9 +813,6 @@
"value": 100,
"keyLabel": "d",
"names": {
- "web": [
- "KeyD"
- ],
"android": [
"D"
],
@@ -992,9 +837,6 @@
"value": 101,
"keyLabel": "e",
"names": {
- "web": [
- "KeyE"
- ],
"android": [
"E"
],
@@ -1019,9 +861,6 @@
"value": 102,
"keyLabel": "f",
"names": {
- "web": [
- "KeyF"
- ],
"android": [
"F"
],
@@ -1046,9 +885,6 @@
"value": 103,
"keyLabel": "g",
"names": {
- "web": [
- "KeyG"
- ],
"android": [
"G"
],
@@ -1073,9 +909,6 @@
"value": 104,
"keyLabel": "h",
"names": {
- "web": [
- "KeyH"
- ],
"android": [
"H"
],
@@ -1100,9 +933,6 @@
"value": 105,
"keyLabel": "i",
"names": {
- "web": [
- "KeyI"
- ],
"android": [
"I"
],
@@ -1127,9 +957,6 @@
"value": 106,
"keyLabel": "j",
"names": {
- "web": [
- "KeyJ"
- ],
"android": [
"J"
],
@@ -1154,9 +981,6 @@
"value": 107,
"keyLabel": "k",
"names": {
- "web": [
- "KeyK"
- ],
"android": [
"K"
],
@@ -1181,9 +1005,6 @@
"value": 108,
"keyLabel": "l",
"names": {
- "web": [
- "KeyL"
- ],
"android": [
"L"
],
@@ -1208,9 +1029,6 @@
"value": 109,
"keyLabel": "m",
"names": {
- "web": [
- "KeyM"
- ],
"android": [
"M"
],
@@ -1235,9 +1053,6 @@
"value": 110,
"keyLabel": "n",
"names": {
- "web": [
- "KeyN"
- ],
"android": [
"N"
],
@@ -1262,9 +1077,6 @@
"value": 111,
"keyLabel": "o",
"names": {
- "web": [
- "KeyO"
- ],
"android": [
"O"
],
@@ -1289,9 +1101,6 @@
"value": 112,
"keyLabel": "p",
"names": {
- "web": [
- "KeyP"
- ],
"android": [
"P"
],
@@ -1316,9 +1125,6 @@
"value": 113,
"keyLabel": "q",
"names": {
- "web": [
- "KeyQ"
- ],
"android": [
"Q"
],
@@ -1343,9 +1149,6 @@
"value": 114,
"keyLabel": "r",
"names": {
- "web": [
- "KeyR"
- ],
"android": [
"R"
],
@@ -1370,9 +1173,6 @@
"value": 115,
"keyLabel": "s",
"names": {
- "web": [
- "KeyS"
- ],
"android": [
"S"
],
@@ -1397,9 +1197,6 @@
"value": 116,
"keyLabel": "t",
"names": {
- "web": [
- "KeyT"
- ],
"android": [
"T"
],
@@ -1424,9 +1221,6 @@
"value": 117,
"keyLabel": "u",
"names": {
- "web": [
- "KeyU"
- ],
"android": [
"U"
],
@@ -1451,9 +1245,6 @@
"value": 118,
"keyLabel": "v",
"names": {
- "web": [
- "KeyV"
- ],
"android": [
"V"
],
@@ -1478,9 +1269,6 @@
"value": 119,
"keyLabel": "w",
"names": {
- "web": [
- "KeyW"
- ],
"android": [
"W"
],
@@ -1505,9 +1293,6 @@
"value": 120,
"keyLabel": "x",
"names": {
- "web": [
- "KeyX"
- ],
"android": [
"X"
],
@@ -1532,9 +1317,6 @@
"value": 121,
"keyLabel": "y",
"names": {
- "web": [
- "KeyY"
- ],
"android": [
"Y"
],
@@ -1559,9 +1341,6 @@
"value": 122,
"keyLabel": "z",
"names": {
- "web": [
- "KeyZ"
- ],
"android": [
"Z"
],
@@ -1584,42 +1363,22 @@
"BraceLeft": {
"name": "BraceLeft",
"value": 123,
- "keyLabel": "{",
- "names": {
- "web": [
- "BraceLeft"
- ]
- }
+ "keyLabel": "{"
},
"Bar": {
"name": "Bar",
"value": 124,
- "keyLabel": "|",
- "names": {
- "web": [
- "Bar"
- ]
- }
+ "keyLabel": "|"
},
"BraceRight": {
"name": "BraceRight",
"value": 125,
- "keyLabel": "}",
- "names": {
- "web": [
- "BraceRight"
- ]
- }
+ "keyLabel": "}"
},
"Tilde": {
"name": "Tilde",
"value": 126,
- "keyLabel": "~",
- "names": {
- "web": [
- "Tilde"
- ]
- }
+ "keyLabel": "~"
},
"Unidentified": {
"name": "Unidentified",
@@ -1633,7 +1392,6 @@
"Backspace": {
"name": "Backspace",
"value": 4294967304,
- "keyLabel": "\b",
"names": {
"web": [
"Backspace"
@@ -1684,7 +1442,6 @@
"Tab": {
"name": "Tab",
"value": 4294967305,
- "keyLabel": "\t",
"names": {
"web": [
"Tab"
@@ -1739,7 +1496,6 @@
"Enter": {
"name": "Enter",
"value": 4294967309,
- "keyLabel": "\r",
"names": {
"web": [
"Enter"
@@ -1794,7 +1550,6 @@
"Escape": {
"name": "Escape",
"value": 4294967323,
- "keyLabel": "\u001b",
"names": {
"web": [
"Escape"
@@ -1845,7 +1600,6 @@
"Delete": {
"name": "Delete",
"value": 4294967423,
- "keyLabel": "",
"names": {
"web": [
"Delete"
@@ -7866,9 +7620,6 @@
"name": "Suspend",
"value": 8589934592,
"names": {
- "web": [
- "Suspend"
- ],
"gtk": [
"Suspend"
]
@@ -7885,11 +7636,6 @@
"Resume": {
"name": "Resume",
"value": 8589934593,
- "names": {
- "web": [
- "Resume"
- ]
- },
"values": {
"fuchsia": [
77309411349
@@ -7900,9 +7646,6 @@
"name": "Sleep",
"value": 8589934594,
"names": {
- "web": [
- "Sleep"
- ],
"gtk": [
"Sleep"
],
@@ -7931,11 +7674,6 @@
"Abort": {
"name": "Abort",
"value": 8589934595,
- "names": {
- "web": [
- "Abort"
- ]
- },
"values": {
"fuchsia": [
77309870235
@@ -7946,9 +7684,6 @@
"name": "Lang1",
"value": 8589934608,
"names": {
- "web": [
- "Lang1"
- ],
"macos": [
"Lang1"
],
@@ -7978,9 +7713,6 @@
"name": "Lang2",
"value": 8589934609,
"names": {
- "web": [
- "Lang2"
- ],
"macos": [
"Lang2"
],
@@ -8004,9 +7736,6 @@
"name": "Lang3",
"value": 8589934610,
"names": {
- "web": [
- "Lang3"
- ],
"ios": [
"Lang3"
]
@@ -8024,9 +7753,6 @@
"name": "Lang4",
"value": 8589934611,
"names": {
- "web": [
- "Lang4"
- ],
"ios": [
"Lang4"
]
@@ -8044,9 +7770,6 @@
"name": "Lang5",
"value": 8589934612,
"names": {
- "web": [
- "Lang5"
- ],
"ios": [
"Lang5"
]
@@ -8063,11 +7786,6 @@
"IntlBackslash": {
"name": "IntlBackslash",
"value": 8589934624,
- "names": {
- "web": [
- "IntlBackslash"
- ]
- },
"values": {
"fuchsia": [
77309870180
@@ -8078,9 +7796,6 @@
"name": "IntlRo",
"value": 8589934625,
"names": {
- "web": [
- "IntlRo"
- ],
"macos": [
"IntlRo"
],
@@ -8110,9 +7825,6 @@
"name": "IntlYen",
"value": 8589934626,
"names": {
- "web": [
- "IntlYen"
- ],
"macos": [
"IntlYen"
],
@@ -8148,9 +7860,6 @@
"name": "ControlLeft",
"value": 8589934848,
"names": {
- "web": [
- "ControlLeft"
- ],
"macos": [
"ControlLeft"
],
@@ -8200,9 +7909,6 @@
"name": "ControlRight",
"value": 8589934849,
"names": {
- "web": [
- "ControlRight"
- ],
"macos": [
"ControlRight"
],
@@ -8250,9 +7956,6 @@
"name": "ShiftLeft",
"value": 8589934850,
"names": {
- "web": [
- "ShiftLeft"
- ],
"macos": [
"ShiftLeft"
],
@@ -8302,9 +8005,6 @@
"name": "ShiftRight",
"value": 8589934851,
"names": {
- "web": [
- "ShiftRight"
- ],
"macos": [
"ShiftRight"
],
@@ -8352,9 +8052,6 @@
"name": "AltLeft",
"value": 8589934852,
"names": {
- "web": [
- "AltLeft"
- ],
"macos": [
"AltLeft"
],
@@ -8402,9 +8099,6 @@
"name": "AltRight",
"value": 8589934853,
"names": {
- "web": [
- "AltRight"
- ],
"macos": [
"AltRight"
],
@@ -8454,9 +8148,6 @@
"name": "MetaLeft",
"value": 8589934854,
"names": {
- "web": [
- "MetaLeft"
- ],
"macos": [
"MetaLeft"
],
@@ -8504,9 +8195,6 @@
"name": "MetaRight",
"value": 8589934855,
"names": {
- "web": [
- "MetaRight"
- ],
"macos": [
"MetaRight"
],
@@ -8552,47 +8240,24 @@
},
"Control": {
"name": "Control",
- "value": 8589935088,
- "names": {
- "web": [
- "Control"
- ]
- }
+ "value": 8589935088
},
"Shift": {
"name": "Shift",
- "value": 8589935090,
- "names": {
- "web": [
- "Shift"
- ]
- }
+ "value": 8589935090
},
"Alt": {
"name": "Alt",
- "value": 8589935092,
- "names": {
- "web": [
- "Alt"
- ]
- }
+ "value": 8589935092
},
"Meta": {
"name": "Meta",
- "value": 8589935094,
- "names": {
- "web": [
- "Meta"
- ]
- }
+ "value": 8589935094
},
"NumpadEnter": {
"name": "NumpadEnter",
"value": 8589935117,
"names": {
- "web": [
- "NumpadEnter"
- ],
"macos": [
"NumpadEnter"
],
@@ -8634,9 +8299,6 @@
"name": "NumpadParenLeft",
"value": 8589935144,
"names": {
- "web": [
- "NumpadParenLeft"
- ],
"android": [
"NUMPAD_LEFT_PAREN"
]
@@ -8654,9 +8316,6 @@
"name": "NumpadParenRight",
"value": 8589935145,
"names": {
- "web": [
- "NumpadParenRight"
- ],
"android": [
"NUMPAD_RIGHT_PAREN"
]
@@ -8674,9 +8333,6 @@
"name": "NumpadMultiply",
"value": 8589935146,
"names": {
- "web": [
- "NumpadMultiply"
- ],
"macos": [
"NumpadMultiply"
],
@@ -8724,9 +8380,6 @@
"name": "NumpadAdd",
"value": 8589935147,
"names": {
- "web": [
- "NumpadAdd"
- ],
"macos": [
"NumpadAdd"
],
@@ -8774,9 +8427,6 @@
"name": "NumpadComma",
"value": 8589935148,
"names": {
- "web": [
- "NumpadComma"
- ],
"macos": [
"NumpadComma"
],
@@ -8812,9 +8462,6 @@
"name": "NumpadSubtract",
"value": 8589935149,
"names": {
- "web": [
- "NumpadSubtract"
- ],
"macos": [
"NumpadSubtract"
],
@@ -8856,9 +8503,6 @@
"name": "NumpadDecimal",
"value": 8589935150,
"names": {
- "web": [
- "NumpadDecimal"
- ],
"macos": [
"NumpadDecimal"
],
@@ -8906,9 +8550,6 @@
"name": "NumpadDivide",
"value": 8589935151,
"names": {
- "web": [
- "NumpadDivide"
- ],
"macos": [
"NumpadDivide"
],
@@ -8956,9 +8597,6 @@
"name": "Numpad0",
"value": 8589935152,
"names": {
- "web": [
- "Numpad0"
- ],
"macos": [
"Numpad0"
],
@@ -9008,9 +8646,6 @@
"name": "Numpad1",
"value": 8589935153,
"names": {
- "web": [
- "Numpad1"
- ],
"macos": [
"Numpad1"
],
@@ -9060,9 +8695,6 @@
"name": "Numpad2",
"value": 8589935154,
"names": {
- "web": [
- "Numpad2"
- ],
"macos": [
"Numpad2"
],
@@ -9112,9 +8744,6 @@
"name": "Numpad3",
"value": 8589935155,
"names": {
- "web": [
- "Numpad3"
- ],
"macos": [
"Numpad3"
],
@@ -9164,9 +8793,6 @@
"name": "Numpad4",
"value": 8589935156,
"names": {
- "web": [
- "Numpad4"
- ],
"macos": [
"Numpad4"
],
@@ -9216,9 +8842,6 @@
"name": "Numpad5",
"value": 8589935157,
"names": {
- "web": [
- "Numpad5"
- ],
"macos": [
"Numpad5"
],
@@ -9266,9 +8889,6 @@
"name": "Numpad6",
"value": 8589935158,
"names": {
- "web": [
- "Numpad6"
- ],
"macos": [
"Numpad6"
],
@@ -9318,9 +8938,6 @@
"name": "Numpad7",
"value": 8589935159,
"names": {
- "web": [
- "Numpad7"
- ],
"macos": [
"Numpad7"
],
@@ -9370,9 +8987,6 @@
"name": "Numpad8",
"value": 8589935160,
"names": {
- "web": [
- "Numpad8"
- ],
"macos": [
"Numpad8"
],
@@ -9422,9 +9036,6 @@
"name": "Numpad9",
"value": 8589935161,
"names": {
- "web": [
- "Numpad9"
- ],
"macos": [
"Numpad9"
],
@@ -9474,9 +9085,6 @@
"name": "NumpadEqual",
"value": 8589935165,
"names": {
- "web": [
- "NumpadEqual"
- ],
"macos": [
"NumpadEqual"
],
@@ -9524,9 +9132,6 @@
"name": "GameButton1",
"value": 8589935361,
"names": {
- "web": [
- "GameButton1"
- ],
"android": [
"BUTTON_1"
]
@@ -9544,9 +9149,6 @@
"name": "GameButton2",
"value": 8589935362,
"names": {
- "web": [
- "GameButton2"
- ],
"android": [
"BUTTON_2"
]
@@ -9564,9 +9166,6 @@
"name": "GameButton3",
"value": 8589935363,
"names": {
- "web": [
- "GameButton3"
- ],
"android": [
"BUTTON_3"
]
@@ -9584,9 +9183,6 @@
"name": "GameButton4",
"value": 8589935364,
"names": {
- "web": [
- "GameButton4"
- ],
"android": [
"BUTTON_4"
]
@@ -9604,9 +9200,6 @@
"name": "GameButton5",
"value": 8589935365,
"names": {
- "web": [
- "GameButton5"
- ],
"android": [
"BUTTON_5"
]
@@ -9624,9 +9217,6 @@
"name": "GameButton6",
"value": 8589935366,
"names": {
- "web": [
- "GameButton6"
- ],
"android": [
"BUTTON_6"
]
@@ -9644,9 +9234,6 @@
"name": "GameButton7",
"value": 8589935367,
"names": {
- "web": [
- "GameButton7"
- ],
"android": [
"BUTTON_7"
]
@@ -9664,9 +9251,6 @@
"name": "GameButton8",
"value": 8589935368,
"names": {
- "web": [
- "GameButton8"
- ],
"windows": [
"GAMEPAD_A"
],
@@ -9690,9 +9274,6 @@
"name": "GameButton9",
"value": 8589935369,
"names": {
- "web": [
- "GameButton9"
- ],
"windows": [
"GAMEPAD_B"
],
@@ -9716,9 +9297,6 @@
"name": "GameButton10",
"value": 8589935370,
"names": {
- "web": [
- "GameButton10"
- ],
"windows": [
"GAMEPAD_X"
],
@@ -9742,9 +9320,6 @@
"name": "GameButton11",
"value": 8589935371,
"names": {
- "web": [
- "GameButton11"
- ],
"windows": [
"GAMEPAD_Y"
],
@@ -9768,9 +9343,6 @@
"name": "GameButton12",
"value": 8589935372,
"names": {
- "web": [
- "GameButton12"
- ],
"windows": [
"GAMEPAD_RIGHT_SHOULDER"
],
@@ -9794,9 +9366,6 @@
"name": "GameButton13",
"value": 8589935373,
"names": {
- "web": [
- "GameButton13"
- ],
"windows": [
"GAMEPAD_LEFT_SHOULDER"
],
@@ -9820,9 +9389,6 @@
"name": "GameButton14",
"value": 8589935374,
"names": {
- "web": [
- "GameButton14"
- ],
"windows": [
"GAMEPAD_LEFT_TRIGGER"
],
@@ -9846,9 +9412,6 @@
"name": "GameButton15",
"value": 8589935375,
"names": {
- "web": [
- "GameButton15"
- ],
"windows": [
"GAMEPAD_RIGHT_TRIGGER"
],
@@ -9872,9 +9435,6 @@
"name": "GameButton16",
"value": 8589935376,
"names": {
- "web": [
- "GameButton16"
- ],
"windows": [
"GAMEPAD_DPAD_UP"
],
@@ -9898,9 +9458,6 @@
"name": "GameButtonA",
"value": 8589935377,
"names": {
- "web": [
- "GameButtonA"
- ],
"android": [
"BUTTON_A"
]
@@ -9918,9 +9475,6 @@
"name": "GameButtonB",
"value": 8589935378,
"names": {
- "web": [
- "GameButtonB"
- ],
"android": [
"BUTTON_B"
]
@@ -9938,9 +9492,6 @@
"name": "GameButtonC",
"value": 8589935379,
"names": {
- "web": [
- "GameButtonC"
- ],
"android": [
"BUTTON_C"
]
@@ -9958,9 +9509,6 @@
"name": "GameButtonLeft1",
"value": 8589935380,
"names": {
- "web": [
- "GameButtonLeft1"
- ],
"android": [
"BUTTON_L1"
]
@@ -9978,9 +9526,6 @@
"name": "GameButtonLeft2",
"value": 8589935381,
"names": {
- "web": [
- "GameButtonLeft2"
- ],
"android": [
"BUTTON_L2"
]
@@ -9998,9 +9543,6 @@
"name": "GameButtonMode",
"value": 8589935382,
"names": {
- "web": [
- "GameButtonMode"
- ],
"android": [
"BUTTON_MODE"
]
@@ -10018,9 +9560,6 @@
"name": "GameButtonRight1",
"value": 8589935383,
"names": {
- "web": [
- "GameButtonRight1"
- ],
"android": [
"BUTTON_R1"
]
@@ -10038,9 +9577,6 @@
"name": "GameButtonRight2",
"value": 8589935384,
"names": {
- "web": [
- "GameButtonRight2"
- ],
"android": [
"BUTTON_R2"
]
@@ -10058,9 +9594,6 @@
"name": "GameButtonSelect",
"value": 8589935385,
"names": {
- "web": [
- "GameButtonSelect"
- ],
"android": [
"BUTTON_SELECT"
]
@@ -10078,9 +9611,6 @@
"name": "GameButtonStart",
"value": 8589935386,
"names": {
- "web": [
- "GameButtonStart"
- ],
"android": [
"BUTTON_START"
]
@@ -10098,9 +9628,6 @@
"name": "GameButtonThumbLeft",
"value": 8589935387,
"names": {
- "web": [
- "GameButtonThumbLeft"
- ],
"android": [
"BUTTON_THUMBL"
]
@@ -10118,9 +9645,6 @@
"name": "GameButtonThumbRight",
"value": 8589935388,
"names": {
- "web": [
- "GameButtonThumbRight"
- ],
"android": [
"BUTTON_THUMBR"
]
@@ -10138,9 +9662,6 @@
"name": "GameButtonX",
"value": 8589935389,
"names": {
- "web": [
- "GameButtonX"
- ],
"android": [
"BUTTON_X"
]
@@ -10158,9 +9679,6 @@
"name": "GameButtonY",
"value": 8589935390,
"names": {
- "web": [
- "GameButtonY"
- ],
"android": [
"BUTTON_Y"
]
@@ -10178,9 +9696,6 @@
"name": "GameButtonZ",
"value": 8589935391,
"names": {
- "web": [
- "GameButtonZ"
- ],
"android": [
"BUTTON_Z"
]
diff --git a/dev/tools/gen_keycodes/lib/logical_key_data.dart b/dev/tools/gen_keycodes/lib/logical_key_data.dart
index a26d4b5..9941902 100644
--- a/dev/tools/gen_keycodes/lib/logical_key_data.dart
+++ b/dev/tools/gen_keycodes/lib/logical_key_data.dart
@@ -11,11 +11,7 @@
import 'constants.dart';
import 'physical_key_data.dart';
-bool _isControlCharacter(String label) {
- if (label.length != 1) {
- return false;
- }
- final int codeUnit = label.codeUnitAt(0);
+bool _isControlCharacter(int codeUnit) {
return (codeUnit <= 0x1f && codeUnit >= 0x00) || (codeUnit >= 0x7f && codeUnit <= 0x9f);
}
@@ -27,8 +23,11 @@
final String right;
}
-List<T> _toNonEmptyArray<T>(dynamic source) {
- final List<dynamic>? dynamicNullableList = source as List<dynamic>?;
+// Return map[key1][key2] as a non-nullable List<T>, where both map[key1] or
+// map[key1][key2] might be null.
+List<T> _getGrandchildList<T>(Map<String, dynamic> map, String key1, String key2) {
+ final dynamic value = (map[key1] as Map<String, dynamic>?)?[key2];
+ final List<dynamic>? dynamicNullableList = value as List<dynamic>?;
final List<dynamic> dynamicList = dynamicNullableList ?? <dynamic>[];
return dynamicList.cast<T>();
}
@@ -155,20 +154,23 @@
final int value = match.namedGroup('unicode') != null ?
getHex(match.namedGroup('unicode')!) :
match.namedGroup('char')!.codeUnitAt(0);
- final String? keyLabel = match.namedGroup('kind')! == 'UNI' ? String.fromCharCode(value) : null;
+ final String? keyLabel = (match.namedGroup('kind')! == 'UNI' && !_isControlCharacter(value)) ?
+ String.fromCharCode(value) : null;
// Skip modifier keys from DOM. They will be added with supplemental data.
if (_chromeModifiers.containsKey(name) && source == 'DOM') {
continue;
}
- final bool isPrintable = (keyLabel != null && !_isControlCharacter(keyLabel))
- || printable.containsKey(name);
+ final bool isPrintable = keyLabel != null;
data.putIfAbsent(name, () {
- return LogicalKeyEntry.fromName(
+ final LogicalKeyEntry entry = LogicalKeyEntry.fromName(
value: toPlane(value, _sourceToPlane(source, isPrintable)),
name: name,
keyLabel: keyLabel,
- )..webNames.add(webName);
+ );
+ if (source == 'DOM' && !isPrintable)
+ entry.webNames.add(webName);
+ return entry;
});
}
}
@@ -418,9 +420,11 @@
})();
static int _sourceToPlane(String source, bool isPrintable) {
+ if (isPrintable)
+ return kUnicodePlane.value;
switch (source) {
case 'DOM':
- return isPrintable ? kUnicodePlane.value : kUnprintablePlane.value;
+ return kUnprintablePlane.value;
case 'FLUTTER':
return kFlutterPlane.value;
default:
@@ -470,20 +474,20 @@
LogicalKeyEntry.fromJsonMapEntry(Map<String, dynamic> map)
: value = map['value'] as int,
name = map['name'] as String,
- webNames = _toNonEmptyArray<String>((map['names'] as Map<String, dynamic>)['web']),
- macOSKeyCodeNames = _toNonEmptyArray<String>((map['names'] as Map<String, dynamic>)['macos']),
- macOSKeyCodeValues = _toNonEmptyArray<int>((map['values'] as Map<String, dynamic>?)?['macos']),
- iOSKeyCodeNames = _toNonEmptyArray<String>((map['names'] as Map<String, dynamic>)['ios']),
- iOSKeyCodeValues = _toNonEmptyArray<int>((map['values'] as Map<String, dynamic>?)?['ios']),
- gtkNames = _toNonEmptyArray<String>((map['names'] as Map<String, dynamic>)['gtk']),
- gtkValues = _toNonEmptyArray<int>((map['values'] as Map<String, dynamic>?)?['gtk']),
- windowsNames = _toNonEmptyArray<String>((map['names'] as Map<String, dynamic>)['windows']),
- windowsValues = _toNonEmptyArray<int>((map['values'] as Map<String, dynamic>?)?['windows']),
- androidNames = _toNonEmptyArray<String>((map['names'] as Map<String, dynamic>)['android']),
- androidValues = _toNonEmptyArray<int>((map['values'] as Map<String, dynamic>?)?['android']),
- fuchsiaValues = _toNonEmptyArray<int>((map['values'] as Map<String, dynamic>?)?['fuchsia']),
- glfwNames = _toNonEmptyArray<String>((map['names'] as Map<String, dynamic>)['glfw']),
- glfwValues = _toNonEmptyArray<int>((map['values'] as Map<String, dynamic>?)?['glfw']),
+ webNames = _getGrandchildList<String>(map, 'names', 'web'),
+ macOSKeyCodeNames = _getGrandchildList<String>(map, 'names', 'macos'),
+ macOSKeyCodeValues = _getGrandchildList<int>(map, 'values', 'macos'),
+ iOSKeyCodeNames = _getGrandchildList<String>(map, 'names', 'ios'),
+ iOSKeyCodeValues = _getGrandchildList<int>(map, 'values', 'ios'),
+ gtkNames = _getGrandchildList<String>(map, 'names', 'gtk'),
+ gtkValues = _getGrandchildList<int>(map, 'values', 'gtk'),
+ windowsNames = _getGrandchildList<String>(map, 'names', 'windows'),
+ windowsValues = _getGrandchildList<int>(map, 'values', 'windows'),
+ androidNames = _getGrandchildList<String>(map, 'names', 'android'),
+ androidValues = _getGrandchildList<int>(map, 'values', 'android'),
+ fuchsiaValues = _getGrandchildList<int>(map, 'values', 'fuchsia'),
+ glfwNames = _getGrandchildList<String>(map, 'names', 'glfw'),
+ glfwValues = _getGrandchildList<int>(map, 'values', 'glfw'),
keyLabel = map['keyLabel'] as String?;
final int value;
diff --git a/dev/tools/gen_keycodes/test/gen_keycodes_test.dart b/dev/tools/gen_keycodes/test/gen_keycodes_test.dart
index 447ee4d..a963eb5 100644
--- a/dev/tools/gen_keycodes/test/gen_keycodes_test.dart
+++ b/dev/tools/gen_keycodes/test/gen_keycodes_test.dart
@@ -22,8 +22,10 @@
return File(path.join(dataRoot, fileName)).readAsStringSync();
}
-final String testPhysicalData = path.join(dataRoot, 'physical_key_data.json');
-final String testLogicalData = path.join(dataRoot,'logical_key_data.json');
+final PhysicalKeyData physicalData = PhysicalKeyData.fromJson(
+ json.decode(readDataFile('physical_key_data.json')) as Map<String, dynamic>);
+final LogicalKeyData logicalData = LogicalKeyData.fromJson(
+ json.decode(readDataFile('logical_key_data.json')) as Map<String, dynamic>);
void main() {
setUp(() {
@@ -45,14 +47,6 @@
}
test('Generate Keycodes for Android', () {
- PhysicalKeyData physicalData;
- LogicalKeyData logicalData;
-
- physicalData = PhysicalKeyData.fromJson(
- json.decode(File(testPhysicalData).readAsStringSync()) as Map<String, dynamic>);
- logicalData = LogicalKeyData.fromJson(
- json.decode(File(testLogicalData).readAsStringSync()) as Map<String, dynamic>);
-
const String platform = 'android';
final PlatformCodeGenerator codeGenerator = AndroidCodeGenerator(
physicalData,
@@ -67,14 +61,6 @@
checkCommonOutput(output);
});
test('Generate Keycodes for macOS', () {
- PhysicalKeyData physicalData;
- LogicalKeyData logicalData;
-
- physicalData = PhysicalKeyData.fromJson(
- json.decode(File(testPhysicalData).readAsStringSync()) as Map<String, dynamic>);
- logicalData = LogicalKeyData.fromJson(
- json.decode(File(testLogicalData).readAsStringSync()) as Map<String, dynamic>);
-
const String platform = 'macos';
final PlatformCodeGenerator codeGenerator = MacOSCodeGenerator(
physicalData,
@@ -93,14 +79,6 @@
checkCommonOutput(output);
});
test('Generate Keycodes for iOS', () {
- PhysicalKeyData physicalData;
- LogicalKeyData logicalData;
-
- physicalData = PhysicalKeyData.fromJson(
- json.decode(File(testPhysicalData).readAsStringSync()) as Map<String, dynamic>);
- logicalData = LogicalKeyData.fromJson(
- json.decode(File(testLogicalData).readAsStringSync()) as Map<String, dynamic>);
-
const String platform = 'ios';
final PlatformCodeGenerator codeGenerator = IOSCodeGenerator(
physicalData,
@@ -120,14 +98,6 @@
checkCommonOutput(output);
});
test('Generate Keycodes for Windows', () {
- PhysicalKeyData physicalData;
- LogicalKeyData logicalData;
-
- physicalData = PhysicalKeyData.fromJson(
- json.decode(File(testPhysicalData).readAsStringSync()) as Map<String, dynamic>);
- logicalData = LogicalKeyData.fromJson(
- json.decode(File(testLogicalData).readAsStringSync()) as Map<String, dynamic>);
-
const String platform = 'windows';
final PlatformCodeGenerator codeGenerator = WindowsCodeGenerator(
physicalData,
@@ -143,14 +113,6 @@
checkCommonOutput(output);
});
test('Generate Keycodes for Linux', () {
- PhysicalKeyData physicalData;
- LogicalKeyData logicalData;
-
- physicalData = PhysicalKeyData.fromJson(
- json.decode(File(testPhysicalData).readAsStringSync()) as Map<String, dynamic>);
- logicalData = LogicalKeyData.fromJson(
- json.decode(File(testLogicalData).readAsStringSync()) as Map<String, dynamic>);
-
const String platform = 'gtk';
final PlatformCodeGenerator codeGenerator = GtkCodeGenerator(
physicalData,
@@ -166,14 +128,6 @@
checkCommonOutput(output);
});
test('Generate Keycodes for Web', () {
- PhysicalKeyData physicalData;
- LogicalKeyData logicalData;
-
- physicalData = PhysicalKeyData.fromJson(
- json.decode(File(testPhysicalData).readAsStringSync()) as Map<String, dynamic>);
- logicalData = LogicalKeyData.fromJson(
- json.decode(File(testLogicalData).readAsStringSync()) as Map<String, dynamic>);
-
const String platform = 'web';
final PlatformCodeGenerator codeGenerator = WebCodeGenerator(
physicalData,
@@ -188,4 +142,25 @@
expect(output, contains('kWebLogicalLocationMap'));
checkCommonOutput(output);
});
+ test('LogicalKeyData', () async {
+ final List<LogicalKeyEntry> entries = logicalData.entries.toList();
+
+ // Regression tests for https://github.com/flutter/flutter/pull/87098
+
+ expect(
+ entries.indexWhere((LogicalKeyEntry entry) => entry.name == 'ShiftLeft'),
+ isNot(-1));
+ expect(
+ entries.indexWhere((LogicalKeyEntry entry) => entry.webNames.contains('ShiftLeft')),
+ -1);
+ // 'Shift' maps to both 'ShiftLeft' and 'ShiftRight', and should be resolved
+ // by other ways.
+ expect(
+ entries.indexWhere((LogicalKeyEntry entry) => entry.webNames.contains('Shift')),
+ -1);
+ // Printable keys must not be added with Web key of their names.
+ expect(
+ entries.indexWhere((LogicalKeyEntry entry) => entry.webNames.contains('Slash')),
+ -1);
+ });
}
diff --git a/packages/flutter/lib/src/services/keyboard_maps.dart b/packages/flutter/lib/src/services/keyboard_maps.dart
index 74cea74..3827e9e 100644
--- a/packages/flutter/lib/src/services/keyboard_maps.dart
+++ b/packages/flutter/lib/src/services/keyboard_maps.dart
@@ -2141,25 +2141,17 @@
const Map<String, LogicalKeyboardKey> kWebToLogicalKey = <String, LogicalKeyboardKey>{
'AVRInput': LogicalKeyboardKey.avrInput,
'AVRPower': LogicalKeyboardKey.avrPower,
- 'Abort': LogicalKeyboardKey.abort,
'Accel': LogicalKeyboardKey.accel,
'Accept': LogicalKeyboardKey.accept,
- 'Add': LogicalKeyboardKey.add,
'Again': LogicalKeyboardKey.again,
'AllCandidates': LogicalKeyboardKey.allCandidates,
'Alphanumeric': LogicalKeyboardKey.alphanumeric,
- 'Alt': LogicalKeyboardKey.alt,
'AltGraph': LogicalKeyboardKey.altGraph,
- 'AltLeft': LogicalKeyboardKey.altLeft,
- 'AltRight': LogicalKeyboardKey.altRight,
- 'Ampersand': LogicalKeyboardKey.ampersand,
'AppSwitch': LogicalKeyboardKey.appSwitch,
'ArrowDown': LogicalKeyboardKey.arrowDown,
'ArrowLeft': LogicalKeyboardKey.arrowLeft,
'ArrowRight': LogicalKeyboardKey.arrowRight,
'ArrowUp': LogicalKeyboardKey.arrowUp,
- 'Asterisk': LogicalKeyboardKey.asterisk,
- 'At': LogicalKeyboardKey.at,
'Attn': LogicalKeyboardKey.attn,
'AudioBalanceLeft': LogicalKeyboardKey.audioBalanceLeft,
'AudioBalanceRight': LogicalKeyboardKey.audioBalanceRight,
@@ -2174,14 +2166,7 @@
'AudioVolumeDown': LogicalKeyboardKey.audioVolumeDown,
'AudioVolumeMute': LogicalKeyboardKey.audioVolumeMute,
'AudioVolumeUp': LogicalKeyboardKey.audioVolumeUp,
- 'Backquote': LogicalKeyboardKey.backquote,
- 'Backslash': LogicalKeyboardKey.backslash,
'Backspace': LogicalKeyboardKey.backspace,
- 'Bar': LogicalKeyboardKey.bar,
- 'BraceLeft': LogicalKeyboardKey.braceLeft,
- 'BraceRight': LogicalKeyboardKey.braceRight,
- 'BracketLeft': LogicalKeyboardKey.bracketLeft,
- 'BracketRight': LogicalKeyboardKey.bracketRight,
'BrightnessDown': LogicalKeyboardKey.brightnessDown,
'BrightnessUp': LogicalKeyboardKey.brightnessUp,
'BrowserBack': LogicalKeyboardKey.browserBack,
@@ -2196,55 +2181,36 @@
'CameraFocus': LogicalKeyboardKey.cameraFocus,
'Cancel': LogicalKeyboardKey.cancel,
'CapsLock': LogicalKeyboardKey.capsLock,
- 'Caret': LogicalKeyboardKey.caret,
'ChannelDown': LogicalKeyboardKey.channelDown,
'ChannelUp': LogicalKeyboardKey.channelUp,
'Clear': LogicalKeyboardKey.clear,
'Close': LogicalKeyboardKey.close,
'ClosedCaptionToggle': LogicalKeyboardKey.closedCaptionToggle,
'CodeInput': LogicalKeyboardKey.codeInput,
- 'Colon': LogicalKeyboardKey.colon,
'ColorF0Red': LogicalKeyboardKey.colorF0Red,
'ColorF1Green': LogicalKeyboardKey.colorF1Green,
'ColorF2Yellow': LogicalKeyboardKey.colorF2Yellow,
'ColorF3Blue': LogicalKeyboardKey.colorF3Blue,
'ColorF4Grey': LogicalKeyboardKey.colorF4Grey,
'ColorF5Brown': LogicalKeyboardKey.colorF5Brown,
- 'Comma': LogicalKeyboardKey.comma,
'Compose': LogicalKeyboardKey.compose,
'ContextMenu': LogicalKeyboardKey.contextMenu,
- 'Control': LogicalKeyboardKey.control,
- 'ControlLeft': LogicalKeyboardKey.controlLeft,
- 'ControlRight': LogicalKeyboardKey.controlRight,
'Convert': LogicalKeyboardKey.convert,
'Copy': LogicalKeyboardKey.copy,
'CrSel': LogicalKeyboardKey.crSel,
'Cut': LogicalKeyboardKey.cut,
'DVR': LogicalKeyboardKey.dvr,
'Delete': LogicalKeyboardKey.delete,
- 'Digit0': LogicalKeyboardKey.digit0,
- 'Digit1': LogicalKeyboardKey.digit1,
- 'Digit2': LogicalKeyboardKey.digit2,
- 'Digit3': LogicalKeyboardKey.digit3,
- 'Digit4': LogicalKeyboardKey.digit4,
- 'Digit5': LogicalKeyboardKey.digit5,
- 'Digit6': LogicalKeyboardKey.digit6,
- 'Digit7': LogicalKeyboardKey.digit7,
- 'Digit8': LogicalKeyboardKey.digit8,
- 'Digit9': LogicalKeyboardKey.digit9,
'Dimmer': LogicalKeyboardKey.dimmer,
'DisplaySwap': LogicalKeyboardKey.displaySwap,
- 'Dollar': LogicalKeyboardKey.dollar,
'Eisu': LogicalKeyboardKey.eisu,
'Eject': LogicalKeyboardKey.eject,
'End': LogicalKeyboardKey.end,
'EndCall': LogicalKeyboardKey.endCall,
'Enter': LogicalKeyboardKey.enter,
- 'Equal': LogicalKeyboardKey.equal,
'EraseEof': LogicalKeyboardKey.eraseEof,
'Escape': LogicalKeyboardKey.escape,
'ExSel': LogicalKeyboardKey.exSel,
- 'Exclamation': LogicalKeyboardKey.exclamation,
'Execute': LogicalKeyboardKey.execute,
'Exit': LogicalKeyboardKey.exit,
'F1': LogicalKeyboardKey.f1,
@@ -2287,40 +2253,8 @@
'Find': LogicalKeyboardKey.find,
'Fn': LogicalKeyboardKey.fn,
'FnLock': LogicalKeyboardKey.fnLock,
- 'GameButton1': LogicalKeyboardKey.gameButton1,
- 'GameButton10': LogicalKeyboardKey.gameButton10,
- 'GameButton11': LogicalKeyboardKey.gameButton11,
- 'GameButton12': LogicalKeyboardKey.gameButton12,
- 'GameButton13': LogicalKeyboardKey.gameButton13,
- 'GameButton14': LogicalKeyboardKey.gameButton14,
- 'GameButton15': LogicalKeyboardKey.gameButton15,
- 'GameButton16': LogicalKeyboardKey.gameButton16,
- 'GameButton2': LogicalKeyboardKey.gameButton2,
- 'GameButton3': LogicalKeyboardKey.gameButton3,
- 'GameButton4': LogicalKeyboardKey.gameButton4,
- 'GameButton5': LogicalKeyboardKey.gameButton5,
- 'GameButton6': LogicalKeyboardKey.gameButton6,
- 'GameButton7': LogicalKeyboardKey.gameButton7,
- 'GameButton8': LogicalKeyboardKey.gameButton8,
- 'GameButton9': LogicalKeyboardKey.gameButton9,
- 'GameButtonA': LogicalKeyboardKey.gameButtonA,
- 'GameButtonB': LogicalKeyboardKey.gameButtonB,
- 'GameButtonC': LogicalKeyboardKey.gameButtonC,
- 'GameButtonLeft1': LogicalKeyboardKey.gameButtonLeft1,
- 'GameButtonLeft2': LogicalKeyboardKey.gameButtonLeft2,
- 'GameButtonMode': LogicalKeyboardKey.gameButtonMode,
- 'GameButtonRight1': LogicalKeyboardKey.gameButtonRight1,
- 'GameButtonRight2': LogicalKeyboardKey.gameButtonRight2,
- 'GameButtonSelect': LogicalKeyboardKey.gameButtonSelect,
- 'GameButtonStart': LogicalKeyboardKey.gameButtonStart,
- 'GameButtonThumbLeft': LogicalKeyboardKey.gameButtonThumbLeft,
- 'GameButtonThumbRight': LogicalKeyboardKey.gameButtonThumbRight,
- 'GameButtonX': LogicalKeyboardKey.gameButtonX,
- 'GameButtonY': LogicalKeyboardKey.gameButtonY,
- 'GameButtonZ': LogicalKeyboardKey.gameButtonZ,
'GoBack': LogicalKeyboardKey.goBack,
'GoHome': LogicalKeyboardKey.goHome,
- 'Greater': LogicalKeyboardKey.greater,
'GroupFirst': LogicalKeyboardKey.groupFirst,
'GroupLast': LogicalKeyboardKey.groupLast,
'GroupNext': LogicalKeyboardKey.groupNext,
@@ -2341,46 +2275,12 @@
'Info': LogicalKeyboardKey.info,
'Insert': LogicalKeyboardKey.insert,
'InstantReplay': LogicalKeyboardKey.instantReplay,
- 'IntlBackslash': LogicalKeyboardKey.intlBackslash,
- 'IntlRo': LogicalKeyboardKey.intlRo,
- 'IntlYen': LogicalKeyboardKey.intlYen,
'JunjaMode': LogicalKeyboardKey.junjaMode,
'KanaMode': LogicalKeyboardKey.kanaMode,
'KanjiMode': LogicalKeyboardKey.kanjiMode,
'Katakana': LogicalKeyboardKey.katakana,
'Key11': LogicalKeyboardKey.key11,
'Key12': LogicalKeyboardKey.key12,
- 'KeyA': LogicalKeyboardKey.keyA,
- 'KeyB': LogicalKeyboardKey.keyB,
- 'KeyC': LogicalKeyboardKey.keyC,
- 'KeyD': LogicalKeyboardKey.keyD,
- 'KeyE': LogicalKeyboardKey.keyE,
- 'KeyF': LogicalKeyboardKey.keyF,
- 'KeyG': LogicalKeyboardKey.keyG,
- 'KeyH': LogicalKeyboardKey.keyH,
- 'KeyI': LogicalKeyboardKey.keyI,
- 'KeyJ': LogicalKeyboardKey.keyJ,
- 'KeyK': LogicalKeyboardKey.keyK,
- 'KeyL': LogicalKeyboardKey.keyL,
- 'KeyM': LogicalKeyboardKey.keyM,
- 'KeyN': LogicalKeyboardKey.keyN,
- 'KeyO': LogicalKeyboardKey.keyO,
- 'KeyP': LogicalKeyboardKey.keyP,
- 'KeyQ': LogicalKeyboardKey.keyQ,
- 'KeyR': LogicalKeyboardKey.keyR,
- 'KeyS': LogicalKeyboardKey.keyS,
- 'KeyT': LogicalKeyboardKey.keyT,
- 'KeyU': LogicalKeyboardKey.keyU,
- 'KeyV': LogicalKeyboardKey.keyV,
- 'KeyW': LogicalKeyboardKey.keyW,
- 'KeyX': LogicalKeyboardKey.keyX,
- 'KeyY': LogicalKeyboardKey.keyY,
- 'KeyZ': LogicalKeyboardKey.keyZ,
- 'Lang1': LogicalKeyboardKey.lang1,
- 'Lang2': LogicalKeyboardKey.lang2,
- 'Lang3': LogicalKeyboardKey.lang3,
- 'Lang4': LogicalKeyboardKey.lang4,
- 'Lang5': LogicalKeyboardKey.lang5,
'LastNumberRedial': LogicalKeyboardKey.lastNumberRedial,
'LaunchApplication1': LogicalKeyboardKey.launchApplication1,
'LaunchApplication2': LogicalKeyboardKey.launchApplication2,
@@ -2397,7 +2297,6 @@
'LaunchWebBrowser': LogicalKeyboardKey.launchWebBrowser,
'LaunchWebCam': LogicalKeyboardKey.launchWebCam,
'LaunchWordProcessor': LogicalKeyboardKey.launchWordProcessor,
- 'Less': LogicalKeyboardKey.less,
'Link': LogicalKeyboardKey.link,
'ListProgram': LogicalKeyboardKey.listProgram,
'LiveContent': LogicalKeyboardKey.liveContent,
@@ -2426,14 +2325,10 @@
'MediaTopMenu': LogicalKeyboardKey.mediaTopMenu,
'MediaTrackNext': LogicalKeyboardKey.mediaTrackNext,
'MediaTrackPrevious': LogicalKeyboardKey.mediaTrackPrevious,
- 'Meta': LogicalKeyboardKey.meta,
- 'MetaLeft': LogicalKeyboardKey.metaLeft,
- 'MetaRight': LogicalKeyboardKey.metaRight,
'MicrophoneToggle': LogicalKeyboardKey.microphoneToggle,
'MicrophoneVolumeDown': LogicalKeyboardKey.microphoneVolumeDown,
'MicrophoneVolumeMute': LogicalKeyboardKey.microphoneVolumeMute,
'MicrophoneVolumeUp': LogicalKeyboardKey.microphoneVolumeUp,
- 'Minus': LogicalKeyboardKey.minus,
'ModeChange': LogicalKeyboardKey.modeChange,
'NavigateIn': LogicalKeyboardKey.navigateIn,
'NavigateNext': LogicalKeyboardKey.navigateNext,
@@ -2446,38 +2341,13 @@
'NonConvert': LogicalKeyboardKey.nonConvert,
'Notification': LogicalKeyboardKey.notification,
'NumLock': LogicalKeyboardKey.numLock,
- 'NumberSign': LogicalKeyboardKey.numberSign,
- 'Numpad0': LogicalKeyboardKey.numpad0,
- 'Numpad1': LogicalKeyboardKey.numpad1,
- 'Numpad2': LogicalKeyboardKey.numpad2,
- 'Numpad3': LogicalKeyboardKey.numpad3,
- 'Numpad4': LogicalKeyboardKey.numpad4,
- 'Numpad5': LogicalKeyboardKey.numpad5,
- 'Numpad6': LogicalKeyboardKey.numpad6,
- 'Numpad7': LogicalKeyboardKey.numpad7,
- 'Numpad8': LogicalKeyboardKey.numpad8,
- 'Numpad9': LogicalKeyboardKey.numpad9,
- 'NumpadAdd': LogicalKeyboardKey.numpadAdd,
- 'NumpadComma': LogicalKeyboardKey.numpadComma,
- 'NumpadDecimal': LogicalKeyboardKey.numpadDecimal,
- 'NumpadDivide': LogicalKeyboardKey.numpadDivide,
- 'NumpadEnter': LogicalKeyboardKey.numpadEnter,
- 'NumpadEqual': LogicalKeyboardKey.numpadEqual,
- 'NumpadMultiply': LogicalKeyboardKey.numpadMultiply,
- 'NumpadParenLeft': LogicalKeyboardKey.numpadParenLeft,
- 'NumpadParenRight': LogicalKeyboardKey.numpadParenRight,
- 'NumpadSubtract': LogicalKeyboardKey.numpadSubtract,
'OnDemand': LogicalKeyboardKey.onDemand,
'Open': LogicalKeyboardKey.open,
'PageDown': LogicalKeyboardKey.pageDown,
'PageUp': LogicalKeyboardKey.pageUp,
'Pairing': LogicalKeyboardKey.pairing,
- 'ParenthesisLeft': LogicalKeyboardKey.parenthesisLeft,
- 'ParenthesisRight': LogicalKeyboardKey.parenthesisRight,
'Paste': LogicalKeyboardKey.paste,
'Pause': LogicalKeyboardKey.pause,
- 'Percent': LogicalKeyboardKey.percent,
- 'Period': LogicalKeyboardKey.period,
'PinPDown': LogicalKeyboardKey.pInPDown,
'PinPMove': LogicalKeyboardKey.pInPMove,
'PinPToggle': LogicalKeyboardKey.pInPToggle,
@@ -2493,14 +2363,10 @@
'PrintScreen': LogicalKeyboardKey.printScreen,
'Process': LogicalKeyboardKey.process,
'Props': LogicalKeyboardKey.props,
- 'Question': LogicalKeyboardKey.question,
- 'Quote': LogicalKeyboardKey.quote,
- 'QuoteSingle': LogicalKeyboardKey.quoteSingle,
'RandomToggle': LogicalKeyboardKey.randomToggle,
'RcLowBattery': LogicalKeyboardKey.rcLowBattery,
'RecordSpeedNext': LogicalKeyboardKey.recordSpeedNext,
'Redo': LogicalKeyboardKey.redo,
- 'Resume': LogicalKeyboardKey.resume,
'RfBypass': LogicalKeyboardKey.rfBypass,
'Romaji': LogicalKeyboardKey.romaji,
'STBInput': LogicalKeyboardKey.stbInput,
@@ -2510,15 +2376,9 @@
'ScreenModeNext': LogicalKeyboardKey.screenModeNext,
'ScrollLock': LogicalKeyboardKey.scrollLock,
'Select': LogicalKeyboardKey.select,
- 'Semicolon': LogicalKeyboardKey.semicolon,
'Settings': LogicalKeyboardKey.settings,
- 'Shift': LogicalKeyboardKey.shift,
- 'ShiftLeft': LogicalKeyboardKey.shiftLeft,
'ShiftLevel5': LogicalKeyboardKey.shiftLevel5,
- 'ShiftRight': LogicalKeyboardKey.shiftRight,
'SingleCandidate': LogicalKeyboardKey.singleCandidate,
- 'Slash': LogicalKeyboardKey.slash,
- 'Sleep': LogicalKeyboardKey.sleep,
'Soft1': LogicalKeyboardKey.soft1,
'Soft2': LogicalKeyboardKey.soft2,
'Soft3': LogicalKeyboardKey.soft3,
@@ -2527,7 +2387,6 @@
'Soft6': LogicalKeyboardKey.soft6,
'Soft7': LogicalKeyboardKey.soft7,
'Soft8': LogicalKeyboardKey.soft8,
- 'Space': LogicalKeyboardKey.space,
'SpeechCorrectionList': LogicalKeyboardKey.speechCorrectionList,
'SpeechInputToggle': LogicalKeyboardKey.speechInputToggle,
'SpellCheck': LogicalKeyboardKey.spellCheck,
@@ -2535,7 +2394,6 @@
'Standby': LogicalKeyboardKey.standby,
'Subtitle': LogicalKeyboardKey.subtitle,
'Super': LogicalKeyboardKey.superKey,
- 'Suspend': LogicalKeyboardKey.suspend,
'Symbol': LogicalKeyboardKey.symbol,
'SymbolLock': LogicalKeyboardKey.symbolLock,
'TV': LogicalKeyboardKey.tv,
@@ -2570,8 +2428,6 @@
'TVTimer': LogicalKeyboardKey.tvTimer,
'Tab': LogicalKeyboardKey.tab,
'Teletext': LogicalKeyboardKey.teletext,
- 'Tilde': LogicalKeyboardKey.tilde,
- 'Underscore': LogicalKeyboardKey.underscore,
'Undo': LogicalKeyboardKey.undo,
'Unidentified': LogicalKeyboardKey.unidentified,
'VideoModeNext': LogicalKeyboardKey.videoModeNext,
diff --git a/packages/flutter/lib/src/services/raw_keyboard.dart b/packages/flutter/lib/src/services/raw_keyboard.dart
index ba67416..e99f28b 100644
--- a/packages/flutter/lib/src/services/raw_keyboard.dart
+++ b/packages/flutter/lib/src/services/raw_keyboard.dart
@@ -285,12 +285,10 @@
/// Creates a concrete [RawKeyEvent] class from a message in the form received
/// on the [SystemChannels.keyEvent] channel.
factory RawKeyEvent.fromMessage(Map<String, dynamic> message) {
- final RawKeyEventData data;
String? character;
-
RawKeyEventData _dataFromWeb() {
final String? key = message['key'] as String?;
- if (key != null && key.isNotEmpty) {
+ if (key != null && key.isNotEmpty && key.length == 1) {
character = key;
}
return RawKeyEventDataWeb(
@@ -300,6 +298,8 @@
metaState: message['metaState'] as int? ?? 0,
);
}
+
+ final RawKeyEventData data;
if (kIsWeb) {
data = _dataFromWeb();
} else {
diff --git a/packages/flutter/lib/src/services/raw_keyboard_web.dart b/packages/flutter/lib/src/services/raw_keyboard_web.dart
index 70e2b94..4ae924e 100644
--- a/packages/flutter/lib/src/services/raw_keyboard_web.dart
+++ b/packages/flutter/lib/src/services/raw_keyboard_web.dart
@@ -10,6 +10,13 @@
import 'keyboard_maps.dart';
import 'raw_keyboard.dart';
+String? _unicodeChar(String key) {
+ if (key.length == 1) {
+ return key.substring(0, 1);
+ }
+ return null;
+}
+
/// Platform-specific key event data for Web.
///
/// See also:
@@ -74,7 +81,7 @@
final int metaState;
@override
- String get keyLabel => key == 'Unidentified' ? '' : key;
+ String get keyLabel => key == 'Unidentified' ? '' : _unicodeChar(key) ?? '';
@override
PhysicalKeyboardKey get physicalKey {
@@ -95,9 +102,14 @@
return newKey;
}
+ final bool isPrintable = key.length == 1;
+ if (isPrintable)
+ return LogicalKeyboardKey(key.codeUnitAt(0));
+
// This is a non-printable key that we don't know about, so we mint a new
- // code.
- return LogicalKeyboardKey(code.hashCode | LogicalKeyboardKey.webPlane);
+ // key from `code`. Don't mint with `key`, because the `key` will always be
+ // "Unidentified" .
+ return LogicalKeyboardKey(code.hashCode + LogicalKeyboardKey.webPlane);
}
@override
diff --git a/packages/flutter/test/services/raw_keyboard_test.dart b/packages/flutter/test/services/raw_keyboard_test.dart
index f5c227c..30a3941 100644
--- a/packages/flutter/test/services/raw_keyboard_test.dart
+++ b/packages/flutter/test/services/raw_keyboard_test.dart
@@ -2400,6 +2400,7 @@
'keymap': 'web',
'code': 'KeyA',
'key': 'a',
+ 'location': 0,
'metaState': 0x0,
});
final RawKeyEventDataWeb data = keyAEvent.data as RawKeyEventDataWeb;
@@ -2413,6 +2414,8 @@
'type': 'keydown',
'keymap': 'web',
'code': 'Escape',
+ 'key': 'Escape',
+ 'location': 0,
'metaState': 0x0,
});
final RawKeyEventDataWeb data = escapeKeyEvent.data as RawKeyEventDataWeb;
@@ -2426,6 +2429,8 @@
'type': 'keydown',
'keymap': 'web',
'code': 'ShiftLeft',
+ 'key': 'Shift',
+ 'location': 1,
'metaState': RawKeyEventDataWeb.modifierShift,
});
final RawKeyEventDataWeb data = shiftKeyEvent.data as RawKeyEventDataWeb;
@@ -2439,6 +2444,8 @@
'type': 'keydown',
'keymap': 'web',
'code': 'ArrowDown',
+ 'key': 'ArrowDown',
+ 'location': 0,
'metaState': 0x0,
});
final RawKeyEventDataWeb data = arrowKeyDown.data as RawKeyEventDataWeb;
@@ -2447,6 +2454,25 @@
expect(data.keyLabel, isEmpty);
});
+ test('Unrecognized keys are mapped to Web plane', () {
+ final RawKeyEvent arrowKeyDown = RawKeyEvent.fromMessage(const <String, dynamic>{
+ 'type': 'keydown',
+ 'keymap': 'web',
+ 'code': 'Unrecog1',
+ 'key': 'Unrecog2',
+ 'location': 0,
+ 'metaState': 0x0,
+ });
+ final RawKeyEventDataWeb data = arrowKeyDown.data as RawKeyEventDataWeb;
+ // This might be easily broken on Web if the code fails to acknowledge
+ // that JavaScript doesn't handle 64-bit bit-wise operation.
+ expect(data.physicalKey.usbHidUsage, greaterThan(0x01700000000));
+ expect(data.physicalKey.usbHidUsage, lessThan(0x01800000000));
+ expect(data.logicalKey.keyId, greaterThan(0x01700000000));
+ expect(data.logicalKey.keyId, lessThan(0x01800000000));
+ expect(data.keyLabel, isEmpty);
+ });
+
test('data.toString', () {
expect(RawKeyEvent.fromMessage(const <String, dynamic>{
'type': 'keydown',
diff --git a/packages/flutter_test/lib/src/event_simulation.dart b/packages/flutter_test/lib/src/event_simulation.dart
index 32f81dc..c4e34e1 100644
--- a/packages/flutter_test/lib/src/event_simulation.dart
+++ b/packages/flutter_test/lib/src/event_simulation.dart
@@ -14,6 +14,16 @@
import 'binding.dart';
import 'test_async_utils.dart';
+// A tuple of `key` and `location` from Web's `KeyboardEvent` class.
+//
+// See [RawKeyEventDataWeb]'s `key` and `location` fields for details.
+@immutable
+class _WebKeyLocationPair {
+ const _WebKeyLocationPair(this.key, this.location);
+ final String key;
+ final int location;
+}
+
// TODO(gspencergoog): Replace this with more robust key simulation code once
// the new key event code is in.
// https://github.com/flutter/flutter/issues/33521
@@ -145,8 +155,32 @@
}
}
- static String _getWebKeyCode(LogicalKeyboardKey key) {
+ static PhysicalKeyboardKey _inferPhysicalKey(LogicalKeyboardKey key) {
+ PhysicalKeyboardKey? result;
+ for (final PhysicalKeyboardKey physicalKey in PhysicalKeyboardKey.knownPhysicalKeys) {
+ if (physicalKey.debugName == key.debugName) {
+ result = physicalKey;
+ break;
+ }
+ }
+ assert(result != null, 'Unable to infer physical key for $key');
+ return result!;
+ }
+
+ static _WebKeyLocationPair _getWebKeyLocation(LogicalKeyboardKey key, String keyLabel) {
String? result;
+ for (final MapEntry<String, List<LogicalKeyboardKey?>> entry in kWebLocationMap.entries) {
+ final int foundIndex = entry.value.indexOf(key);
+ // If foundIndex is -1, then the key is not defined in kWebLocationMap.
+ // If foundIndex is 0, then the key is in the standard part of the keyboard,
+ // but we have to check `keyLabel` to see if it's remapped or modified.
+ if (foundIndex != -1 && foundIndex != 0) {
+ return _WebKeyLocationPair(entry.key, foundIndex);
+ }
+ }
+ if (keyLabel.isNotEmpty) {
+ return _WebKeyLocationPair(keyLabel, 0);
+ }
for (final String code in kWebToLogicalKey.keys) {
if (key.keyId == kWebToLogicalKey[code]!.keyId) {
result = code;
@@ -154,6 +188,18 @@
}
}
assert(result != null, 'Key $key not found in web keyCode map');
+ return _WebKeyLocationPair(result!, 0);
+ }
+
+ static String _getWebCode(PhysicalKeyboardKey key) {
+ String? result;
+ for (final MapEntry<String, PhysicalKeyboardKey> entry in kWebToPhysicalKey.entries) {
+ if (entry.value.usbHidUsage == key.usbHidUsage) {
+ result = entry.key;
+ break;
+ }
+ }
+ assert(result != null, 'Key $key not found in web code map');
return result!;
}
@@ -215,8 +261,6 @@
physicalKey ??= _findPhysicalKeyByPlatform(key, platform);
assert(key.debugName != null);
- final int keyCode = _getKeyCode(key, platform);
- final int scanCode = _getScanCode(physicalKey, platform);
final Map<String, dynamic> result = <String, dynamic>{
'type': isDown ? 'keydown' : 'keyup',
@@ -225,14 +269,19 @@
final String resultCharacter = character ?? _keyLabel(key) ?? '';
void assignWeb() {
- result['code'] = _getWebKeyCode(key);
- result['key'] = resultCharacter;
+ final _WebKeyLocationPair keyLocation = _getWebKeyLocation(key, resultCharacter);
+ final PhysicalKeyboardKey actualPhysicalKey = physicalKey ?? _inferPhysicalKey(key);
+ result['code'] = _getWebCode(actualPhysicalKey);
+ result['key'] = keyLocation.key;
+ result['location'] = keyLocation.location;
result['metaState'] = _getWebModifierFlags(key, isDown);
}
if (kIsWeb) {
assignWeb();
return result;
}
+ final int keyCode = _getKeyCode(key, platform);
+ final int scanCode = _getScanCode(physicalKey, platform);
switch (platform) {
case 'android':