Skip to content

Repeated hardware keyboard events not received on iOS #99252

Closed

Description

@collinjackson

KeyRepeatEvent notifications are not received by a Flutter app when using a hardware keyboard connected to an iOS device or simulator. It works on Android.

When testing on physical devices I used an MX Keys keyboard connected via Bluetooth. For the iOS simulator test, I used the built-in keyboard on the host machine.

The code sample below uses a Focus, but I also tested FocusScope, CallbackShortcuts, KeyboardListener, and RawKeyboardListener. The behavior is the same.

Steps to Reproduce

  1. Execute flutter run on the code sample
  2. Hold down any key on a connected hardware keyboard
  3. Observe the text on the screen

Expected results:
All devices show the text "KeyDownEvent" and then it quickly changes to "KeyRepeatEvent"

Actual results:

The iOS devices are stuck on "KeyDownEvent" and don't show "KeyRepeatEvent"

iPhone 12 Pro iPhone simulator Samsung Galaxy A12:
iPhone 12 Pro simulator showing KeyDownEvent text iPhone 12 Pro showing KeyDownEvent text Samsung Galaxy A12 showing KeyRepeatEvent text
Code sample
import 'package:flutter/material.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatefulWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  String _text = "Hold down a key";

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: Scaffold(
        body: Center(
          child: Focus(
            autofocus: true,
            onKeyEvent: (_, event) {
              setState(() {
                _text = '${event.runtimeType}';
              });
              return KeyEventResult.handled;
            },
            child: Text(_text, style: const TextStyle(fontSize: 40),
            )
          ),
        ),
      ),
    );
  }
}
Logs
[   +2 ms] Flutter run key commands.
[   +1 ms] 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 iPhone is available at: http://127.0.0.1:60927/Y2196qBaw50=/
[ +255 ms] The Flutter DevTools debugger and profiler on iPhone is available at: http://127.0.0.1:9100?uri=http://127.0.0.1:60927/Y2196qBaw50=/
% flutter analyze
Analyzing hardware_keyboard_test...                                     
No issues found! (ran in 1.5s)

Flutter doctor shows an issue with IntelliJ but I don't think it's related. I'm launching using the command line.

[✓] Flutter (Channel stable, 2.10.2, on macOS 12.2 21D49 darwin-x64, locale en-US)
    • Flutter version 2.10.2 at /Users/jackson/flutter
    • Upstream repository https://github.com/flutter/flutter.git
    • Framework revision 097d3313d8 (9 days ago), 2022-02-18 19:33:08 -0600
    • Engine revision a83ed0e5e3
    • Dart version 2.16.1
    • DevTools version 2.9.2

[✓] Android toolchain - develop for Android devices (Android SDK version 32.0.0)
    • Android SDK at /Users/jackson/Library/Android/sdk
    • Platform android-32, build-tools 32.0.0
    • ANDROID_SDK_ROOT = /home/jackson/Library/Android/sdk
    • Java binary at: /Applications/Android Studio.app/Contents/jre/Contents/Home/bin/java
    • Java version OpenJDK Runtime Environment (build 11.0.10+0-b96-7281165)
    • All Android licenses accepted.

[✓] Xcode - develop for iOS and macOS (Xcode 13.2.1)
    • Xcode at /Applications/Xcode.app/Contents/Developer
    • CocoaPods version 1.11.2

[✓] Chrome - develop for the web
    • Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome

[✓] Android Studio (version 2020.3)
    • 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.10+0-b96-7281165)

[☠] IntelliJ IDEA Community Edition (the doctor check crashed)
    ✗ Due to an error, the doctor check did not complete. If the error message below is not helpful, please let us know about this issue at
      https://github.com/flutter/flutter/issues.
    ✗ FormatException: Unexpected extension byte (at offset 5)
    • #0      _Utf8Decoder.convertSingle (dart:convert-patch/convert_patch.dart:1789:7)
      #1      Utf8Decoder.convert (dart:convert/utf.dart:351:42)
      #2      InputStream.readString (package:archive/src/util/input_stream.dart:207:30)
      #3      new ZipDirectory.read (package:archive/src/zip/zip_directory.dart:40:30)
      #4      ZipDecoder.decodeBuffer (package:archive/src/zip_decoder.dart:19:30)
      #5      ZipDecoder.decodeBytes (package:archive/src/zip_decoder.dart:14:12)
      #6      IntelliJPlugins._findPluginXml (package:flutter_tools/src/intellij/intellij.dart:130:44)
      #7      IntelliJPlugins._readPackageVersion (package:flutter_tools/src/intellij/intellij.dart:141:40)
      #8      IntelliJPlugins.validatePackage (package:flutter_tools/src/intellij/intellij.dart:63:35)
      #9      IntelliJValidator.validate (package:flutter_tools/src/intellij/intellij_validator.dart:103:15)
      #10     asyncGuard.<anonymous closure> (package:flutter_tools/src/base/async_guard.dart:111:32)
      #11     asyncGuard.<anonymous closure> (package:flutter_tools/src/base/async_guard.dart:109:18)
      #12     _rootRun (dart:async/zone.dart:1426:13)
      #13     _CustomZone.run (dart:async/zone.dart:1328:19)
      #14     _runZoned (dart:async/zone.dart:1861:10)
      #15     runZonedGuarded (dart:async/zone.dart:1849:12)
      #16     runZoned (dart:async/zone.dart:1780:12)
      #17     asyncGuard (package:flutter_tools/src/base/async_guard.dart:109:3)
      #18     Doctor.startValidatorTasks (package:flutter_tools/src/doctor.dart:205:9)
      #19     Doctor.diagnose (package:flutter_tools/src/doctor.dart:309:47)
      #20     DoctorCommand.runCommand (package:flutter_tools/src/commands/doctor.dart:50:48)
      #21     FlutterCommand.verifyThenRunCommand (package:flutter_tools/src/runner/flutter_command.dart:1320:12)
      <asynchronous suspension>
      #22     FlutterCommand.run.<anonymous closure> (package:flutter_tools/src/runner/flutter_command.dart:1161:27)
      <asynchronous suspension>
      #23     AppContext.run.<anonymous closure> (package:flutter_tools/src/base/context.dart:150:19)
      <asynchronous suspension>
      #24     CommandRunner.runCommand (package:args/command_runner.dart:209:13)
      <asynchronous suspension>
      #25     FlutterCommandRunner.runCommand.<anonymous closure> (package:flutter_tools/src/runner/flutter_command_runner.dart:281:9)
      <asynchronous suspension>
      #26     AppContext.run.<anonymous closure> (package:flutter_tools/src/base/context.dart:150:19)
      <asynchronous suspension>
      #27     FlutterCommandRunner.runCommand (package:flutter_tools/src/runner/flutter_command_runner.dart:229:5)
      <asynchronous suspension>
      #28     run.<anonymous closure>.<anonymous closure> (package:flutter_tools/runner.dart:62:9)
      <asynchronous suspension>
      #29     AppContext.run.<anonymous closure> (package:flutter_tools/src/base/context.dart:150:19)
      <asynchronous suspension>
      #30     main (package:flutter_tools/executable.dart:94:3)
      <asynchronous suspension>


[✓] Connected device (5 available)
    • SM A125U (mobile)      • R58R85BBCAV                          • android-arm64  • Android 11 (API 30)
    • iPhone (mobile)        • 00008101-001155042188801E            • ios            • iOS 15.1 19B74
    • iPhone 12 Pro (mobile) • 132369FE-696E-42C9-B0F4-EE1A24E377FC • ios            • com.apple.CoreSimulator.SimRuntime.iOS-15-2 (simulator)
    • macOS (desktop)        • macos                                • darwin-x64     • macOS 12.2 21D49 darwin-x64
    • Chrome (web)           • chrome                               • web-javascript • Google Chrome 98.0.4758.109

[✓] HTTP Host Availability
    • All required HTTP hosts are available

! Doctor found issues in 1 category.

Activity

  1. added
    a: text inputEntering text in a text field or keyboard related problems
    platform-iosiOS applications specifically
    on Feb 28, 2022
  2. added
    engineflutter/engine related. See also e: labels.
    on Feb 28, 2022
  3. jmagman commented on Feb 28, 2022

    @jmagman
    Member

    @dkwingsmt or @gspencergoog I know you're not working on iOS but you may have the most context for key event issues like this.

  4. gspencergoog commented on Feb 28, 2022

    @gspencergoog
    Contributor

    As far as I know, iOS doesn't provide key repeat event information through their API, so we can't generate those events.

  5. gspencergoog commented on Feb 28, 2022

    @gspencergoog
    Contributor

    At least that was true at the time the iOS key event code was implemented.

  6. chinmaygarde commented on Feb 28, 2022

    @chinmaygarde
    Contributor

    @gspencergoog So, is this working as intended? Also, hey Collin 👋

  7. added
    P2Important issues not at the top of the work list
    on Feb 28, 2022
  8. gspencergoog commented on Feb 28, 2022

    @gspencergoog
    Contributor

    Oh! I didn't even notice this was from Collin! Hey Collin!

  9. gspencergoog commented on Feb 28, 2022

    @gspencergoog
    Contributor

    Well, we intend to provide key repeat events, but Apple doesn't. :-)

  10. collinjackson commented on Feb 28, 2022

    @collinjackson
    ContributorAuthor

    It sounds like the issue is not possible to fix in Flutter and can be closed. Perhaps the documentation for KeyRepeatEvent could mention that repeat events are provided if supported by the underlying platform. Creative use of TextFormField or flutter_native_text_input may be better options than making guesses about the user's repeat settings.

  11. dkwingsmt commented on Jan 10, 2023

    @dkwingsmt
    Contributor

    Is it possible to simulate this behavior, such as listening to the iOS text API and synthesize a repeat event if the same text keeps coming?

  12. github-actions commented on Mar 4, 2023

    @github-actions

    This thread has been automatically locked since there has not been any recent activity after it was closed. If you are still experiencing a similar issue, please open a new bug, including the output of flutter doctor -v and a minimal reproduction of the issue.

  13. locked as resolved and limited conversation to collaborators on Mar 4, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    P2Important issues not at the top of the work lista: text inputEntering text in a text field or keyboard related problemsd: api docsIssues with https://api.flutter.dev/engineflutter/engine related. See also e: labels.platform-iosiOS applications specifically

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions