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
b60c855a
Unverified
Commit
b60c855a
authored
Mar 27, 2021
by
Tong Mu
Committed by
GitHub
Mar 27, 2021
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Make LogicalKeyboardKey.keyLabel a getter and better (#79100)
parent
7c2b969a
Changes
14
Show whitespace changes
Inline
Side-by-side
Showing
14 changed files
with
1450 additions
and
797 deletions
+1450
-797
keyboard_key.tmpl
dev/tools/gen_keycodes/data/keyboard_key.tmpl
+128
-68
keyboard_keys_code_gen.dart
dev/tools/gen_keycodes/lib/keyboard_keys_code_gen.dart
+36
-15
keyboard_key.dart
packages/flutter/lib/src/services/keyboard_key.dart
+1213
-611
raw_keyboard_android.dart
packages/flutter/lib/src/services/raw_keyboard_android.dart
+2
-9
raw_keyboard_fuchsia.dart
packages/flutter/lib/src/services/raw_keyboard_fuchsia.dart
+3
-9
raw_keyboard_ios.dart
packages/flutter/lib/src/services/raw_keyboard_ios.dart
+3
-15
raw_keyboard_linux.dart
packages/flutter/lib/src/services/raw_keyboard_linux.dart
+2
-9
raw_keyboard_macos.dart
packages/flutter/lib/src/services/raw_keyboard_macos.dart
+3
-14
raw_keyboard_web.dart
packages/flutter/lib/src/services/raw_keyboard_web.dart
+1
-4
raw_keyboard_windows.dart
packages/flutter/lib/src/services/raw_keyboard_windows.dart
+2
-11
keyboard_key_test.dart
packages/flutter/test/services/keyboard_key_test.dart
+32
-11
raw_keyboard_test.dart
packages/flutter/test/services/raw_keyboard_test.dart
+0
-3
shortcuts_test.dart
packages/flutter/test/widgets/shortcuts_test.dart
+3
-3
event_simulation.dart
packages/flutter_test/lib/src/event_simulation.dart
+22
-15
No files found.
dev/tools/gen_keycodes/data/keyboard_key.tmpl
View file @
b60c855a
...
...
@@ -76,9 +76,9 @@ abstract class KeyboardKey with Diagnosticable {
/// _message = 'Pressed the "Q" key!';
/// } else {
/// if (kReleaseMode) {
/// _message = 'Not a Q:
Key label is "${event.logicalKey.keyLabel}"
';
/// _message = 'Not a Q:
Pressed 0x${event.logicalKey.keyId.toRadixString(16)}
';
/// } else {
/// // Th
is
will only print useful information in debug mode.
/// // Th
e debugName
will only print useful information in debug mode.
/// _message = 'Not a Q: Pressed ${event.logicalKey.debugName}';
/// }
/// }
...
...
@@ -124,21 +124,18 @@ abstract class KeyboardKey with Diagnosticable {
/// keyboard events.
@immutable
class LogicalKeyboardKey extends KeyboardKey {
/// Creates a LogicalKeyboardKey object with an optional key label and debug
/// name.
/// A LogicalKeyboardKey object for a key ID.
///
/// [keyId] must not be null.
///
/// {@tool snippet}
/// To save executable size, it is recommended that the [debugName] be null in
/// release mode. You can do this by using the [kReleaseMode] constant.
///
/// ```dart
/// const LogicalKeyboardKey(0x0010000000a, debugName: kReleaseMode ? null : 'Special Key')
/// ```
/// {@end-tool}
const LogicalKeyboardKey(this.keyId, {this.debugName, this.keyLabel = ''})
: assert(keyId != null);
/// This factory constructor ensures that the same `keyId` always results
/// in the identical instance. It looks up an object from the predefined values
/// if possible, or construct a new one and cache it.
factory LogicalKeyboardKey(int keyId) {
return findKeyByKeyId(keyId) ??
_additionalKeyPool.putIfAbsent(keyId, () => LogicalKeyboardKey._(keyId));
}
/// Creates a LogicalKeyboardKey object for a key ID.
const LogicalKeyboardKey._(this.keyId);
/// A unique code representing this key.
///
...
...
@@ -146,37 +143,95 @@ class LogicalKeyboardKey extends KeyboardKey {
/// from it, as the representation of the code could change at any time.
final int keyId;
/// The debug string to print for this keyboard key, which will be null in
/// release mode.
final String? debugName;
// Returns the bits that are not included in [valueMask], shifted to the
// right.
//
// For example, if the input is 0x12abcdabcd, then the result is 0x12.
//
// This is mostly equivalent to a right shift, resolving the problem that
// JavaScript only support 32-bit bitwise operation and needs to use division
// instead.
static int _nonValueBits(int n) {
// `n >> valueMaskWidth` is equivalent to `n / divisorForValueMask`.
const int divisorForValueMask = valueMask + 1;
const int valueMaskWidth = 32;
// Equivalent to assert(divisorForValueMask == (1 << valueMaskWidth)).
const int _firstDivisorWidth = 28;
assert(divisorForValueMask ==
(1 << _firstDivisorWidth) * (1 << (valueMaskWidth - _firstDivisorWidth)));
// JS only supports up to 2^53 - 1, therefore non-value bits can only
// contain (maxSafeIntegerWidth - valueMaskWidth) bits.
const int maxSafeIntegerWidth = 52;
const int nonValueMask = (1 << (maxSafeIntegerWidth - valueMaskWidth)) - 1;
if (kIsWeb) {
return (n / divisorForValueMask).floor() & nonValueMask;
} else {
return (n >> valueMaskWidth) & nonValueMask;
}
}
/// The Unicode string representing the character produced by a [RawKeyEvent].
static String? _unicodeKeyLabel(int keyId) {
if (_nonValueBits(keyId) == 0) {
return String.fromCharCode(keyId).toUpperCase();
}
return null;
}
/// A description representing the character produced by a [RawKeyEvent].
///
/// This value is useful for describing or matching mnemonic keyboard
/// shortcuts.
/// This value is useful for providing readable strings for keys or keyboard
/// shortcuts. Do not use this value to compare equality of keys; compare
/// [keyId] instead.
///
/// This value is an empty string if there's no key label data for a key.
/// For printable keys, this is usually the printable character in upper case
/// ignoring modifiers or combining keys, such as 'A', '1', or '/'. This
/// might also return accented letters (such as 'Ù') for keys labeled as so,
/// but not if such character is a result from preceding combining keys ('`̀'
/// followed by key U).
///
///
On most platforms this is a single code point, but it could contain any
///
Unicode string. The `keyLabel` differs from [RawKeyEvent.character]
///
because `keyLabel` only takes into account the key being pressed, not any
///
combining keys pressed before it, so, for example, an “o” that follows a
///
combining dieresis (“¨”, COMBINING DIAERESIS (U+0308)) would just return
///
“o” for [keyLabel], but would return “ö” for
[RawKeyEvent.character].
///
For other keys, [keyLabel] looks up the full key name from a predefined
///
map, such as 'F1', 'Shift Left', or 'Media Down'. This value is an empty
///
string if there's no key label data for a key.
///
///
For the printable representation that takes into consideration the
///
modifiers and combining keys, see
[RawKeyEvent.character].
///
/// {@macro flutter.services.RawKeyEventData.keyLabel}
final String keyLabel;
@override
int get hashCode => keyId.hashCode;
String get keyLabel {
return _unicodeKeyLabel(keyId)
?? _keyLabels[keyId]
?? '';
}
@override
bool operator ==(Object other) {
if (other.runtimeType != runtimeType) {
return false;
/// The debug string to print for this keyboard key, which will be null in
/// release mode.
///
/// For printable keys, this is usually a more descriptive name related to
/// [keyLabel], such as 'Key A', 'Digit 1', 'Backslash'. This might
/// also return accented letters (such as 'Key Ù') for keys labeled as so.
///
/// For other keys, this looks up the full key name from a predefined map (the
/// same value as [keyLabel]), such as 'F1', 'Shift Left', or 'Media Down'. If
/// there's no key label data for a key, this returns a name that explains the
/// ID (such as 'Key with ID 0x00100012345').
String? get debugName {
String? result;
assert(() {
result = _keyLabels[keyId];
if (result == null) {
final String? unicodeKeyLabel = _unicodeKeyLabel(keyId);
if (unicodeKeyLabel != null) {
result = 'Key $unicodeKeyLabel';
} else {
result = 'Key with ID 0x${keyId.toRadixString(16).padLeft(11, '0')}';
}
}
return other is LogicalKeyboardKey
&& other.keyId == keyId;
return true;
}());
return result;
}
/// Returns the [LogicalKeyboardKey] constant that matches the given ID, or
...
...
@@ -261,10 +316,11 @@ class LogicalKeyboardKey extends KeyboardKey {
void debugFillProperties(DiagnosticPropertiesBuilder properties) {
super.debugFillProperties(properties);
properties.add(StringProperty('keyId', '0x${keyId.toRadixString(16).padLeft(8, '0')}', showName: true));
properties.add(StringProperty('keyLabel', keyLabel, showName: true));
properties.add(StringProperty('debugName', debugName, showName: true, defaultValue: null));
}
static final Map<int, LogicalKeyboardKey> _additionalKeyPool = <int, LogicalKeyboardKey>{};
/// Mask for the 32-bit value portion of the key code.
///
/// This is used by platform-specific code to generate Flutter key codes.
...
...
@@ -313,6 +369,9 @@ class LogicalKeyboardKey extends KeyboardKey {
// A map of keys to the pseudo-key synonym for that key. Used by getSynonyms.
static final Map<LogicalKeyboardKey, LogicalKeyboardKey> _synonyms = <LogicalKeyboardKey, LogicalKeyboardKey>{
@@@LOGICAL_KEY_SYNONYMS@@@ };
static const Map<int, String> _keyLabels = <int, String>{
@@@LOGICAL_KEY_KEY_LABELS@@@ };
}
/// A class with static values that describe the keys that are returned from
...
...
@@ -387,7 +446,7 @@ class LogicalKeyboardKey extends KeyboardKey {
/// onTap: () {
/// FocusScope.of(context).requestFocus(_focusNode);
/// },
/// child: Text('Tap to focus'),
/// child:
const
Text('Tap to focus'),
/// );
/// }
/// return Text(_message ?? 'Press a key');
...
...
@@ -408,20 +467,18 @@ class LogicalKeyboardKey extends KeyboardKey {
/// keyboard events.
@immutable
class PhysicalKeyboardKey extends KeyboardKey {
/// Creates a PhysicalKeyboardKey object with an optional debug name.
///
/// The [usbHidUsage] must not be null.
///
/// {@tool snippet}
/// To save executable size, it is recommended that the [debugName] be null in
/// release mode. You can do this using the [kReleaseMode] constant.
/// A PhysicalKeyboardKey object for a USB HID usage.
///
/// ```dart
/// const PhysicalKeyboardKey(0x0000ffff, debugName: kReleaseMode ? null : 'Special Key')
/// ```
/// {@end-tool}
const PhysicalKeyboardKey(this.usbHidUsage, {this.debugName})
: assert(usbHidUsage != null);
/// This factory constructor ensures that the same `usbHidUsage` always results
/// in the identical instance. It looks up an object from the predefined values
/// if possible, or construct a new one and cache it.
factory PhysicalKeyboardKey(int usbHidUsage) {
return findKeyByCode(usbHidUsage) ??
_additionalKeyPool.putIfAbsent(usbHidUsage, () => PhysicalKeyboardKey._(usbHidUsage));
}
/// Creates a PhysicalKeyboardKey object for a USB HID usage.
const PhysicalKeyboardKey._(this.usbHidUsage);
/// The unique USB HID usage ID of this physical key on the keyboard.
///
...
...
@@ -435,24 +492,20 @@ class PhysicalKeyboardKey extends KeyboardKey {
/// The debug string to print for this keyboard key, which will be null in
/// release mode.
final String? debugName;
String? get debugName {
String? result;
assert(() {
result = _debugNames[usbHidUsage] ??
'Key with ID 0x${usbHidUsage.toRadixString(16).padLeft(8, '0')}';
return true;
}());
return result;
}
/// Finds a known [PhysicalKeyboardKey] that matches the given USB HID usage
/// code.
static PhysicalKeyboardKey? findKeyByCode(int usageCode) => _knownPhysicalKeys[usageCode];
@override
int get hashCode => usbHidUsage.hashCode;
@override
bool operator ==(Object other) {
if (other.runtimeType != runtimeType) {
return false;
}
return other is PhysicalKeyboardKey
&& other.usbHidUsage == usbHidUsage;
}
@override
void debugFillProperties(DiagnosticPropertiesBuilder properties) {
super.debugFillProperties(properties);
...
...
@@ -460,6 +513,8 @@ class PhysicalKeyboardKey extends KeyboardKey {
properties.add(StringProperty('debugName', debugName, showName: true, defaultValue: null));
}
static final Map<int, PhysicalKeyboardKey> _additionalKeyPool = <int, PhysicalKeyboardKey>{};
// Key constants for all keyboard keys in the USB HID specification at the
// time Flutter was built.
@@@PHYSICAL_KEY_DEFINITIONS@@@
...
...
@@ -468,4 +523,9 @@ class PhysicalKeyboardKey extends KeyboardKey {
static const Map<int, PhysicalKeyboardKey> _knownPhysicalKeys = <int, PhysicalKeyboardKey>{
@@@PHYSICAL_KEY_MAP@@@
};
static const Map<int, String> _debugNames = kReleaseMode ?
<int, String>{} :
<int, String>{
@@@PHYSICAL_KEY_DEBUG_NAMES@@@ };
}
dev/tools/gen_keycodes/lib/keyboard_keys_code_gen.dart
View file @
b60c855a
...
...
@@ -45,38 +45,38 @@ class KeyboardKeysCodeGenerator extends BaseCodeGenerator {
definitions
.
write
(
'''
$firstComment
///
$otherComments
static const PhysicalKeyboardKey
${entry.constantName}
= PhysicalKeyboardKey
(
${toHex(entry.usbHidCode, digits: 8)}
, debugName: kReleaseMode ? null : '
$
{
entry
.
commentName
}
'
);
$otherComments
static const PhysicalKeyboardKey
${entry.constantName}
= PhysicalKeyboardKey
._(
${toHex(entry.usbHidCode, digits: 8)}
);
'''
);
}
return
definitions
.
toString
();
}
String
get
_physicalDebugNames
{
final
StringBuffer
result
=
StringBuffer
();
for
(
final
Key
entry
in
keyData
.
data
)
{
result
.
write
(
'''
${toHex(entry.usbHidCode, digits: 8)}
: '
$
{
entry
.
commentName
}
',
'''
);
}
return
result
.
toString
();
}
/// Gets the generated definitions of LogicalKeyboardKeys.
String
get
_logicalDefinitions
{
String
escapeLabel
(
String
label
)
=>
label
.
contains
(
"'"
)
?
'r"
$label
"'
:
"r'
$label
'"
;
final
StringBuffer
definitions
=
StringBuffer
();
void
printKey
(
int
flutterId
,
String
keyLabel
,
String
constantName
,
String
commentName
,
{
String
otherComments
})
{
void
printKey
(
int
flutterId
,
String
constantName
,
String
commentName
,
{
String
otherComments
})
{
final
String
firstComment
=
_wrapString
(
'Represents the logical "
$commentName
" key on the keyboard.'
);
otherComments
??=
_wrapString
(
'See the function [RawKeyEvent.logicalKey] for more information.'
);
if
(
keyLabel
==
null
)
{
definitions
.
write
(
'''
$firstComment
///
$otherComments
static const LogicalKeyboardKey
$constantName
= LogicalKeyboardKey
(
${toHex(flutterId, digits: 11)}
, debugName: kReleaseMode ? null : '
$commentName
'
);
$otherComments
static const LogicalKeyboardKey
$constantName
= LogicalKeyboardKey
._(
${toHex(flutterId, digits: 11)}
);
'''
);
}
else
{
definitions
.
write
(
'''
$firstComment
///
$otherComments
static const LogicalKeyboardKey
$constantName
= LogicalKeyboardKey(
${toHex(flutterId, digits: 11)}
, keyLabel:
${escapeLabel(keyLabel)}
, debugName: kReleaseMode ? null : '
$commentName
');
'''
);
}
}
for
(
final
Key
entry
in
keyData
.
data
)
{
printKey
(
entry
.
flutterId
,
entry
.
keyLabel
,
entry
.
constantName
,
entry
.
commentName
,
);
...
...
@@ -89,7 +89,7 @@ $otherComments static const LogicalKeyboardKey $constantName = LogicalKeyboardK
final
Set
<
String
>
unionNames
=
Key
.
synonyms
[
name
].
map
<
String
>((
dynamic
name
)
{
return
upperCamelToLowerCamel
(
name
as
String
);
}).
toSet
();
printKey
(
Key
.
synonymPlane
|
entry
.
flutterId
,
entry
.
keyLabel
,
name
,
Key
.
getCommentName
(
name
),
printKey
(
Key
.
synonymPlane
|
entry
.
flutterId
,
name
,
Key
.
getCommentName
(
name
),
otherComments:
_wrapString
(
'This key represents the union of the keys '
'
$unionNames
when comparing keys. This key will never be generated '
'directly, its main use is in defining key maps.'
));
...
...
@@ -108,6 +108,25 @@ $otherComments static const LogicalKeyboardKey $constantName = LogicalKeyboardK
return
synonyms
.
toString
();
}
String
get
_logicalKeyLabels
{
final
StringBuffer
result
=
StringBuffer
();
for
(
final
Key
entry
in
keyData
.
data
)
{
result
.
write
(
'''
${toHex(entry.flutterId, digits: 11)}
: '
$
{
entry
.
commentName
}
',
'''
);
}
for
(
final
String
name
in
Key
.
synonyms
.
keys
)
{
// Use the first item in the synonyms as a template for the ID to use.
// It won't end up being the same value because it'll be in the pseudo-key
// plane.
final
Key
entry
=
keyData
.
data
.
firstWhere
((
Key
item
)
=>
item
.
name
==
Key
.
synonyms
[
name
][
0
]);
result
.
write
(
'''
${toHex(Key.synonymPlane | entry.flutterId, digits: 11)}
: '
$
{
Key
.
getCommentName
(
name
)}
',
'''
);
}
return
result
.
toString
();
}
/// This generates the map of USB HID codes to physical keys.
String
get
_predefinedHidCodeMap
{
final
StringBuffer
scanCodeMap
=
StringBuffer
();
...
...
@@ -146,7 +165,9 @@ $otherComments static const LogicalKeyboardKey $constantName = LogicalKeyboardK
'LOGICAL_KEY_MAP'
:
_predefinedKeyCodeMap
,
'LOGICAL_KEY_DEFINITIONS'
:
_logicalDefinitions
,
'LOGICAL_KEY_SYNONYMS'
:
_logicalSynonyms
,
'LOGICAL_KEY_KEY_LABELS'
:
_logicalKeyLabels
,
'PHYSICAL_KEY_DEFINITIONS'
:
_physicalDefinitions
,
'PHYSICAL_KEY_DEBUG_NAMES'
:
_physicalDebugNames
,
};
}
}
packages/flutter/lib/src/services/keyboard_key.dart
View file @
b60c855a
This source diff could not be displayed because it is too large. You can
view the blob
instead.
packages/flutter/lib/src/services/raw_keyboard_android.dart
View file @
b60c855a
...
...
@@ -194,11 +194,7 @@ class RawKeyEventDataAndroid extends RawKeyEventData {
if
(
keyLabel
.
isNotEmpty
&&
!
LogicalKeyboardKey
.
isControlCharacter
(
keyLabel
))
{
final
int
combinedCodePoint
=
plainCodePoint
&
_kCombiningCharacterMask
;
final
int
keyId
=
LogicalKeyboardKey
.
unicodePlane
|
(
combinedCodePoint
&
LogicalKeyboardKey
.
valueMask
);
return
LogicalKeyboardKey
.
findKeyByKeyId
(
keyId
)
??
LogicalKeyboardKey
(
keyId
,
keyLabel:
keyLabel
,
debugName:
kReleaseMode
?
null
:
'Key
${keyLabel.toUpperCase()}
'
,
);
return
LogicalKeyboardKey
.
findKeyByKeyId
(
keyId
)
??
LogicalKeyboardKey
(
keyId
);
}
// Look to see if the keyCode is one we know about and have a mapping for.
...
...
@@ -210,10 +206,7 @@ class RawKeyEventDataAndroid extends RawKeyEventData {
// This is a non-printable key that we don't know about, so we mint a new
// code with the autogenerated bit set.
const
int
androidKeyIdPlane
=
0x00200000000
;
newKey
??=
LogicalKeyboardKey
(
androidKeyIdPlane
|
keyCode
|
LogicalKeyboardKey
.
autogeneratedMask
,
debugName:
kReleaseMode
?
null
:
'Unknown Android key code
$keyCode
'
,
);
newKey
??=
LogicalKeyboardKey
(
androidKeyIdPlane
|
keyCode
|
LogicalKeyboardKey
.
autogeneratedMask
);
return
newKey
;
}
...
...
packages/flutter/lib/src/services/raw_keyboard_fuchsia.dart
View file @
b60c855a
...
...
@@ -68,11 +68,8 @@ class RawKeyEventDataFuchsia extends RawKeyEventData {
// If the key has a printable representation, then make a logical key based
// on that.
if
(
codePoint
!=
0
)
{
return
LogicalKeyboardKey
(
LogicalKeyboardKey
.
unicodePlane
|
codePoint
&
LogicalKeyboardKey
.
valueMask
,
keyLabel:
keyLabel
,
debugName:
kReleaseMode
?
null
:
'Key
$keyLabel
'
,
);
final
int
flutterId
=
LogicalKeyboardKey
.
unicodePlane
|
codePoint
&
LogicalKeyboardKey
.
valueMask
;
return
kFuchsiaToLogicalKey
[
flutterId
]
??
LogicalKeyboardKey
(
LogicalKeyboardKey
.
unicodePlane
|
codePoint
&
LogicalKeyboardKey
.
valueMask
);
}
// Look to see if the hidUsage is one we know about and have a mapping for.
...
...
@@ -84,10 +81,7 @@ class RawKeyEventDataFuchsia extends RawKeyEventData {
// This is a non-printable key that we don't know about, so we mint a new
// code with the autogenerated bit set.
const
int
fuchsiaKeyIdPlane
=
0x00300000000
;
newKey
??=
LogicalKeyboardKey
(
fuchsiaKeyIdPlane
|
hidUsage
|
LogicalKeyboardKey
.
autogeneratedMask
,
debugName:
kReleaseMode
?
null
:
'Ephemeral Fuchsia key code
$hidUsage
'
,
);
newKey
??=
LogicalKeyboardKey
(
fuchsiaKeyIdPlane
|
hidUsage
|
LogicalKeyboardKey
.
autogeneratedMask
);
return
newKey
;
}
...
...
packages/flutter/lib/src/services/raw_keyboard_ios.dart
View file @
b60c855a
...
...
@@ -92,7 +92,6 @@ class RawKeyEventDataIos extends RawKeyEventData {
@override
PhysicalKeyboardKey
get
physicalKey
=>
kIosToPhysicalKey
[
keyCode
]
??
PhysicalKeyboardKey
.
none
;
@override
LogicalKeyboardKey
get
logicalKey
{
// Look to see if the keyCode is a printable number pad key, so that a
...
...
@@ -126,11 +125,7 @@ class RawKeyEventDataIos extends RawKeyEventData {
}
final
int
keyId
=
LogicalKeyboardKey
.
unicodePlane
|
(
codeUnit
&
LogicalKeyboardKey
.
valueMask
);
return
LogicalKeyboardKey
.
findKeyByKeyId
(
keyId
)
??
LogicalKeyboardKey
(
keyId
,
keyLabel:
keyLabel
,
debugName:
kReleaseMode
?
null
:
'Key
${keyLabel.toUpperCase()}
'
,
);
return
LogicalKeyboardKey
.
findKeyByKeyId
(
keyId
)
??
LogicalKeyboardKey
(
keyId
);
}
// Control keys like "backspace" and movement keys like arrow keys don't
...
...
@@ -141,21 +136,14 @@ class RawKeyEventDataIos extends RawKeyEventData {
// physical key map.
if
(
physicalKey
!=
PhysicalKeyboardKey
.
none
)
{
final
int
keyId
=
physicalKey
.
usbHidUsage
|
LogicalKeyboardKey
.
hidPlane
;
return
LogicalKeyboardKey
.
findKeyByKeyId
(
keyId
)
??
LogicalKeyboardKey
(
keyId
,
keyLabel:
physicalKey
.
debugName
??
''
,
debugName:
physicalKey
.
debugName
,
);
return
LogicalKeyboardKey
.
findKeyByKeyId
(
keyId
)
??
LogicalKeyboardKey
(
keyId
);
}
// This is a non-printable key that is unrecognized, so a new code is minted
// with the autogenerated bit set.
const
int
iosKeyIdPlane
=
0x00400000000
;
return
LogicalKeyboardKey
(
iosKeyIdPlane
|
keyCode
|
LogicalKeyboardKey
.
autogeneratedMask
,
debugName:
kReleaseMode
?
null
:
'Unknown iOS key code
$keyCode
'
,
);
return
LogicalKeyboardKey
(
iosKeyIdPlane
|
keyCode
|
LogicalKeyboardKey
.
autogeneratedMask
);
}
bool
_isLeftRightModifierPressed
(
KeyboardSide
side
,
int
anyMask
,
int
leftMask
,
int
rightMask
)
{
...
...
packages/flutter/lib/src/services/raw_keyboard_linux.dart
View file @
b60c855a
...
...
@@ -92,11 +92,7 @@ class RawKeyEventDataLinux extends RawKeyEventData {
if
(
keyLabel
.
isNotEmpty
&&
!
LogicalKeyboardKey
.
isControlCharacter
(
keyLabel
))
{
final
int
keyId
=
LogicalKeyboardKey
.
unicodePlane
|
(
unicodeScalarValues
&
LogicalKeyboardKey
.
valueMask
);
return
LogicalKeyboardKey
.
findKeyByKeyId
(
keyId
)
??
LogicalKeyboardKey
(
keyId
,
keyLabel:
keyLabel
,
debugName:
kReleaseMode
?
null
:
'Key
${keyLabel.toUpperCase()}
'
,
);
return
LogicalKeyboardKey
.
findKeyByKeyId
(
keyId
)
??
LogicalKeyboardKey
(
keyId
);
}
// Look to see if the keyCode is one we know about and have a mapping for.
...
...
@@ -109,10 +105,7 @@ class RawKeyEventDataLinux extends RawKeyEventData {
// This is a non-printable key that we don't know about, so we mint a new
// code with the autogenerated bit set.
newKey
??=
LogicalKeyboardKey
(
linuxKeyIdPlane
|
keyCode
|
LogicalKeyboardKey
.
autogeneratedMask
,
debugName:
kReleaseMode
?
null
:
'Unknown key code
$keyCode
'
,
);
newKey
??=
LogicalKeyboardKey
(
linuxKeyIdPlane
|
keyCode
|
LogicalKeyboardKey
.
autogeneratedMask
);
return
newKey
;
}
...
...
packages/flutter/lib/src/services/raw_keyboard_macos.dart
View file @
b60c855a
...
...
@@ -95,11 +95,7 @@ class RawKeyEventDataMacOs extends RawKeyEventData {
}
final
int
keyId
=
LogicalKeyboardKey
.
unicodePlane
|
(
codeUnit
&
LogicalKeyboardKey
.
valueMask
);
return
LogicalKeyboardKey
.
findKeyByKeyId
(
keyId
)
??
LogicalKeyboardKey
(
keyId
,
keyLabel:
keyLabel
,
debugName:
kReleaseMode
?
null
:
'Key
${keyLabel.toUpperCase()}
'
,
);
return
LogicalKeyboardKey
.
findKeyByKeyId
(
keyId
)
??
LogicalKeyboardKey
(
keyId
);
}
// Control keys like "backspace" and movement keys like arrow keys don't
...
...
@@ -110,21 +106,14 @@ class RawKeyEventDataMacOs extends RawKeyEventData {
// physical key map.
if
(
physicalKey
!=
PhysicalKeyboardKey
.
none
)
{
final
int
keyId
=
physicalKey
.
usbHidUsage
|
LogicalKeyboardKey
.
hidPlane
;
return
LogicalKeyboardKey
.
findKeyByKeyId
(
keyId
)
??
LogicalKeyboardKey
(
keyId
,
keyLabel:
physicalKey
.
debugName
??
''
,
debugName:
physicalKey
.
debugName
,
);
return
LogicalKeyboardKey
.
findKeyByKeyId
(
keyId
)
??
LogicalKeyboardKey
(
keyId
);
}
// This is a non-printable key that is unrecognized, so a new code is minted
// with the autogenerated bit set.
const
int
macOsKeyIdPlane
=
0x00500000000
;
return
LogicalKeyboardKey
(
macOsKeyIdPlane
|
keyCode
|
LogicalKeyboardKey
.
autogeneratedMask
,
debugName:
kReleaseMode
?
null
:
'Unknown macOS key code
$keyCode
'
,
);
return
LogicalKeyboardKey
(
macOsKeyIdPlane
|
keyCode
|
LogicalKeyboardKey
.
autogeneratedMask
);
}
bool
_isLeftRightModifierPressed
(
KeyboardSide
side
,
int
anyMask
,
int
leftMask
,
int
rightMask
)
{
...
...
packages/flutter/lib/src/services/raw_keyboard_web.dart
View file @
b60c855a
...
...
@@ -82,10 +82,7 @@ class RawKeyEventDataWeb extends RawKeyEventData {
// This is a non-printable key that we don't know about, so we mint a new
// code with the autogenerated bit set.
const
int
webKeyIdPlane
=
0x00800000000
;
return
LogicalKeyboardKey
(
webKeyIdPlane
|
code
.
hashCode
|
LogicalKeyboardKey
.
autogeneratedMask
,
debugName:
kReleaseMode
?
null
:
'Unknown Web code "
$code
"'
,
);
return
LogicalKeyboardKey
(
webKeyIdPlane
|
code
.
hashCode
|
LogicalKeyboardKey
.
autogeneratedMask
);
}
@override
...
...
packages/flutter/lib/src/services/raw_keyboard_windows.dart
View file @
b60c855a
...
...
@@ -3,8 +3,6 @@
// found in the LICENSE file.
import
'package:flutter/foundation.dart'
;
import
'keyboard_key.dart'
;
import
'keyboard_maps.dart'
;
import
'raw_keyboard.dart'
;
...
...
@@ -80,11 +78,7 @@ class RawKeyEventDataWindows extends RawKeyEventData {
// plane.
if
(
keyLabel
.
isNotEmpty
&&
!
LogicalKeyboardKey
.
isControlCharacter
(
keyLabel
))
{
final
int
keyId
=
LogicalKeyboardKey
.
unicodePlane
|
(
characterCodePoint
&
LogicalKeyboardKey
.
valueMask
);
return
LogicalKeyboardKey
.
findKeyByKeyId
(
keyId
)
??
LogicalKeyboardKey
(
keyId
,
keyLabel:
keyLabel
,
debugName:
kReleaseMode
?
null
:
'Key
${keyLabel.toUpperCase()}
'
,
);
return
LogicalKeyboardKey
.
findKeyByKeyId
(
keyId
)
??
LogicalKeyboardKey
(
keyId
);
}
// Look to see if the keyCode is one we know about and have a mapping for.
LogicalKeyboardKey
?
newKey
=
kWindowsToLogicalKey
[
keyCode
];
...
...
@@ -95,10 +89,7 @@ class RawKeyEventDataWindows extends RawKeyEventData {
// This is a non-printable key that we don't know about, so we mint a new
// code with the autogenerated bit set.
const
int
windowsKeyIdPlane
=
0x00700000000
;
newKey
??=
LogicalKeyboardKey
(
windowsKeyIdPlane
|
keyCode
|
LogicalKeyboardKey
.
autogeneratedMask
,
debugName:
kReleaseMode
?
null
:
'Unknown Windows key code
$keyCode
'
,
);
newKey
??=
LogicalKeyboardKey
(
windowsKeyIdPlane
|
keyCode
|
LogicalKeyboardKey
.
autogeneratedMask
);
return
newKey
;
}
...
...
packages/flutter/test/services/keyboard_key_test.dart
View file @
b60c855a
...
...
@@ -15,11 +15,14 @@ void main() {
// Check a modifier key
expect
(
PhysicalKeyboardKey
.
findKeyByCode
(
0x000700e1
),
equals
(
PhysicalKeyboardKey
.
shiftLeft
));
});
test
(
'Equality is only based on HID code.'
,
()
async
{
const
PhysicalKeyboardKey
key1
=
PhysicalKeyboardKey
(
0x01
,
debugName:
'key1'
);
const
PhysicalKeyboardKey
key2
=
PhysicalKeyboardKey
(
0x01
,
debugName:
'key2'
);
expect
(
key1
,
equals
(
key1
));
expect
(
key1
,
equals
(
key2
));
test
(
'Values are cached'
,
()
async
{
expect
(
identical
(
PhysicalKeyboardKey
.
keyA
,
PhysicalKeyboardKey
(
PhysicalKeyboardKey
.
keyA
.
usbHidUsage
)),
true
);
expect
(
identical
(
PhysicalKeyboardKey
(
0x12345
),
PhysicalKeyboardKey
(
0x12345
)),
true
);
});
test
(
'debugNames'
,
()
async
{
expect
(
PhysicalKeyboardKey
.
keyA
.
debugName
,
'Key A'
);
expect
(
PhysicalKeyboardKey
.
backslash
.
debugName
,
'Backslash'
);
expect
(
PhysicalKeyboardKey
(
0x12345
).
debugName
,
'Key with ID 0x00012345'
);
});
});
group
(
LogicalKeyboardKey
,
()
{
...
...
@@ -44,12 +47,6 @@ void main() {
expect
(
LogicalKeyboardKey
.
isControlCharacter
(
'~'
),
isFalse
);
expect
(
LogicalKeyboardKey
.
isControlCharacter
(
'
\
xa0'
),
isFalse
);
// NO-BREAK SPACE
});
test
(
'Equality is only based on ID.'
,
()
async
{
const
LogicalKeyboardKey
key1
=
LogicalKeyboardKey
(
0x01
,
keyLabel:
'label1'
,
debugName:
'key1'
);
const
LogicalKeyboardKey
key2
=
LogicalKeyboardKey
(
0x01
,
keyLabel:
'label2'
,
debugName:
'key2'
);
expect
(
key1
,
equals
(
key1
));
expect
(
key1
,
equals
(
key2
));
});
test
(
'Basic synonyms can be looked up.'
,
()
async
{
expect
(
LogicalKeyboardKey
.
shiftLeft
.
synonyms
.
first
,
equals
(
LogicalKeyboardKey
.
shift
));
expect
(
LogicalKeyboardKey
.
controlLeft
.
synonyms
.
first
,
equals
(
LogicalKeyboardKey
.
control
));
...
...
@@ -106,5 +103,29 @@ void main() {
LogicalKeyboardKey
.
meta
,
}));
});
test
(
'Values are cached'
,
()
async
{
expect
(
identical
(
LogicalKeyboardKey
.
keyA
,
LogicalKeyboardKey
(
LogicalKeyboardKey
.
keyA
.
keyId
)),
true
);
expect
(
identical
(
LogicalKeyboardKey
(
0x12345
),
LogicalKeyboardKey
(
0x12345
)),
true
);
});
test
(
'keyLabel'
,
()
async
{
expect
(
LogicalKeyboardKey
.
keyA
.
keyLabel
,
'A'
);
expect
(
LogicalKeyboardKey
.
backslash
.
keyLabel
,
r'\'
);
expect
(
LogicalKeyboardKey
(
0xD9
).
keyLabel
,
'Ù'
);
expect
(
LogicalKeyboardKey
(
0xF9
).
keyLabel
,
'Ù'
);
expect
(
LogicalKeyboardKey
.
shiftLeft
.
keyLabel
,
'Shift Left'
);
expect
(
LogicalKeyboardKey
.
numpadDecimal
.
keyLabel
,
'Numpad Decimal'
);
expect
(
LogicalKeyboardKey
.
numpad1
.
keyLabel
,
'Numpad 1'
);
expect
(
LogicalKeyboardKey
.
delete
.
keyLabel
,
'Delete'
);
expect
(
LogicalKeyboardKey
.
f12
.
keyLabel
,
'F12'
);
expect
(
LogicalKeyboardKey
.
mediaPlay
.
keyLabel
,
'Media Play'
);
expect
(
LogicalKeyboardKey
(
0x100012345
).
keyLabel
,
''
);
});
test
(
'debugName'
,
()
async
{
expect
(
LogicalKeyboardKey
.
keyA
.
debugName
,
'Key A'
);
expect
(
LogicalKeyboardKey
.
backslash
.
debugName
,
'Backslash'
);
expect
(
LogicalKeyboardKey
(
0xD9
).
debugName
,
'Key Ù'
);
expect
(
LogicalKeyboardKey
.
mediaPlay
.
debugName
,
'Media Play'
);
expect
(
LogicalKeyboardKey
(
0x100012345
).
debugName
,
'Key with ID 0x00100012345'
);
});
});
}
packages/flutter/test/services/raw_keyboard_test.dart
View file @
b60c855a
...
...
@@ -1178,7 +1178,6 @@ void main() {
final
RawKeyEventDataMacOs
data
=
leftArrowKey
.
data
as
RawKeyEventDataMacOs
;
expect
(
data
.
physicalKey
,
equals
(
PhysicalKeyboardKey
.
arrowLeft
));
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.
...
...
@@ -1324,7 +1323,6 @@ void main() {
final
RawKeyEventDataIos
data
=
leftArrowKey
.
data
as
RawKeyEventDataIos
;
expect
(
data
.
physicalKey
,
equals
(
PhysicalKeyboardKey
.
arrowLeft
));
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.
...
...
@@ -1469,7 +1467,6 @@ void main() {
final
RawKeyEventDataWindows
data
=
leftArrowKey
.
data
as
RawKeyEventDataWindows
;
expect
(
data
.
physicalKey
,
equals
(
PhysicalKeyboardKey
.
arrowLeft
));
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'
;
...
...
packages/flutter/test/widgets/shortcuts_test.dart
View file @
b60c855a
...
...
@@ -68,7 +68,7 @@ void main() {
LogicalKeyboardKey
.
keyC
,
LogicalKeyboardKey
.
keyD
,
);
final
LogicalKeySet
setFromSet
=
LogicalKeySet
.
fromSet
(<
LogicalKeyboardKey
>{
final
LogicalKeySet
setFromSet
=
LogicalKeySet
.
fromSet
(
const
<
LogicalKeyboardKey
>{
LogicalKeyboardKey
.
keyA
,
LogicalKeyboardKey
.
keyB
,
LogicalKeyboardKey
.
keyC
,
...
...
@@ -123,7 +123,7 @@ void main() {
LogicalKeyboardKey
.
keyB
,
LogicalKeyboardKey
.
keyA
,
);
final
LogicalKeySet
set4
=
LogicalKeySet
.
fromSet
(<
LogicalKeyboardKey
>{
final
LogicalKeySet
set4
=
LogicalKeySet
.
fromSet
(
const
<
LogicalKeyboardKey
>{
LogicalKeyboardKey
.
keyD
,
LogicalKeyboardKey
.
keyC
,
LogicalKeyboardKey
.
keyB
,
...
...
@@ -138,7 +138,7 @@ void main() {
expect
(
map
.
containsKey
(
LogicalKeySet
(
LogicalKeyboardKey
.
keyA
)),
isTrue
);
expect
(
set2
,
equals
(
LogicalKeySet
.
fromSet
(<
LogicalKeyboardKey
>{
equals
(
LogicalKeySet
.
fromSet
(
const
<
LogicalKeyboardKey
>{
LogicalKeyboardKey
.
keyA
,
LogicalKeyboardKey
.
keyB
,
LogicalKeyboardKey
.
keyC
,
...
...
packages/flutter_test/lib/src/event_simulation.dart
View file @
b60c855a
...
...
@@ -13,6 +13,13 @@ import 'test_async_utils.dart';
// https://github.com/flutter/flutter/issues/33521
// This code can only simulate keys which appear in the key maps.
String
_keyLabel
(
LogicalKeyboardKey
key
)
{
final
String
keyLabel
=
key
.
keyLabel
;
if
(
keyLabel
.
length
==
1
)
return
keyLabel
.
toLowerCase
();
return
''
;
}
/// A class that serves as a namespace for a bunch of keyboard-key generation
/// utilities.
class
KeyEventSimulator
{
...
...
@@ -206,7 +213,7 @@ class KeyEventSimulator {
if
(
kIsWeb
)
{
result
[
'code'
]
=
_getWebKeyCode
(
key
);
result
[
'key'
]
=
key
.
keyLabel
;
result
[
'key'
]
=
_keyLabel
(
key
)
;
result
[
'metaState'
]
=
_getWebModifierFlags
(
key
,
isDown
);
return
result
;
}
...
...
@@ -214,17 +221,17 @@ class KeyEventSimulator {
switch
(
platform
)
{
case
'android'
:
result
[
'keyCode'
]
=
keyCode
;
if
(
key
.
keyLabel
.
isNotEmpty
)
{
result
[
'codePoint'
]
=
key
.
keyLabel
.
codeUnitAt
(
0
);
result
[
'character'
]
=
key
.
keyLabel
;
if
(
_keyLabel
(
key
)
.
isNotEmpty
)
{
result
[
'codePoint'
]
=
_keyLabel
(
key
)
.
codeUnitAt
(
0
);
result
[
'character'
]
=
_keyLabel
(
key
)
;
}
result
[
'scanCode'
]
=
scanCode
;
result
[
'metaState'
]
=
_getAndroidModifierFlags
(
key
,
isDown
);
break
;
case
'fuchsia'
:
result
[
'hidUsage'
]
=
physicalKey
.
usbHidUsage
;
if
(
key
.
keyLabel
.
isNotEmpty
)
{
result
[
'codePoint'
]
=
key
.
keyLabel
.
codeUnitAt
(
0
);
if
(
_keyLabel
(
key
)
.
isNotEmpty
)
{
result
[
'codePoint'
]
=
_keyLabel
(
key
)
.
codeUnitAt
(
0
);
}
result
[
'modifiers'
]
=
_getFuchsiaModifierFlags
(
key
,
isDown
);
break
;
...
...
@@ -233,32 +240,32 @@ class KeyEventSimulator {
result
[
'keyCode'
]
=
keyCode
;
result
[
'scanCode'
]
=
scanCode
;
result
[
'modifiers'
]
=
_getGlfwModifierFlags
(
key
,
isDown
);
result
[
'unicodeScalarValues'
]
=
key
.
keyLabel
.
isNotEmpty
?
key
.
keyLabel
.
codeUnitAt
(
0
)
:
0
;
result
[
'unicodeScalarValues'
]
=
_keyLabel
(
key
).
isNotEmpty
?
_keyLabel
(
key
)
.
codeUnitAt
(
0
)
:
0
;
break
;
case
'macos'
:
result
[
'keyCode'
]
=
scanCode
;
if
(
key
.
keyLabel
.
isNotEmpty
)
{
result
[
'characters'
]
=
key
.
keyLabel
;
result
[
'charactersIgnoringModifiers'
]
=
key
.
keyLabel
;
if
(
_keyLabel
(
key
)
.
isNotEmpty
)
{
result
[
'characters'
]
=
_keyLabel
(
key
)
;
result
[
'charactersIgnoringModifiers'
]
=
_keyLabel
(
key
)
;
}
result
[
'modifiers'
]
=
_getMacOsModifierFlags
(
key
,
isDown
);
break
;
case
'ios'
:
result
[
'keyCode'
]
=
scanCode
;
result
[
'characters'
]
=
key
.
keyLabel
;
result
[
'charactersIgnoringModifiers'
]
=
key
.
keyLabel
;
result
[
'characters'
]
=
_keyLabel
(
key
)
;
result
[
'charactersIgnoringModifiers'
]
=
_keyLabel
(
key
)
;
result
[
'modifiers'
]
=
_getIOSModifierFlags
(
key
,
isDown
);
break
;
case
'web'
:
result
[
'code'
]
=
_getWebKeyCode
(
key
);
result
[
'key'
]
=
key
.
keyLabel
;
result
[
'key'
]
=
_keyLabel
(
key
)
;
result
[
'metaState'
]
=
_getWebModifierFlags
(
key
,
isDown
);
break
;
case
'windows'
:
result
[
'keyCode'
]
=
keyCode
;
result
[
'scanCode'
]
=
scanCode
;
if
(
key
.
keyLabel
.
isNotEmpty
)
{
result
[
'characterCodePoint'
]
=
key
.
keyLabel
.
codeUnitAt
(
0
);
if
(
_keyLabel
(
key
)
.
isNotEmpty
)
{
result
[
'characterCodePoint'
]
=
_keyLabel
(
key
)
.
codeUnitAt
(
0
);
}
result
[
'modifiers'
]
=
_getWindowsModifierFlags
(
key
,
isDown
);
}
...
...
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