HardwareKeyboard class Null safety
Manages key events from hardware keyboards.
HardwareKeyboard manages all key events of the Flutter application from hardware keyboards (in contrast to on-screen keyboards). It receives key data from the native platform, dispatches key events to registered handlers, and records the keyboard state.
To stay notified whenever keys are pressed, held, or released, add a
handler with addHandler. To only be notified when a specific part of the
app is focused, use a Focus widget's onFocusChanged
attribute instead
of addHandler. Handlers should be removed with removeHandler when
notification is no longer necessary, or when the handler is being disposed.
To query whether a key is being held, or a lock mode is enabled, use physicalKeysPressed, logicalKeysPressed, or lockModesEnabled. These states will have been updated with the event when used during a key event handler.
The singleton HardwareKeyboard instance is held by the ServicesBinding as ServicesBinding.keyboard, and can be conveniently accessed using the HardwareKeyboard.instance static accessor.
Event model
Flutter uses a universal event model (KeyEvent) and key options (LogicalKeyboardKey and PhysicalKeyboardKey) regardless of the native platform, while preserving platform-specific features as much as possible.
HardwareKeyboard guarantees that the key model is "regularized": The key event stream consists of "key tap sequences", where a key tap sequence is defined as one KeyDownEvent, zero or more KeyRepeatEvents, and one KeyUpEvent in order, all with the same physical key and logical key.
Example:
- Tap and hold key A, US layout:
- KeyDownEvent(physicalKey: keyA, logicalKey: keyA, character: "a")
- KeyRepeatEvent(physicalKey: keyA, logicalKey: keyA, character: "a")
- KeyUpEvent(physicalKey: keyA, logicalKey: keyA)
- Press ShiftLeft, tap key A, then release ShiftLeft, US layout:
- KeyDownEvent(physicalKey: shiftLeft, logicalKey: shiftLeft)
- KeyDownEvent(physicalKey: keyA, logicalKey: keyA, character: "A")
- KeyRepeatEvent(physicalKey: keyA, logicalKey: keyA, character: "A")
- KeyUpEvent(physicalKey: keyA, logicalKey: keyA)
- KeyUpEvent(physicalKey: shiftLeft, logicalKey: shiftLeft)
- Tap key Q, French layout:
- KeyDownEvent(physicalKey: keyA, logicalKey: keyQ, character: "q")
- KeyUpEvent(physicalKey: keyA, logicalKey: keyQ)
- Tap CapsLock:
- KeyDownEvent(physicalKey: capsLock, logicalKey: capsLock)
- KeyUpEvent(physicalKey: capsLock, logicalKey: capsLock)
When the Flutter application starts, all keys are released, and all lock modes are disabled. Upon key events, HardwareKeyboard will update its states, then dispatch callbacks: KeyDownEvents and KeyUpEvents set or reset the pressing state, while KeyDownEvents also toggle lock modes.
Flutter will try to synchronize with the ground truth of keyboard states using synthesized events (KeyEvent.synthesized), subject to the availability of the platform. The desynchronization can be caused by non-empty initial state or a change in the focused window or application. For example, if CapsLock is enabled when the application starts, then immediately before the first key event, a synthesized KeyDownEvent and KeyUpEvent of CapsLock will be dispatched.
The resulting event stream does not map one-to-one to the native key event stream. Some native events might be skipped, while some events might be synthesized and do not correspond to native events. Synthesized events will be indicated by KeyEvent.synthesized.
Example:
- Flutter starts with CapsLock on, the first press of keyA:
- KeyDownEvent(physicalKey: capsLock, logicalKey: capsLock, synthesized: true)
- KeyUpEvent(physicalKey: capsLock, logicalKey: capsLock, synthesized: true)
- KeyDownEvent(physicalKey: keyA, logicalKey: keyA, character: "a")
- While holding ShiftLeft, lose window focus, release shiftLeft, then focus
back and press keyA:
- KeyUpEvent(physicalKey: shiftLeft, logicalKey: shiftLeft, synthesized: true)
- KeyDownEvent(physicalKey: keyA, logicalKey: keyA, character: "a")
Flutter does not distinguish between multiple keyboards. Flutter will process all events as if they come from a single keyboard, and try to resolve any conflicts and provide a regularized key event stream, which can deviate from the ground truth.
Compared to RawKeyboard
RawKeyboard is the legacy API, and will be deprecated and removed in the future. It is recommended to always use HardwareKeyboard and KeyEvent APIs (such as FocusNode.onKeyEvent) to handle key events.
Behavior-wise, RawKeyboard provides a less unified, less regular event model than HardwareKeyboard. For example:
- Down events might not be matched with an up event, and vice versa (the set of pressed keys is silently updated).
- The logical key of the down event might not be the same as that of the up event.
- Down events and repeat events are not easily distinguishable (must be tracked manually).
- Lock modes (such as CapsLock) only have their "enabled" state recorded. There's no way to acquire their pressing state.
See also:
- KeyDownEvent, KeyRepeatEvent, and KeyUpEvent, the classes used to describe specific key events.
- instance, the singleton instance of this class.
- RawKeyboard, the legacy API that dispatches key events containing raw system data.
Constructors
Properties
- hashCode → int
-
The hash code for this object.
read-onlyinherited
-
lockModesEnabled
→ Set<
KeyboardLockMode> -
The set of
KeyboardLockMode
that are enabled.read-only -
logicalKeysPressed
→ Set<
LogicalKeyboardKey> -
The set of
LogicalKeyboardKey
s that are pressed.read-only -
physicalKeysPressed
→ Set<
PhysicalKeyboardKey> -
The set of
PhysicalKeyboardKey
s that are pressed.read-only - runtimeType → Type
-
A representation of the runtime type of the object.
read-onlyinherited
Methods
-
addHandler(
KeyEventCallback handler) → void - Register a listener that is called every time a hardware key event occurs.
-
clearState(
) → void -
Clear all keyboard states and additional handlers.
visibleForTesting">@visibleForTesting
-
handleKeyEvent(
KeyEvent event) → bool - Process a new KeyEvent by recording the state changes and dispatching to handlers.
-
lookUpLayout(
PhysicalKeyboardKey physicalKey) → LogicalKeyboardKey? - Returns the logical key that corresponds to the given pressed physical key.
-
noSuchMethod(
Invocation invocation) → dynamic -
Invoked when a non-existent method or property is accessed.
inherited
-
removeHandler(
KeyEventCallback handler) → void - Stop calling the given listener every time a hardware key event occurs.
-
toString(
) → String -
A string representation of this object.
inherited
Operators
-
operator ==(
Object other) → bool -
The equality operator.
inherited
Static Properties
- instance → HardwareKeyboard
-
Provides convenient access to the current HardwareKeyboard singleton from
the ServicesBinding instance.
read-only