Disable escape key navigation in Flutter Web

Viewed 1385

When typing the escape key on Flutter web, Flutter performs Navigator.of(context).pop(). How can I disable this functionality?

Here are the scenarios I tested which all resulted in consistent functionality:

  • Chrome on Mac, Edge on Windows, and in DartPad 1.20.0
  • MaterialApp, CupertinoApp, and WidgetsApp
  • Debug mode and Release mode

I can disable it using WillPopScope, but this also disabled pressing the back button in the browser. I still want to allow users to navigate using the browser, so this is not a viable option.

Side question: Does anyone know why this is default functionality? This is not expected behavior on a website (excluding popup menus).

1 Answers

Flutter web (and desktop too) uses Esc shortcut to dismiss modal dialog or popup menu. This binding is defined at application level in WidgetsApp.defaultShortcuts and, unfortunately, affects Navigator too. Of course for navigation between pages keyboard shortcuts should be somewhat different, but for now Flutter web status is beta and some features are still under development.

As a workaround, we can remove this shortcut from MaterialApp:

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    final shortcuts = Map.of(WidgetsApp.defaultShortcuts)
      ..remove(LogicalKeySet(LogicalKeyboardKey.escape));
    return MaterialApp(
      shortcuts: shortcuts,
      home: HomePage(),
    );
  }
}

and have to restore one locally as needed:

  Future<void> openDialog(BuildContext context) async {
    final shortcuts = Shortcuts.of(context).shortcuts;
    final key = LogicalKeySet(LogicalKeyboardKey.escape);
    shortcuts[key] = WidgetsApp.defaultShortcuts[key];
    await showDialog(
      context: context,
      builder: (BuildContext context) {
        return AlertDialog(
          title: Text("Alert Dialog"),
          content: Text("Dialog Content"),
        );
      },
    );
    shortcuts.remove(key);
  }
Related