Portable shortcut deck for radiology reports — copy pre-written phrases to the clipboard without stealing focus from the RIS/PACS.
RadKeys is a companion app for radiologists. You connect a custom keypad (up to 36 buttons, wired in a 6×6 matrix) via USB, and each button inserts a pre-written report template. No keyboard shortcuts to memorize and no focus stealing from your RIS/PACS — the radiologist just presses a keypad button.
You write your report templates once in a config file. The app shows them in configurable blocks that mirror your physical keypad — split the deck into a function pad and a content pad, or any arrangement of sub-grids. Press a physical button → the phrase appears on screen → press Copy → paste into the RIS. That's it.
Works on Linux, Windows, and macOS. One executable, one config file, zero install. Everything else (icon, translations, themes) is embedded in the binary.
- Up to 36 buttons (6×6 matrix) organized in navigable screens and user-defined blocks (sub-grids)
- 13 actions: text templates, clipboard, navigation, editing keystrokes, and bash command execution
- Paste via the device's USB keyboard — no focus stealing, no host-side software
- 7 languages, 13 color themes, custom icon
- Single binary per OS (Linux + Windows; macOS builds from source)
- Split-deck layouts: define multiple blocks (e.g. 2×4 function pad + 4×7 content pad)
- One-shot firmware version check on connect (warns if outdated)
The RP2040-Zero is a composite USB device with two HID interfaces:
- Vendor HID — sends report-ID'd
[0x00, row, col]button events to the host (background, no focus stealing). The report ID makes button events and the firmware-version reply unambiguous. - HID keyboard — sends Ctrl+V (Linux/Windows) or Cmd+V (macOS) to the already-focused window when the host commands a paste.
The app is a configurator: all configuration (phrases, button actions) lives
in radkeys.config.toml. The device is flashed once at the factory and
never reflashed for configuration. Paste goes through the device's keyboard
interface, so the RIS keeps focus — the app never injects keystrokes into the
OS. At connect, the app checks the firmware version once and warns if it is
outdated or unknown. The host requires firmware v1.1+ (report-ID
protocol); older firmware cannot produce valid reports and is warned about.
Get the latest release from Releases. Each release includes:
| File | Platform |
|---|---|
radkeys-linux-amd64 |
Linux x86_64 (main app) |
radkeys-windows-amd64.exe |
Windows x86_64 (main app) |
radkeys-config-linux-amd64 |
Linux x86_64 (config editor) |
radkeys-config-windows-amd64.exe |
Windows x86_64 (config editor) |
radkeys.config.toml |
Config template (all platforms) |
macOS: binary not provided (cross-compile from Linux is impossible — needs Apple's proprietary SDK). macOS is supported in code: build from source on a Mac following the instructions below. Paste is cross-platform via the device (no per-OS keystroke injection), so macOS works the same as Linux/Windows.
Put the binary and radkeys.config.toml in the same directory and run.
Use -c to specify a different config path:
./radkeys-linux-amd64 -c ~/my-config.tomlIf the device is not found, the app runs in mock mode — the UI works via mouse clicks. If a device matching the config exists but cannot be opened (e.g. missing udev permission on Linux), the app shows a warning dialog and still starts in mock mode.
-
Edit
radkeys.config.tomlto add your phrases. The file is heavily commented — a human or LLM can read it and generate a custom config following the rules in the comments. -
Connect your USB device with the DIY keypad (RP2040-Zero).
-
Run RadKeys.
-
Press a text button → phrase appears in the preview.
-
Press Copy → phrase goes to the clipboard.
-
Press Paste → the device sends Ctrl+V (Linux/Windows) or Cmd+V (macOS) to the focused window (your RIS/PACS) as a USB keyboard. The phrase appears at the cursor position. Editing commands (select_all, select_line, line_start, line_end, backspace, delete) are also sent by the device keyboard — they go to the currently focused window without stealing focus. No host-side software is needed — the device is the keyboard. RadKeys never steals focus.
Press an
execbutton to run an arbitrary bash command (fire-and-forget, user permissions).To configure the keypad visually, use the
radkeys-configbinary instead of hand-editing the TOML file.
The radiologist never touches the keyboard.
| Dependency | Linux | Windows | macOS |
|---|---|---|---|
| Go 1.25+ | sudo apt install golang-go |
go.dev/dl | go.dev/dl |
| GCC (CGO) | sudo apt install gcc |
MinGW-w64 | xcode-select --install |
| Fyne | sudo apt install libgl1-mesa-dev xorg-dev libxxf86vm-dev |
— | — |
| HIDAPI | sudo apt install libudev-dev |
— | IOKit (system) |
# Linux
CGO_ENABLED=1 go build -tags flatpak -o dist/radkeys-linux-amd64 .
CGO_ENABLED=1 go build -tags flatpak -o dist/radkeys-config-linux-amd64 ./cmd/radkeys-config
# Windows (on Windows, or cross-compile from Linux with mingw)
CGO_ENABLED=1 GOOS=windows GOARCH=amd64 CC=x86_64-w64-mingw32-gcc go build -o dist/radkeys-windows-amd64.exe .
CGO_ENABLED=1 GOOS=windows GOARCH=amd64 CC=x86_64-w64-mingw32-gcc go build -o dist/radkeys-config-windows-amd64.exe ./cmd/radkeys-config
# macOS Intel (on a Mac — cross-compile from Linux is impossible)
CGO_ENABLED=1 go build -o dist/radkeys-macos-amd64 .
CGO_ENABLED=1 go build -o dist/radkeys-config-macos-amd64 ./cmd/radkeys-config
# macOS Apple Silicon (on a Mac)
CGO_ENABLED=1 GOARCH=arm64 go build -o dist/radkeys-macos-arm64 .
CGO_ENABLED=1 GOARCH=arm64 go build -o dist/radkeys-config-macos-arm64 ./cmd/radkeys-configsudo apt install -y gcc-mingw-w64
CGO_ENABLED=1 GOOS=windows GOARCH=amd64 CC=x86_64-w64-mingw32-gcc go build -o dist/radkeys-windows-amd64.exe .
CGO_ENABLED=1 GOOS=windows GOARCH=amd64 CC=x86_64-w64-mingw32-gcc go build -o dist/radkeys-config-windows-amd64.exe ./cmd/radkeys-configgo test ./... -vThe device enumerates as a standard composite HID device (vendor + keyboard). No host-side software is needed for paste — the device is the USB keyboard.
| Dependency | Linux | Windows | macOS |
|---|---|---|---|
| HID access (hidapi) | libudev (system, via systemd) | bundled with the binary | IOKit (system) |
| Option | Device | Keys | Cost |
|---|---|---|---|
| DIY | RP2040-Zero + push buttons + 3D case | Up to 36 | ~R$55-70 |
Firmware: firmware/rp2040-zero/
Assembly guide: BUILD.md
Bill of materials: BOM.md — links and prices across AliExpress, Mercado Livre, and Shopee
All settings live in radkeys.config.toml (TOML, plaintext, shareable).
The file is heavily commented so a human or LLM can understand and edit
everything:
- Radiologist name, language (7 options), color theme (13 presets)
- Device VID/PID and protocol
- Keypad layout: an ordered list of blocks (sub-grids) whose cells consume
firmware slots 0–35 (
n = row×6 + col) — split the deck into physical groups like a 2×4 function pad plus a 4×6 content pad - Screens and buttons (phrases organized in a hierarchy)
Use the radkeys-config binary (included in each release) to edit the config
visually — never touch TOML syntax. The editor shows every block with its
slot numbers on the keys, lets you add/remove blocks, layers and buttons,
and validates everything before saving.
You can also edit the TOML file directly with any text editor.
Note: saving the config strips comments (BurntSushi/toml limitation). The
save is atomic and keeps two backup generations — the previous save at
radkeys.config.toml.bak and the one before it at .bak2 — so your
commented original always survives.
See AGENTS.md for AI agent rules, the dev cycle (test → tag →
CI publishes the release notes → agent uploads the locally-built binaries),
and project conventions.
RadKeys is distributed under the RadKeys Source-Available License v1.0 (LICENSE).
The hardware design, firmware, and host software are free for personal, educational, and hobby use. You may modify, share, and repair freely, as long as the use is non-commercial. Any commercial use requires a separate written license — see COMMERCIAL-LICENSE.md or email galvani4987@gmail.com.
