-
Notifications
You must be signed in to change notification settings - Fork 29.7k
Description
When simulating a key press, there's an optional "platform" parameter. That parameter defaults to "android". Due to the hard-coded default value, it's easy to end up with mismatched platform values, and it appears that mixing platform values results in unexpected behaviors.
Here's a minimal test repro:
testWidgets("bug repro", (widgetTester) async {
debugDefaultTargetPlatformOverride = TargetPlatform.linux;
await widgetTester.pumpWidget(
MaterialApp(
home: Scaffold(
body: Focus(
onKey: (FocusNode node, RawKeyEvent keyEvent) {
print("Key event");
print("$keyEvent");
print("Is shift pressed? ${keyEvent.isShiftPressed}");
print("");
return KeyEventResult.ignored;
},
autofocus: true,
child: const SizedBox.expand(),
),
),
),
);
print("Pressing SHIFT down");
await widgetTester.sendKeyDownEvent(LogicalKeyboardKey.shift);
await widgetTester.sendKeyDownEvent(LogicalKeyboardKey.arrowLeft, platform: "linux");
await widgetTester.sendKeyUpEvent(LogicalKeyboardKey.arrowLeft, platform: "linux");
print("Releasing SHIFT");
await widgetTester.sendKeyUpEvent(LogicalKeyboardKey.shift);
debugDefaultTargetPlatformOverride = null;
});Here's the test output:
Pressing SHIFT down
Key event
RawKeyDownEvent#e1bcc(logicalKey: LogicalKeyboardKey#df100(keyId: "0x200000102", keyLabel: "Shift Left", debugName: "Shift Left"), physicalKey: PhysicalKeyboardKey#ed430(usbHidUsage: "0x000700e1", debugName: "Shift Left"), repeat: false)
Is shift pressed? true
Key event
RawKeyDownEvent#3d221(logicalKey: LogicalKeyboardKey#860f3(keyId: "0x100000302", keyLabel: "Arrow Left", debugName: "Arrow Left"), physicalKey: PhysicalKeyboardKey#52951(usbHidUsage: "0x00070050", debugName: "Arrow Left"), repeat: false)
Is shift pressed? true
Key event
RawKeyUpEvent#fc85a(logicalKey: LogicalKeyboardKey#860f3(keyId: "0x100000302", keyLabel: "Arrow Left", debugName: "Arrow Left"), physicalKey: PhysicalKeyboardKey#52951(usbHidUsage: "0x00070050", debugName: "Arrow Left"))
Is shift pressed? true
Releasing SHIFT
Key event
RawKeyUpEvent#14075(logicalKey: LogicalKeyboardKey#df100(keyId: "0x200000102", keyLabel: "Shift Left", debugName: "Shift Left"), physicalKey: PhysicalKeyboardKey#ed430(usbHidUsage: "0x000700e1", debugName: "Shift Left"))
Is shift pressed? true
Notice that the final "Is shift pressed" is true, when it should be false.
Switching the test to the following results in the correct shift recognition:
testWidgets("bug repro", (widgetTester) async {
debugDefaultTargetPlatformOverride = TargetPlatform.linux;
await widgetTester.pumpWidget(
MaterialApp(
home: Scaffold(
body: Focus(
onKey: (FocusNode node, RawKeyEvent keyEvent) {
print("Key event");
print("$keyEvent");
print("Is shift pressed? ${keyEvent.isShiftPressed}");
print("");
return KeyEventResult.ignored;
},
autofocus: true,
child: const SizedBox.expand(),
),
),
),
);
print("Pressing SHIFT down");
await widgetTester.sendKeyDownEvent(LogicalKeyboardKey.shift, platform: "linux");
await widgetTester.sendKeyDownEvent(LogicalKeyboardKey.arrowLeft, platform: "linux");
await widgetTester.sendKeyUpEvent(LogicalKeyboardKey.arrowLeft, platform: "linux");
print("Releasing SHIFT");
await widgetTester.sendKeyUpEvent(LogicalKeyboardKey.shift, platform: "linux");
debugDefaultTargetPlatformOverride = null;
});The reason that this situation is a problem, is because sometimes a package is used to simulate key presses. This expectation that independent key calls all match their platform then requires knowledge about the internals of a package's selection, and also requires careful and consistent adherence through all simulation calls that one executes.
For example, this problem was originally found by way of the following snippet:
await tester.sendKeyDownEvent(LogicalKeyboardKey.shift);
await tester.pressCtlLeftArrow();
await tester.sendKeyUpEvent(LogicalKeyboardKey.shift);The pressCtlLeftArrow() method chose its platform based on defaultTargetPlatform, which happened to be "linux". But the regular simulation calls around it used Flutter's default, which is always "android". Thus, the unexpected SHIFT result.
Metadata
Metadata
Assignees
Labels
Type
Projects
Status