Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Sign in
Toggle navigation
F
Front-End
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
abdullh.alsoleman
Front-End
Commits
b70d260b
Unverified
Commit
b70d260b
authored
Mar 28, 2019
by
Francisco Magdaleno
Committed by
GitHub
Mar 28, 2019
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Adds the keyboard mapping for Linux (#29993)
parent
a1712dcf
Changes
12
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
2308 additions
and
372 deletions
+2308
-372
raw_keyboard.dart
dev/manual_tests/lib/raw_keyboard.dart
+5
-0
gen_keycodes.dart
dev/tools/gen_keycodes/bin/gen_keycodes.dart
+28
-1
key_data.json
dev/tools/gen_keycodes/data/key_data.json
+1273
-361
key_name_to_glfw_name.json
dev/tools/gen_keycodes/data/key_name_to_glfw_name.json
+116
-0
keyboard_maps.tmpl
dev/tools/gen_keycodes/data/keyboard_maps.tmpl
+18
-0
code_gen.dart
dev/tools/gen_keycodes/lib/code_gen.dart
+43
-0
key_data.dart
dev/tools/gen_keycodes/lib/key_data.dart
+79
-5
services.dart
packages/flutter/lib/services.dart
+1
-0
keyboard_maps.dart
packages/flutter/lib/src/services/keyboard_maps.dart
+350
-2
raw_keyboard.dart
packages/flutter/lib/src/services/raw_keyboard.dart
+9
-0
raw_keyboard_linux.dart
packages/flutter/lib/src/services/raw_keyboard_linux.dart
+258
-0
raw_keyboard_test.dart
packages/flutter/test/services/raw_keyboard_test.dart
+128
-3
No files found.
dev/manual_tests/lib/raw_keyboard.dart
View file @
b70d260b
...
...
@@ -97,6 +97,11 @@ class _HardwareKeyDemoState extends State<RawKeyboardDemo> {
dataText
.
add
(
Text
(
'characters:
${data.characters}
'
));
dataText
.
add
(
Text
(
'charactersIgnoringModifiers:
${data.charactersIgnoringModifiers}
'
));
dataText
.
add
(
Text
(
'modifiers:
${data.modifiers}
(
${_asHex(data.modifiers)}
)'
));
}
else
if
(
data
is
RawKeyEventDataLinux
)
{
dataText
.
add
(
Text
(
'keyCode:
${data.keyCode}
(
${_asHex(data.keyCode)}
)'
));
dataText
.
add
(
Text
(
'scanCode:
${data.scanCode}
'
));
dataText
.
add
(
Text
(
'codePoint:
${data.codePoint}
'
));
dataText
.
add
(
Text
(
'modifiers:
${data.modifiers}
(
${_asHex(data.modifiers)}
)'
));
}
dataText
.
add
(
Text
(
'logical:
${_event.logicalKey}
'
));
dataText
.
add
(
Text
(
'physical:
${_event.physicalKey}
'
));
...
...
dev/tools/gen_keycodes/bin/gen_keycodes.dart
View file @
b70d260b
...
...
@@ -38,6 +38,11 @@ Future<String> getAndroidScanCodes() async {
return
utf8
.
decode
(
base64
.
decode
(
await
http
.
read
(
scanCodesUri
)));
}
Future
<
String
>
getGlfwKeyCodes
()
async
{
final
Uri
keyCodesUri
=
Uri
.
parse
(
'https://raw.githubusercontent.com/glfw/glfw/master/include/GLFW/glfw3.h'
);
return
await
http
.
read
(
keyCodesUri
);
}
Future
<
void
>
main
(
List
<
String
>
rawArguments
)
async
{
final
ArgParser
argParser
=
ArgParser
();
argParser
.
addOption
(
...
...
@@ -66,6 +71,19 @@ Future<void> main(List<String> rawArguments) async {
defaultsTo:
path
.
join
(
flutterRoot
.
path
,
'dev'
,
'tools'
,
'gen_keycodes'
,
'data'
,
'key_name_to_android_name.json'
),
help:
'The path to where the Android keycode to DomKey mapping is.'
,
);
argParser
.
addOption
(
'glfw-keycodes'
,
defaultsTo:
null
,
help:
'The path to where the GLFW keycodes header file should be read. '
'If --glfw-keycodes is not specified, the input will be read from the '
'correct file in the GLFW github repository.'
,
);
argParser
.
addOption
(
'glfw-domkey'
,
defaultsTo:
path
.
join
(
flutterRoot
.
path
,
'dev'
,
'tools'
,
'gen_keycodes'
,
'data'
,
'key_name_to_glfw_name.json'
),
help:
'The path to where the GLFW keycode to DomKey mapping is.'
,
);
argParser
.
addOption
(
'data'
,
defaultsTo:
path
.
join
(
flutterRoot
.
path
,
'dev'
,
'tools'
,
'gen_keycodes'
,
'data'
,
'key_data.json'
),
...
...
@@ -136,8 +154,17 @@ Future<void> main(List<String> rawArguments) async {
androidScanCodes
=
File
(
parsedArguments
[
'android-scancodes'
]).
readAsStringSync
();
}
String
glfwKeyCodes
;
if
(
parsedArguments
[
'glfw-keycodes'
]
==
null
)
{
glfwKeyCodes
=
await
getGlfwKeyCodes
();
}
else
{
glfwKeyCodes
=
File
(
parsedArguments
[
'glfw-keycodes'
]).
readAsStringSync
();
}
final
String
glfwToDomKey
=
File
(
parsedArguments
[
'glfw-domkey'
]).
readAsStringSync
();
final
String
androidToDomKey
=
File
(
parsedArguments
[
'android-domkey'
]).
readAsStringSync
();
data
=
KeyData
(
hidCodes
,
androidScanCodes
,
androidKeyCodes
,
androidToDomKey
);
data
=
KeyData
(
hidCodes
,
androidScanCodes
,
androidKeyCodes
,
androidToDomKey
,
glfwKeyCodes
,
glfwToDomKey
);
const
JsonEncoder
encoder
=
JsonEncoder
.
withIndent
(
' '
);
File
(
parsedArguments
[
'data'
]).
writeAsStringSync
(
encoder
.
convert
(
data
.
toJson
()));
...
...
dev/tools/gen_keycodes/data/key_data.json
View file @
b70d260b
This diff is collapsed.
Click to expand it.
dev/tools/gen_keycodes/data/key_name_to_glfw_name.json
0 → 100644
View file @
b70d260b
{
"altLeft"
:
[
"LEFT_ALT"
],
"altRight"
:
[
"RIGHT_ALT"
],
"arrowDown"
:
[
"DOWN"
],
"arrowLeft"
:
[
"LEFT"
],
"arrowRight"
:
[
"RIGHT"
],
"arrowUp"
:
[
"UP"
],
"backquote"
:
[
"GRAVE_ACCENT"
],
"backslash"
:
[
"BACKSLASH"
],
"backspace"
:
[
"BACKSPACE"
],
"bracketLeft"
:
[
"LEFT_BRACKET"
],
"bracketRight"
:
[
"RIGHT_BRACKET"
],
"capsLock"
:
[
"CAPS_LOCK"
],
"controlLeft"
:
[
"LEFT_CONTROL"
],
"controlRight"
:
[
"RIGHT_CONTROL"
],
"contextMenu"
:
[
"MENU"
],
"comma"
:
[
"COMMA"
],
"delete"
:
[
"DELETE"
],
"digit0"
:
[
"0"
],
"digit1"
:
[
"1"
],
"digit2"
:
[
"2"
],
"digit3"
:
[
"3"
],
"digit4"
:
[
"4"
],
"digit5"
:
[
"5"
],
"digit6"
:
[
"6"
],
"digit7"
:
[
"7"
],
"digit8"
:
[
"8"
],
"digit9"
:
[
"9"
],
"end"
:
[
"END"
],
"enter"
:
[
"ENTER"
],
"equal"
:
[
"EQUAL"
],
"escape"
:
[
"ESCAPE"
],
"f1"
:
[
"F1"
],
"f2"
:
[
"F2"
],
"f3"
:
[
"F3"
],
"f4"
:
[
"F4"
],
"f5"
:
[
"F5"
],
"f6"
:
[
"F6"
],
"f7"
:
[
"F7"
],
"f8"
:
[
"F8"
],
"f9"
:
[
"F9"
],
"f10"
:
[
"F10"
],
"f11"
:
[
"F11"
],
"f12"
:
[
"F12"
],
"f13"
:
[
"F13"
],
"f14"
:
[
"F14"
],
"f15"
:
[
"F15"
],
"f16"
:
[
"F16"
],
"f17"
:
[
"F17"
],
"f18"
:
[
"F18"
],
"f19"
:
[
"F19"
],
"f20"
:
[
"F20"
],
"f21"
:
[
"F21"
],
"f22"
:
[
"F22"
],
"f23"
:
[
"F23"
],
"f25"
:
[
"F25"
],
"home"
:
[
"HOME"
],
"insert"
:
[
"INSERT"
],
"keyA"
:
[
"A"
],
"keyB"
:
[
"B"
],
"keyC"
:
[
"C"
],
"keyD"
:
[
"D"
],
"keyE"
:
[
"E"
],
"keyF"
:
[
"F"
],
"keyG"
:
[
"G"
],
"keyH"
:
[
"H"
],
"keyI"
:
[
"I"
],
"keyJ"
:
[
"J"
],
"keyK"
:
[
"K"
],
"keyL"
:
[
"L"
],
"keyM"
:
[
"M"
],
"keyN"
:
[
"N"
],
"keyO"
:
[
"O"
],
"keyP"
:
[
"P"
],
"keyQ"
:
[
"Q"
],
"keyR"
:
[
"R"
],
"keyS"
:
[
"S"
],
"keyT"
:
[
"T"
],
"keyU"
:
[
"U"
],
"keyV"
:
[
"V"
],
"keyW"
:
[
"W"
],
"keyX"
:
[
"X"
],
"keyY"
:
[
"Y"
],
"keyZ"
:
[
"Z"
],
"minus"
:
[
"MINUS"
],
"numLock"
:
[
"NUM_LOCK"
],
"numpad0"
:
[
"KP_0"
],
"numpad1"
:
[
"KP_1"
],
"numpad2"
:
[
"KP_2"
],
"numpad3"
:
[
"KP_3"
],
"numpad4"
:
[
"KP_4"
],
"numpad5"
:
[
"KP_5"
],
"numpad6"
:
[
"KP_6"
],
"numpad7"
:
[
"KP_7"
],
"numpad8"
:
[
"KP_8"
],
"numpad9"
:
[
"KP_9"
],
"numpadDecimal"
:
[
"KP_DECIMAL"
],
"numpadDivide"
:
[
"KP_DIVIDE"
],
"numpadMultiply"
:
[
"KP_MULTIPLY"
],
"numpadSubtract"
:
[
"NUMPAD_SUBTRACT"
],
"numpadAdd"
:
[
"KP_ADD"
],
"numpadEnter"
:
[
"KP_ENTER"
],
"numpadEqual"
:
[
"KP_EQUAL"
],
"pageDown"
:
[
"PAGE_DOWN"
],
"pageUp"
:
[
"PAGE_UP"
],
"pause"
:
[
"PAUSE"
],
"printScreen"
:
[
"PRINT_SCREEN"
],
"quote"
:
[
"APOSTROPHE"
],
"period"
:
[
"PERIOD"
],
"semicolon"
:
[
"SEMICOLON"
],
"slash"
:
[
"SLASH"
],
"space"
:
[
"SPACE"
],
"shiftLeft"
:
[
"LEFT_SHIFT"
],
"shiftRight"
:
[
"RIGHT_SHIFT"
],
"tab"
:
[
"TAB"
]
}
dev/tools/gen_keycodes/data/keyboard_maps.tmpl
View file @
b70d260b
...
...
@@ -50,3 +50,21 @@ const Map<int, PhysicalKeyboardKey> kMacOsToPhysicalKey = <int, PhysicalKeyboard
const Map<int, LogicalKeyboardKey> kMacOsNumPadMap = <int, LogicalKeyboardKey>{
@@@MACOS_NUMPAD_MAP@@@
};
/// Maps GLFW-specific key codes to the matching [LogicalKeyboardKey].
const Map<int, LogicalKeyboardKey> kGlfwToLogicalKey = <int, LogicalKeyboardKey>{
@@@GLFW_KEY_CODE_MAP@@@
};
/// A map of GLFW key codes which have printable representations, but appear
/// on the number pad. Used to provide different key objects for keys like
/// KEY_EQUALS and NUMPAD_EQUALS.
const Map<int, LogicalKeyboardKey> kGlfwNumpadMap = <int, LogicalKeyboardKey>{
@@@GLFW_NUMPAD_MAP@@@
};
/// Maps XKB specific key code values representing [PhysicalKeyboardKey].
const Map<int, PhysicalKeyboardKey> kLinuxToPhysicalKey = <int, PhysicalKeyboardKey>{
@@@XKB_SCAN_CODE_MAP@@@
};
dev/tools/gen_keycodes/lib/code_gen.dart
View file @
b70d260b
...
...
@@ -93,6 +93,46 @@ $otherComments static const LogicalKeyboardKey ${entry.constantName} = LogicalK
return
keyCodeMap
.
toString
().
trimRight
();
}
/// This generates the map of GLFW number pad key codes to logical keys.
String
get
glfwNumpadMap
{
final
StringBuffer
glfwNumpadMap
=
StringBuffer
();
final
List
<
Key
>
onlyNumpads
=
keyData
.
data
.
where
((
Key
entry
)
{
return
entry
.
constantName
.
startsWith
(
'numpad'
)
&&
entry
.
keyLabel
!=
null
;
}).
toList
();
for
(
Key
entry
in
onlyNumpads
)
{
if
(
entry
.
glfwKeyCodes
!=
null
)
{
for
(
int
code
in
entry
.
glfwKeyCodes
.
cast
<
int
>())
{
glfwNumpadMap
.
writeln
(
'
$code
: LogicalKeyboardKey.
${entry.constantName}
,'
);
}
}
}
return
glfwNumpadMap
.
toString
().
trimRight
();
}
/// This generates the map of GLFW key codes to logical keys.
String
get
glfwKeyCodeMap
{
final
StringBuffer
glfwKeyCodeMap
=
StringBuffer
();
for
(
Key
entry
in
keyData
.
data
)
{
if
(
entry
.
glfwKeyCodes
!=
null
)
{
for
(
int
code
in
entry
.
glfwKeyCodes
.
cast
<
int
>())
{
glfwKeyCodeMap
.
writeln
(
'
$code
: LogicalKeyboardKey.
${entry.constantName}
,'
);
}
}
}
return
glfwKeyCodeMap
.
toString
().
trimRight
();
}
/// This generates the map of XKB USB HID codes to physical keys.
String
get
xkbScanCodeMap
{
final
StringBuffer
xkbScanCodeMap
=
StringBuffer
();
for
(
Key
entry
in
keyData
.
data
)
{
if
(
entry
.
xKbScanCode
!=
null
)
{
xkbScanCodeMap
.
writeln
(
'
${toHex(entry.xKbScanCode)}
: PhysicalKeyboardKey.
${entry.constantName}
,'
);
}
}
return
xkbScanCodeMap
.
toString
().
trimRight
();
}
/// This generates the map of Android key codes to logical keys.
String
get
androidKeyCodeMap
{
final
StringBuffer
androidKeyCodeMap
=
StringBuffer
();
...
...
@@ -210,6 +250,9 @@ $otherComments static const LogicalKeyboardKey ${entry.constantName} = LogicalK
'FUCHSIA_KEY_CODE_MAP'
:
fuchsiaKeyCodeMap
,
'MACOS_SCAN_CODE_MAP'
:
macOsScanCodeMap
,
'MACOS_NUMPAD_MAP'
:
macOsNumpadMap
,
'GLFW_KEY_CODE_MAP'
:
glfwKeyCodeMap
,
'GLFW_NUMPAD_MAP'
:
glfwNumpadMap
,
'XKB_SCAN_CODE_MAP'
:
xkbScanCodeMap
,
};
final
String
template
=
File
(
path
.
join
(
flutterRoot
.
path
,
'dev'
,
'tools'
,
'gen_keycodes'
,
'data'
,
'keyboard_maps.tmpl'
)).
readAsStringSync
();
...
...
dev/tools/gen_keycodes/lib/key_data.dart
View file @
b70d260b
...
...
@@ -26,14 +26,25 @@ class KeyData {
String
androidKeyboardLayout
,
String
androidKeyCodeHeader
,
String
androidNameMap
,
String
glfwKeyCodeHeader
,
String
glfwNameMap
)
:
assert
(
chromiumHidCodes
!=
null
),
assert
(
androidKeyboardLayout
!=
null
),
assert
(
androidKeyCodeHeader
!=
null
),
assert
(
androidNameMap
!=
null
)
{
assert
(
androidNameMap
!=
null
),
assert
(
glfwKeyCodeHeader
!=
null
),
assert
(
glfwNameMap
!=
null
)
{
_nameToAndroidScanCodes
=
_readAndroidScanCodes
(
androidKeyboardLayout
);
_nameToAndroidKeyCode
=
_readAndroidKeyCodes
(
androidKeyCodeHeader
);
final
Map
<
String
,
List
<
dynamic
>>
dynamicNames
=
json
.
decode
(
androidNameMap
).
cast
<
String
,
List
<
dynamic
>>();
_nameToAndroidName
=
dynamicNames
.
map
<
String
,
List
<
String
>>((
String
key
,
List
<
dynamic
>
value
)
{
_nameToGlfwKeyCode
=
_readGlfwKeyCodes
(
glfwKeyCodeHeader
);
// Cast Android dom map
final
Map
<
String
,
List
<
dynamic
>>
dynamicAndroidNames
=
json
.
decode
(
androidNameMap
).
cast
<
String
,
List
<
dynamic
>>();
_nameToAndroidName
=
dynamicAndroidNames
.
map
<
String
,
List
<
String
>>((
String
key
,
List
<
dynamic
>
value
)
{
return
MapEntry
<
String
,
List
<
String
>>(
key
,
value
.
cast
<
String
>());
});
// Cast GLFW dom map
final
Map
<
String
,
List
<
dynamic
>>
dynamicGlfwNames
=
json
.
decode
(
glfwNameMap
).
cast
<
String
,
List
<
dynamic
>>();
_nameToGlfwName
=
dynamicGlfwNames
.
map
<
String
,
List
<
String
>>((
String
key
,
List
<
dynamic
>
value
)
{
return
MapEntry
<
String
,
List
<
String
>>(
key
,
value
.
cast
<
String
>());
});
data
=
_readHidEntries
(
chromiumHidCodes
);
...
...
@@ -51,6 +62,7 @@ class KeyData {
/// [KeyData.fromJson].
Map
<
String
,
dynamic
>
toJson
()
{
for
(
Key
entry
in
data
)
{
// Android Key names
entry
.
androidKeyNames
=
_nameToAndroidName
[
entry
.
constantName
]?.
cast
<
String
>();
if
(
entry
.
androidKeyNames
!=
null
&&
entry
.
androidKeyNames
.
isNotEmpty
)
{
for
(
String
androidKeyName
in
entry
.
androidKeyNames
)
{
...
...
@@ -64,6 +76,17 @@ class KeyData {
}
}
}
// GLFW key names
entry
.
glfwKeyNames
=
_nameToGlfwName
[
entry
.
constantName
]?.
cast
<
String
>();
if
(
entry
.
glfwKeyNames
!=
null
&&
entry
.
glfwKeyNames
.
isNotEmpty
)
{
for
(
String
glfwKeyName
in
entry
.
glfwKeyNames
)
{
if
(
_nameToGlfwKeyCode
[
glfwKeyName
]
!=
null
)
{
entry
.
glfwKeyCodes
??=
<
int
>[];
entry
.
glfwKeyCodes
.
add
(
_nameToGlfwKeyCode
[
glfwKeyName
]);
}
}
}
}
final
Map
<
String
,
dynamic
>
outputMap
=
<
String
,
dynamic
>{};
...
...
@@ -83,6 +106,13 @@ class KeyData {
/// JSON.
Map
<
String
,
List
<
String
>>
_nameToAndroidName
;
/// The mapping from the Flutter name (e.g. "eject") to the GLFW name (e.g.
/// "GLFW_MEDIA_EJECT").
///
/// Only populated if data is parsed from the source files, not if parsed from
/// JSON.
Map
<
String
,
List
<
String
>>
_nameToGlfwName
;
/// The mapping from the Android name (e.g. "MEDIA_EJECT") to the integer scan
/// code (physical location) of the key.
///
...
...
@@ -97,6 +127,13 @@ class KeyData {
/// JSON.
Map
<
String
,
int
>
_nameToAndroidKeyCode
;
/// The mapping from GLFW name (e.g. "GLFW_KEY_COMMA") to the integer key code
/// (logical meaning) of the key.
///
/// Only populated if data is parsed from the source files, not if parsed from
/// JSON.
Map
<
String
,
int
>
_nameToGlfwKeyCode
;
/// Parses entries from Androids Generic.kl scan code data file.
///
/// Lines in this file look like this (without the ///):
...
...
@@ -147,6 +184,30 @@ class KeyData {
return
result
;
}
/// Parses entries from GLFW's keycodes.h key code data file.
///
/// Lines in this file look like this (without the ///):
/// /** Space key. */
/// #define GLFW_KEY_SPACE 32,
Map
<
String
,
int
>
_readGlfwKeyCodes
(
String
headerFile
)
{
// Only get the KEY definitions, ignore the rest (mouse, joystick, etc).
final
RegExp
enumEntry
=
RegExp
(
r''
'define GLFW_KEY_([A-Z0-9_]+)
\
s*([A-Z0-9_]+),?'''
);
final
Map
<
String
,
dynamic
>
replaced
=
<
String
,
dynamic
>{};
headerFile
.
replaceAllMapped
(
enumEntry
,
(
Match
match
)
{
replaced
[
match
.
group
(
1
)]
=
int
.
tryParse
(
match
.
group
(
2
))
??
match
.
group
(
2
).
replaceAll
(
'GLFW_KEY_'
,
''
);
});
final
Map
<
String
,
int
>
result
=
<
String
,
int
>{};
replaced
.
forEach
((
String
key
,
dynamic
value
)
{
// Some definition values point to other definitions (e.g #define GLFW_KEY_LAST GLFW_KEY_MENU).
if
(
value
is
String
)
{
result
[
key
]
=
replaced
[
value
];
}
else
{
result
[
key
]
=
value
;
}
});
return
result
;
}
/// Parses entries from Chromium's HID code mapping header file.
///
/// Lines in this file look like this (without the ///):
...
...
@@ -211,6 +272,8 @@ class Key {
this
.
androidKeyNames
,
this
.
androidScanCodes
,
this
.
androidKeyCodes
,
this
.
glfwKeyNames
,
this
.
glfwKeyCodes
,
})
:
assert
(
usbHidCode
!=
null
),
assert
(
chromiumName
!=
null
),
_constantName
=
enumName
;
...
...
@@ -261,6 +324,15 @@ class Key {
/// code value.
List
<
int
>
androidScanCodes
;
/// The list of names that GFLW gives to this key (symbol names minus the
/// prefix).
List
<
String
>
glfwKeyNames
;
/// The list of GLFW key codes matching this key, created by looking up the
/// Linux name in the Chromium data, and substituting the GLFW key code
/// value.
List
<
int
>
glfwKeyCodes
;
/// Creates a JSON map from the key data.
Map
<
String
,
dynamic
>
toJson
()
{
return
<
String
,
dynamic
>{
...
...
@@ -269,6 +341,7 @@ class Key {
'android'
:
androidKeyNames
,
'english'
:
commentName
,
'chromium'
:
chromiumName
,
'glfw'
:
glfwKeyNames
,
},
'scanCodes'
:
<
String
,
dynamic
>{
'android'
:
androidScanCodes
,
...
...
@@ -280,6 +353,7 @@ class Key {
},
'keyCodes'
:
<
String
,
List
<
int
>>{
'android'
:
androidKeyCodes
,
'glfw'
:
glfwKeyCodes
,
},
};
}
...
...
@@ -337,8 +411,8 @@ class Key {
@override
String
toString
()
{
return
"""'
$constantName
': (name: "
$name
", usbHidCode:
${toHex(usbHidCode)}
, """
'''linux
KeyCode:
${toHex(linuxScanCode)}
, xKbKey
Code:
${toHex(xKbScanCode)}
, '''
'''windowsKeyCode:
${toHex(windowsScanCode)}
, macOs
Key
Code:
${toHex(macOsScanCode)}
, '''
'''linux
ScanCode:
${toHex(linuxScanCode)}
, xKbScan
Code:
${toHex(xKbScanCode)}
, '''
'''windowsKeyCode:
${toHex(windowsScanCode)}
, macOs
Scan
Code:
${toHex(macOsScanCode)}
, '''
'''chromiumSymbolName:
$chromiumName
'''
;
}
...
...
packages/flutter/lib/services.dart
View file @
b70d260b
...
...
@@ -24,6 +24,7 @@ export 'src/services/platform_views.dart';
export
'src/services/raw_keyboard.dart'
;
export
'src/services/raw_keyboard_android.dart'
;
export
'src/services/raw_keyboard_fuchsia.dart'
;
export
'src/services/raw_keyboard_linux.dart'
;
export
'src/services/raw_keyboard_macos.dart'
;
export
'src/services/system_channels.dart'
;
export
'src/services/system_chrome.dart'
;
...
...
packages/flutter/lib/src/services/keyboard_maps.dart
View file @
b70d260b
This diff is collapsed.
Click to expand it.
packages/flutter/lib/src/services/raw_keyboard.dart
View file @
b70d260b
...
...
@@ -9,6 +9,7 @@ import 'package:flutter/foundation.dart';
import
'keyboard_key.dart'
;
import
'raw_keyboard_android.dart'
;
import
'raw_keyboard_fuchsia.dart'
;
import
'raw_keyboard_linux.dart'
;
import
'raw_keyboard_macos.dart'
;
import
'system_channels.dart'
;
...
...
@@ -272,6 +273,14 @@ abstract class RawKeyEvent {
keyCode:
message
[
'keyCode'
]
??
0
,
modifiers:
message
[
'modifiers'
]
??
0
);
break
;
case
'linux'
:
data
=
RawKeyEventDataLinux
(
keyHelper:
KeyHelper
(
message
[
'toolkit'
]
??
''
),
codePoint:
message
[
'codePoint'
]
??
0
,
keyCode:
message
[
'keyCode'
]
??
0
,
scanCode:
message
[
'scanCode'
]
??
0
,
modifiers:
message
[
'modifiers'
]
??
0
);
break
;
default
:
// We don't yet implement raw key events on iOS or other platforms, but
// we don't hit this exception because the engine never sends us these
...
...
packages/flutter/lib/src/services/raw_keyboard_linux.dart
0 → 100644
View file @
b70d260b
This diff is collapsed.
Click to expand it.
packages/flutter/test/services/raw_keyboard_test.dart
View file @
b70d260b
...
...
@@ -92,7 +92,7 @@ void main() {
expect
(
data
.
isModifierPressed
(
key
,
side:
modifierTests
[
modifier
].
side
),
isFalse
,
reason:
'
$key
should not be pressed with metaState
$modifier
with metaState
$modifier
'
reason:
'
$key
should not be pressed with metaState
$modifier
'
'and additional key
${RawKeyEventDataAndroid.modifierFunction}
.'
,
);
}
...
...
@@ -264,7 +264,7 @@ void main() {
expect
(
data
.
keyLabel
,
isNull
);
});
});
group
(
'RawKeyEventDataMacOs'
,
()
{
group
(
'RawKeyEventDataMacOs'
,
()
{
const
Map
<
int
,
_ModifierCheck
>
modifierTests
=
<
int
,
_ModifierCheck
>{
RawKeyEventDataMacOs
.
modifierOption
|
RawKeyEventDataMacOs
.
modifierLeftOption
:
_ModifierCheck
(
ModifierKey
.
altModifier
,
KeyboardSide
.
left
),
RawKeyEventDataMacOs
.
modifierOption
|
RawKeyEventDataMacOs
.
modifierRightOption
:
_ModifierCheck
(
ModifierKey
.
altModifier
,
KeyboardSide
.
right
),
...
...
@@ -340,7 +340,7 @@ void main() {
expect
(
data
.
isModifierPressed
(
key
,
side:
modifierTests
[
modifier
].
side
),
isFalse
,
reason:
'
$key
should not be pressed with metaState
$modifier
with metaState
$modifier
'
reason:
'
$key
should not be pressed with metaState
$modifier
'
'and additional key
${RawKeyEventDataMacOs.modifierFunction}
.'
,
);
}
...
...
@@ -393,4 +393,129 @@ void main() {
expect
(
data
.
keyLabel
,
isNull
);
});
});
group
(
'RawKeyEventDataLinux-GFLW'
,
()
{
const
Map
<
int
,
_ModifierCheck
>
modifierTests
=
<
int
,
_ModifierCheck
>{
GLFWKeyHelper
.
modifierAlt
:
_ModifierCheck
(
ModifierKey
.
altModifier
,
KeyboardSide
.
any
),
GLFWKeyHelper
.
modifierShift
:
_ModifierCheck
(
ModifierKey
.
shiftModifier
,
KeyboardSide
.
any
),
GLFWKeyHelper
.
modifierControl
:
_ModifierCheck
(
ModifierKey
.
controlModifier
,
KeyboardSide
.
any
),
GLFWKeyHelper
.
modifierMeta
:
_ModifierCheck
(
ModifierKey
.
metaModifier
,
KeyboardSide
.
any
),
GLFWKeyHelper
.
modifierNumericPad
:
_ModifierCheck
(
ModifierKey
.
numLockModifier
,
KeyboardSide
.
all
),
GLFWKeyHelper
.
modifierCapsLock
:
_ModifierCheck
(
ModifierKey
.
capsLockModifier
,
KeyboardSide
.
all
),
};
test
(
'modifier keys are recognized individually'
,
()
{
for
(
int
modifier
in
modifierTests
.
keys
)
{
final
RawKeyEvent
event
=
RawKeyEvent
.
fromMessage
(<
String
,
dynamic
>{
'type'
:
'keydown'
,
'keymap'
:
'linux'
,
'toolkit'
:
'glfw'
,
'keyCode'
:
0x04
,
'scanCode'
:
0x01
,
'codePoint'
:
0x10
,
'modifiers'
:
modifier
,
});
final
RawKeyEventDataLinux
data
=
event
.
data
;
for
(
ModifierKey
key
in
ModifierKey
.
values
)
{
if
(
modifierTests
[
modifier
].
key
==
key
)
{
expect
(
data
.
isModifierPressed
(
key
,
side:
modifierTests
[
modifier
].
side
),
isTrue
,
reason:
"
$key
should be pressed with metaState
$modifier
, but isn't."
,
);
expect
(
data
.
getModifierSide
(
key
),
equals
(
modifierTests
[
modifier
].
side
));
}
else
{
expect
(
data
.
isModifierPressed
(
key
,
side:
modifierTests
[
modifier
].
side
),
isFalse
,
reason:
'
$key
should not be pressed with metaState
$modifier
.'
,
);
}
}
}
});
test
(
'modifier keys are recognized when combined'
,
()
{
for
(
int
modifier
in
modifierTests
.
keys
)
{
if
(
modifier
==
GLFWKeyHelper
.
modifierControl
)
{
// No need to combine CTRL key with itself.
continue
;
}
final
RawKeyEvent
event
=
RawKeyEvent
.
fromMessage
(<
String
,
dynamic
>{
'type'
:
'keydown'
,
'keymap'
:
'linux'
,
'toolkit'
:
'glfw'
,
'keyCode'
:
0x04
,
'scanCode'
:
0x64
,
'codePoint'
:
0x1
,
'modifiers'
:
modifier
|
GLFWKeyHelper
.
modifierControl
,
});
final
RawKeyEventDataLinux
data
=
event
.
data
;
for
(
ModifierKey
key
in
ModifierKey
.
values
)
{
if
(
modifierTests
[
modifier
].
key
==
key
||
key
==
ModifierKey
.
controlModifier
)
{
expect
(
data
.
isModifierPressed
(
key
,
side:
modifierTests
[
modifier
].
side
),
isTrue
,
reason:
'
$key
should be pressed with metaState
$modifier
'
"and additional key
${GLFWKeyHelper.modifierControl}
, but isn't."
,
);
if
(
key
!=
ModifierKey
.
controlModifier
)
{
expect
(
data
.
getModifierSide
(
key
),
equals
(
modifierTests
[
modifier
].
side
));
}
else
{
expect
(
data
.
getModifierSide
(
key
),
equals
(
KeyboardSide
.
any
));
}
}
else
{
expect
(
data
.
isModifierPressed
(
key
,
side:
modifierTests
[
modifier
].
side
),
isFalse
,
reason:
'
$key
should not be pressed with metaState
$modifier
'
'and additional key
${GLFWKeyHelper.modifierControl}
.'
,
);
}
}
}
});
test
(
'Printable keyboard keys are correctly translated'
,
()
{
final
RawKeyEvent
keyAEvent
=
RawKeyEvent
.
fromMessage
(
const
<
String
,
dynamic
>{
'type'
:
'keydown'
,
'keymap'
:
'linux'
,
'toolkit'
:
'glfw'
,
'keyCode'
:
65
,
'scanCode'
:
0x00000026
,
'codePoint'
:
97
,
'modifiers'
:
0x0
,
});
final
RawKeyEventDataLinux
data
=
keyAEvent
.
data
;
expect
(
data
.
physicalKey
,
equals
(
PhysicalKeyboardKey
.
keyA
));
expect
(
data
.
logicalKey
,
equals
(
LogicalKeyboardKey
.
keyA
));
expect
(
data
.
keyLabel
,
equals
(
'a'
));
});
test
(
'Control keyboard keys are correctly translated'
,
()
{
final
RawKeyEvent
escapeKeyEvent
=
RawKeyEvent
.
fromMessage
(
const
<
String
,
dynamic
>{
'type'
:
'keydown'
,
'keymap'
:
'linux'
,
'toolkit'
:
'glfw'
,
'keyCode'
:
256
,
'scanCode'
:
0x00000009
,
'codePoint'
:
0
,
'modifiers'
:
0x0
,
});
final
RawKeyEventDataLinux
data
=
escapeKeyEvent
.
data
;
expect
(
data
.
physicalKey
,
equals
(
PhysicalKeyboardKey
.
escape
));
expect
(
data
.
logicalKey
,
equals
(
LogicalKeyboardKey
.
escape
));
expect
(
data
.
keyLabel
,
isNull
);
});
test
(
'Modifier keyboard keys are correctly translated'
,
()
{
final
RawKeyEvent
shiftLeftKeyEvent
=
RawKeyEvent
.
fromMessage
(
const
<
String
,
dynamic
>{
'type'
:
'keydown'
,
'keymap'
:
'linux'
,
'toolkit'
:
'glfw'
,
'keyCode'
:
340
,
'scanCode'
:
0x00000032
,
'codePoint'
:
0
,
});
final
RawKeyEventDataLinux
data
=
shiftLeftKeyEvent
.
data
;
expect
(
data
.
physicalKey
,
equals
(
PhysicalKeyboardKey
.
shiftLeft
));
expect
(
data
.
logicalKey
,
equals
(
LogicalKeyboardKey
.
shiftLeft
));
expect
(
data
.
keyLabel
,
isNull
);
});
});
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment