Skip to content

Keyboard Shortcuts: any menu command can take a key, and a key can be cleared - #186

Open
Fvzion wants to merge 1 commit into
robbietilton:mainfrom
Fvzion:feature/shortcuts
Open

Fvzion wants to merge 1 commit into
robbietilton:mainfrom
Fvzion:feature/shortcuts

Conversation

@Fvzion

@Fvzion Fvzion commented Sep 30, 2026

Copy link
Copy Markdown

The problem today

  • Most menu commands can't get a shortcut. Edit › Keyboard Shortcuts only lists commands that already come with one. Every filter (Gaussian Blur, Unsharp Mask…), New Adjustment Layer › Levels / Curves…, Select › Color Range…, Image › Trim…, Layer › Rename Layer… can't be given a key, however often they're used.
  • A shortcut can't be removed. You can change a key but not free it, so a default like ⌘J (Duplicate Layer) can't be turned off to use it elsewhere.
  • Custom shortcuts can vanish after an update. Saved shortcuts are read all or nothing: if a later version renames or adds one command, the whole list fails to load and every customization is lost.
  • A recorded Delete key never worked (it was stored as U+0008, the canvas checks U+007F).

What changes for the user

  • A new "More Menu Commands" section in Edit › Keyboard Shortcuts lists every menu command without a shortcut. Pick one, press a key, and it shows in the menu and works.
  • A ⊗ button next to each shortcut clears it, defaults included.
  • Saved shortcuts are read one by one, so an update keeps every one that still applies.

How to try it

  1. Edit › Keyboard Shortcuts…, scroll to More Menu Commands, click Filter › Gaussian Blur… and press ⌃⌥G.
  2. Close the sheet: the Filter menu now shows ⌃⌥G next to Gaussian Blur, and the key opens it.
  3. Back in the sheet, click ⊗ next to a default (for example Merge Layers, ⌘E): the menu item loses its key.

In the code

  • KeyboardShortcuts.swift: the assignable commands list, clearing (ShortcutChord.unassigned), the one-at-a-time loader, the Delete fix.
  • CompositorApp.swift: menu items without a default get .assignableShortcut("Menu › Item"), so their key comes from the registry.
  • A Debug build stops with a clear message if a menu item asks for a shortcut that isn't registered, so the list can't drift from the menus.
  • KeyboardShortcutTests (13 tests): no duplicate ids, no conflicting defaults, clearing, recording Delete, loading a list with an unknown entry.

Tested on macOS 26.6 (Apple silicon): the full test suite passes. Not yet tried on macOS 27.

🤖 Generated with Claude Code

Every menu command can now take a shortcut, including the dozens that
have none (the filters, Select › Color Range…, Image › Trim…, Layer ›
Rename Layer…): they are listed in a new section of Edit › Keyboard
Shortcuts. The ⊗ button clears a shortcut, the default ones included, so
a key can be freed. A Debug build stops with a clear message when a menu
item asks for a shortcut that isn't registered, and tests keep the list
free of duplicates and default conflicts.

Saved shortcuts were read all or nothing, so one entry a build didn't
know (a command renamed or added by a later version) threw away every
custom shortcut; they are now read one at a time, keeping the ones that
still apply.

Fixed on the way: Delete recorded as U+0008 never matched the canvas's
U+007F, so a recorded Delete didn't work.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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.

1 participant