Skip to content

Make shortcuts portable across different keyboard layouts #116658

@jpnurmi

Description

@jpnurmi

Flutter shortcuts defined with SingleActivator or LogicalKeySet are not keyboard layout agnostic. For example, the classic zoom-in shortcut Control++ only works with such keyboard layouts (e.g. Finnish) that do not require the Shift modifier to be pressed to access +. If the system has e.g. US English keyboard layout in use, the shortcut has to be defined as Control+Shift++ instead. A single shortcut definition does not work with both keyboard layouts.

The "logical" shortcut is Control++ and what is typically presented in GUIs. Application developers should not need to know that in some keyboard layouts, the "physical" key combination to activate the shortcut includes an "extra" Shift modifier.

Steps to Reproduce

  1. Switch to Finnish keyboard layout
  2. Execute flutter run on the code sample
  3. Try pressing Control++ and Control+-
  4. Observe "zoom in" and "zoom out" in the debug output
  5. Switch to US English keyboard layout
  6. Try pressing Control++ and Control+-
  7. Observe the debug output. "zoom in" doesn't get activated

Expected results:

Control++ should work regardless of the keyboard layout.

Actual results:

  • Control++ works with the Finnish keyboard layout:
    SingleActivator(LogicalKeyboardKey.add, control: true)

vs.

  • Control+Shift++ works with the US English keyboard layout:
    SingleActivator(LogicalKeyboardKey.add, control: true, shift: true)
Code sample
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';

const zoomIn = SingleActivator(LogicalKeyboardKey.add, control: true);
const zoomOut = SingleActivator(LogicalKeyboardKey.minus, control: true);

void main() {
  runApp(
    MaterialApp(
      home: Scaffold(
        body: CallbackShortcuts(
          bindings: {
            zoomIn: () => print('zoom in'),
            zoomOut: () => print('zoom out'),
          },
          child: const Focus(autofocus: true, child: SizedBox.shrink()),
        ),
      ),
    ),
  );
}
Logs
[✓] Flutter (Channel main, 3.7.0-3.0.pre.57, on Ubuntu 22.10 5.19.0-23-generic, locale en_DK.UTF-8)
    • Flutter version 3.7.0-3.0.pre.57 on channel main at /home/jpnurmi/Flutter
    • Upstream repository https://github.com/flutter/flutter.git
    • Framework revision ef6ead4401 (10 hours ago), 2022-12-06 23:15:24 -0500
    • Engine revision 67254d6e4b
    • Dart version 2.19.0 (build 2.19.0-467.0.dev)
    • DevTools version 2.20.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/linux#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.


[✓] Chrome - develop for the web
    • Chrome at google-chrome

[✓] Linux toolchain - develop for Linux desktop
    • Ubuntu clang version 15.0.2-1
    • cmake version 3.24.2
    • ninja version 1.11.0
    • pkg-config version 0.29.2

[!] 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/linux#android-setup for detailed instructions).

[✓] VS Code
    • VS Code at /snap/code/current
    • Flutter extension version 3.54.0

[✓] Connected device (2 available)
    • Linux (desktop) • linux  • linux-x64      • Ubuntu 22.10 5.19.0-23-generic
    • Chrome (web)    • chrome • web-javascript • Google Chrome 108.0.5359.94

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

! Doctor found issues in 2 categories.

Metadata

Metadata

Assignees

No one assigned

    Labels

    P3Issues that are less important to the Flutter projecta: text inputEntering text in a text field or keyboard related problemsc: new featureNothing broken; request for a new capabilityc: proposalA detailed proposal for a change to Flutterengineflutter/engine related. See also e: labels.team-engineOwned by Engine teamtriaged-engineTriaged by Engine team

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions