Input Event Dispatcher
Relevant source files
The following files were used as context for generating this wiki page:
- app/src/main/kotlin/dev/patrickgold/florisboard/ime/input/InputEventDispatcher.kt
- app/src/main/kotlin/dev/patrickgold/florisboard/ime/keyboard/KeyboardManager.kt
- app/src/main/kotlin/dev/patrickgold/florisboard/FlorisImeService.kt
- app/src/main/kotlin/dev/patrickgold/florisboard/ime/editor/AbstractEditorInstance.kt
- app/src/main/kotlin/dev/patrickgold/florisboard/ime/keyboard/KeyData.kt
The Input Event Dispatcher is a central component in the Ownkey Keyboard (FlorisBoard derivative) architecture responsible for capturing, processing, and routing raw hardware and software key events. It manages low-level timing logic such as long-press detection and key repetition, ensuring that user interactions are translated into meaningful actions within the Input Method Editor (IME).
The dispatcher acts as an intermediary between raw view events (from the keyboard layout) and the high-level logic managed by the KeyboardManager. It ensures thread-safe tracking of pressed keys and handles complex input sequences, such as double-taps for Shift/Caps Lock behavior.
Core Architecture and Data Flow
The InputEventDispatcher utilizes a reactive approach to event management, leveraging Kotlin Coroutines for asynchronous timing tasks.
Architecture Components
- InputEventDispatcher: The primary engine that tracks
pressedKeysusing aSparseArrayCompatofPressedKeyInfo. It manages coroutine jobs for long-press and repeat delays. - InputKeyEventReceiver: An interface implemented by
KeyboardManagerto receive processed events (onInputKeyDown,onInputKeyUp,onInputKeyRepeat,onInputKeyCancel). - PressedKeyInfo: A data structure that stores the initial event time and the active coroutine job for a specific key code.
Event Propagation Flow
The diagram above illustrates how raw events are intercepted by the dispatcher, which then manages asynchronous timers before notifying the receiver.
Sources: InputEventDispatcher.kt:33-54, KeyboardManager.kt:98-111
Timing and Threshold Logic
The dispatcher implements specific timing behaviors based on user preferences and the nature of the key being pressed.
Key Delay Modifiers
The time required to trigger a long-press or a repeat event is not uniform across all keys. The dispatcher applies factors to the base longPressDelay configured in the application preferences.
| Key Category / Code | Long-press Delay Factor | Repeat Delay Factor |
|---|---|---|
| Space / Shift | 2.5x | 1.0x |
| Language Switch | 2.0x | 1.0x |
| Delete Word / Undo / Redo | 1.0x | 5.0x |
| Default Keys | 1.0x | 1.0x |
Sources: InputEventDispatcher.kt:56-72
Long-press and Repeat Handling
When sendDown is called, a coroutine job is launched that performs the following sequence:
- Delay: Waits for the calculated long-press duration.
- Long-press Trigger: Executes the
onLongPresscallback. If it returns true, the subsequent "up" event is blocked. - Repetition Loop: If the key is in the
repeatableKeyCodeslist, it enters awhile(isActive)loop, triggeringonInputKeyRepeatat intervals defined by the repeat delay.
Sources: InputEventDispatcher.kt:85-115
Integration with KeyboardManager
The KeyboardManager implements the InputKeyEventReceiver interface and serves as the primary consumer of the dispatcher's output. It translates specific KeyCode values into editor actions.
Key Event Handling Map
The implementation of onInputKeyUp in KeyboardManager routes key codes to their respective logic:
| Key Code | Logic Executed |
|---|---|
KeyCode.DELETE | Calls handleBackwardDelete(OperationUnit.CHARACTERS) |
KeyCode.SHIFT | Calls handleShiftUp(data) |
KeyCode.SPACE | Calls handleSpace(data) |
KeyCode.ENTER | Calls handleEnter() |
KeyCode.SETTINGS | Launches the settings activity via FlorisImeService |
Sources: KeyboardManager.kt:625-750
Hardware Keyboard Integration
Hardware events are captured by FlorisImeService and passed to the dispatcher via KeyboardManager. This ensures that physical keyboards respect the same shift state and repetition logic as the soft keyboard.
State Management
The dispatcher provides utility functions to query the current state of physical or virtual keys, which is critical for complex UI logic like manual text selection.
isPressed(code): Checks if a specific key code is currently in thepressedKeysarray.isConsecutiveDown(data): Determines if a "down" event occurred within the system'sDoubleTapTimeout, used to detect rapid multi-taps for Caps Lock.isUninterruptedEventSequence(data): Verifies if the last "down" event matches the current key, ensuring that intervening key presses didn't break the sequence.
Sources: InputEventDispatcher.kt:156-175
Conclusion
The Input Event Dispatcher provides the robust foundation necessary for high-performance typing in the Ownkey Keyboard. By abstracting coroutine-based timing and key-tracking logic away from the high-level IME service, it allows for consistent behavior across various input modes while maintaining the responsiveness required for professional-grade text entry.