HardwareKeyboard class

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.

See also:

Constructors

HardwareKeyboard()

Properties

hashCode int
The hash code for this object.
no setterinherited
isAltPressed bool
Returns true if a logical ALT modifier key is pressed, regardless of which side of the keyboard it is on.
no setter
isControlPressed bool
Returns true if a logical CTRL modifier key is pressed, regardless of which side of the keyboard it is on.
no setter
isMetaPressed bool
Returns true if a logical META modifier key is pressed, regardless of which side of the keyboard it is on.
no setter
isShiftPressed bool
Returns true if a logical SHIFT modifier key is pressed, regardless of which side of the keyboard it is on.
no setter
lockModesEnabled Set<KeyboardLockMode>
The set of KeyboardLockMode that are enabled.
no setter
logicalKeysPressed Set<LogicalKeyboardKey>
The set of LogicalKeyboardKeys that are pressed.
no setter
physicalKeysPressed Set<PhysicalKeyboardKey>
The set of PhysicalKeyboardKeys that are pressed.
no setter
runtimeType Type
A representation of the runtime type of the object.
no setterinherited

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.
handleKeyEvent(KeyEvent event) bool
Process a new KeyEvent by recording the state changes and dispatching to handlers.
isLogicalKeyPressed(LogicalKeyboardKey key) bool
Returns true if the given LogicalKeyboardKey is pressed, according to the HardwareKeyboard.
isPhysicalKeyPressed(PhysicalKeyboardKey key) bool
Returns true if the given PhysicalKeyboardKey is pressed, according to the HardwareKeyboard.
lookUpLayout(PhysicalKeyboardKey physicalKey) LogicalKeyboardKey?
Returns the logical key that corresponds to the given pressed physical key.
noSuchMethod(Invocation invocation) → dynamic
Invoked when a nonexistent method or property is accessed.
inherited
removeHandler(KeyEventCallback handler) → void
Stop calling the given listener every time a hardware key event occurs.
syncKeyboardState() Future<void>
Query the engine and update _pressedKeys accordingly to the engine answer. Both the framework and the engine maintain a state of the current pressed keys. There are edge cases, related to startup and restart, where the framework needs to resynchronize its keyboard state.
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.
no setter