Third chord in a day, and each move was the owner naming a collision on the machine he actually uses: ctrl-space is Brave's address bar, shift-space types a space, alt-space is the window menu — and he rebound that rather than give up the chord. Shift-space was the worst of the three and it is worth saying why, because it read as the safe choice. It is a real key combination inside a text field: it types a space, and people hold shift through one more often than they think while typing capitals. So it had to stand down whenever focus was in an input — which is where focus usually is, the chat composer — and a launcher you have to click out of a field to reach is not a launcher. Alt-space means nothing in a text field, so the isTyping guard stops being the thing holding the feature up and becomes belt-and-braces. Kept anyway: two lines against some layout delivering alt-space as a literal character, which is cheap to prevent and expensive to discover. `altKey` with `ev.code`, not `ev.key` — alt-space produces a different `key` on several layouts and nothing at all on others, while the physical key is `Space` everywhere. No second chord. Two triggers for one thing means two things to collide with, and this one has moved twice. The TODO item's id still says ctrl-space. Ids are stable by design, so it stays; its body now records all three moves and which guard was load-bearing for which. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
45 lines
2.5 KiB
Markdown
45 lines
2.5 KiB
Markdown
---
|
|
id: shell/a-spotlight-style-launcher-on-ctrl-space
|
|
title: 'A Spotlight-style launcher, on `alt-space`'
|
|
theme: shell
|
|
status: done
|
|
created: 2026-08-20
|
|
date_source: assumed
|
|
order: 1
|
|
---
|
|
|
|
**A Spotlight-style launcher, on `ctrl-space`.** The dock is full and cannot grow; navigation
|
|
already borrows from macOS (see `docs/navigation-audit.md`), so the launcher is the same borrowing
|
|
taken one step further. Type a few letters, get routes, chats, files, plugins, settings sections —
|
|
and hit enter. Dock settings already exist, so the other half is pruning the dock down to what is
|
|
actually used and letting the launcher carry the rest.
|
|
**Trigger to confirm:** `alt-space` is the owner's preferred chord but is already load-bearing for
|
|
him elsewhere, so `ctrl-space` unless that clashes too.
|
|
|
|
---
|
|
|
|
**Built 2026-08-21** (`81f32a1f`, retriggered in `a2cca526`). **`alt-space`** in the end, after two moves: `ctrl-space`
|
|
focuses the address bar in Brave and never reached the app.
|
|
|
|
It **indexes the dock** rather than keeping a list of its own — the dock is already the composed,
|
|
permission-filtered answer to "what can this account open here", so a plugin appears in the launcher for
|
|
the reason it appears in the dock, and nothing is edited when one is installed. Settings sections are
|
|
added on top, hand-listed, which is a known cost written into the file.
|
|
|
|
Matching is subsequence with weighted scoring in its own testable file: `chq` finds Command HQ, `apik`
|
|
finds API keys, `fi` gives Files rather than Profile. Nine tests, all about ORDER rather than matching.
|
|
|
|
The trigger moved twice, and both moves were the owner naming a real collision: `ctrl-space` is Brave's
|
|
address bar, then `shift-space` types a space in every text field. The second was the worse one, because
|
|
guarding against it meant standing down whenever focus was in an input — which is where focus usually is,
|
|
the chat composer — so the launcher had to be prepared for rather than used. **`alt-space`** has no meaning
|
|
in a text field, so the guard is now belt-and-braces rather than the thing holding the feature up. It stays
|
|
anyway: two lines against a layout somewhere delivering alt-space as a character.
|
|
|
|
The id of this item still says `ctrl-space`. Ids are stable by design — see `todo/README.md` — so it is
|
|
left alone.
|
|
|
|
**Still open, and the other half of this item:** pruning the dock, and dock auto-hide with effects. Those
|
|
live in `shell/dock-effects-and-auto-hide`. Chats, files and actions are not in the index yet — routes
|
|
and settings are known client-side, so this slice needed no API.
|