Skip to content

fix(keyboard): keep Ctrl for the terminal on macOS, bind app shortcuts to Cmd - #844

Merged
kipavy merged 2 commits into
devfrom
fix/843-macos-ctrl-cmd
Nov 11, 2026
Merged

kipavy merged 2 commits into
devfrom
fix/843-macos-ctrl-cmd

Conversation

@kipavy

@kipavy kipavy commented Nov 11, 2026 •

Copy link
Copy Markdown
Contributor

Fixes #843

Problem

On macOS every shortcut check accepted Ctrl or Cmd interchangeably (e.ctrlKey || e.metaKey in matchShortcut, the recorder and plugin keybindings; hard-coded e.ctrlKey in terminal copy/paste). So in a terminal:

  • Ctrl+C copied a live selection instead of sending ^C
  • Ctrl+V pasted
  • Ctrl+K / F / T / W / B / Z opened the palette, search, new tab, close tab, sidebar, undo

Change

src/utils/primaryModifier.ts names the app-shortcut modifier once: Cmd on macOS, Ctrl elsewhere. Ctrl+Tab and Ctrl+Space keep Ctrl on macOS because the OS owns Cmd+Tab (app switcher) and Cmd+Space (Spotlight).

Routed through it:

  • matchShortcut (every rebindable shortcut, panel shortcuts, duplicate session)
  • the shortcut recorder in Settings
  • terminal copy/paste (terminalClipboard): Cmd+C copies a selection, Cmd+V pastes; Ctrl+C / Ctrl+V always reach the shell on macOS. This replaces the old macOS-only Cmd+V special case.
  • split-pane maximise / focus keys and search next/previous (Cmd+G on macOS)
  • plugin keybindings: ctrl in a plugin binding means the primary modifier
  • labels: formatShortcut shows Cmd+K on macOS; alias labels and the settings-manifest value now come from formatShortcut instead of hand-written strings; the "Ctrl+, to open" hint in Settings is interpolated

Persisted and synced shortcut data does not change: ctrl: true keeps meaning "primary modifier", so a binding synced from Linux reads as Cmd on a Mac.

Behaviour changes to know about

  • Linux / Windows: a chord holding Super/Win no longer fires a Ctrl shortcut (it used to, via || metaKey).
  • macOS: "Duplicate to split" stays on Ctrl+Option+D, because macOS takes Cmd+Option+D for the Dock. Option shortcuts match by physical key on macOS, since Option rewrites e.key (Option+D is "∂").

Tests

  • shortcutStore.macModifier.test.ts: on macOS, Cmd matches and Ctrl does not, Ctrl+Tab / Ctrl+Space still match, Ctrl never fires unmodified shortcuts, labels read Cmd; elsewhere Ctrl only.
  • terminalClipboard.test.ts: on macOS Ctrl+C / Ctrl+V with a selection return null (passed to xterm, so the shell gets ^C / ^V); Cmd+C copies.
  • Both fail on the old code. vitest passes on i18n, stores, hooks, plugins, services, utils, lib and components/{settings,terminal,shared,omni,home,layout}; tsc --noEmit is clean.

Not tested on a real Mac. macOS-only behaviour needs a hand check on the next build.

…s to Cmd

On macOS every shortcut check treated Ctrl and Cmd as the same key, so
Ctrl+C copied a selection, Ctrl+V pasted, and Ctrl+K/F/T/W/B/Z opened app
actions instead of reaching the shell.

One helper now names the app-shortcut modifier: Cmd on macOS, Ctrl
elsewhere. Ctrl+Tab and Ctrl+Space keep Ctrl on macOS because the OS owns
Cmd+Tab and Cmd+Space. Shortcut matching, the shortcut recorder, terminal
copy/paste, split-pane keys, search next/previous and plugin keybindings
all use it, and shortcut labels read "Cmd" on macOS. Holding the other
modifier never matches an app shortcut, so Super/Win chords on Linux and
Windows no longer fire Ctrl shortcuts.

Fixes #843
macOS takes Cmd+Option+D to toggle the Dock, so the shortcut never reached
the app. That chord keeps Ctrl, like Ctrl+Tab and Ctrl+Space. Option also
rewrites e.key on macOS (Option+D is "∂"), so Option shortcuts match and
record by physical key there.
@kipavy
kipavy merged commit 82ece40 into dev Nov 11, 2026
9 of 10 checks passed
@kipavy
kipavy deleted the fix/843-macos-ctrl-cmd branch November 11, 2026 17:13
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