Skip to content

Commit 5907c97

Browse files
authored
Add isLogicalKeyPressed to KeyEvent (#136856)
## Description Adds some convenience methods to `KeyEvent` that allow testing to see if a logical or physical key is pressed from the event object. These are similar to the ones already on `RawKeyEvent`, and will make migration the to `KeyEvent` easier (so it could more easily be a `flutter fix` migration). Added: - `bool isLogicalKeyPressed(LogicalKeyboardKey key)` - `bool isPhysicalKeyPressed(PhysicalKeyboardKey key)` - `bool get isControlPressed` - `bool get isShiftPressed` - `bool get isAltPressed` - `bool get isMetaPressed` ## Related Issues - flutter/flutter#136419 ## Tests - Added tests for the new methods.
1 parent 4cae1af commit 5907c97

File tree

3 files changed

+82
-2
lines changed

3 files changed

+82
-2
lines changed

packages/flutter/lib/src/services/hardware_keyboard.dart

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -457,6 +457,53 @@ class HardwareKeyboard {
457457
/// of the event.
458458
Set<KeyboardLockMode> get lockModesEnabled => _lockModes;
459459

460+
/// Returns true if the given [LogicalKeyboardKey] is pressed, according to
461+
/// the [HardwareKeyboard].
462+
bool isLogicalKeyPressed(LogicalKeyboardKey key) => _pressedKeys.values.contains(key);
463+
464+
/// Returns true if the given [PhysicalKeyboardKey] is pressed, according to
465+
/// the [HardwareKeyboard].
466+
bool isPhysicalKeyPressed(PhysicalKeyboardKey key) => _pressedKeys.containsKey(key);
467+
468+
/// Returns true if a logical CTRL modifier key is pressed, regardless of
469+
/// which side of the keyboard it is on.
470+
///
471+
/// Use [isLogicalKeyPressed] if you need to know which control key was
472+
/// pressed.
473+
bool get isControlPressed {
474+
return isLogicalKeyPressed(LogicalKeyboardKey.controlLeft) || isLogicalKeyPressed(LogicalKeyboardKey.controlRight);
475+
}
476+
477+
/// Returns true if a logical SHIFT modifier key is pressed, regardless of
478+
/// which side of the keyboard it is on.
479+
///
480+
/// Use [isLogicalKeyPressed] if you need to know which shift key was pressed.
481+
bool get isShiftPressed {
482+
return isLogicalKeyPressed(LogicalKeyboardKey.shiftLeft) || isLogicalKeyPressed(LogicalKeyboardKey.shiftRight);
483+
}
484+
485+
/// Returns true if a logical ALT modifier key is pressed, regardless of which
486+
/// side of the keyboard it is on.
487+
///
488+
/// The `AltGr` key that appears on some keyboards is considered to be the
489+
/// same as [LogicalKeyboardKey.altRight] on some platforms (notably Android).
490+
/// On platforms that can distinguish between `altRight` and `altGr`, a press
491+
/// of `AltGr` will not return true here, and will need to be tested for
492+
/// separately.
493+
///
494+
/// Use [isLogicalKeyPressed] if you need to know which alt key was pressed.
495+
bool get isAltPressed {
496+
return isLogicalKeyPressed(LogicalKeyboardKey.altLeft) || isLogicalKeyPressed(LogicalKeyboardKey.altRight);
497+
}
498+
499+
/// Returns true if a logical META modifier key is pressed, regardless of
500+
/// which side of the keyboard it is on.
501+
///
502+
/// Use [isLogicalKeyPressed] if you need to know which meta key was pressed.
503+
bool get isMetaPressed {
504+
return isLogicalKeyPressed(LogicalKeyboardKey.metaLeft) || isLogicalKeyPressed(LogicalKeyboardKey.metaRight);
505+
}
506+
460507
void _assertEventIsRegular(KeyEvent event) {
461508
assert(() {
462509
const String common = 'If this occurs in real application, please report this '

packages/flutter/lib/src/services/raw_keyboard.dart

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ import 'package:flutter/foundation.dart';
88

99
import 'binding.dart';
1010
import 'hardware_keyboard.dart';
11-
import 'keyboard_key.g.dart';
1211
import 'raw_keyboard_android.dart';
1312
import 'raw_keyboard_fuchsia.dart';
1413
import 'raw_keyboard_ios.dart';
@@ -407,7 +406,7 @@ abstract class RawKeyEvent with Diagnosticable {
407406
}
408407
}
409408

410-
/// Returns true if the given [KeyboardKey] is pressed.
409+
/// Returns true if the given [LogicalKeyboardKey] is pressed.
411410
bool isKeyPressed(LogicalKeyboardKey key) => RawKeyboard.instance.keysPressed.contains(key);
412411

413412
/// Returns true if a CTRL modifier key is pressed, regardless of which side

packages/flutter/test/services/hardware_keyboard_test.dart

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,40 @@ void main() {
6969
equals(<KeyboardLockMode>{}));
7070
}, variant: KeySimulatorTransitModeVariant.keyDataThenRawKeyData());
7171

72+
testWidgetsWithLeakTracking('KeyEvent can tell which keys are pressed', (WidgetTester tester) async {
73+
await tester.pumpWidget(const Focus(autofocus: true, child: SizedBox()));
74+
await tester.pump();
75+
76+
await simulateKeyDownEvent(LogicalKeyboardKey.numLock, platform: 'windows');
77+
78+
expect(HardwareKeyboard.instance.isPhysicalKeyPressed(PhysicalKeyboardKey.numLock), isTrue);
79+
expect(HardwareKeyboard.instance.isLogicalKeyPressed(LogicalKeyboardKey.numLock), isTrue);
80+
81+
await simulateKeyDownEvent(LogicalKeyboardKey.numpad1, platform: 'windows');
82+
expect(HardwareKeyboard.instance.isPhysicalKeyPressed(PhysicalKeyboardKey.numpad1), isTrue);
83+
expect(HardwareKeyboard.instance.isLogicalKeyPressed(LogicalKeyboardKey.numpad1), isTrue);
84+
85+
await simulateKeyRepeatEvent(LogicalKeyboardKey.numpad1, platform: 'windows');
86+
expect(HardwareKeyboard.instance.isPhysicalKeyPressed(PhysicalKeyboardKey.numpad1), isTrue);
87+
expect(HardwareKeyboard.instance.isLogicalKeyPressed(LogicalKeyboardKey.numpad1), isTrue);
88+
89+
await simulateKeyUpEvent(LogicalKeyboardKey.numLock);
90+
expect(HardwareKeyboard.instance.isPhysicalKeyPressed(PhysicalKeyboardKey.numpad1), isTrue);
91+
expect(HardwareKeyboard.instance.isLogicalKeyPressed(LogicalKeyboardKey.numpad1), isTrue);
92+
93+
await simulateKeyDownEvent(LogicalKeyboardKey.numLock, platform: 'windows');
94+
expect(HardwareKeyboard.instance.isPhysicalKeyPressed(PhysicalKeyboardKey.numLock), isTrue);
95+
expect(HardwareKeyboard.instance.isLogicalKeyPressed(LogicalKeyboardKey.numLock), isTrue);
96+
97+
await simulateKeyUpEvent(LogicalKeyboardKey.numpad1, platform: 'windows');
98+
expect(HardwareKeyboard.instance.isPhysicalKeyPressed(PhysicalKeyboardKey.numpad1), isFalse);
99+
expect(HardwareKeyboard.instance.isLogicalKeyPressed(LogicalKeyboardKey.numpad1), isFalse);
100+
101+
await simulateKeyUpEvent(LogicalKeyboardKey.numLock, platform: 'windows');
102+
expect(HardwareKeyboard.instance.isPhysicalKeyPressed(PhysicalKeyboardKey.numLock), isFalse);
103+
expect(HardwareKeyboard.instance.isLogicalKeyPressed(LogicalKeyboardKey.numLock), isFalse);
104+
}, variant: KeySimulatorTransitModeVariant.keyDataThenRawKeyData());
105+
72106
testWidgetsWithLeakTracking('KeyboardManager synthesizes modifier keys in rawKeyData mode', (WidgetTester tester) async {
73107
final List<KeyEvent> events = <KeyEvent>[];
74108
HardwareKeyboard.instance.addHandler((KeyEvent event) {

0 commit comments

Comments
 (0)