Label canvas-layout shortcuts in Settings so the ⌘=/⌘-/⌘0 zoom duplicates read as context-scoped (#5810)
Fixes #5810
Problem
Issue #5810 reports that Zoom In/Out (⌘= / ⌘-) and Markdown Viewer: Zoom In/Out ship the same default chords, so Settings → Keyboard Shortcuts looks like it has duplicate-default collisions. The endorsed resolutions are either to re-scope the defaults or to label the context-scoped duplicates in the UI.
These zoom bindings are intentionally context-scoped — ⌘= zooms the browser when a browser pane is focused and the markdown viewer when a markdown preview is focused; they never both fire — so unbinding would regress the feature. The right fix is the UI labeling.
That labeling already exists for most cases: #5196 added a per-row scope caption ("Only while a browser pane is focused" / "Only while a markdown preview is focused" / "…right sidebar…"), and #5394 fixed the browser/markdown non‑US‑layout zoom path. But there's a remaining gap in the same mechanism:
- The
⌘0"Actual Size" trio ships on the browser, the markdown viewer, and the canvas (Canvas: Actual Size). The canvas member — like every canvas-layout-scoped shortcut — fell through to the catch-all and was mislabeled "Only while a terminal pane is focused", which is wrong and undercuts the very indication this issue asks for.
Fix
- Extract the built-in scope→caption mapping out of
KeyboardShortcutsSection.scopeCaptioninto a testablebuiltInScopeCaption(for:)seam. - Map the
workspaceCanvasLayoutclause (and the compoundcanvas && !browser && !markdownclause used byCanvas: Actual Size) to a new, accurate "Only while the canvas layout is active" caption.
After this, the whole ⌘= / ⌘- / ⌘0 zoom-shortcut family is accurately scoped in Settings: browser, markdown, and canvas each read with their own context instead of looking like a raw collision.
Tests (two-commit red → green)
ShortcutScopeCaptionTests (package test target, auto-discovered by SwiftPM):
- Commit 1 adds the failing regression: canvas-scoped bindings (incl.
Canvas: Actual Size, ⌘0) assert a canvas caption while the code still returns the terminal caption → red. - Commit 2 adds the canvas mapping + localization → green.
Coverage asserts: the clause→caption mapping for every built-in scope; each zoom action's caption (browser/markdown/canvas) including the explicit "canvas must not be the terminal caption" regression; and that the ⌘=/⌘-/⌘0 duplicate defaults share a keystroke yet are context-disjoint (bindingsCollide == false), which is exactly why the scope caption is required.
Scope notes
- Problem 2 (zoom-in unreachable on non-US layouts) is tracked elsewhere: #5394 (merged) fixed the browser/markdown path; #4302 (open) fixes the terminal path. This PR does not touch keystroke translation.
- No behavior change for browser/markdown/sidebar/terminal captions — only canvas was mislabeled.
Localization audit
Added one new user-facing string, shortcut.when.caption.canvasLayout, to Resources/Localizable.xcstrings with translations for all 20 supported locales (verified at locale parity with the sibling shortcut.when.caption.terminalFocus key). No web/ or docs message catalogs are involved. No new bare English literals — all captions go through String(localized:).
Summary by cubic
Label canvas-layout shortcuts in Settings with “Only while the canvas layout is active” so the ⌘=/⌘-/⌘0 zoom defaults read as context-scoped, not duplicates. Fixes #5810; detection now handles the canvas key regardless of clause order.
-
Bug Fixes
- Map
workspaceCanvasLayoutand any clause that requires that key (at any&&depth) to the new caption; negated ororcases are excluded to avoid mislabels. - Applies to canvas zoom and “Actual Size” (⌘0); browser/markdown captions unchanged.
- Added
shortcut.when.caption.canvasLayoutinLocalizable.xcstringswith translations for all supported locales.
- Map
-
Refactors
- Moved built-in scope→caption logic into
ShortcutScopeCaptionResolverand used it inKeyboardShortcutsSection.scopeCaption. - Added
ShortcutScopeCaptionTests; covers caption mapping (incl. the combined browser-or-text-preview caption), zoom defaults’ context-disjointness, and right-placed/nested/negated canvas conjuncts.
- Moved built-in scope→caption logic into
Summary by CodeRabbit
-
New Features
- Added clearer keyboard shortcut scope captions across more contexts, including canvas layout and combined browser/file preview scopes.
- Localized the new canvas-layout caption for multiple languages.
-
Bug Fixes
- Improved scope labeling for shortcuts so zoom and reset actions now show the correct caption for their active context.
- Fixed canvas-related shortcuts to display the right scope even when conditions are combined in different ways.
-
Tests
- Added coverage for shortcut scope caption behavior and several regression cases.