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
 - https://github.com/flutter/flutter/issues/136419

## Tests
 - Added tests for the new methods.
This commit is contained in:
Greg Spencer 2023-10-27 11:52:08 -07:00 committed by GitHub
parent 4cae1af41d
commit 5907c9757e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 82 additions and 2 deletions

View File

@ -457,6 +457,53 @@ class HardwareKeyboard {
/// of the event.
Set<KeyboardLockMode> get lockModesEnabled => _lockModes;
/// Returns true if the given [LogicalKeyboardKey] is pressed, according to
/// the [HardwareKeyboard].
bool isLogicalKeyPressed(LogicalKeyboardKey key) => _pressedKeys.values.contains(key);
/// Returns true if the given [PhysicalKeyboardKey] is pressed, according to
/// the [HardwareKeyboard].
bool isPhysicalKeyPressed(PhysicalKeyboardKey key) => _pressedKeys.containsKey(key);
/// Returns true if a logical CTRL modifier key is pressed, regardless of
/// which side of the keyboard it is on.
///
/// Use [isLogicalKeyPressed] if you need to know which control key was
/// pressed.
bool get isControlPressed {
return isLogicalKeyPressed(LogicalKeyboardKey.controlLeft) || isLogicalKeyPressed(LogicalKeyboardKey.controlRight);
}
/// Returns true if a logical SHIFT modifier key is pressed, regardless of
/// which side of the keyboard it is on.
///
/// Use [isLogicalKeyPressed] if you need to know which shift key was pressed.
bool get isShiftPressed {
return isLogicalKeyPressed(LogicalKeyboardKey.shiftLeft) || isLogicalKeyPressed(LogicalKeyboardKey.shiftRight);
}
/// Returns true if a logical ALT modifier key is pressed, regardless of which
/// side of the keyboard it is on.
///
/// The `AltGr` key that appears on some keyboards is considered to be the
/// same as [LogicalKeyboardKey.altRight] on some platforms (notably Android).
/// On platforms that can distinguish between `altRight` and `altGr`, a press
/// of `AltGr` will not return true here, and will need to be tested for
/// separately.
///
/// Use [isLogicalKeyPressed] if you need to know which alt key was pressed.
bool get isAltPressed {
return isLogicalKeyPressed(LogicalKeyboardKey.altLeft) || isLogicalKeyPressed(LogicalKeyboardKey.altRight);
}
/// Returns true if a logical META modifier key is pressed, regardless of
/// which side of the keyboard it is on.
///
/// Use [isLogicalKeyPressed] if you need to know which meta key was pressed.
bool get isMetaPressed {
return isLogicalKeyPressed(LogicalKeyboardKey.metaLeft) || isLogicalKeyPressed(LogicalKeyboardKey.metaRight);
}
void _assertEventIsRegular(KeyEvent event) {
assert(() {
const String common = 'If this occurs in real application, please report this '

View File

@ -8,7 +8,6 @@ import 'package:flutter/foundation.dart';
import 'binding.dart';
import 'hardware_keyboard.dart';
import 'keyboard_key.g.dart';
import 'raw_keyboard_android.dart';
import 'raw_keyboard_fuchsia.dart';
import 'raw_keyboard_ios.dart';
@ -407,7 +406,7 @@ abstract class RawKeyEvent with Diagnosticable {
}
}
/// Returns true if the given [KeyboardKey] is pressed.
/// Returns true if the given [LogicalKeyboardKey] is pressed.
bool isKeyPressed(LogicalKeyboardKey key) => RawKeyboard.instance.keysPressed.contains(key);
/// Returns true if a CTRL modifier key is pressed, regardless of which side

View File

@ -69,6 +69,40 @@ void main() {
equals(<KeyboardLockMode>{}));
}, variant: KeySimulatorTransitModeVariant.keyDataThenRawKeyData());
testWidgetsWithLeakTracking('KeyEvent can tell which keys are pressed', (WidgetTester tester) async {
await tester.pumpWidget(const Focus(autofocus: true, child: SizedBox()));
await tester.pump();
await simulateKeyDownEvent(LogicalKeyboardKey.numLock, platform: 'windows');
expect(HardwareKeyboard.instance.isPhysicalKeyPressed(PhysicalKeyboardKey.numLock), isTrue);
expect(HardwareKeyboard.instance.isLogicalKeyPressed(LogicalKeyboardKey.numLock), isTrue);
await simulateKeyDownEvent(LogicalKeyboardKey.numpad1, platform: 'windows');
expect(HardwareKeyboard.instance.isPhysicalKeyPressed(PhysicalKeyboardKey.numpad1), isTrue);
expect(HardwareKeyboard.instance.isLogicalKeyPressed(LogicalKeyboardKey.numpad1), isTrue);
await simulateKeyRepeatEvent(LogicalKeyboardKey.numpad1, platform: 'windows');
expect(HardwareKeyboard.instance.isPhysicalKeyPressed(PhysicalKeyboardKey.numpad1), isTrue);
expect(HardwareKeyboard.instance.isLogicalKeyPressed(LogicalKeyboardKey.numpad1), isTrue);
await simulateKeyUpEvent(LogicalKeyboardKey.numLock);
expect(HardwareKeyboard.instance.isPhysicalKeyPressed(PhysicalKeyboardKey.numpad1), isTrue);
expect(HardwareKeyboard.instance.isLogicalKeyPressed(LogicalKeyboardKey.numpad1), isTrue);
await simulateKeyDownEvent(LogicalKeyboardKey.numLock, platform: 'windows');
expect(HardwareKeyboard.instance.isPhysicalKeyPressed(PhysicalKeyboardKey.numLock), isTrue);
expect(HardwareKeyboard.instance.isLogicalKeyPressed(LogicalKeyboardKey.numLock), isTrue);
await simulateKeyUpEvent(LogicalKeyboardKey.numpad1, platform: 'windows');
expect(HardwareKeyboard.instance.isPhysicalKeyPressed(PhysicalKeyboardKey.numpad1), isFalse);
expect(HardwareKeyboard.instance.isLogicalKeyPressed(LogicalKeyboardKey.numpad1), isFalse);
await simulateKeyUpEvent(LogicalKeyboardKey.numLock, platform: 'windows');
expect(HardwareKeyboard.instance.isPhysicalKeyPressed(PhysicalKeyboardKey.numLock), isFalse);
expect(HardwareKeyboard.instance.isLogicalKeyPressed(LogicalKeyboardKey.numLock), isFalse);
}, variant: KeySimulatorTransitModeVariant.keyDataThenRawKeyData());
testWidgetsWithLeakTracking('KeyboardManager synthesizes modifier keys in rawKeyData mode', (WidgetTester tester) async {
final List<KeyEvent> events = <KeyEvent>[];
HardwareKeyboard.instance.addHandler((KeyEvent event) {