diff options
| author | Danilo M. <danix@danix.xyz> | 2026-09-25 19:01:49 +0200 |
|---|---|---|
| committer | Danilo M. <danix@danix.xyz> | 2026-09-25 19:01:49 +0200 |
| commit | 3ba00d86ab05bc1b01294d2db684c2eee37e8164 (patch) | |
| tree | d85f6a7f93507181849adfe0e9564452ce2b47f3 /docs | |
| parent | 30bebb6f36cc32fdeac03d4848635a1911ebcdd8 (diff) | |
| download | quickshell-3ba00d86ab05bc1b01294d2db684c2eee37e8164.tar.gz quickshell-3ba00d86ab05bc1b01294d2db684c2eee37e8164.zip | |
docs(keybinds): design for a live keybind reminder
The list comes from hyprctl binds -j on every opening, so it is always
what Hyprland has loaded, loop-generated binds included. Labels come
from each bind's description option, since hyprctl reports Lua actions
as an opaque __lua handle.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Diffstat (limited to 'docs')
| -rw-r--r-- | docs/superpowers/specs/2026-09-25-keybinds-design.md | 64 |
1 files changed, 64 insertions, 0 deletions
diff --git a/docs/superpowers/specs/2026-09-25-keybinds-design.md b/docs/superpowers/specs/2026-09-25-keybinds-design.md new file mode 100644 index 0000000..e516c77 --- /dev/null +++ b/docs/superpowers/specs/2026-09-25-keybinds-design.md @@ -0,0 +1,64 @@ +# Keybind reminder design + +A full-screen overlay listing every Hyprland keybind with what it does, opened +with `SUPER + k`. It exists to recall shortcuts, so it must never show a bind +that is not live or miss one that is. + +## Source of truth + +`hyprctl binds -j`, run on every opening. This is what Hyprland has loaded, +including binds generated in Lua loops, and it stays correct when +`keybindings.lua` has been edited but not reloaded. Parsing the Lua file was +rejected for exactly those two cases. No cache: the call is cheap and a cache +is the only way the list could go stale. + +`hyprctl` reports every Lua action as `dispatcher: "__lua"` with an opaque +numeric `arg`, so the action text comes from the bind's `description`, a +documented `HL.BindOptions` field (`/usr/share/hypr/stubs/hl.meta.lua`). + +## Hypr side (`hypr-theme` repo) + +- Every `hl.bind` gains `{ description = "Group: Label" }`, merged into any + options it already has (`locked`, `repeating`, `mouse`). Loop-generated + binds build theirs in the loop, e.g. `"Workspaces: Go to 3"`. +- The text before the first `": "` is the group heading in the overlay. +- New bind: `SUPER + k` → `qs -p <repo>/keybinds ipc call keybinds toggle`, + description `"Help: Keybind reminder"`. +- `autostart.lua` starts `qs -p <repo>/keybinds`. +- `decorations.lua` gains a `blur-keybinds` layer rule matching namespace + `^(quickshell-keybinds)$`, copied from `blur-window-switcher`. +- `SUPER + s` is defined in `dashboard.lua`, a symlink into the + `conky-theme-udt` repo; its description is a commit there. + +## Quickshell side: `keybinds/` + +- `shell.qml`: `ShellRoot` with the overlay and an `IpcHandler` target + `keybinds` exposing `toggle`, `show`, `close`. +- `Keybinds.qml`: `Scope` holding the 1x1 click-through keepalive + `PanelWindow` and a `LazyLoader` overlay on `root.open`. Overlay layer, + namespace `quickshell-keybinds`, `ExclusionMode.Ignore`, exclusive keyboard. + A focused `Item` handles Esc; a click anywhere closes. +- Opening sets `running = false` then `true` on a `Process` running + `hyprctl binds -j`; `StdioCollector` output is parsed on exit. +- `Binds.js` (pure, `.pragma library`): `mods(mask)` decodes SHIFT=1, + CTRL=4, ALT=8, SUPER=64 in the order SUPER, CTRL, ALT, SHIFT; + `group(binds)` returns `[{ name, rows: [{ keys, label }] }]`, groups in + first-seen order. A bind with no description goes to group `Undescribed` + with its raw key as label, so gaps stay visible. Mouse binds show as + written (`mouse:272`). +- Layout: groups flow in a `Flow` of columns, each a heading plus + `keys label` rows. Theme from the `Theme.qml` symlink to + `../shared/Theme.qml`; glyph-free. +- While loading or on `hyprctl` failure, the overlay says so rather than + drawing empty. +- `README.md`, GPLv2 headers on every file. + +## Testing + +`keybinds/test_binds.js`, runnable with `node` (it strips the `.pragma` line and evaluates `Binds.js`), asserts `mods` and `group` +against a fixture shaped like `hyprctl binds -j`. Visual check by the user. + +## Out of scope + +Search box (add if the list outgrows a screen, ~80 binds today). Submaps (none +in use). |
