docs: simplify the README
Trim the technical detail (state file paths, reload pipeline internals, scoring formulas) and move the combo mode GIF next to the preview image. Also fixes stale references: the bar widget section now says Filter and six placements, and the How it works table is gone.
This commit is contained in:
@@ -1,171 +1,81 @@
|
||||
# Omarchy Key Visualizer
|
||||
|
||||
A tiny [Omarchy](https://omarchy.org/) plugin that shows the keys you press
|
||||
on screen. No keycap images, no animations — just the characters and
|
||||
combinations, rendered with the shell's own styles, appearing while a key is
|
||||
held and lingering briefly after release.
|
||||
|
||||
Built for keybinding tutorials and screencasts: Omarchy is a keybinding-heavy
|
||||
desktop, so a combo like `Super + Shift + G` shows up as three small chips
|
||||
at the bottom of the screen.
|
||||
on screen — no keycap images, no fuss. Great for keybinding tutorials, demos
|
||||
and screencasts.
|
||||
|
||||
## Preview
|
||||
|
||||

|
||||
|
||||
## How it works
|
||||
|
||||
| Piece | Where it runs | What it does |
|
||||
|----------------|--------------------------------------------|--------------|
|
||||
| `key-visualizer.lua`| Hyprland Lua config (inside the compositor)| Listens to `input.keyboard.key`, tracks the pressed combo, writes it to `$XDG_RUNTIME_DIR/omarchy-key-visualizer.json` |
|
||||
| `KeyVisualizer.qml`| Quickshell `omarchy-shell` (keep-loaded panel)| Watches the state file and renders the chips |
|
||||
| `BarWidget.qml`| Quickshell bar (per monitor) | Keyboard glyph that pauses/resumes the display |
|
||||
|
||||
No background daemons, no special permissions, no extra packages: the
|
||||
compositor is already the source of truth for keys, and the shell is already
|
||||
running.
|
||||

|
||||
|
||||
## Install
|
||||
|
||||
Validate the folder first (optional but handy for plugin authors):
|
||||
|
||||
```bash
|
||||
omarchy plugin validate ./omarchy-key-visualizer
|
||||
```
|
||||
|
||||
Then add it — a local path works as well as a git URL (`plugin add` clones
|
||||
with git, and `git clone` accepts local paths):
|
||||
|
||||
```bash
|
||||
omarchy plugin add /path/to/omarchy-key-visualizer --enable
|
||||
# or once published:
|
||||
# omarchy plugin add https://github.com/YOU/omarchy-key-visualizer --enable
|
||||
```
|
||||
|
||||
`--enable` enables it right away; without it, enable later with
|
||||
`omarchy plugin enable felixzsh.key-visualizer`. The plugin is a panel and a bar
|
||||
widget: the panel shows the keys, and the bar widget is a toggle — enable
|
||||
prompts for its bar section (or pass `--section right`). If you added from a
|
||||
local path, `omarchy plugin update felixzsh.key-visualizer` pulls your local
|
||||
changes into the installed copy.
|
||||
That's it: the panel shows the keys and the keyboard glyph in the bar opens
|
||||
the menu. On first load the plugin adds a small hook to your
|
||||
`~/.config/hypr/hyprland.lua` (safe to remove) and Hyprland reloads it on
|
||||
its own — no manual steps.
|
||||
|
||||
That's the whole install: on first load the panel appends a small guarded
|
||||
block to `~/.config/hypr/hyprland.lua` that loads the capture script into
|
||||
Hyprland's Lua config, and Hyprland auto-reloads on save. Nothing else to
|
||||
do — no manual edits, no `hyprctl reload`.
|
||||
> Plugin authors: `omarchy plugin validate ./omarchy-key-visualizer` checks
|
||||
> the manifest first.
|
||||
|
||||
### Requirements
|
||||
|
||||
- Hyprland with Lua config support (0.56+), as shipped by Omarchy.
|
||||
- The plugin enabled in the shell (done above).
|
||||
**Notes**
|
||||
- If the glyph doesn't appear right after enabling, run
|
||||
`omarchy-shell shell rescanPlugins`.
|
||||
- If a deployed change seems stuck, `omarchy restart shell` loads everything
|
||||
fresh.
|
||||
|
||||
## Bar widget
|
||||
|
||||
The keyboard glyph in the bar (right section by default) opens a small
|
||||
menu, following the native bar-widget pattern:
|
||||
The keyboard glyph (right section by default) opens a small menu:
|
||||
|
||||
- **Show keys** — toggle that pauses/resumes the display (useful mid-demo).
|
||||
The glyph button itself does not toggle; the menu does.
|
||||
- **Mode** — `All keys` or `Bindings only` (only combos with a modifier).
|
||||
- **Position** — a dropdown with all nine placements (top/middle/bottom
|
||||
× left/center/right) of the screen.
|
||||
- **Linger** — a numeric field (wheel, +/− buttons, or typing) for how long
|
||||
a released combo stays, 0–10s in 500ms steps; `0` keeps the last combo on
|
||||
screen until the next key.
|
||||
- **Show keys** — pause/resume the display.
|
||||
- **Filter** — `All keys` or `Bindings only` (only combos with a modifier).
|
||||
- **Position** — six placements (top/bottom × left/center/right).
|
||||
- **Linger** — how long a released combo stays, 0–10s; `0` keeps it until
|
||||
the next key.
|
||||
- **History** — how many combos stack on screen (1–5); older ones fade.
|
||||
- **Combo mode** — turns the display into a game counter with score and
|
||||
effects (see below).
|
||||
|
||||
The menu writes the same pause flag and `config.json` that the display
|
||||
panel watches, so it stays in sync across monitors. You can also drive it
|
||||
over IPC (routed to the display panel):
|
||||
You can also drive it from the terminal:
|
||||
|
||||
```bash
|
||||
omarchy-shell key-visualizer toggle
|
||||
omarchy-shell key-visualizer pause
|
||||
omarchy-shell key-visualizer resume
|
||||
omarchy-shell key-visualizer paused # true | false
|
||||
```
|
||||
|
||||
Move the glyph with `omarchy bar move felixzsh.key-visualizer --section left`
|
||||
(or right/center).
|
||||
|
||||
### After installing: no restart needed
|
||||
|
||||
If the glyph does not appear in the bar right after `omarchy plugin enable`,
|
||||
run a plugin rescan instead of restarting the whole shell:
|
||||
|
||||
```bash
|
||||
omarchy-shell shell rescanPlugins
|
||||
```
|
||||
|
||||
The shell's enable flow persists the bar layout before it registers new
|
||||
third-party widgets (a shell-side ordering detail, not specific to this
|
||||
plugin); a rescan registers them.
|
||||
|
||||
**One caveat**: the plugin reload pipeline is debounced and can leave a
|
||||
stale component in the running shell — especially after rapid uninstall +
|
||||
reinstall cycles or editing plugin files. If a change you deployed does not
|
||||
take effect (old behavior persists), run `omarchy restart shell` once; that
|
||||
unconditionally loads everything from disk. This applies to any third-party
|
||||
plugin, not just this one.
|
||||
|
||||
## Behavior
|
||||
|
||||
- **Typing** — shows just the character: `g`, `G`, `!`, `5`.
|
||||
- **Modifier combos** — shows every modifier plus the key: `Super Shift G`,
|
||||
`Ctrl C`, `Super Enter`.
|
||||
- **Combos are a unit** — a combination stays intact no matter the order you
|
||||
release it: press `Ctrl Shift N`, let go of `Ctrl` first, then `Shift`,
|
||||
then `N`, and the display keeps showing `Ctrl Shift N` the whole time
|
||||
(keyviz shrinks key-by-key; this plugin treats the chord as one unit).
|
||||
- **Typing** — shows the character: `g`, `G`, `!`, `5`.
|
||||
- **Combos** — modifiers plus the key, shown as a unit: `Super Shift G`.
|
||||
The combination stays intact no matter the order you release it.
|
||||
- **Non-printing keys** — labeled: `Esc`, `Tab`, `F1`, arrows, `Space`.
|
||||
- Modifiers that produce the shifted character (`Shift` with a letter) are
|
||||
folded into the character itself: `Shift + 1` shows `!`.
|
||||
- Key repeat is ignored; a held key shows once.
|
||||
- After the last key is released the combo lingers briefly (1s by default,
|
||||
keyviz-style "Duration") and then vanishes in one frame — no fade. The
|
||||
lingering combo is always the last full one, never a partial release state.
|
||||
`lingerMs: 0` means "always show": the last combo stays on screen until
|
||||
the next key replaces it.
|
||||
- **History** (`historyCount`, 1–5, default 1) — the last few combos stack
|
||||
on screen instead of vanishing. Each new combo pushes the previous one
|
||||
down the stack; the current combo is fully opaque and every older entry
|
||||
fades step by step, so a `Super + G` → `Super + Shift + G` sequence shows
|
||||
both, with the older one visibly dimmer. The stack direction follows the
|
||||
position: top positions grow downward (newest on top), bottom positions
|
||||
grow upward (newest at the bottom edge) — not configurable, by design.
|
||||
With `lingerMs: 0` entries never expire, so the stack keeps the last few
|
||||
combos on screen until newer ones push them out.
|
||||
- **Combo mode** (toggle in the panel, `comboMode` in config) — turns the
|
||||
display into a game-style counter. Chords that contain a modifier
|
||||
(`Super`, `Ctrl`, `Alt`, `Shift`, `Menu`, `AltGr`) are **combos**: they
|
||||
build a combo counter, apply a multiplier (`×2` at 5, `×3` at 10, … up to
|
||||
`×8` at 50) and escalate the effects. Plain characters (and shifted chars
|
||||
typed alone, which render as the character itself) are **hits**: +10
|
||||
score only, they never touch the combo counter. Scoring:
|
||||
`hit = +10`, `combo = (20 + 15×(mods−1) + 5×(keys−1)) × multiplier`.
|
||||
The banner (`COMBO 12 ×3 · 3,450`) sits below the history for bottom
|
||||
positions and above it for top positions, with a floating `+N` pop per
|
||||
press. Effects scale with modifiers and chain length: banner pulse,
|
||||
hue shift, screen shake (up to 5px) and, at 10+ combos, continuous hue
|
||||
cycling — at 20+, a constant subtle vibration while the combo is hot.
|
||||
The combo counter resets after `comboWindowMs` (2s) without a new combo,
|
||||
and when the linger window then passes (the display clears) the **score
|
||||
resets with it**, so every run starts from zero. A chord made only of
|
||||
modifiers (`Super` alone, `Super+Ctrl+Shift`) is not a valid combo —
|
||||
modifiers of nothing — and scores zero; a valid combo always ends on a
|
||||
non-modifier key. Counted once
|
||||
per physical chord (on release), so growing key presses never double-count.
|
||||
|
||||

|
||||
- In `mode: "bindings"` only combos with a modifier are shown; plain typing
|
||||
stays off screen.
|
||||
- **Shift** is folded into the character: `Shift + 1` shows `!`.
|
||||
- After release, the combo lingers briefly (1s by default) and vanishes;
|
||||
a Linger of `0` keeps it until the next key.
|
||||
- **History** — the last few combos stack instead of vanishing, with older
|
||||
ones fading out. Top positions stack downward, bottom positions upward.
|
||||
- **Combo mode** — a game counter. Combos with modifiers score points and
|
||||
build a streak (multiplier up to ×8); plain typing scores a little too.
|
||||
The banner shows `COMBO 12 ×3 · 3,450`. The longer the streak, the bigger
|
||||
the effects: pulsing, color shifts, screen shake — and at high streaks a
|
||||
constant vibration. Stop for a moment and the streak resets; when the
|
||||
display fades away, the score resets too.
|
||||
- **Bindings only** — shows only combos with a modifier; plain typing stays
|
||||
off screen.
|
||||
|
||||
## Customize
|
||||
|
||||
Options live in `~/.config/omarchy/key-visualizer.json` (created with the
|
||||
defaults below on first run). It sits **outside** the plugin folder on
|
||||
purpose: the shell reloads all plugin code whenever any file under
|
||||
`~/.config/omarchy/plugins/` changes, so a config file there would restart
|
||||
the plugin on every edit. Editing this file updates the display live:
|
||||
Options live in `~/.config/omarchy/key-visualizer.json` and apply live:
|
||||
|
||||
```json
|
||||
{
|
||||
@@ -178,35 +88,18 @@ the plugin on every edit. Editing this file updates the display live:
|
||||
}
|
||||
```
|
||||
|
||||
| Option | Values | Default |
|
||||
|----------------|----------------------------------------------------|-----------------|
|
||||
| `mode` | `all` or `bindings` (only combos with a modifier) | `all` |
|
||||
| `position` | six placements: `top-left` … `bottom-right` (middle positions were dropped; the stack anchors to the top or bottom edge) | `bottom-center` |
|
||||
| `margin` | px from the screen edge | `67` |
|
||||
| `lingerMs` | ms a released combo stays; `0` keeps it until the next key (keyviz defaults to `5000`) | `1000` |
|
||||
| `historyCount` | how many combos stack on screen (1–5); older entries fade | `1` |
|
||||
| `comboMode` | `true`/`false` — game-style combo counter, score and effects | `false` |
|
||||
|
||||
Deeper tweaks still live in the QML/Lua sources:
|
||||
|
||||
| Want to change... | Edit |
|
||||
|-----------------------------------|-----------------------------------------|
|
||||
| Chip font / padding | `chipFont`, `chipPadX/Y` in `KeyVisualizer.qml` |
|
||||
| Key labels or layout mapping | `KEYS` / `CHARS` / `SHIFTED` tables in `key-visualizer.lua` |
|
||||
|
||||
The key tables use **US layout** keycode mapping. Letters and digits match
|
||||
most layouts; on other layouts, symbol keys (`;`, `[`, `ñ`, …) may show the
|
||||
US glyph or fall back to the key name. Dead keys and compose sequences are
|
||||
not expanded.
|
||||
|
||||
## Status
|
||||
|
||||
`omarchy-shell key-visualizer ping` — health check.
|
||||
`omarchy-shell key-visualizer state` — `open` while a combo is on screen.
|
||||
| Option | What it does | Default |
|
||||
|----------------|---------------------------------------------------|-----------------|
|
||||
| `mode` | `all` or `bindings` (only combos with a modifier) | `all` |
|
||||
| `position` | `top-left` … `bottom-right` | `bottom-center` |
|
||||
| `margin` | distance from the screen edge (px) | `67` |
|
||||
| `lingerMs` | how long a released combo stays; `0` = keep until the next key | `1000` |
|
||||
| `historyCount` | combos stacked on screen (1–5) | `1` |
|
||||
| `comboMode` | game counter, score and effects | `false` |
|
||||
|
||||
## Roadmap
|
||||
|
||||
- Layout-aware keysyms via `xkbcommon` instead of the static US table.
|
||||
- Layout-aware key symbols (`xkbcommon`) instead of the static US table.
|
||||
- Per-monitor placement.
|
||||
|
||||
## License
|
||||
|
||||
Reference in New Issue
Block a user