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
cc9b78fc
Unverified
Commit
cc9b78fc
authored
Feb 25, 2021
by
Ferhat
Committed by
GitHub
Feb 25, 2021
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[web] Treeshake keymaps for web (4% code size reduction in hello world) (#75945)
parent
3e77f5e4
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
309 additions
and
161 deletions
+309
-161
raw_keyboard.dart
packages/flutter/lib/src/services/raw_keyboard.dart
+95
-81
raw_keyboard_test.dart
packages/flutter/test/services/raw_keyboard_test.dart
+110
-27
raw_keyboard_listener_test.dart
...ages/flutter/test/widgets/raw_keyboard_listener_test.dart
+31
-0
event_simulation.dart
packages/flutter_test/lib/src/event_simulation.dart
+73
-53
No files found.
packages/flutter/lib/src/services/raw_keyboard.dart
View file @
cc9b78fc
...
...
@@ -267,92 +267,106 @@ abstract class RawKeyEvent with Diagnosticable {
String
?
character
;
final
String
keymap
=
message
[
'keymap'
]
as
String
;
switch
(
keymap
)
{
case
'android'
:
data
=
RawKeyEventDataAndroid
(
flags:
message
[
'flags'
]
as
int
?
??
0
,
codePoint:
message
[
'codePoint'
]
as
int
?
??
0
,
keyCode:
message
[
'keyCode'
]
as
int
?
??
0
,
plainCodePoint:
message
[
'plainCodePoint'
]
as
int
?
??
0
,
scanCode:
message
[
'scanCode'
]
as
int
?
??
0
,
metaState:
message
[
'metaState'
]
as
int
?
??
0
,
eventSource:
message
[
'source'
]
as
int
?
??
0
,
vendorId:
message
[
'vendorId'
]
as
int
?
??
0
,
productId:
message
[
'productId'
]
as
int
?
??
0
,
deviceId:
message
[
'deviceId'
]
as
int
?
??
0
,
repeatCount:
message
[
'repeatCount'
]
as
int
?
??
0
,
);
if
(
message
.
containsKey
(
'character'
))
{
character
=
message
[
'character'
]
as
String
?;
}
break
;
case
'fuchsia'
:
final
int
codePoint
=
message
[
'codePoint'
]
as
int
?
??
0
;
data
=
RawKeyEventDataFuchsia
(
hidUsage:
message
[
'hidUsage'
]
as
int
?
??
0
,
codePoint:
codePoint
,
modifiers:
message
[
'modifiers'
]
as
int
?
??
0
,
);
if
(
codePoint
!=
0
)
{
character
=
String
.
fromCharCode
(
codePoint
);
}
break
;
case
'macos'
:
data
=
RawKeyEventDataMacOs
(
characters:
message
[
'characters'
]
as
String
?
??
''
,
charactersIgnoringModifiers:
message
[
'charactersIgnoringModifiers'
]
as
String
?
??
''
,
keyCode:
message
[
'keyCode'
]
as
int
?
??
0
,
modifiers:
message
[
'modifiers'
]
as
int
?
??
0
);
character
=
message
[
'characters'
]
as
String
?;
break
;
case
'ios'
:
data
=
RawKeyEventDataIos
(
characters:
message
[
'characters'
]
as
String
?
??
''
,
charactersIgnoringModifiers:
message
[
'charactersIgnoringModifiers'
]
as
String
?
??
''
,
if
(
kIsWeb
)
{
final
String
?
key
=
message
[
'key'
]
as
String
?;
data
=
RawKeyEventDataWeb
(
code:
message
[
'code'
]
as
String
?
??
''
,
key:
key
??
''
,
metaState:
message
[
'metaState'
]
as
int
?
??
0
,
);
if
(
key
!=
null
&&
key
.
isNotEmpty
)
{
character
=
key
;
}
}
else
{
switch
(
keymap
)
{
case
'android'
:
data
=
RawKeyEventDataAndroid
(
flags:
message
[
'flags'
]
as
int
?
??
0
,
codePoint:
message
[
'codePoint'
]
as
int
?
??
0
,
keyCode:
message
[
'keyCode'
]
as
int
?
??
0
,
modifiers:
message
[
'modifiers'
]
as
int
?
??
0
);
break
;
case
'linux'
:
final
int
unicodeScalarValues
=
message
[
'unicodeScalarValues'
]
as
int
?
??
0
;
data
=
RawKeyEventDataLinux
(
keyHelper:
KeyHelper
(
message
[
'toolkit'
]
as
String
?
??
''
),
unicodeScalarValues:
unicodeScalarValues
,
plainCodePoint:
message
[
'plainCodePoint'
]
as
int
?
??
0
,
scanCode:
message
[
'scanCode'
]
as
int
?
??
0
,
metaState:
message
[
'metaState'
]
as
int
?
??
0
,
eventSource:
message
[
'source'
]
as
int
?
??
0
,
vendorId:
message
[
'vendorId'
]
as
int
?
??
0
,
productId:
message
[
'productId'
]
as
int
?
??
0
,
deviceId:
message
[
'deviceId'
]
as
int
?
??
0
,
repeatCount:
message
[
'repeatCount'
]
as
int
?
??
0
,
);
if
(
message
.
containsKey
(
'character'
))
{
character
=
message
[
'character'
]
as
String
?;
}
break
;
case
'fuchsia'
:
final
int
codePoint
=
message
[
'codePoint'
]
as
int
?
??
0
;
data
=
RawKeyEventDataFuchsia
(
hidUsage:
message
[
'hidUsage'
]
as
int
?
??
0
,
codePoint:
codePoint
,
modifiers:
message
[
'modifiers'
]
as
int
?
??
0
,
);
if
(
codePoint
!=
0
)
{
character
=
String
.
fromCharCode
(
codePoint
);
}
break
;
case
'macos'
:
data
=
RawKeyEventDataMacOs
(
characters:
message
[
'characters'
]
as
String
?
??
''
,
charactersIgnoringModifiers:
message
[
'charactersIgnoringModifiers'
]
as
String
?
??
''
,
keyCode:
message
[
'keyCode'
]
as
int
?
??
0
,
modifiers:
message
[
'modifiers'
]
as
int
?
??
0
);
character
=
message
[
'characters'
]
as
String
?;
break
;
case
'ios'
:
data
=
RawKeyEventDataIos
(
characters:
message
[
'characters'
]
as
String
?
??
''
,
charactersIgnoringModifiers:
message
[
'charactersIgnoringModifiers'
]
as
String
?
??
''
,
keyCode:
message
[
'keyCode'
]
as
int
?
??
0
,
modifiers:
message
[
'modifiers'
]
as
int
?
??
0
);
break
;
case
'linux'
:
final
int
unicodeScalarValues
=
message
[
'unicodeScalarValues'
]
as
int
?
??
0
;
data
=
RawKeyEventDataLinux
(
keyHelper:
KeyHelper
(
message
[
'toolkit'
]
as
String
?
??
''
),
unicodeScalarValues:
unicodeScalarValues
,
keyCode:
message
[
'keyCode'
]
as
int
?
??
0
,
scanCode:
message
[
'scanCode'
]
as
int
?
??
0
,
modifiers:
message
[
'modifiers'
]
as
int
?
??
0
,
isDown:
message
[
'type'
]
==
'keydown'
);
if
(
unicodeScalarValues
!=
0
)
{
character
=
String
.
fromCharCode
(
unicodeScalarValues
);
}
break
;
case
'windows'
:
final
int
characterCodePoint
=
message
[
'characterCodePoint'
]
as
int
?
??
0
;
data
=
RawKeyEventDataWindows
(
keyCode:
message
[
'keyCode'
]
as
int
?
??
0
,
scanCode:
message
[
'scanCode'
]
as
int
?
??
0
,
characterCodePoint:
characterCodePoint
,
modifiers:
message
[
'modifiers'
]
as
int
?
??
0
,
isDown:
message
[
'type'
]
==
'keydown'
);
if
(
unicodeScalarValues
!=
0
)
{
character
=
String
.
fromCharCode
(
unicodeScalarValues
);
}
break
;
case
'web'
:
data
=
RawKeyEventDataWeb
(
code:
message
[
'code'
]
as
String
?
??
''
,
key:
message
[
'key'
]
as
String
?
??
''
,
metaState:
message
[
'metaState'
]
as
int
?
??
0
,
);
character
=
message
[
'key'
]
as
String
?;
break
;
case
'windows'
:
final
int
characterCodePoint
=
message
[
'characterCodePoint'
]
as
int
?
??
0
;
data
=
RawKeyEventDataWindows
(
keyCode:
message
[
'keyCode'
]
as
int
?
??
0
,
scanCode:
message
[
'scanCode'
]
as
int
?
??
0
,
characterCodePoint:
characterCodePoint
,
modifiers:
message
[
'modifiers'
]
as
int
?
??
0
,
);
if
(
characterCodePoint
!=
0
)
{
character
=
String
.
fromCharCode
(
characterCodePoint
);
}
break
;
default
:
/// This exception would only be hit on platforms that haven't yet
/// implemented raw key events, but will only be triggered if the
/// engine for those platforms sends raw key event messages in the
/// first place.
throw
FlutterError
(
'Unknown keymap for key events:
$keymap
'
);
);
if
(
characterCodePoint
!=
0
)
{
character
=
String
.
fromCharCode
(
characterCodePoint
);
}
break
;
case
'web'
:
final
String
?
key
=
message
[
'key'
]
as
String
?;
data
=
RawKeyEventDataWeb
(
code:
message
[
'code'
]
as
String
?
??
''
,
key:
key
??
''
,
metaState:
message
[
'metaState'
]
as
int
?
??
0
,
);
if
(
key
!=
null
&&
key
.
isNotEmpty
)
{
character
=
key
;
}
break
;
default
:
/// This exception would only be hit on platforms that haven't yet
/// implemented raw key events, but will only be triggered if the
/// engine for those platforms sends raw key event messages in the
/// first place.
throw
FlutterError
(
'Unknown keymap for key events:
$keymap
'
);
}
}
final
String
type
=
message
[
'type'
]
as
String
;
switch
(
type
)
{
case
'keydown'
:
...
...
packages/flutter/test/services/raw_keyboard_test.dart
View file @
cc9b78fc
...
...
@@ -31,7 +31,7 @@ void main() {
}
});
testWidgets
(
'No character is produced for non-printables'
,
(
WidgetTester
tester
)
async
{
for
(
final
String
platform
in
<
String
>[
'linux'
,
'android'
,
'macos'
,
'fuchsia'
,
'windows'
])
{
for
(
final
String
platform
in
<
String
>[
'linux'
,
'android'
,
'macos'
,
'fuchsia'
,
'windows'
,
'web'
])
{
void
handleKey
(
RawKeyEvent
event
)
{
expect
(
event
.
character
,
isNull
,
reason:
'on
$platform
'
);
}
...
...
@@ -194,7 +194,7 @@ void main() {
await
simulateKeyUpEvent
(
LogicalKeyboardKey
.
keyA
,
platform:
platform
,
physicalKey:
PhysicalKeyboardKey
.
keyA
);
expect
(
RawKeyboard
.
instance
.
keysPressed
,
isEmpty
,
reason:
'on
$platform
'
);
}
}
);
}
,
skip:
isBrowser
);
// https://github.com/flutter/flutter/issues/76741
testWidgets
(
'keysPressed modifiers are synchronized with key events on macOS'
,
(
WidgetTester
tester
)
async
{
expect
(
RawKeyboard
.
instance
.
keysPressed
,
isEmpty
);
...
...
@@ -219,7 +219,7 @@ void main() {
<
LogicalKeyboardKey
>{
LogicalKeyboardKey
.
shiftLeft
,
LogicalKeyboardKey
.
keyA
},
),
);
}
);
}
,
skip:
isBrowser
);
// This is a macOS-specific test.
testWidgets
(
'keysPressed modifiers are synchronized with key events on iOS'
,
(
WidgetTester
tester
)
async
{
expect
(
RawKeyboard
.
instance
.
keysPressed
,
isEmpty
);
...
...
@@ -244,7 +244,7 @@ void main() {
<
LogicalKeyboardKey
>{
LogicalKeyboardKey
.
shiftLeft
,
LogicalKeyboardKey
.
keyA
},
),
);
}
);
}
,
skip:
isBrowser
);
// This is an iOS-specific test.
testWidgets
(
'keysPressed modifiers are synchronized with key events on Windows'
,
(
WidgetTester
tester
)
async
{
expect
(
RawKeyboard
.
instance
.
keysPressed
,
isEmpty
);
...
...
@@ -269,7 +269,7 @@ void main() {
<
LogicalKeyboardKey
>{
LogicalKeyboardKey
.
shiftLeft
,
LogicalKeyboardKey
.
keyA
},
),
);
}
);
}
,
skip:
isBrowser
);
// This is a Windows-specific test.
testWidgets
(
'keysPressed modifiers are synchronized with key events on android'
,
(
WidgetTester
tester
)
async
{
expect
(
RawKeyboard
.
instance
.
keysPressed
,
isEmpty
);
...
...
@@ -294,7 +294,7 @@ void main() {
<
LogicalKeyboardKey
>{
LogicalKeyboardKey
.
shiftLeft
,
LogicalKeyboardKey
.
keyA
},
),
);
}
);
}
,
skip:
isBrowser
);
// This is an Android-specific test.
testWidgets
(
'keysPressed modifiers are synchronized with key events on fuchsia'
,
(
WidgetTester
tester
)
async
{
expect
(
RawKeyboard
.
instance
.
keysPressed
,
isEmpty
);
...
...
@@ -319,7 +319,7 @@ void main() {
<
LogicalKeyboardKey
>{
LogicalKeyboardKey
.
shiftLeft
,
LogicalKeyboardKey
.
keyA
},
),
);
}
);
}
,
skip:
isBrowser
);
// This is a Fuchsia-specific test.
testWidgets
(
'keysPressed modifiers are synchronized with key events on Linux GLFW'
,
(
WidgetTester
tester
)
async
{
expect
(
RawKeyboard
.
instance
.
keysPressed
,
isEmpty
);
...
...
@@ -350,6 +350,37 @@ void main() {
},
),
);
},
skip:
isBrowser
);
// This is a GLFW-specific test.
testWidgets
(
'keysPressed modifiers are synchronized with key events on web'
,
(
WidgetTester
tester
)
async
{
expect
(
RawKeyboard
.
instance
.
keysPressed
,
isEmpty
);
// Generate the data for a regular key down event.
final
Map
<
String
,
dynamic
>
data
=
KeyEventSimulator
.
getKeyData
(
LogicalKeyboardKey
.
keyA
,
platform:
'web'
,
isDown:
true
,
);
// Change the modifiers so that they show the shift key as already down
// when this event is received, but it's not in keysPressed yet.
data
[
'metaState'
]
|=
RawKeyEventDataWeb
.
modifierShift
;
// dispatch the modified data.
await
ServicesBinding
.
instance
!.
defaultBinaryMessenger
.
handlePlatformMessage
(
SystemChannels
.
keyEvent
.
name
,
SystemChannels
.
keyEvent
.
codec
.
encodeMessage
(
data
),
(
ByteData
?
data
)
{},
);
expect
(
RawKeyboard
.
instance
.
keysPressed
,
equals
(
<
LogicalKeyboardKey
>{
LogicalKeyboardKey
.
shiftLeft
,
// Web doesn't distinguish between left and right keys, so they're
// all shown as down when either is pressed.
LogicalKeyboardKey
.
shiftRight
,
LogicalKeyboardKey
.
keyA
,
},
),
);
});
testWidgets
(
'sided modifiers without a side set return all sides on Android'
,
(
WidgetTester
tester
)
async
{
...
...
@@ -388,7 +419,7 @@ void main() {
},
),
);
}
);
}
,
skip:
isBrowser
);
// This is an Android-specific test.
testWidgets
(
'sided modifiers without a side set return all sides on macOS'
,
(
WidgetTester
tester
)
async
{
expect
(
RawKeyboard
.
instance
.
keysPressed
,
isEmpty
);
...
...
@@ -426,7 +457,7 @@ void main() {
},
),
);
}
);
}
,
skip:
isBrowser
);
// This is a macOS-specific test.
testWidgets
(
'sided modifiers without a side set return all sides on iOS'
,
(
WidgetTester
tester
)
async
{
expect
(
RawKeyboard
.
instance
.
keysPressed
,
isEmpty
);
...
...
@@ -464,7 +495,7 @@ void main() {
},
),
);
}
);
}
,
skip:
isBrowser
);
// This is an iOS-specific test.
testWidgets
(
'sided modifiers without a side set return all sides on Windows'
,
(
WidgetTester
tester
)
async
{
expect
(
RawKeyboard
.
instance
.
keysPressed
,
isEmpty
);
...
...
@@ -500,7 +531,7 @@ void main() {
},
),
);
}
);
}
,
skip:
isBrowser
);
// This is a Windows-specific test.
testWidgets
(
'sided modifiers without a side set return all sides on Linux GLFW'
,
(
WidgetTester
tester
)
async
{
expect
(
RawKeyboard
.
instance
.
keysPressed
,
isEmpty
);
...
...
@@ -539,6 +570,44 @@ void main() {
},
),
);
},
skip:
isBrowser
);
// This is a GLFW-specific test.
testWidgets
(
'sided modifiers without a side set return all sides on web'
,
(
WidgetTester
tester
)
async
{
expect
(
RawKeyboard
.
instance
.
keysPressed
,
isEmpty
);
// Generate the data for a regular key down event.
final
Map
<
String
,
dynamic
>
data
=
KeyEventSimulator
.
getKeyData
(
LogicalKeyboardKey
.
keyA
,
platform:
'web'
,
isDown:
true
,
);
// Set only the generic "shift down" modifier, without setting a side.
data
[
'metaState'
]
|=
RawKeyEventDataWeb
.
modifierShift
|
RawKeyEventDataWeb
.
modifierAlt
|
RawKeyEventDataWeb
.
modifierControl
|
RawKeyEventDataWeb
.
modifierMeta
;
// dispatch the modified data.
await
ServicesBinding
.
instance
!.
defaultBinaryMessenger
.
handlePlatformMessage
(
SystemChannels
.
keyEvent
.
name
,
SystemChannels
.
keyEvent
.
codec
.
encodeMessage
(
data
),
(
ByteData
?
data
)
{},
);
expect
(
RawKeyboard
.
instance
.
keysPressed
,
equals
(
<
LogicalKeyboardKey
>{
LogicalKeyboardKey
.
shiftLeft
,
LogicalKeyboardKey
.
shiftRight
,
LogicalKeyboardKey
.
altLeft
,
LogicalKeyboardKey
.
altRight
,
LogicalKeyboardKey
.
controlLeft
,
LogicalKeyboardKey
.
controlRight
,
LogicalKeyboardKey
.
metaLeft
,
LogicalKeyboardKey
.
metaRight
,
LogicalKeyboardKey
.
keyA
,
},
),
);
});
testWidgets
(
'RawKeyboard asserts if no keys are in keysPressed after receiving a key down event'
,
(
WidgetTester
tester
)
async
{
...
...
@@ -547,19 +616,32 @@ void main() {
FlutterError
.
onError
=
(
FlutterErrorDetails
details
)
{
errorDetails
=
details
;
};
final
Map
<
String
,
dynamic
>
keyEventMessage
;
if
(
kIsWeb
)
{
keyEventMessage
=
const
<
String
,
dynamic
>{
'type'
:
'keydown'
,
'keymap'
:
'web'
,
'code'
:
'ShiftLeft'
,
// Left shift code
'metaState'
:
0x0
,
// No shift key metaState set!
};
}
else
{
keyEventMessage
=
const
<
String
,
dynamic
>{
'type'
:
'keydown'
,
'keymap'
:
'android'
,
'keyCode'
:
0x3b
,
// Left shift key keyCode
'scanCode'
:
0x2a
,
'metaState'
:
0x0
,
// No shift key metaState set!
'source'
:
0x101
,
'deviceId'
:
1
,
};
}
try
{
await
ServicesBinding
.
instance
!.
defaultBinaryMessenger
.
handlePlatformMessage
(
SystemChannels
.
keyEvent
.
name
,
SystemChannels
.
keyEvent
.
codec
.
encodeMessage
(
const
<
String
,
dynamic
>{
'type'
:
'keydown'
,
'keymap'
:
'android'
,
'keyCode'
:
0x3b
,
// Left shift key keyCode
'scanCode'
:
0x2a
,
'metaState'
:
0x0
,
// No shift key metaState set!
'source'
:
0x101
,
'deviceId'
:
1
,
}),
SystemChannels
.
keyEvent
.
codec
.
encodeMessage
(
keyEventMessage
),
(
ByteData
?
data
)
{},
);
}
finally
{
...
...
@@ -837,7 +919,8 @@ void main() {
expect
(
message
,
equals
(<
String
,
dynamic
>{
'handled'
:
true
}));
ServicesBinding
.
instance
!.
defaultBinaryMessenger
.
setMockMessageHandler
(
SystemChannels
.
keyEvent
.
name
,
null
);
});
});
},
skip:
isBrowser
);
// This is an Android-specific group.
group
(
'RawKeyEventDataFuchsia'
,
()
{
const
Map
<
int
,
_ModifierCheck
>
modifierTests
=
<
int
,
_ModifierCheck
>{
RawKeyEventDataFuchsia
.
modifierAlt
:
_ModifierCheck
(
ModifierKey
.
altModifier
,
KeyboardSide
.
any
),
...
...
@@ -951,7 +1034,7 @@ void main() {
expect
(
data
.
logicalKey
,
equals
(
LogicalKeyboardKey
.
shiftLeft
));
expect
(
data
.
keyLabel
,
isEmpty
);
},
skip:
isBrowser
);
// https://github.com/flutter/flutter/issues/35347
}
);
}
,
skip:
isBrowser
);
// This is a Fuchsia-specific group.
group
(
'RawKeyEventDataMacOs'
,
()
{
const
Map
<
int
,
_ModifierCheck
>
modifierTests
=
<
int
,
_ModifierCheck
>{
...
...
@@ -1097,7 +1180,7 @@ void main() {
expect
(
data
.
logicalKey
,
equals
(
LogicalKeyboardKey
.
arrowLeft
));
expect
(
data
.
logicalKey
.
keyLabel
,
isEmpty
);
},
skip:
isBrowser
);
// https://github.com/flutter/flutter/issues/35347
}
);
}
,
skip:
isBrowser
);
// This is a macOS-specific group.
group
(
'RawKeyEventDataIos'
,
()
{
const
Map
<
int
,
_ModifierCheck
>
modifierTests
=
<
int
,
_ModifierCheck
>{
...
...
@@ -1243,7 +1326,7 @@ void main() {
expect
(
data
.
logicalKey
,
equals
(
LogicalKeyboardKey
.
arrowLeft
));
expect
(
data
.
logicalKey
.
keyLabel
,
isEmpty
);
},
skip:
isBrowser
);
// https://github.com/flutter/flutter/issues/35347
}
);
}
,
skip:
isBrowser
);
// This is an iOS-specific group.
group
(
'RawKeyEventDataWindows'
,
()
{
const
Map
<
int
,
_ModifierCheck
>
modifierTests
=
<
int
,
_ModifierCheck
>{
...
...
@@ -1388,7 +1471,7 @@ void main() {
expect
(
data
.
logicalKey
,
equals
(
LogicalKeyboardKey
.
arrowLeft
));
expect
(
data
.
logicalKey
.
keyLabel
,
isEmpty
);
});
}
);
}
,
skip:
isBrowser
);
// This is a Windows-specific group.
group
(
'RawKeyEventDataLinux-GFLW'
,
()
{
const
Map
<
int
,
_ModifierCheck
>
modifierTests
=
<
int
,
_ModifierCheck
>{
...
...
@@ -1572,7 +1655,7 @@ void main() {
expect
(
data
.
logicalKey
,
equals
(
LogicalKeyboardKey
.
shiftLeft
));
expect
(
data
.
keyLabel
,
isEmpty
);
});
}
);
}
,
skip:
isBrowser
);
// This is a GLFW-specific group.
group
(
'RawKeyEventDataLinux-GTK'
,
()
{
const
Map
<
int
,
_ModifierCheck
>
modifierTests
=
<
int
,
_ModifierCheck
>{
...
...
@@ -1756,7 +1839,7 @@ void main() {
expect
(
data
.
logicalKey
,
equals
(
LogicalKeyboardKey
.
shiftLeft
));
expect
(
data
.
keyLabel
,
isEmpty
);
});
}
);
}
,
skip:
isBrowser
);
// This is a GTK-specific group.
group
(
'RawKeyEventDataWeb'
,
()
{
const
Map
<
int
,
ModifierKey
>
modifierTests
=
<
int
,
ModifierKey
>{
...
...
packages/flutter/test/widgets/raw_keyboard_listener_test.dart
View file @
cc9b78fc
...
...
@@ -42,6 +42,37 @@ void main() {
expect
(
typedData
.
modifiers
,
RawKeyEventDataFuchsia
.
modifierLeftMeta
);
expect
(
typedData
.
isModifierPressed
(
ModifierKey
.
metaModifier
,
side:
KeyboardSide
.
left
),
isTrue
);
await
tester
.
pumpWidget
(
Container
());
focusNode
.
dispose
();
},
skip:
isBrowser
);
// This is a Fuchsia-specific test.
testWidgets
(
'Web key event'
,
(
WidgetTester
tester
)
async
{
final
List
<
RawKeyEvent
>
events
=
<
RawKeyEvent
>[];
final
FocusNode
focusNode
=
FocusNode
();
await
tester
.
pumpWidget
(
RawKeyboardListener
(
focusNode:
focusNode
,
onKey:
events
.
add
,
child:
Container
(),
),
);
focusNode
.
requestFocus
();
await
tester
.
idle
();
await
tester
.
sendKeyEvent
(
LogicalKeyboardKey
.
metaLeft
,
platform:
'web'
);
await
tester
.
idle
();
expect
(
events
.
length
,
2
);
expect
(
events
[
0
].
runtimeType
,
equals
(
RawKeyDownEvent
));
expect
(
events
[
0
].
data
,
isA
<
RawKeyEventDataWeb
>());
final
RawKeyEventDataWeb
typedData
=
events
[
0
].
data
as
RawKeyEventDataWeb
;
expect
(
typedData
.
code
,
'MetaLeft'
);
expect
(
typedData
.
metaState
,
RawKeyEventDataWeb
.
modifierMeta
);
expect
(
typedData
.
isModifierPressed
(
ModifierKey
.
metaModifier
,
side:
KeyboardSide
.
left
),
isTrue
);
await
tester
.
pumpWidget
(
Container
());
focusNode
.
dispose
();
});
...
...
packages/flutter_test/lib/src/event_simulation.dart
View file @
cc9b78fc
...
...
@@ -4,6 +4,7 @@
import
'dart:io'
;
import
'package:flutter/foundation.dart'
show
kIsWeb
;
import
'package:flutter/services.dart'
;
import
'test_async_utils.dart'
;
...
...
@@ -85,40 +86,47 @@ class KeyEventSimulator {
static
int
_getKeyCode
(
LogicalKeyboardKey
key
,
String
platform
)
{
assert
(
_osIsSupported
(
platform
),
'Platform
$platform
not supported for key simulation'
);
late
Map
<
int
,
LogicalKeyboardKey
>
map
;
switch
(
platform
)
{
case
'android'
:
map
=
kAndroidToLogicalKey
;
break
;
case
'fuchsia'
:
map
=
kFuchsiaToLogicalKey
;
break
;
case
'macos'
:
// macOS doesn't do key codes, just scan codes.
return
-
1
;
case
'ios'
:
// iOS doesn't do key codes, just scan codes.
return
-
1
;
case
'web'
:
// web doesn't have int type code
return
-
1
;
case
'linux'
:
map
=
kGlfwToLogicalKey
;
break
;
case
'windows'
:
map
=
kWindowsToLogicalKey
;
break
;
}
int
?
keyCode
;
for
(
final
int
code
in
map
.
keys
)
{
if
(
key
.
keyId
==
map
[
code
]!.
keyId
)
{
keyCode
=
code
;
break
;
if
(
kIsWeb
)
{
// web doesn't have int type code. This check is used to treeshake
// keyboard map code.
return
-
1
;
}
else
{
late
Map
<
int
,
LogicalKeyboardKey
>
map
;
switch
(
platform
)
{
case
'android'
:
map
=
kAndroidToLogicalKey
;
break
;
case
'fuchsia'
:
map
=
kFuchsiaToLogicalKey
;
break
;
case
'macos'
:
// macOS doesn't do key codes, just scan codes.
return
-
1
;
case
'ios'
:
// iOS doesn't do key codes, just scan codes.
return
-
1
;
case
'web'
:
// web doesn't have int type code.
return
-
1
;
case
'linux'
:
map
=
kGlfwToLogicalKey
;
break
;
case
'windows'
:
map
=
kWindowsToLogicalKey
;
break
;
}
int
?
keyCode
;
for
(
final
int
code
in
map
.
keys
)
{
if
(
key
.
keyId
==
map
[
code
]!.
keyId
)
{
keyCode
=
code
;
break
;
}
}
assert
(
keyCode
!=
null
,
'Key
$key
not found in
$platform
keyCode map'
);
return
keyCode
!;
}
assert
(
keyCode
!=
null
,
'Key
$key
not found in
$platform
keyCode map'
);
return
keyCode
!;
}
static
String
_getWebKeyCode
(
LogicalKeyboardKey
key
)
{
String
?
result
;
for
(
final
String
code
in
kWebToLogicalKey
.
keys
)
{
...
...
@@ -134,28 +142,33 @@ class KeyEventSimulator {
static
PhysicalKeyboardKey
_findPhysicalKey
(
LogicalKeyboardKey
key
,
String
platform
)
{
assert
(
_osIsSupported
(
platform
),
'Platform
$platform
not supported for key simulation'
);
late
Map
<
dynamic
,
PhysicalKeyboardKey
>
map
;
switch
(
platform
)
{
case
'android'
:
map
=
kAndroidToPhysicalKey
;
break
;
case
'fuchsia'
:
map
=
kFuchsiaToPhysicalKey
;
break
;
case
'macos'
:
map
=
kMacOsToPhysicalKey
;
break
;
case
'ios'
:
map
=
kIosToPhysicalKey
;
break
;
case
'linux'
:
map
=
kLinuxToPhysicalKey
;
break
;
case
'web'
:
map
=
kWebToPhysicalKey
;
break
;
case
'windows'
:
map
=
kWindowsToPhysicalKey
;
break
;
if
(
kIsWeb
)
{
// This check is used to treeshake keymap code.
map
=
kWebToPhysicalKey
;
}
else
{
switch
(
platform
)
{
case
'android'
:
map
=
kAndroidToPhysicalKey
;
break
;
case
'fuchsia'
:
map
=
kFuchsiaToPhysicalKey
;
break
;
case
'macos'
:
map
=
kMacOsToPhysicalKey
;
break
;
case
'ios'
:
map
=
kIosToPhysicalKey
;
break
;
case
'linux'
:
map
=
kLinuxToPhysicalKey
;
break
;
case
'web'
:
map
=
kWebToPhysicalKey
;
break
;
case
'windows'
:
map
=
kWindowsToPhysicalKey
;
break
;
}
}
PhysicalKeyboardKey
?
result
;
for
(
final
PhysicalKeyboardKey
physicalKey
in
map
.
values
)
{
...
...
@@ -191,6 +204,13 @@ class KeyEventSimulator {
'keymap'
:
platform
,
};
if
(
kIsWeb
)
{
result
[
'code'
]
=
_getWebKeyCode
(
key
);
result
[
'key'
]
=
key
.
keyLabel
;
result
[
'metaState'
]
=
_getWebModifierFlags
(
key
,
isDown
);
return
result
;
}
switch
(
platform
)
{
case
'android'
:
result
[
'keyCode'
]
=
keyCode
;
...
...
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