1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
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).
|