1

I'm writing a Flutter app targeted towards macOS and want to be able to show a modal dialog that allows navigation within that dialog (somewhat like a sequence of onboarding screens).

In order to facilitate the navigation within the dialog, I need to wrap my widgets in a navigator of some sort. See the following (simplified) code:

showDialog(
  context: context,
  builder: (context) => Dialog(
    child: SizedBox(
      width: 400,
      height: 400,
      child: Navigator(
        onGenerateRoute: (_) => MaterialPageRoute(
          builder: (_) => const Center(child: Text('hi there'))
        ),
      ),
    ),
  ),
);

Now this works perfectly - except for dismissal. I can dismiss the dialog by tapping in the barrier area (which is good), however, pressing ESC on the keyboard doesn't dismiss the dialog.

If I just embed the child directly (without the navigator), pressing ESC dismisses the dialog perfectly. But for some reason, it looks like Navigator is swallowing the ESC key. I've also tried using MaterialApp as the navigator and it also eats the ESC key.

Any theories on how I can get the navigator to let me dismiss the dialog using the ESC key? Thanks

Craig Edwards
  • 2,118
  • 1
  • 18
  • 23

1 Answers1

1

You can use a RawKeyboardListener to listen to keypresses, and pop when an ESC event fired.

Old response that didn't work: Try wrapping the widget inside the page route (in this case, the Center) with a WillPopScope. You should be able to receive the ESC event on the onWillPop callback before the inner Navigator receives it, then you can call pop on the outer Navigator to dismiss the dialog.

caiopo
  • 454
  • 2
  • 8
  • That's a neat idea, but sadly `onWillPop()` doesn't get called (either when you press ESC or if the dialog gets dismissed by clicking on the barrier) – Craig Edwards Aug 12 '21 at 05:25
  • One other idea is to use a RawKeyboardListener to listen to keypresses, and pop when an ESC event fired. – caiopo Aug 12 '21 at 17:59