Skip to content

KeyDetector

Low-level key handling inside a widget: sees each key that reaches its subtree and consumes only the ones it handles.

See also: KeyBindings for declared, labeled shortcuts.

Learn more: Key handling

Import: package:fleury/fleury.dart, or package:fleury/fleury_core.dart in browser code.

KeyDetector(
onKey: (event) {
if (event.code == KeyCode.arrowDown && cursor < rows.length - 1) {
setState(() => cursor++);
event.consume(); // handled inside the pane
}
// At the last row the arrow is not consumed, so it reaches the
// ancestors' key bindings.
},
child: Focus(child: pane),
)

Keys propagate unless consumed — the reverse of a key binding, which consumes the key it matches. A detector observes by default, so a key it forgets to consume does visible double duty while you test it, instead of silently starving an ancestor’s shortcut.

Prefer KeyBindings for app shortcuts. Bindings are data the framework can read: the hint bar, which-key, and devtools list them, and none of them can read a closure. Use a detector when the handling belongs inside a reusable control, such as a scroll region or a terminal pane that forwards raw keys.

A detector is active while focus is within its subtree and is matched deepest-first, like a binding scope. It is not a focus node: adding one never changes traversal, so wrap the focusable part in Focus yourself. It sees key presses and repeats, never releases.

ParameterTypeDefaultDescription
onKey:void Function(KeyEvent event)requiredCalled for each key event routed through this subtree. Consume with KeyEvent.consume; do nothing to let it continue.
child:WidgetrequiredThe subtree whose keys onKey sees. The detector only fires while this subtree holds focus — it is scoped, not ambient.

KeyDetector is defined in packages/fleury/lib/src/widgets/keyboard.dart.

Category: Input handling & focus · All widgets