Shortcut to open Settings: ',' (and ⌘, / Ctrl+, where the host allows) #541

Closed
opened 2026-09-30 17:30:59 +00:00 by kayg · 7 comments
Owner

Owner request (2026-09-30): "I find it odd that we don't have a shortcut to enter settings? i suppose ',' would be a great shortcut?"

Today no shortcut opens Settings. registry.test.ts lists ⌘, as reserved: Safari and Chrome use it for their own settings in a normal tab, so a web page cannot rely on it.
Build:

  • Add the app.settings entry to apps/web/src/lib/shortcuts/registry.ts, group general, label "Open Settings".
    • Primary key: bare ,. It is active only when focus is not in a text field, editor or contenteditable, and no dialog or menu is open. This is the same guard the other single-key app shortcuts use (reuse it).
    • Alternate: ⌘, / Ctrl+,. It only works where the host passes the key to the page (installed app/PWA window, the later native app). Keep the reserved-list test honest: record the alternate as host-dependent, not guaranteed.
  • If Settings is already open, the shortcut does nothing (no toggle). Esc still closes it.
  • Opening Settings with the keyboard does not animate (#527) and returns to the last open section (deep link, DESIGN §33).
  • Every Settings entry point (sidebar, avatar menu) shows the shortcut in its warm tooltip or menu hint through Kbd, and aria-keyshortcuts comes from the registry.
    Test: a unit test for the registry entry and the guard; an e2e where a User presses , on Calendar and sees Settings open; pressing , while typing in a note inserts a comma and does not open Settings.
## Owner request (2026-09-30): "I find it odd that we don't have a shortcut to enter settings? i suppose ',' would be a great shortcut?" Today no shortcut opens Settings. `registry.test.ts` lists ⌘, as reserved: Safari and Chrome use it for their own settings in a normal tab, so a web page cannot rely on it. **Build:** - Add the `app.settings` entry to `apps/web/src/lib/shortcuts/registry.ts`, group `general`, label "Open Settings". - Primary key: bare `,`. It is active only when focus is not in a text field, editor or contenteditable, and no dialog or menu is open. This is the same guard the other single-key app shortcuts use (reuse it). - Alternate: ⌘, / Ctrl+,. It only works where the host passes the key to the page (installed app/PWA window, the later native app). Keep the reserved-list test honest: record the alternate as host-dependent, not guaranteed. - If Settings is already open, the shortcut does nothing (no toggle). Esc still closes it. - Opening Settings with the keyboard does not animate (#527) and returns to the last open section (deep link, DESIGN §33). - Every Settings entry point (sidebar, avatar menu) shows the shortcut in its warm tooltip or menu hint through `Kbd`, and `aria-keyshortcuts` comes from the registry. **Test:** a unit test for the registry entry and the guard; an e2e where a User presses `,` on Calendar and sees Settings open; pressing `,` while typing in a note inserts a comma and does not open Settings.
Author
Owner

Starting issue #541 on branch job/settings-key-541, based on aa372eef6c9312403f59a65d5b90cb3648ff52ed (origin/dev). I am tracing the existing shortcut registry, guard, and Settings entry points before adding the registry entry and keyboard/e2e coverage.

Starting issue #541 on branch `job/settings-key-541`, based on `aa372eef6c9312403f59a65d5b90cb3648ff52ed` (`origin/dev`). I am tracing the existing shortcut registry, guard, and Settings entry points before adding the registry entry and keyboard/e2e coverage.
Author
Owner

Owner correction (2026-09-30): a bare , was only a suggestion. Follow a widely used, published convention, and cite the sources:

  • Apple HIG / macOS standard menu: ⌘, opens Settings.
  • GNOME HIG standard shortcuts and KDE standard shortcuts: Ctrl+, opens Preferences. Microsoft apps (Office, VS Code, Teams) use the same.
    Rule: the primary key is ⌘, / Ctrl+, per preset (#542). Where a browser tab does not pass that key to the page, first test which browsers really reserve it (Safari, Chrome, Firefox on macOS, Windows and Linux; record the results). Use a fallback only for those, and pick it from a widely used web-app convention with a source (for example the "G then S" style go-to sequences), not an invention. Every choice in the Shortcuts audit follows the same rule.
**Owner correction (2026-09-30):** a bare `,` was only a suggestion. Follow a widely used, published convention, and cite the sources: - Apple HIG / macOS standard menu: **⌘,** opens Settings. - GNOME HIG standard shortcuts and KDE standard shortcuts: **Ctrl+,** opens Preferences. Microsoft apps (Office, VS Code, Teams) use the same. Rule: the primary key is ⌘, / Ctrl+, per preset (#542). Where a browser tab does not pass that key to the page, first test which browsers really reserve it (Safari, Chrome, Firefox on macOS, Windows and Linux; record the results). Use a fallback only for those, and pick it from a widely used web-app convention with a source (for example the "G then S" style go-to sequences), not an invention. Every choice in the Shortcuts audit follows the same rule.
Author
Owner

Starting #541 on branch job/settings-key-541 from base SHA aa372eef6c. I am checking the shortcut registry, settings entry points, and browser handling before adding the shortcut and tests.

Starting #541 on branch job/settings-key-541 from base SHA aa372eef6c9312403f59a65d5b90cb3648ff52ed. I am checking the shortcut registry, settings entry points, and browser handling before adding the shortcut and tests.
Author
Owner

Shortcut convention evidence: Apple lists Command-Comma for front-app Settings (https://support.apple.com/en-us/102650); GNOME HIG lists Ctrl+, for Preferences (https://developer.gnome.org/hig/reference/keyboard); and VS Code uses ⌘, on macOS / Ctrl+, on Windows and Linux (https://code.visualstudio.com/docs/reference/default-keybindings). Google documents ⌘, opening Chrome Settings on Mac (https://support.google.com/chrome/answer/157179?hl=en). These sources confirm the preset choice and a real browser collision on macOS; I am testing the browser matrix before choosing any fallback.

Shortcut convention evidence: Apple lists Command-Comma for front-app Settings (https://support.apple.com/en-us/102650); GNOME HIG lists Ctrl+, for Preferences (https://developer.gnome.org/hig/reference/keyboard); and VS Code uses ⌘, on macOS / Ctrl+, on Windows and Linux (https://code.visualstudio.com/docs/reference/default-keybindings). Google documents ⌘, opening Chrome Settings on Mac (https://support.google.com/chrome/answer/157179?hl=en). These sources confirm the preset choice and a real browser collision on macOS; I am testing the browser matrix before choosing any fallback.
Author
Owner

Browser probe evidence: in Playwright headless on Linux, Chromium 153.0.8010.12, Firefox 155.0 and WebKit 26.6 each delivered Control+, to the page as a keydown (key=Comma); none navigated away. This is a page-event test, not proof about browser chrome on other OSes. No Mac or Windows SSH/browser host is configured in this worktree. Apple/Google docs confirm Safari and Chrome on macOS bind Command+, to their own Settings; Mozilla’s current keyboard-shortcut list does not list Ctrl+, as a browser command. I am treating the Linux Ctrl+, binding as page-available and keeping the Mac browser fallback host-scoped.

Browser probe evidence: in Playwright headless on Linux, Chromium 153.0.8010.12, Firefox 155.0 and WebKit 26.6 each delivered Control+, to the page as a keydown (key=Comma); none navigated away. This is a page-event test, not proof about browser chrome on other OSes. No Mac or Windows SSH/browser host is configured in this worktree. Apple/Google docs confirm Safari and Chrome on macOS bind Command+, to their own Settings; Mozilla’s current keyboard-shortcut list does not list Ctrl+, as a browser command. I am treating the Linux Ctrl+, binding as page-available and keeping the Mac browser fallback host-scoped.
Author
Owner

Implemented

  • Added registry entry app.settings with ⌘, on macOS and Ctrl+, elsewhere. The ⌘, alternative is marked host-dependent because browser chrome may consume it.
  • On desktop Safari and Chrome for macOS, a G then S sequence opens Settings when the browser owns ⌘,. The primary shortcut is guarded in editable fields, editors, contenteditable regions, dialogs, and menus. Opening Settings while it is already open is a no-op; Escape closes it.
  • Keyboard opening restores the last validated same-origin Settings section and deep link, skips surface and rail entrance motion, and keeps normal motion for later section selection. Sidebar and account menu hints use Kbd; aria-keyshortcuts comes from the registry.
  • Added registry/guard and Settings destination unit tests, plus a production e2e covering the Calendar open, last-section restore, no-animation behavior, no-toggle behavior, Note comma insertion, and simulated Mac Chrome fallback.
  • Attached 18 production-build screenshots: sidebar, Settings, and account menu at 390, 820, and 1440 px in light and dark themes.

Shortcut sources and host observations

The convention follows Apple’s Settings HIG, GNOME’s standard keyboard shortcuts, and VS Code’s default keybindings. The host conflict is documented by Chrome’s shortcut list and Safari’s shortcut list. The G then S fallback follows Gmail’s published Go to starred shortcut.

Linux headless Chromium 153, Firefox 155, and WebKit 26.6 delivered Ctrl+, to the page. The e2e simulates a Mac Chrome user agent to exercise the fallback handler; this does not test browser-level key interception. Native macOS Safari/Chrome/Firefox and Windows browsers were not available for runtime probes. The Safari/Chrome reservation behavior is sourced from their published shortcut lists; native delivery on those other hosts remains unverified.

Performance

The new bench/settings-shortcut.mjs completed 30 opens and a 50-key burst against a loaded live Plugins section (13 real rows; 20 Settings sections). Local Linux Chromium 153 results: surface-open latency p50 207.71 ms / p95 278.62 ms; browser CPU mean 346.667 ms per open; browser process RSS p50 661,084 KiB / p95 689,434.6 KiB; server RSS p50 214,656 KiB / p95 214,707.2 KiB; Settings JS heap 16,100,000 bytes. The 50-key burst took 428.67 ms and 610 ms browser CPU, with Settings remaining open.

docs/perf/baseline.json has no Settings-shortcut profile. Its closest existing interaction, open_palette, is 191/405 ms p50/p95; the 1440 px /settings/appearance route data-ready metric is 1,584/2,069 ms. Those measurements use the perf-test host and different actions, so they are reference values rather than a direct regression comparison. This profile ran locally on a shared host.

Verification

bun run check output:

$ node scripts/check-type-tokens.mjs && node scripts/check-motion-tokens.mjs && svelte-kit sync && svelte-check --tsconfig ./tsconfig.json
Text sizes and UI shape values use shared role tokens.
UI transitions and animation options use shared motion tokens or documented exceptions.
Loading svelte-check in workspace: /home/kayg/Developer/calternal-wt/settings-key-541/apps/web
Getting Svelte diagnostics...

svelte-check found 0 errors and 0 warnings

bun run test final summary, verbatim:

 Test Files  141 passed (141)
      Tests  920 passed (920)
   Start at  22:31:27
   Duration  51.53s (transform 46%, environment 20%, import 18%, tests 12%, setup 4%)

Production e2e output:

settings-shortcut e2e passed: primary key, last section, no animation, non-toggle, Note comma guard, and host fallback; screenshots in /home/kayg/Developer/calternal-wt/settings-key-541/artifacts/settings-key-541

The first full test run found one static markup assertion mismatch after a generic sidebar prop was added. The assertion was left unchanged; motion suppression moved to parent CSS variables, and the final full suite passed. No Rust crates changed, so Rust crate gates were not applicable. cargo clean removed 7,169 files (4.5 GiB); apps/web/build and .svelte-kit were removed.

Files

  • apps/web/src/lib/shortcuts/registry.ts, settingsShortcut.ts, settingsDestination.ts
  • apps/web/src/lib/shortcuts/registry.test.ts, settingsDestination.test.ts
  • apps/web/src/routes/+layout.svelte, settings/[...path]/+page.svelte, src/app.d.ts
  • apps/web/src/lib/components/app-sidebar.svelte, SidebarLinks.svelte, apps/web/package.json
  • packages/ui/src/components/ChromeActions.svelte, Kbd.svelte, OverlaySurface.svelte, FloatingSidebar.svelte, menu/MenuItem.svelte, tooltip/TooltipLayer.svelte, tooltip/tip.ts
  • apps/web/e2e/settings-shortcut.mjs, bench/settings-shortcut.mjs

Decisions and gaps

  • First-use or invalid saved Settings destination opens Account; DESIGN §33 defines stable Settings deep links but not a cold-start section.
  • Chose G then S from Gmail as the host fallback, and scope it only to desktop Safari/Chrome on macOS based on their published ⌘, bindings. Native macOS and Windows browser delivery still needs runtime verification.
  • Build succeeded with existing vendor use client directive and plugin-timing warnings. No API routes changed.

Head: e29f2b27c0a0cb519aff90a2e6183cc343d9203f (job/settings-key-541; not pushed).

### Implemented - Added registry entry `app.settings` with `⌘,` on macOS and `Ctrl+,` elsewhere. The `⌘,` alternative is marked host-dependent because browser chrome may consume it. - On desktop Safari and Chrome for macOS, a `G` then `S` sequence opens Settings when the browser owns `⌘,`. The primary shortcut is guarded in editable fields, editors, contenteditable regions, dialogs, and menus. Opening Settings while it is already open is a no-op; Escape closes it. - Keyboard opening restores the last validated same-origin Settings section and deep link, skips surface and rail entrance motion, and keeps normal motion for later section selection. Sidebar and account menu hints use `Kbd`; `aria-keyshortcuts` comes from the registry. - Added registry/guard and Settings destination unit tests, plus a production e2e covering the Calendar open, last-section restore, no-animation behavior, no-toggle behavior, Note comma insertion, and simulated Mac Chrome fallback. - Attached 18 production-build screenshots: sidebar, Settings, and account menu at 390, 820, and 1440 px in light and dark themes. ### Shortcut sources and host observations The convention follows [Apple’s Settings HIG](https://developer.apple.com/design/human-interface-guidelines/settings), [GNOME’s standard keyboard shortcuts](https://developer.gnome.org/hig/reference/keyboard), and [VS Code’s default keybindings](https://code.visualstudio.com/docs/reference/default-keybindings). The host conflict is documented by [Chrome’s shortcut list](https://support.google.com/chrome/answer/157179?co=GENIE.Platform%3DDesktop&hl=en) and [Safari’s shortcut list](https://support.apple.com/en-ie/guide/safari/cpsh003/mac). The `G` then `S` fallback follows Gmail’s published [Go to starred shortcut](https://support.google.com/mail/answer/6594?co=GENIE.Platform%3DDesktop&hl=en-tt). Linux headless Chromium 153, Firefox 155, and WebKit 26.6 delivered `Ctrl+,` to the page. The e2e simulates a Mac Chrome user agent to exercise the fallback handler; this does not test browser-level key interception. Native macOS Safari/Chrome/Firefox and Windows browsers were not available for runtime probes. The Safari/Chrome reservation behavior is sourced from their published shortcut lists; native delivery on those other hosts remains unverified. ### Performance The new `bench/settings-shortcut.mjs` completed 30 opens and a 50-key burst against a loaded live Plugins section (13 real rows; 20 Settings sections). Local Linux Chromium 153 results: surface-open latency p50 207.71 ms / p95 278.62 ms; browser CPU mean 346.667 ms per open; browser process RSS p50 661,084 KiB / p95 689,434.6 KiB; server RSS p50 214,656 KiB / p95 214,707.2 KiB; Settings JS heap 16,100,000 bytes. The 50-key burst took 428.67 ms and 610 ms browser CPU, with Settings remaining open. `docs/perf/baseline.json` has no Settings-shortcut profile. Its closest existing interaction, `open_palette`, is 191/405 ms p50/p95; the 1440 px `/settings/appearance` route data-ready metric is 1,584/2,069 ms. Those measurements use the perf-test host and different actions, so they are reference values rather than a direct regression comparison. This profile ran locally on a shared host. ### Verification `bun run check` output: ```text $ node scripts/check-type-tokens.mjs && node scripts/check-motion-tokens.mjs && svelte-kit sync && svelte-check --tsconfig ./tsconfig.json Text sizes and UI shape values use shared role tokens. UI transitions and animation options use shared motion tokens or documented exceptions. Loading svelte-check in workspace: /home/kayg/Developer/calternal-wt/settings-key-541/apps/web Getting Svelte diagnostics... svelte-check found 0 errors and 0 warnings ``` `bun run test` final summary, verbatim: ```text Test Files 141 passed (141) Tests 920 passed (920) Start at 22:31:27 Duration 51.53s (transform 46%, environment 20%, import 18%, tests 12%, setup 4%) ``` Production e2e output: ```text settings-shortcut e2e passed: primary key, last section, no animation, non-toggle, Note comma guard, and host fallback; screenshots in /home/kayg/Developer/calternal-wt/settings-key-541/artifacts/settings-key-541 ``` The first full test run found one static markup assertion mismatch after a generic sidebar prop was added. The assertion was left unchanged; motion suppression moved to parent CSS variables, and the final full suite passed. No Rust crates changed, so Rust crate gates were not applicable. `cargo clean` removed 7,169 files (4.5 GiB); `apps/web/build` and `.svelte-kit` were removed. ### Files - `apps/web/src/lib/shortcuts/registry.ts`, `settingsShortcut.ts`, `settingsDestination.ts` - `apps/web/src/lib/shortcuts/registry.test.ts`, `settingsDestination.test.ts` - `apps/web/src/routes/+layout.svelte`, `settings/[...path]/+page.svelte`, `src/app.d.ts` - `apps/web/src/lib/components/app-sidebar.svelte`, `SidebarLinks.svelte`, `apps/web/package.json` - `packages/ui/src/components/ChromeActions.svelte`, `Kbd.svelte`, `OverlaySurface.svelte`, `FloatingSidebar.svelte`, `menu/MenuItem.svelte`, `tooltip/TooltipLayer.svelte`, `tooltip/tip.ts` - `apps/web/e2e/settings-shortcut.mjs`, `bench/settings-shortcut.mjs` ### Decisions and gaps - First-use or invalid saved Settings destination opens Account; DESIGN §33 defines stable Settings deep links but not a cold-start section. - Chose `G` then `S` from Gmail as the host fallback, and scope it only to desktop Safari/Chrome on macOS based on their published `⌘,` bindings. Native macOS and Windows browser delivery still needs runtime verification. - Build succeeded with existing vendor `use client` directive and plugin-timing warnings. No API routes changed. Head: `e29f2b27c0a0cb519aff90a2e6183cc343d9203f` (`job/settings-key-541`; not pushed).
Author
Owner

Shipped in merge round 4, deployed to calternal.cloud in 1af8ead26 (healthy).

Shipped in merge round 4, deployed to calternal.cloud in 1af8ead26 (healthy).
kayg closed this issue 2026-10-01 09:17:49 +00:00
Sign in to join this conversation.
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
kayg/calternal#541
No description provided.