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
77925192
Unverified
Commit
77925192
authored
Mar 02, 2021
by
Tong Mu
Committed by
GitHub
Mar 02, 2021
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
RawKeyboardWindows: Filter out IME events (#77039)
parent
2e8b5c7e
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
94 additions
and
15 deletions
+94
-15
raw_keyboard.dart
packages/flutter/lib/src/services/raw_keyboard.dart
+38
-15
raw_keyboard_macos.dart
packages/flutter/lib/src/services/raw_keyboard_macos.dart
+11
-0
raw_keyboard_windows.dart
packages/flutter/lib/src/services/raw_keyboard_windows.dart
+14
-0
raw_keyboard_test.dart
packages/flutter/test/services/raw_keyboard_test.dart
+31
-0
No files found.
packages/flutter/lib/src/services/raw_keyboard.dart
View file @
77925192
...
...
@@ -226,6 +226,24 @@ abstract class RawKeyEventData {
/// interacting with an input method editor (IME).
/// {@endtemplate}
String
get
keyLabel
;
/// Whether a key down event, and likewise its accompanying key up event,
/// should be disapatched.
///
/// Certain events on some platforms should not be dispatched to listeners
/// according to Flutter's event model. For example, on macOS, Fn keys are
/// skipped to be consistant with other platform. On Win32, events dispatched
/// for IME (`VK_PROCESSKEY`) are also skipped.
///
/// This method will be called upon every down events. By default, this method
/// always return true. Subclasses should override this method to define the
/// filtering rule for the platform. If this method returns false for an event
/// message, the event will not be dispatched to listeners, but respond with
/// "handled: true" immediately. Moreover, the following up event with the
/// same physical key will also be skipped.
bool
shouldDispatchEvent
()
{
return
true
;
}
}
/// Defines the interface for raw key events.
...
...
@@ -614,23 +632,27 @@ class RawKeyboard {
Future
<
dynamic
>
_handleKeyEvent
(
dynamic
message
)
async
{
final
RawKeyEvent
event
=
RawKeyEvent
.
fromMessage
(
message
as
Map
<
String
,
dynamic
>);
if
(
event
.
data
is
RawKeyEventDataMacOs
&&
event
.
logicalKey
==
LogicalKeyboardKey
.
fn
)
{
// On macOS laptop keyboards, the fn key is used to generate home/end and
// f1-f12, but it ALSO generates a separate down/up event for the fn key
// itself. Other platforms hide the fn key, and just produce the key that
// it is combined with, so to keep it possible to write cross platform
// code that looks at which keys are pressed, the fn key is ignored on
// macOS.
return
;
}
bool
shouldDispatch
=
true
;
if
(
event
is
RawKeyDownEvent
)
{
_keysPressed
[
event
.
physicalKey
]
=
event
.
logicalKey
;
if
(
event
.
data
.
shouldDispatchEvent
())
{
_keysPressed
[
event
.
physicalKey
]
=
event
.
logicalKey
;
}
else
{
shouldDispatch
=
false
;
_hiddenKeysPressed
.
add
(
event
.
physicalKey
);
}
}
else
if
(
event
is
RawKeyUpEvent
)
{
if
(!
_hiddenKeysPressed
.
contains
(
event
.
physicalKey
))
{
// Use the physical key in the key up event to find the physical key from
// the corresponding key down event and remove it, even if the logical
// keys don't match.
_keysPressed
.
remove
(
event
.
physicalKey
);
}
else
{
_hiddenKeysPressed
.
remove
(
event
.
physicalKey
);
shouldDispatch
=
false
;
}
}
if
(
event
is
RawKeyUpEvent
)
{
// Use the physical key in the key up event to find the physical key from
// the corresponding key down event and remove it, even if the logical
// keys don't match.
_keysPressed
.
remove
(
event
.
physicalKey
);
if
(!
shouldDispatch
)
{
return
<
String
,
dynamic
>{
'handled'
:
true
};
}
// Make sure that the modifiers reflect reality, in case a modifier key was
// pressed/released while the app didn't have focus.
...
...
@@ -742,6 +764,7 @@ class RawKeyboard {
}
final
Map
<
PhysicalKeyboardKey
,
LogicalKeyboardKey
>
_keysPressed
=
<
PhysicalKeyboardKey
,
LogicalKeyboardKey
>{};
final
Set
<
PhysicalKeyboardKey
>
_hiddenKeysPressed
=
<
PhysicalKeyboardKey
>{};
/// Returns the set of keys currently pressed.
Set
<
LogicalKeyboardKey
>
get
keysPressed
=>
_keysPressed
.
values
.
toSet
();
...
...
packages/flutter/lib/src/services/raw_keyboard_macos.dart
View file @
77925192
...
...
@@ -221,6 +221,17 @@ class RawKeyEventDataMacOs extends RawKeyEventData {
}
}
@override
bool
shouldDispatchEvent
()
{
// On macOS laptop keyboards, the fn key is used to generate home/end and
// f1-f12, but it ALSO generates a separate down/up event for the fn key
// itself. Other platforms hide the fn key, and just produce the key that
// it is combined with, so to keep it possible to write cross platform
// code that looks at which keys are pressed, the fn key is ignored on
// macOS.
return
logicalKey
!=
LogicalKeyboardKey
.
fn
;
}
/// Returns true if the given label represents an unprintable key.
///
/// Examples of unprintable keys are "NSUpArrowFunctionKey = 0xF700"
...
...
packages/flutter/lib/src/services/raw_keyboard_windows.dart
View file @
77925192
...
...
@@ -9,6 +9,11 @@ import 'keyboard_key.dart';
import
'keyboard_maps.dart'
;
import
'raw_keyboard.dart'
;
// Virtual key VK_PROCESSKEY in Win32 API.
//
// Key down events related to IME operations use this as keyCode.
const
int
_vkProcessKey
=
0xe5
;
/// Platform-specific key event data for Windows.
///
/// This object contains information about key events obtained from Windows's
...
...
@@ -194,6 +199,15 @@ class RawKeyEventDataWindows extends RawKeyEventData {
}
}
@override
bool
shouldDispatchEvent
()
{
// In Win32 API, down events related to IME operations use VK_PROCESSKEY as
// keyCode. This event, as well as the following key up event (which uses a
// normal keyCode), should be skipped, because the effect of IME operations
// will be handled by the text input API.
return
keyCode
!=
_vkProcessKey
;
}
// These are not the values defined by the Windows header for each modifier. Since they
// can't be packaged into a single int, we are re-defining them here to reduce the size
// of the message from the embedder. Embedders should map these values to the native key codes.
...
...
packages/flutter/test/services/raw_keyboard_test.dart
View file @
77925192
...
...
@@ -1471,6 +1471,37 @@ void main() {
expect
(
data
.
logicalKey
,
equals
(
LogicalKeyboardKey
.
arrowLeft
));
expect
(
data
.
logicalKey
.
keyLabel
,
isEmpty
);
});
testWidgets
(
'Win32 VK_PROCESSKEY events are skipped'
,
(
WidgetTester
tester
)
async
{
const
String
platform
=
'windows'
;
bool
lastHandled
=
true
;
final
List
<
RawKeyEvent
>
events
=
<
RawKeyEvent
>[];
// Simulate raw events because VK_PROCESSKEY does not exist in the key mapping.
Future
<
void
>
simulateKeyEventMessage
(
String
type
,
int
keyCode
,
int
scanCode
)
{
return
ServicesBinding
.
instance
!.
defaultBinaryMessenger
.
handlePlatformMessage
(
SystemChannels
.
keyEvent
.
name
,
SystemChannels
.
keyEvent
.
codec
.
encodeMessage
(<
String
,
dynamic
>{
'type'
:
type
,
'keymap'
:
platform
,
'keyCode'
:
keyCode
,
'scanCode'
:
scanCode
,
'modifiers'
:
0
,
}),
(
ByteData
?
data
)
{
final
Map
<
String
,
dynamic
>
decoded
=
SystemChannels
.
keyEvent
.
codec
.
decodeMessage
(
data
)
as
Map
<
String
,
dynamic
>;
lastHandled
=
decoded
[
'handled'
]
as
bool
;
}
);
}
RawKeyboard
.
instance
.
addListener
(
events
.
add
);
await
simulateKeyEventMessage
(
'keydown'
,
229
,
30
);
expect
(
events
,
isEmpty
);
expect
(
lastHandled
,
true
);
expect
(
RawKeyboard
.
instance
.
keysPressed
,
isEmpty
);
await
simulateKeyEventMessage
(
'keyup'
,
65
,
30
);
expect
(
events
,
isEmpty
);
expect
(
lastHandled
,
true
);
expect
(
RawKeyboard
.
instance
.
keysPressed
,
isEmpty
);
});
},
skip:
isBrowser
);
// This is a Windows-specific group.
group
(
'RawKeyEventDataLinux-GFLW'
,
()
{
...
...
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