keyMessageHandler property Null safety

KeyMessageHandler? keyMessageHandler
read / write

The global entrance which handles all key events sent to Flutter.

Typical applications use WidgetsBinding, where this field is set by the focus system (see FocusManger) on startup to a function that dispatches incoming events to the focus system, including FocusNode.onKey, FocusNode.onKeyEvent, and Shortcuts. In this case, the application does not need to read, assign, or invoke this value.

For advanced uses, the application can "patch" this callback. See below for details.

Handlers and event results

Roughly speaking, Flutter processes each native key event with the following phases:

  1. Platform-side pre-filtering, sometimes used for IME.
  2. The key event system.
  3. The text input system.
  4. Other native components (possibly non-Flutter).

Each phase will conclude with a boolean called an "event result". If the result is true, this phase handles the event and prevents the event from being propagated to the next phase. This mechanism allows shortcuts such as "Ctrl-C" to not generate a text "C" in the text field, or shortcuts that are not handled by any components to trigger special alerts (such as the "bonk" noise on macOS).

In the second phase, known as "the key event system", the event is dispatched to several destinations: RawKeyboard's listeners, HardwareKeyboard's handlers, and keyMessageHandler. All destinations will always receive the event regardless of the handlers' results. If any handler's result is true, then the overall result of the second phase is true, and event propagation is stopped.

See also:

Advanced usages: Manual assignment or patching

If you are not using the focus system to manage focus, set this attribute to a KeyMessageHandler that returns true if the propagation on the platform should not be continued. If this field is null, key events will be assumed to not have been handled by Flutter, a result of "false".

Even if you are using the focus system, you might also want to do more than the focus system allows. In these cases, you can patch keyMessageHandler by setting it to a callback that performs your tasks and calls the original callback in between (or not at all.)

Patching keyMessageHandler can not be reverted. You should always assume that another component might haved patched it before you and after you. This means that you might want to write your own global notification manager, to which callbacks can be added and removed.

You should not patch keyMessageHandler until the FocusManager has assigned its callback. This is assured during any time within the widget lifecycle (such as initState), or after calling WidgetManager.instance.

This example shows how to process key events that are not handled by any focus handler (such as Shortcuts) by patching keyMessageHandler.

The app prints out any key events that are not handled by the app body. Try typing something in the first text field. These key presses are not handled by Shorcuts and will be sent to the fallback handler and printed out. Now try some text shortcuts, such as Ctrl+A. The KeyA press is handled as a shortcut, and is not sent to the fallback handler and so is not printed out.

The key widget is FallbackKeyEventRegistrar, a necessity class to allow reversible patching. FallbackFocus and FallbackFocusNode are also useful to recognize the widget tree's structure. FallbackDemo is an example of using them in an app.

To create a local project with this code sample, run:
flutter create --sample=services.KeyEventManager.keyMessageHandler.1 mysample

See also:

Implementation

KeyMessageHandler? keyMessageHandler;