Skip to content

Add keyboard shortcuts for switching layout presets - #216

Closed
vik-j wants to merge 1 commit into
acmerobotics:masterfrom
6165-MSET-Cuttlefish:keyboardShortcut
Closed

vik-j wants to merge 1 commit into
acmerobotics:masterfrom
6165-MSET-Cuttlefish:keyboardShortcut

Conversation

@vik-j

@vik-j vik-j commented Jul 22, 2026

Copy link
Copy Markdown

Add keyboard shortcuts for switching layout presets

Summary

Adds keyboard shortcuts for switching between layout presets (Default, Field, Graph, Hardware, Original, Configurable) without reaching for the mouse, plus a
discoverable reference for them inside the Settings dialog. The shortcut layer is self-contained in a new useLayoutShortcuts hook and works consistently across
Windows/Linux and macOS.

What's included

Layout-switching shortcuts

  • Alt/⌥ + 1…9 — jump directly to a preset by position. Index order is fixed by PRESET_ORDER, so Alt + 1 = Default, Alt + 2 = Field, and so on.
  • Alt/⌥ + ] — cycle to the next preset (wraps around).
  • Alt/⌥ + [ — cycle to the previous preset (wraps around).

Switching dispatches saveLayoutPreset, so it goes through the same path as choosing a preset from the header dropdown and persists like any other preset change.

Settings dialog reference panel

  • A collapsible "⌨ Keyboard Shortcuts" disclosure section (built with Headless UI's Disclosure) lists every shortcut with its key combo rendered in styling.
  • The list is generated from the same SHORTCUTS source the hook uses, so the displayed bindings can never drift from the actual behavior.
  • A note clarifies the modifier per-platform (e.g. "⌥ is the Option key (Alt on Windows/Linux)").

Implementation notes / design decisions

  • Modifier choice: Alt (Option on Mac) is used deliberately — Ctrl/Cmd + digit and Cmd + [ / ] are reserved by browsers for tab and history navigation, so those would
    never reach the app.
  • Cross-platform key matching: the handler keys off e.code (physical key — Digit1, BracketLeft, BracketRight) rather than e.key, because on macOS Option + key produces
    special characters (e.g. Option + [ → "), which would otherwise break matching.
  • Modifier strictness: shortcuts only fire on a clean Alt press — Ctrl, Cmd, and Shift held alongside are explicitly rejected to avoid clobbering other combos.
  • Typing safety: keystrokes are ignored when focus is in an input, textarea, select, or any contenteditable element, so shortcuts never interfere with text entry.
  • Cleanup: the keydown listener is added/removed in a useEffect and re-bound when the active preset changes.

Maintainability

Presets and their shortcuts are kept in sync through explicit pointers: a comment in LayoutPreset.tsx directs anyone adding a preset to also append it to PRESET_ORDER in useLayoutShortcuts.ts, and PRESET_ORDER documents that new entries must be appended (to keep existing digit shortcuts stable) with a max of 9.

Files changed

  • client/src/hooks/useLayoutShortcuts.ts (new) — the shortcut hook, PRESET_ORDER, and the SHORTCUTS reference data.

  • client/src/components/Dashboard/Dashboard.tsx — mounts the hook.

  • client/src/components/Dashboard/SettingsModal.tsx — the collapsible shortcuts reference panel.

  • client/src/enums/LayoutPreset.tsx — maintainer comment tying presets

    Testing

  • Verified each Alt + digit selects the expected preset and Alt + [ / Alt + ] cycle correctly with wraparound.

  • Confirmed shortcuts are suppressed while typing in config/input fields.

  • Confirmed the Settings panel lists bindings matching actual behavior on both macOS (⌥) and Windows/Linux (Alt).

Video and image below of feature working:

Screen.Recording.2026-07-21.at.8.49.21.PM.mov
image

Adds Alt/Option-based shortcuts for switching layout presets: Alt + 1..9 to
jump to a preset by position, and Alt + [ / Alt + ] to cycle to the previous
and next preset. Switching dispatches saveLayoutPreset, the same path used by
the header dropdown, so the change persists like any other preset selection.

The shortcut layer lives in a new useLayoutShortcuts hook. It matches on
e.code (physical keys) so Option-produced special characters on macOS still
resolve, requires a clean Alt press (Ctrl/Cmd/Shift are rejected), and ignores
keystrokes while an input, textarea, select, or contenteditable is focused.

A collapsible Keyboard Shortcuts panel in the Settings dialog lists the
bindings, generated from the same SHORTCUTS source the hook uses so the
reference cannot drift from behavior.
@rbrott

rbrott commented Sep 7, 2026

Copy link
Copy Markdown
Member

I'm not entirely opposed to this but my general hope with the presets is that you pick one that suits the task at hand (or make a custom one) and don't need to rapidly change between different layouts. In the rare case that you want to rapidly switch between layouts is there a reason that separate tabs pointing to the same dashboard instance doesn't work? (I understand that there's more bandwidth/overhead but it probably addresses most use cases?)

@vik-j

vik-j commented Sep 22, 2026

Copy link
Copy Markdown
Author

Honestly I feel like the idea behind this feature could be better incorporated into PR #229, which allows users to save custom layouts, as the only thing that would really need toggling would probably be a custom layout with extra features. I'll close this PR and let the creator of #229 work on theirs instead.

@vik-j vik-j closed this Sep 22, 2026
mxtmx added a commit to 6165-MSET-Cuttlefish/slothboard that referenced this pull request Sep 23, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants