Skip to content
nitant.dev
Index
systemsin development2026

gkey

Vimium for the whole Windows desktop — modal keyboard-only control on a global low-level input hook.

Language
Rust
Hook
WH_KEYBOARD_LL
Modes
3
idle · normal · hint
License
MIT

My role

Sole author

Domains

Systems/Windows internals/Input

01

Context

Browsers solved keyboard-only navigation years ago. The desktop around them did not: you still reach for the mouse to click a button in a native app, and every attempt to fix it with global hotkeys collides with whatever application wanted the same chord.

02

The problem

Low-level keyboard hooks are a hostile environment. Windows silently unhooks a callback that exceeds its timeout, leaving a daemon that is running but permanently deaf. AltGr layouts inject a synthetic left Control before every right Alt, so a remapped Control misfires on every accented character. Key auto-repeat means a held key can rapid-toggle a mode. Each of these is invisible until it happens to a user.

03

What I built

The hook thread only classifies and enqueues — all real work happens on a separate engine thread, keeping the callback far below the unhook timeout. A heartbeat watchdog detects the silent removal anyway and reinstalls the hook from the hook thread. Injected input is tagged with a signature so the engine ignores its own events, and SendInput uses scancodes so bindings are keyboard-layout independent. Motion and scroll ride the OS auto-repeat for continuous movement while one-shot actions fire once per physical press, and a one-second reconciler clears stuck modifiers cross-checked against GetAsyncKeyState.

04

Outcome

Cursor drive, click and scroll, hint-mode overlays over clickable elements, key remaps, and BSP tiling with live re-tiling driven by window lifecycle events. Windows Smart App Control blocks unsigned binaries on my dev machine, so the runtime status of each milestone is documented honestly in the repository rather than assumed.

How it works

Detail
Hook watchdog
Windows removes a low-level hook whose callback overruns its timeout, and tells nobody. A heartbeat detects the silence and reinstalls from the hook thread — the difference between a daemon that degrades and one that dies quietly.
Layout-independent input
Scancode-based SendInput with a self-injection signature, plus explicit AltGr handling that swallows the synthetic LeftControl injected before RightAlt so remapped modifiers do not misfire on every accented keystroke.
Live BSP tiling
A window-event hook thread watches show, hide, destroy and minimise events and a debounced tiler re-tiles every affected monitor. Real app windows only — visible, titled, not cloaked or tool windows — with DWM shadow-frame compensation.

Built with

Rust/Win32/SendInput/SetWinEventHook