flutter / flutter

Flutter makes it easy and fast to build beautiful apps for mobile and beyond
https://flutter.dev
BSD 3-Clause "New" or "Revised" License
165.24k stars 27.27k forks source link

HardwareKeyboard logicalKeysPressed returns previously pressed keys #95634

Open prasmussen opened 2 years ago

prasmussen commented 2 years ago

HardwareKeyboard.instance.logicalKeysPressed returns keys that was previously pressed instead of only the currently pressed key. Happens when pressing the meta key in addition to other keys, on Mac OS.

Steps to Reproduce

  1. flutter create --platforms web foo
  2. Put attached code sample in lib/main.dart
  3. flutter run -d chrome -t lib/main.dart
  4. Open page in chrome
  5. Press keys cmd + k and release
  6. Press key arrow left and release
  7. Check console output
  8. See that the last keypress includes the key k when only the arrow left key was pressed

Expected results:

LogicalKeySet#4b191(keys: Meta Left)
LogicalKeySet#5c7f7(keys: Meta Left + Key K)
LogicalKeySet#6c398(keys: Arrow Left)

Actual results:

LogicalKeySet#4b191(keys: Meta Left)
LogicalKeySet#5c7f7(keys: Meta Left + Key K)
LogicalKeySet#6c398(keys: Arrow Left + Key K)
Code sample ```dart import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; void main() { runApp(const MyApp()); } class MyApp extends StatelessWidget { const MyApp({Key? key}) : super(key: key); @override Widget build(BuildContext context) { return MaterialApp( home: GlobalKeyboardListener( onKeyEvent: (KeyEvent event) { if (event is KeyDownEvent) { if (HardwareKeyboard.instance.logicalKeysPressed.isNotEmpty) { final pressedKeys = LogicalKeySet.fromSet( HardwareKeyboard.instance.logicalKeysPressed, ); // ignore: avoid_print print(pressedKeys); } } return false; }, child: const Text("hello"), ), ); } } class GlobalKeyboardListener extends StatefulWidget { final bool Function(KeyEvent keyEvent) onKeyEvent; final Widget child; const GlobalKeyboardListener({ required this.onKeyEvent, required this.child, Key? key, }) : super(key: key); @override State createState() { return _GlobalKeyboardListenerState(); } } class _GlobalKeyboardListenerState extends State { @override void initState() { startListen(); super.initState(); } @override void dispose() { stopListen(); super.dispose(); } @override Widget build(BuildContext context) { return widget.child; } void startListen() { HardwareKeyboard.instance.addHandler(widget.onKeyEvent); } void stopListen() { HardwareKeyboard.instance.removeHandler(widget.onKeyEvent); } } ```
Logs ``` Analyzing foo... No issues found! (ran in 1.3s) ``` ``` $ flutter doctor -v [✓] Flutter (Channel stable, 2.8.0, on macOS 12.0.1 21A559 darwin-x64, locale en-GB) • Flutter version 2.8.0 at /usr/local/Caskroom/flutter/2.2.1/flutter • Upstream repository git@github.com:flutter/flutter.git • Framework revision cf44000065 (13 days ago), 2021-12-08 14:06:50 -0800 • Engine revision 40a99c5951 • Dart version 2.15.0 [✗] Android toolchain - develop for Android devices ✗ Unable to locate Android SDK. Install Android Studio from: https://developer.android.com/studio/index.html On first launch it will assist you in installing the Android SDK components. (or visit https://flutter.dev/docs/get-started/install/macos#android-setup for detailed instructions). If the Android SDK has been installed to a custom location, please use `flutter config --android-sdk` to update to that location. [!] Xcode - develop for iOS and macOS (Xcode 13.2.1) • Xcode at /Applications/Xcode.app/Contents/Developer ✗ CocoaPods not installed. CocoaPods is used to retrieve the iOS and macOS platform side's plugin code that responds to your plugin usage on the Dart side. Without CocoaPods, plugins will not work on iOS or macOS. For more info, see https://flutter.dev/platform-plugins To install see https://guides.cocoapods.org/using/getting-started.html#installation for instructions. [✓] Chrome - develop for the web • Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome [!] Android Studio (not installed) • Android Studio not found; download from https://developer.android.com/studio/index.html (or visit https://flutter.dev/docs/get-started/install/macos#android-setup for detailed instructions). [✓] VS Code (version 1.63.2) • VS Code at /Applications/Visual Studio Code.app/Contents • Flutter extension version 3.29.0 [✓] Connected device (1 available) • Chrome (web) • chrome • web-javascript • Google Chrome 96.0.4664.110 ! Doctor found issues in 3 categories. ```
maheshj01 commented 2 years ago

Hi @prasmussen, Thanks for filing the issue. I am able to reproduce the issue on stable and the master channel on the web, When cmd+k is pressed and then released (both keys) and when the left arrow is pressed and released the console outputs: keys: Arrow Left + Key K) instead of (keys: Arrow Left)

This issue is only on the web and works fine on Desktop.

logs (web) ``` mahesh@Maheshs-MacBook-Air-M1 counter_app % flutter run -d chrome Launching lib/main.dart on Chrome in debug mode... Waiting for connection from debug service on Chrome... 13.9s This app is linked to the debug service: ws://127.0.0.1:56848/J7BTWRCU9Zk=/ws Debug service listening on ws://127.0.0.1:56848/J7BTWRCU9Zk=/ws 💪 Running with sound null safety 💪 🔥 To hot restart changes while running, press "r" or "R". For a more detailed help message, press "h". To quit, press "q". An Observatory debugger and profiler on Chrome is available at: http://127.0.0.1:56848/J7BTWRCU9Zk= The Flutter DevTools debugger and profiler on Chrome is available at: http://127.0.0.1:9101?uri=http://127.0.0.1:56848/J7BTWRCU9Zk= LogicalKeySet#4b191(keys: Meta Left) LogicalKeySet#5c7f7(keys: Meta Left + Key K) LogicalKeySet#6c398(keys: Arrow Left + Key K) LogicalKeySet#4b191(keys: Meta Left) LogicalKeySet#5c7f7(keys: Meta Left + Key K) LogicalKeySet#6c398(keys: Arrow Left + Key K) LogicalKeySet#5c7f7(keys: Meta Left + Key K) LogicalKeySet#7a008(keys: Arrow Left) LogicalKeySet#4b191(keys: Meta Left) LogicalKeySet#5c7f7(keys: Meta Left + Key K) LogicalKeySet#6c398(keys: Arrow Left + Key K) ```
logs (macos) ``` mahesh@Maheshs-MacBook-Air-M1 counter_app % flutter run -d macos Launching lib/main.dart on macOS in debug mode... --- xcodebuild: WARNING: Using the first of multiple matching destinations: { platform:macOS, arch:x86_64, id:6A745C96-D83E-5C8D-8EE9-5958E598001B } { platform:macOS, name:Any Mac } Building macOS application... Syncing files to device macOS... 111ms Flutter run key commands. r Hot reload. 🔥🔥🔥 R Hot restart. h List all available interactive commands. d Detach (terminate "flutter run" but leave application running). c Clear the screen q Quit (terminate the application on the device). 💪 Running with sound null safety 💪 An Observatory debugger and profiler on macOS is available at: http://127.0.0.1:56640/9oDhGyz1Joc=/ The Flutter DevTools debugger and profiler on macOS is available at: http://127.0.0.1:9101?uri=http://127.0.0.1:56640/9oDhGyz1Joc=/ flutter: LogicalKeySet#00106(keys: Meta Left) flutter: LogicalKeySet#de8aa(keys: Meta Left + Key K) flutter: LogicalKeySet#00302(keys: Arrow Left) flutter: LogicalKeySet#00106(keys: Meta Left) flutter: LogicalKeySet#de8aa(keys: Meta Left + Key K) flutter: LogicalKeySet#00302(keys: Arrow Left) flutter: LogicalKeySet#00106(keys: Meta Left) flutter: LogicalKeySet#de8aa(keys: Meta Left + Key K) flutter: LogicalKeySet#00302(keys: Arrow Left) flutter: LogicalKeySet#00106(keys: Meta Left) flutter: LogicalKeySet#de8aa(keys: Meta Left + Key K) flutter: LogicalKeySet#00302(keys: Arrow Left) ```
flutter doctor -v ``` [✓] Flutter (Channel stable, 2.8.1, on macOS 12.1 21C52 darwin-arm, locale en-GB) • Flutter version 2.8.1 at /Users/mahesh/Documents/flutter • Upstream repository https://github.com/flutter/flutter.git • Framework revision 77d935af4d (6 days ago), 2021-12-16 08:37:33 -0800 • Engine revision 890a5fca2e • Dart version 2.15.1 [✓] Android toolchain - develop for Android devices (Android SDK version 31.0.0) • Android SDK at /Users/mahesh/Library/Android/sdk • Platform android-31, build-tools 31.0.0 • ANDROID_HOME = /Users/mahesh/Library/Android/sdk • Java binary at: /Applications/Android Studio.app/Contents/jre/jdk/Contents/Home/bin/java • Java version OpenJDK Runtime Environment (build 11.0.8+10-b944.6916264) • All Android licenses accepted. [✓] Xcode - develop for iOS and macOS (Xcode 13.1) • Xcode at /Applications/Xcode.app/Contents/Developer • CocoaPods version 1.10.2 [✓] Chrome - develop for the web • Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome [✓] Android Studio (version 4.2) • Android Studio at /Applications/Android Studio.app/Contents • Flutter plugin can be installed from: 🔨 https://plugins.jetbrains.com/plugin/9212-flutter • Dart plugin can be installed from: 🔨 https://plugins.jetbrains.com/plugin/6351-dart • Java version OpenJDK Runtime Environment (build 11.0.8+10-b944.6916264) [✓] IntelliJ IDEA Community Edition (version 2021.2.1) • IntelliJ at /Applications/IntelliJ IDEA CE.app • Flutter plugin version 60.1.4 • Dart plugin version 212.5080.8 [✓] VS Code (version 1.61.2) • VS Code at /Applications/Visual Studio Code.app/Contents • Flutter extension version 3.29.0 [✓] Connected device (2 available) • macOS (desktop) • macos • darwin-arm64 • macOS 12.1 21C52 darwin-arm • Chrome (web) • chrome • web-javascript • Google Chrome 96.0.4664.110 • No issues found! ``` ``` [✓] Flutter (Channel master, 2.9.0-1.0.pre.93, on macOS 12.1 21C52 darwin-arm, locale en-GB) • Flutter version 2.9.0-1.0.pre.93 at /Users/mahesh/Documents/flutter_master • Upstream repository https://github.com/flutter/flutter.git • Framework revision 1be7f1ea56 (7 days ago), 2021-12-14 22:14:07 -0500 • Engine revision e444009bf4 • Dart version 2.16.0 (build 2.16.0-109.0.dev) • DevTools version 2.9.1 [✓] Android toolchain - develop for Android devices (Android SDK version 31.0.0) • Android SDK at /Users/mahesh/Library/Android/sdk • Platform android-31, build-tools 31.0.0 • ANDROID_HOME = /Users/mahesh/Library/Android/sdk • Java binary at: /Applications/Android Studio.app/Contents/jre/jdk/Contents/Home/bin/java • Java version OpenJDK Runtime Environment (build 11.0.8+10-b944.6916264) • All Android licenses accepted. [✓] Xcode - develop for iOS and macOS (Xcode 13.1) • Xcode at /Applications/Xcode.app/Contents/Developer • CocoaPods version 1.10.2 [✓] Chrome - develop for the web • Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome [✓] Android Studio (version 4.2) • Android Studio at /Applications/Android Studio.app/Contents • Flutter plugin can be installed from: 🔨 https://plugins.jetbrains.com/plugin/9212-flutter • Dart plugin can be installed from: 🔨 https://plugins.jetbrains.com/plugin/6351-dart • Java version OpenJDK Runtime Environment (build 11.0.8+10-b944.6916264) [✓] IntelliJ IDEA Community Edition (version 2021.2.1) • IntelliJ at /Applications/IntelliJ IDEA CE.app • Flutter plugin version 60.1.4 • Dart plugin version 212.5080.8 [✓] VS Code (version 1.61.2) • VS Code at /Applications/Visual Studio Code.app/Contents • Flutter extension version 3.29.0 [✓] Connected device (2 available) • macOS (desktop) • macos • darwin-arm64 • macOS 12.1 21C52 darwin-arm • Chrome (web) • chrome • web-javascript • Google Chrome 96.0.4664.110 • No issues found! ```
maheshj01 commented 2 years ago

cc: @dkwingsmt

yjbanov commented 2 years ago

This looks like a framework issue. Removing the web label for now.

TahaTesser commented 2 years ago

I can reproduce it on windows desktop but not on macOS desktop, this indeed seems to be from the framework

flutter: LogicalKeySet#00104(keys: Alt Left)
flutter: LogicalKeySet#720bd(keys: Alt Left + Key K)
flutter: LogicalKeySet#e3f7b(keys: Arrow Left + Key K)
flutter: LogicalKeySet#c8814(keys: Arrow Right + Key K)
flutter: LogicalKeySet#113e1(keys: Arrow Down + Key K)
flutter: LogicalKeySet#6b3a8(keys: Arrow Up + Key K)
flutter: LogicalKeySet#113e1(keys: Arrow Down + Key K)
flutter: LogicalKeySet#e3f7b(keys: Arrow Left + Key K)
flutter: LogicalKeySet#113e1(keys: Arrow Down + Key K)
flutter: LogicalKeySet#6b3a8(keys: Arrow Up + Key K)
flutter: LogicalKeySet#caf5e(keys: Key B + Key K + Key V)
flutter: LogicalKeySet#61f76(keys: Key J + Key K)
flutter-triage-bot[bot] commented 4 months ago

The triaged-desktop label is irrelevant if there is no team-desktop label or fyi-desktop label.