[web] Treeshake keymaps for web (4% code size reduction in hello world) (#75945)
This commit is contained in:
parent
3e77f5e42e
commit
cc9b78fc5c
@ -267,6 +267,17 @@ abstract class RawKeyEvent with Diagnosticable {
|
|||||||
String? character;
|
String? character;
|
||||||
|
|
||||||
final String keymap = message['keymap'] as String;
|
final String keymap = message['keymap'] 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) {
|
switch (keymap) {
|
||||||
case 'android':
|
case 'android':
|
||||||
data = RawKeyEventDataAndroid(
|
data = RawKeyEventDataAndroid(
|
||||||
@ -325,14 +336,6 @@ abstract class RawKeyEvent with Diagnosticable {
|
|||||||
character = String.fromCharCode(unicodeScalarValues);
|
character = String.fromCharCode(unicodeScalarValues);
|
||||||
}
|
}
|
||||||
break;
|
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':
|
case 'windows':
|
||||||
final int characterCodePoint = message['characterCodePoint'] as int? ?? 0;
|
final int characterCodePoint = message['characterCodePoint'] as int? ?? 0;
|
||||||
data = RawKeyEventDataWindows(
|
data = RawKeyEventDataWindows(
|
||||||
@ -345,6 +348,17 @@ abstract class RawKeyEvent with Diagnosticable {
|
|||||||
character = String.fromCharCode(characterCodePoint);
|
character = String.fromCharCode(characterCodePoint);
|
||||||
}
|
}
|
||||||
break;
|
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:
|
default:
|
||||||
/// This exception would only be hit on platforms that haven't yet
|
/// This exception would only be hit on platforms that haven't yet
|
||||||
/// implemented raw key events, but will only be triggered if the
|
/// implemented raw key events, but will only be triggered if the
|
||||||
@ -352,7 +366,7 @@ abstract class RawKeyEvent with Diagnosticable {
|
|||||||
/// first place.
|
/// first place.
|
||||||
throw FlutterError('Unknown keymap for key events: $keymap');
|
throw FlutterError('Unknown keymap for key events: $keymap');
|
||||||
}
|
}
|
||||||
|
}
|
||||||
final String type = message['type'] as String;
|
final String type = message['type'] as String;
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case 'keydown':
|
case 'keydown':
|
||||||
|
@ -31,7 +31,7 @@ void main() {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
testWidgets('No character is produced for non-printables', (WidgetTester tester) async {
|
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) {
|
void handleKey(RawKeyEvent event) {
|
||||||
expect(event.character, isNull, reason: 'on $platform');
|
expect(event.character, isNull, reason: 'on $platform');
|
||||||
}
|
}
|
||||||
@ -194,7 +194,7 @@ void main() {
|
|||||||
await simulateKeyUpEvent(LogicalKeyboardKey.keyA, platform: platform, physicalKey: PhysicalKeyboardKey.keyA);
|
await simulateKeyUpEvent(LogicalKeyboardKey.keyA, platform: platform, physicalKey: PhysicalKeyboardKey.keyA);
|
||||||
expect(RawKeyboard.instance.keysPressed, isEmpty, reason: 'on $platform');
|
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 {
|
testWidgets('keysPressed modifiers are synchronized with key events on macOS', (WidgetTester tester) async {
|
||||||
expect(RawKeyboard.instance.keysPressed, isEmpty);
|
expect(RawKeyboard.instance.keysPressed, isEmpty);
|
||||||
@ -219,7 +219,7 @@ void main() {
|
|||||||
<LogicalKeyboardKey>{LogicalKeyboardKey.shiftLeft, LogicalKeyboardKey.keyA},
|
<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 {
|
testWidgets('keysPressed modifiers are synchronized with key events on iOS', (WidgetTester tester) async {
|
||||||
expect(RawKeyboard.instance.keysPressed, isEmpty);
|
expect(RawKeyboard.instance.keysPressed, isEmpty);
|
||||||
@ -244,7 +244,7 @@ void main() {
|
|||||||
<LogicalKeyboardKey>{LogicalKeyboardKey.shiftLeft, LogicalKeyboardKey.keyA},
|
<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 {
|
testWidgets('keysPressed modifiers are synchronized with key events on Windows', (WidgetTester tester) async {
|
||||||
expect(RawKeyboard.instance.keysPressed, isEmpty);
|
expect(RawKeyboard.instance.keysPressed, isEmpty);
|
||||||
@ -269,7 +269,7 @@ void main() {
|
|||||||
<LogicalKeyboardKey>{LogicalKeyboardKey.shiftLeft, LogicalKeyboardKey.keyA},
|
<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 {
|
testWidgets('keysPressed modifiers are synchronized with key events on android', (WidgetTester tester) async {
|
||||||
expect(RawKeyboard.instance.keysPressed, isEmpty);
|
expect(RawKeyboard.instance.keysPressed, isEmpty);
|
||||||
@ -294,7 +294,7 @@ void main() {
|
|||||||
<LogicalKeyboardKey>{LogicalKeyboardKey.shiftLeft, LogicalKeyboardKey.keyA},
|
<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 {
|
testWidgets('keysPressed modifiers are synchronized with key events on fuchsia', (WidgetTester tester) async {
|
||||||
expect(RawKeyboard.instance.keysPressed, isEmpty);
|
expect(RawKeyboard.instance.keysPressed, isEmpty);
|
||||||
@ -319,7 +319,7 @@ void main() {
|
|||||||
<LogicalKeyboardKey>{LogicalKeyboardKey.shiftLeft, LogicalKeyboardKey.keyA},
|
<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 {
|
testWidgets('keysPressed modifiers are synchronized with key events on Linux GLFW', (WidgetTester tester) async {
|
||||||
expect(RawKeyboard.instance.keysPressed, isEmpty);
|
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 {
|
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 {
|
testWidgets('sided modifiers without a side set return all sides on macOS', (WidgetTester tester) async {
|
||||||
expect(RawKeyboard.instance.keysPressed, isEmpty);
|
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 {
|
testWidgets('sided modifiers without a side set return all sides on iOS', (WidgetTester tester) async {
|
||||||
expect(RawKeyboard.instance.keysPressed, isEmpty);
|
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 {
|
testWidgets('sided modifiers without a side set return all sides on Windows', (WidgetTester tester) async {
|
||||||
expect(RawKeyboard.instance.keysPressed, isEmpty);
|
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 {
|
testWidgets('sided modifiers without a side set return all sides on Linux GLFW', (WidgetTester tester) async {
|
||||||
expect(RawKeyboard.instance.keysPressed, isEmpty);
|
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 {
|
testWidgets('RawKeyboard asserts if no keys are in keysPressed after receiving a key down event', (WidgetTester tester) async {
|
||||||
@ -547,11 +616,17 @@ void main() {
|
|||||||
FlutterError.onError = (FlutterErrorDetails details) {
|
FlutterError.onError = (FlutterErrorDetails details) {
|
||||||
errorDetails = details;
|
errorDetails = details;
|
||||||
};
|
};
|
||||||
try {
|
|
||||||
await ServicesBinding.instance!.defaultBinaryMessenger
|
final Map<String, dynamic> keyEventMessage;
|
||||||
.handlePlatformMessage(
|
if (kIsWeb) {
|
||||||
SystemChannels.keyEvent.name,
|
keyEventMessage = const <String, dynamic>{
|
||||||
SystemChannels.keyEvent.codec.encodeMessage(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',
|
'type': 'keydown',
|
||||||
'keymap': 'android',
|
'keymap': 'android',
|
||||||
'keyCode': 0x3b, // Left shift key keyCode
|
'keyCode': 0x3b, // Left shift key keyCode
|
||||||
@ -559,7 +634,14 @@ void main() {
|
|||||||
'metaState': 0x0, // No shift key metaState set!
|
'metaState': 0x0, // No shift key metaState set!
|
||||||
'source': 0x101,
|
'source': 0x101,
|
||||||
'deviceId': 1,
|
'deviceId': 1,
|
||||||
}),
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
await ServicesBinding.instance!.defaultBinaryMessenger
|
||||||
|
.handlePlatformMessage(
|
||||||
|
SystemChannels.keyEvent.name,
|
||||||
|
SystemChannels.keyEvent.codec.encodeMessage(keyEventMessage),
|
||||||
(ByteData? data) {},
|
(ByteData? data) {},
|
||||||
);
|
);
|
||||||
} finally {
|
} finally {
|
||||||
@ -837,7 +919,8 @@ void main() {
|
|||||||
expect(message, equals(<String, dynamic>{ 'handled': true }));
|
expect(message, equals(<String, dynamic>{ 'handled': true }));
|
||||||
ServicesBinding.instance!.defaultBinaryMessenger.setMockMessageHandler(SystemChannels.keyEvent.name, null);
|
ServicesBinding.instance!.defaultBinaryMessenger.setMockMessageHandler(SystemChannels.keyEvent.name, null);
|
||||||
});
|
});
|
||||||
});
|
}, skip: isBrowser); // This is an Android-specific group.
|
||||||
|
|
||||||
group('RawKeyEventDataFuchsia', () {
|
group('RawKeyEventDataFuchsia', () {
|
||||||
const Map<int, _ModifierCheck> modifierTests = <int, _ModifierCheck>{
|
const Map<int, _ModifierCheck> modifierTests = <int, _ModifierCheck>{
|
||||||
RawKeyEventDataFuchsia.modifierAlt: _ModifierCheck(ModifierKey.altModifier, KeyboardSide.any),
|
RawKeyEventDataFuchsia.modifierAlt: _ModifierCheck(ModifierKey.altModifier, KeyboardSide.any),
|
||||||
@ -951,7 +1034,7 @@ void main() {
|
|||||||
expect(data.logicalKey, equals(LogicalKeyboardKey.shiftLeft));
|
expect(data.logicalKey, equals(LogicalKeyboardKey.shiftLeft));
|
||||||
expect(data.keyLabel, isEmpty);
|
expect(data.keyLabel, isEmpty);
|
||||||
}, skip: isBrowser); // https://github.com/flutter/flutter/issues/35347
|
}, skip: isBrowser); // https://github.com/flutter/flutter/issues/35347
|
||||||
});
|
}, skip: isBrowser); // This is a Fuchsia-specific group.
|
||||||
|
|
||||||
group('RawKeyEventDataMacOs', () {
|
group('RawKeyEventDataMacOs', () {
|
||||||
const Map<int, _ModifierCheck> modifierTests = <int, _ModifierCheck>{
|
const Map<int, _ModifierCheck> modifierTests = <int, _ModifierCheck>{
|
||||||
@ -1097,7 +1180,7 @@ void main() {
|
|||||||
expect(data.logicalKey, equals(LogicalKeyboardKey.arrowLeft));
|
expect(data.logicalKey, equals(LogicalKeyboardKey.arrowLeft));
|
||||||
expect(data.logicalKey.keyLabel, isEmpty);
|
expect(data.logicalKey.keyLabel, isEmpty);
|
||||||
}, skip: isBrowser); // https://github.com/flutter/flutter/issues/35347
|
}, skip: isBrowser); // https://github.com/flutter/flutter/issues/35347
|
||||||
});
|
}, skip: isBrowser); // This is a macOS-specific group.
|
||||||
|
|
||||||
group('RawKeyEventDataIos', () {
|
group('RawKeyEventDataIos', () {
|
||||||
const Map<int, _ModifierCheck> modifierTests = <int, _ModifierCheck>{
|
const Map<int, _ModifierCheck> modifierTests = <int, _ModifierCheck>{
|
||||||
@ -1243,7 +1326,7 @@ void main() {
|
|||||||
expect(data.logicalKey, equals(LogicalKeyboardKey.arrowLeft));
|
expect(data.logicalKey, equals(LogicalKeyboardKey.arrowLeft));
|
||||||
expect(data.logicalKey.keyLabel, isEmpty);
|
expect(data.logicalKey.keyLabel, isEmpty);
|
||||||
}, skip: isBrowser); // https://github.com/flutter/flutter/issues/35347
|
}, skip: isBrowser); // https://github.com/flutter/flutter/issues/35347
|
||||||
});
|
}, skip: isBrowser); // This is an iOS-specific group.
|
||||||
|
|
||||||
group('RawKeyEventDataWindows', () {
|
group('RawKeyEventDataWindows', () {
|
||||||
const Map<int, _ModifierCheck> modifierTests = <int, _ModifierCheck>{
|
const Map<int, _ModifierCheck> modifierTests = <int, _ModifierCheck>{
|
||||||
@ -1388,7 +1471,7 @@ void main() {
|
|||||||
expect(data.logicalKey, equals(LogicalKeyboardKey.arrowLeft));
|
expect(data.logicalKey, equals(LogicalKeyboardKey.arrowLeft));
|
||||||
expect(data.logicalKey.keyLabel, isEmpty);
|
expect(data.logicalKey.keyLabel, isEmpty);
|
||||||
});
|
});
|
||||||
});
|
}, skip: isBrowser); // This is a Windows-specific group.
|
||||||
|
|
||||||
group('RawKeyEventDataLinux-GFLW', () {
|
group('RawKeyEventDataLinux-GFLW', () {
|
||||||
const Map<int, _ModifierCheck> modifierTests = <int, _ModifierCheck>{
|
const Map<int, _ModifierCheck> modifierTests = <int, _ModifierCheck>{
|
||||||
@ -1572,7 +1655,7 @@ void main() {
|
|||||||
expect(data.logicalKey, equals(LogicalKeyboardKey.shiftLeft));
|
expect(data.logicalKey, equals(LogicalKeyboardKey.shiftLeft));
|
||||||
expect(data.keyLabel, isEmpty);
|
expect(data.keyLabel, isEmpty);
|
||||||
});
|
});
|
||||||
});
|
}, skip: isBrowser); // This is a GLFW-specific group.
|
||||||
|
|
||||||
group('RawKeyEventDataLinux-GTK', () {
|
group('RawKeyEventDataLinux-GTK', () {
|
||||||
const Map<int, _ModifierCheck> modifierTests = <int, _ModifierCheck>{
|
const Map<int, _ModifierCheck> modifierTests = <int, _ModifierCheck>{
|
||||||
@ -1756,7 +1839,7 @@ void main() {
|
|||||||
expect(data.logicalKey, equals(LogicalKeyboardKey.shiftLeft));
|
expect(data.logicalKey, equals(LogicalKeyboardKey.shiftLeft));
|
||||||
expect(data.keyLabel, isEmpty);
|
expect(data.keyLabel, isEmpty);
|
||||||
});
|
});
|
||||||
});
|
}, skip: isBrowser); // This is a GTK-specific group.
|
||||||
|
|
||||||
group('RawKeyEventDataWeb', () {
|
group('RawKeyEventDataWeb', () {
|
||||||
const Map<int, ModifierKey> modifierTests = <int, ModifierKey>{
|
const Map<int, ModifierKey> modifierTests = <int, ModifierKey>{
|
||||||
|
@ -42,6 +42,37 @@ void main() {
|
|||||||
expect(typedData.modifiers, RawKeyEventDataFuchsia.modifierLeftMeta);
|
expect(typedData.modifiers, RawKeyEventDataFuchsia.modifierLeftMeta);
|
||||||
expect(typedData.isModifierPressed(ModifierKey.metaModifier, side: KeyboardSide.left), isTrue);
|
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());
|
await tester.pumpWidget(Container());
|
||||||
focusNode.dispose();
|
focusNode.dispose();
|
||||||
});
|
});
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
|
|
||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
|
|
||||||
|
import 'package:flutter/foundation.dart' show kIsWeb;
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
import 'test_async_utils.dart';
|
import 'test_async_utils.dart';
|
||||||
|
|
||||||
@ -85,6 +86,11 @@ class KeyEventSimulator {
|
|||||||
|
|
||||||
static int _getKeyCode(LogicalKeyboardKey key, String platform) {
|
static int _getKeyCode(LogicalKeyboardKey key, String platform) {
|
||||||
assert(_osIsSupported(platform), 'Platform $platform not supported for key simulation');
|
assert(_osIsSupported(platform), 'Platform $platform not supported for key simulation');
|
||||||
|
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;
|
late Map<int, LogicalKeyboardKey> map;
|
||||||
switch (platform) {
|
switch (platform) {
|
||||||
case 'android':
|
case 'android':
|
||||||
@ -100,7 +106,7 @@ class KeyEventSimulator {
|
|||||||
// iOS doesn't do key codes, just scan codes.
|
// iOS doesn't do key codes, just scan codes.
|
||||||
return -1;
|
return -1;
|
||||||
case 'web':
|
case 'web':
|
||||||
// web doesn't have int type code
|
// web doesn't have int type code.
|
||||||
return -1;
|
return -1;
|
||||||
case 'linux':
|
case 'linux':
|
||||||
map = kGlfwToLogicalKey;
|
map = kGlfwToLogicalKey;
|
||||||
@ -119,6 +125,8 @@ class KeyEventSimulator {
|
|||||||
assert(keyCode != null, 'Key $key not found in $platform keyCode map');
|
assert(keyCode != null, 'Key $key not found in $platform keyCode map');
|
||||||
return keyCode!;
|
return keyCode!;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static String _getWebKeyCode(LogicalKeyboardKey key) {
|
static String _getWebKeyCode(LogicalKeyboardKey key) {
|
||||||
String? result;
|
String? result;
|
||||||
for (final String code in kWebToLogicalKey.keys) {
|
for (final String code in kWebToLogicalKey.keys) {
|
||||||
@ -134,6 +142,10 @@ class KeyEventSimulator {
|
|||||||
static PhysicalKeyboardKey _findPhysicalKey(LogicalKeyboardKey key, String platform) {
|
static PhysicalKeyboardKey _findPhysicalKey(LogicalKeyboardKey key, String platform) {
|
||||||
assert(_osIsSupported(platform), 'Platform $platform not supported for key simulation');
|
assert(_osIsSupported(platform), 'Platform $platform not supported for key simulation');
|
||||||
late Map<dynamic, PhysicalKeyboardKey> map;
|
late Map<dynamic, PhysicalKeyboardKey> map;
|
||||||
|
if (kIsWeb) {
|
||||||
|
// This check is used to treeshake keymap code.
|
||||||
|
map = kWebToPhysicalKey;
|
||||||
|
} else {
|
||||||
switch (platform) {
|
switch (platform) {
|
||||||
case 'android':
|
case 'android':
|
||||||
map = kAndroidToPhysicalKey;
|
map = kAndroidToPhysicalKey;
|
||||||
@ -157,6 +169,7 @@ class KeyEventSimulator {
|
|||||||
map = kWindowsToPhysicalKey;
|
map = kWindowsToPhysicalKey;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
PhysicalKeyboardKey? result;
|
PhysicalKeyboardKey? result;
|
||||||
for (final PhysicalKeyboardKey physicalKey in map.values) {
|
for (final PhysicalKeyboardKey physicalKey in map.values) {
|
||||||
if (key.debugName == physicalKey.debugName) {
|
if (key.debugName == physicalKey.debugName) {
|
||||||
@ -191,6 +204,13 @@ class KeyEventSimulator {
|
|||||||
'keymap': platform,
|
'keymap': platform,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if (kIsWeb) {
|
||||||
|
result['code'] = _getWebKeyCode(key);
|
||||||
|
result['key'] = key.keyLabel;
|
||||||
|
result['metaState'] = _getWebModifierFlags(key, isDown);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
switch (platform) {
|
switch (platform) {
|
||||||
case 'android':
|
case 'android':
|
||||||
result['keyCode'] = keyCode;
|
result['keyCode'] = keyCode;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user