Key Extension Architecture Technical Guide
Technical architecture documentation covering the deterministic 4-State FSM engine, scaling timers, suppression-first snippet model, and atomic output pipelines in fjFlow.
Deterministic 4-State FSM, race condition prevention, 0ms remapping, and suppression-first snippet expansion architecture
This document details the engineering architecture behind fjFlow’s Key Extension engine, including its state machine, scaling timer algorithms, suppression-first snippet expansion, and output pipeline.
Table of Contents
- 1. Core Philosophy: Strict Decoupling of Detection and Execution
- 2. Deterministic 4-State FSM Model
- 3. Variable-Length Sequences (Up to 5 Keystrokes) & Scaling Timer
- 4. Snippet Expansion Advantages: Suppression-First Model
- 5. Instant 0ms Remapping via Silence Bypass
- 6. Smart Coexistence of Intermediate Matches and Longest Prefix
- 7. Safe Combo Cancellation via Shift Key
- 8. Race Condition Elimination via Serialized Low-Level Hooks
1. Core Philosophy: Strict Decoupling of Detection and Execution
The key extension engine strictly separates the Detection Phase from the Output Phase.
┌────────────────────────────────────────────────────────┐
│ 1. Detection Phase (FSM Engine) │
│ - Receives raw physical keystrokes & timestamps │
│ - Isolates real-time modifier/layer variations │
│ - Captures down-state layer snapshot (downCond) │
│ - Evaluates exact match, prefix match & silence │
└──────────────────────────┬─────────────────────────────┘
│ Commit (Execute / Flush)
┌──────────────────────────▼─────────────────────────────┐
│ 2. Output Phase (Output Pipeline) │
│ - Executes target mapping using preserved snapshot │
│ - Applies synthetic modifier locks (Ctrl/Alt/Win/Shift)│
│ - Sends atomic OS keystrokes via {Blind} mode │
└────────────────────────────────────────────────────────┘
Even if a user releases the modifier trigger (Space) immediately after striking a key, execution evaluates against the press-down snapshot (g_FsmKey1Cond), preventing modifier release errors.
2. Deterministic 4-State FSM Model
The engine operates on a 4-state deterministic state machine:
STATE_READY: Idle state. No keystrokes pending in queue.STATE_WAIT_HOLD: Hold detection state (waiting after pre-silence to see if key remains held).STATE_WAIT_NEXT: Next key / tap detection state (first key withheld, awaiting subsequent strokes or timeout).STATE_WAIT_POST_SILENCE: Post-silence wait state (longest match reached, awaiting brief pause to confirm intention).
stateDiagram-v2
[*] --> STATE_READY
state STATE_READY {
[*] --> Idle
}
STATE_READY --> STATE_READY : 1. [a] (Instant tap)<br/>0ms immediate remap
STATE_READY --> STATE_READY : 2. Active typing (no pre-silence)<br/>Normal pass-through
STATE_READY --> STATE_WAIT_HOLD : 3. Pre-silence + < a > (hold defined)<br/>Hold timer started (holdMs)
STATE_READY --> STATE_WAIT_NEXT : 4. Pre-silence + [a] (tap) / Sequence<br/>Withhold 1st stroke (comboMs)
state STATE_WAIT_HOLD {
[*] --> HoldWaiting
}
STATE_WAIT_HOLD --> STATE_READY : 5. holdMs elapsed (held down)<br/>Execute hold target
STATE_WAIT_HOLD --> STATE_READY : 6. KeyUp before holdMs (released)<br/>Cancel hold ➔ tap fallback
STATE_WAIT_HOLD --> STATE_READY : 7. Other key struck before holdMs<br/>Instant cancel ➔ flush pending
state STATE_WAIT_NEXT {
[*] --> Pending
}
STATE_WAIT_NEXT --> STATE_WAIT_NEXT : 8. Prefix matched (e.g., 'us' in 'usa')<br/>Withhold next key (Timer: Nx ms)
STATE_WAIT_NEXT --> STATE_WAIT_POST_SILENCE : 9. Longest exact match (e.g., 'usa')<br/>Wait for post-silence (Nx ms)
STATE_WAIT_NEXT --> STATE_READY : 10. Timeout reached<br/>Execute intermediate match
STATE_WAIT_NEXT --> STATE_READY : 11. No match / expired<br/>Flush pending keys in order
state STATE_WAIT_POST_SILENCE {
[*] --> PostSilenceWait
}
STATE_WAIT_POST_SILENCE --> STATE_READY : 12. Post-silence confirmed (pause)<br/>Execute target snippet!
STATE_WAIT_POST_SILENCE --> STATE_READY : 13. Rapid subsequent key struck<br/>Break combo ➔ flush raw strokes
STATE_WAIT_HOLD --> STATE_READY : 14. Shift Up<br/>Flush raw lowercase characters
STATE_WAIT_NEXT --> STATE_READY : 14. Shift Up<br/>Flush raw lowercase characters
STATE_WAIT_POST_SILENCE --> STATE_READY : 14. Shift Up<br/>Flush raw lowercase characters
3. Variable-Length Sequences (Up to 5 Keystrokes) & Scaling Timer
Detection wait times scale dynamically with sequence length $N$ (up to 5 keystrokes):
$$\text{Detection Window} = N \times x \text{ (ms)}$$
- With base interval $x = 300\text{ms}$:
- 1 Key: $300\text{ms}$ (single tap evaluation)
- 2 Keys: $600\text{ms}$ (e.g.,
hh,eq) - 3 Keys: $900\text{ms}$ (e.g.,
usa,btw) - 4 Keys: $1200\text{ms}$ (e.g.,
date,mail) - 5 Keys: $1500\text{ms}$ (e.g.,
azasu,yoros)
- Longer sequences automatically grant a wider, relaxed typing window for confident input without rush.
4. Snippet Expansion Advantages: Suppression-First Model
4.1 Structural Flaws of Traditional “Post-hoc Delete” Snippet Tools
Traditional text expansion tools almost exclusively rely on a “Post-hoc Delete” sequence: the abbreviation is printed on screen, a series of synthetic Backspace strokes erases it, and the expanded string is pasted.
In multi-lingual or East Asian IME environments, this model suffers from 3 fatal flaws:
- Divergence of Key Count and Character Count:
In English, typing
btw(3 keys) produces 3 characters, erased cleanly by 3 Backspaces. In Japanese Romaji IME, typinga-z-a-s-u(5 keys) produces only 3 characters (あ・ざ・す). Tools cannot reliably query rendered character counts from Windows or IMEs, causing excess Backspaces that accidentally destroy existing, valuable text. - Collision with Active Inline IME Composition: Sending Backspaces during uncommitted IME composition closes suggestion candidates, breaks phrase segments, and corrupts the input queue.
- Screen Flicker and Visual Noise: The cycle of “Render ➔ Backspace Erase ➔ Insert” creates perceptible visual flicker and layout stuttering.
4.2 fjFlow’s Suppression-First & Deferred Execution Model
The fjFlow key extension engine does not draw keys on screen and delete them later. Instead, keystrokes are withheld (suppressed) in memory during evaluation. Once the sequence matches, the target text is injected cleanly without sending a single Backspace. If unmatched, pending keys flush instantly in exact sequence.
| Evaluation Metric | Traditional Snippet Tools | fjFlow Sequence Combos (Up to 5 Keys) |
|---|---|---|
| Existing Text Safety | High risk of over-deletion (Destructive) | 100% Non-destructive (Zero Backspaces sent) |
| IME Mode Independence | Behavior breaks depending on IME state | Completely transparent via physical key hook |
| Visual Ergonomics (UX) | Visible flicker (Type ➔ Erase ➔ Insert) | Zero flicker; target string appears cleanly |
| Cancellation Safety | Difficult to revert accidental triggers | Tap Shift once to cancel and flush raw characters |
4.3 The Paradigm Shift of Expanding to 5 Keystrokes
Extending sequence combos from 2 keys to 5 keys unlocks an entirely new domain of productivity:
- 2-Key Domain (Symbols & Quick Shortcuts):
eq➔=,pt➔(),br➔[],s;➔ Center window. Designed to access punctuation and window commands without lifting hands from home row. - 3 to 5-Key Domain (Natural Language Snippets & Boilerplates):
- English Abbreviations:
btw(by the way),omw(on my way),afaik(as far as I know) - Japanese Greetings:
azasu(ありがとうございます),otk(お疲れ様です),yoros(よろしくお願いいたします) - System & Contact:
mail1(Email address),tel1(Phone number),date(Today’s date)
- English Abbreviations:
Over 90% of intuitive human mnemonic abbreviations and consonant contractions fit within 3 to 5 keystrokes. With 5-keystroke support, fjFlow transcends simple keyboard remapping to become a reliable, non-destructive snippet engine for multi-lingual desktop environments.
5. Instant 0ms Remapping via Silence Bypass
Enclosing trigger keys in brackets ([]) completely bypasses pre- and post-silence detection:
- Single Tap
[a]: Executed with 0ms latency the moment the key is struck, replacing it immediately (pure key remap). - Sequence
[ca]: Committed immediately upon striking the final keya, bypassing post-silence wait times.
6. Smart Coexistence of Intermediate Matches and Longest Prefix
When both us ➔ _ (2 keys) and usa ➔ United States (3 keys) are registered:
- Striking
u➔sidentifies_as a candidate match while detecting thatusaremains a valid prefix. - The FSM holds state
STATE_WAIT_NEXTand preserves_as an intermediate target while the timer runs. - If
aarrives, it transitions tousaand commitsUnited States. - If the timer expires without further input, it commits the intermediate candidate
_. - If an unrelated key arrives, it flushes all pending keystrokes in raw order.
7. Safe Combo Cancellation via Shift Key
To safely cancel a pending sequence and output raw letters:
- Press the
Shiftkey during combo evaluation. FsmOnShiftDown()triggers and immediately halts all pending timers without outputting text.- Release the
Shiftkey.FsmFlushOnShiftUp()flushes all buffered keys (u,s,a) in safe lowercase form.
8. Race Condition Elimination via Serialized Low-Level Hooks
To prevent keystroke order inversion (sh ➔ hs) during fast typing:
- All mapping trigger keys are registered under the default layer (L0) as serialized
$keyhooks. - Because all keystrokes pass sequentially through the single FSM pipeline, race conditions between OS native dispatch and hook dispatch are structurally eliminated.