A Rust-based macOS keyboard-only mouse navigation utility. Control your cursor entirely from the keyboard — no trackpad, no mouse required. Inspired by warpd and mouseless.
output.mp4
Status: Active development | macOS 13+ | Requires Accessibility permission
Downloads and installs the latest pre-built binary for your architecture:
curl -fsSL https://raw.githubusercontent.com/unitf90/keytogo/main/install.sh | shGrab the latest archive from the Releases page:
| Architecture | File |
|---|---|
| Apple Silicon | keytogo-aarch64-apple-darwin.tar.gz |
| Intel | keytogo-x86_64-apple-darwin.tar.gz |
tar -xzf keytogo-*.tar.gz
sudo mv keytogo /usr/local/bin/Requires the Rust toolchain (rustup.rs):
cargo install --git https://github.com/unitf90/keytogokeytogo intercepts keyboard events system-wide via the macOS CGEventTap API, which requires explicit user consent:
- Open System Settings → Privacy & Security → Accessibility
- Click the lock and authenticate
- Add or enable
keytogoin the list
Without this permission the event tap cannot start. You will be prompted on first launch.
Install a per-user LaunchAgent so keytogo starts automatically at login:
keytogo --installTo remove it:
keytogo --uninstallOr run once in the foreground without installing as a daemon:
keytogokeytogo uses a three-stage keyboard navigation model to place the cursor anywhere on screen without moving your hands.
Press the activation chord from any context:
Right-Cmd + Space
A full-screen overlay appears. Press Escape at any time to return to Idle.
The screen is divided into a grid of labeled cells, each identified by a single key. The layout is configurable (see Configuration); the default covers the full screen with your keyboard home rows.
Press a key to select a macro cell and highlight it. The overlay updates to show which sub-cells are available inside it.
Backspace — return to Idle (dismiss overlay).
After the macro key, press a second key to zoom into one of the sub-cells within the selected macro region. The cursor moves to the center of the selected sub-cell and the subcell precision grid appears.
Backspace — return to Stage 1 (clear macro selection, pick a different macro cell).
Escape — return to Idle.
A fine-grained grid fills the selected region. Press a key to place the cursor at that exact position and fire a click.
Backspace — return to Stage 2 (keep your macro key, re-pick the sub-cell).
Escape — return to Stage 1.
Apply modifier keys at the final keypress to change what happens on landing:
| Modifier | Action |
|---|---|
| (none) | Left click |
| Shift | Right click |
| Ctrl | Middle click |
| Option | Move cursor only (no click) |
| Option + Shift | Drag from activation point to selected position |
Press the same subcell key again within the click window (default 250 ms) to upgrade the click:
- 2nd press → double-click
- 3rd press → triple-click
Press Tab from the macro grid to enter Scroll mode. A HUD appears showing available keys.
| Key | Action |
|---|---|
j |
Scroll down |
k |
Scroll up |
h |
Scroll left |
l |
Scroll right |
d |
Half-page down |
u |
Half-page up |
Shift + any direction |
Fast scroll (3× speed) |
Space |
Hold left button (for drag-scrolling) |
Option + Space |
Hold right button |
Tab |
Return to grid |
Escape |
Exit to Idle |
| Action | Key |
|---|---|
| Activate | Right-Cmd + Space |
| Back one stage | Backspace |
| Cancel to Idle | Escape |
| Enter Scroll mode | Tab (from grid overlay) |
| Exit Scroll mode | Escape or Tab |
| Double / triple click | Repeat subcell key within window |
| Drag to position | Option + Shift + subcell key |
| Move cursor only | Option + subcell key |
The status bar icon provides quick access to:
- Pause / Resume — disable keytogo temporarily without stopping the daemon; all keys pass through normally while paused
- Launch at Login — toggle the LaunchAgent
- Quit
All configuration is optional — the defaults work out of the box. To generate a config file with all options pre-filled:
keytogo --init-configThis writes ~/.config/keytogo/config.toml. Edit it, then restart keytogo (or run keytogo --stop && keytogo --start).
For the full reference see docs/config.md.
The three grids are fully configurable. Each is a multiline string where each line is a keyboard row; spaces are ignored and can be used for visual alignment. Row lengths must all match within a grid.
[layout]
# Stage 1 — macro grid (rows × cols inferred from the string)
macro_keys = """
qwer
asdf
zxcv
yuio
hjkl
nm,.
"""
# Stage 2 — sub-cell grid
# Omit this key entirely to let keytogo compute square sub-cells automatically
# based on your screen's aspect ratio.
sub_keys = """
ertyuio
dfghjkl
cvbnm,.
"""
# Stage 3 — precision subcell grid
subcell_keys = """
ertyui
dfghjk
xcvbnm
"""[scroll]
line_px = 60 # pixels scrolled per j/k/h/l press
half_page_lines = 10 # lines for d/u half-page commands[hud]
# Anchor point for the scroll mode HUD pill.
# bottom-center | bottom-left | bottom-right | top-center | top-left | top-right
position = "bottom-center"
margin_x = 0.0 # horizontal offset from the edge (ignored for *-center)
margin_y = 64.0 # vertical offset from the screen edge[subcell]
tap_window_ms = 250 # max ms between presses to count as double/triple click- macOS 13 Ventura or later
- Accessibility permission (prompted on first launch)
- Rust toolchain (build from source only)
- Configuration reference — all config keys, types, defaults, examples
- Testing — test coverage, CLI flags, running tests