Skip to content

macos: add menu key equivalent option#12597

Closed
knu wants to merge 1 commit into
ghostty-org:mainfrom
knu:macos-menu-key-equivalents
Closed

macos: add menu key equivalent option#12597
knu wants to merge 1 commit into
ghostty-org:mainfrom
knu:macos-menu-key-equivalents

Conversation

@knu

@knu knu commented May 6, 2026

Copy link
Copy Markdown
Contributor

Refs #12293
Related: #3493 (duplicates: #4374, #5091), #7013

Add macos-menu-key-equivalents, a macOS-specific setting for disabling menu key equivalents before they can intercept key events. It defaults to true, preserving existing menu behavior unless explicitly disabled.

On macOS, AppKit evaluates menu key equivalents before Ghostty receives key events. This means a remap such as key-remap = command=left_alt still leaves Command+N captured by the New Window menu item before Ghostty can turn it into Alt+N for keybind and terminal input handling.

Setting macos-menu-key-equivalents to false clears those menu shortcuts, so the key event reaches Ghostty instead of being consumed by AppKit. That allows Ghostty to apply key-remap first and dispatch the remapped key as terminal input or a Ghostty keybind.

When disabled, this clears Ghostty-managed menu bindings and known standard macOS menu items, including dynamic items as their menus are opened. The original key equivalents are restored when the option is enabled again.

Document the option and add Swift and Zig config coverage for it.

AI usage: OpenAI Codex helped investigate, implement, test, and refine this change. I reviewed and tested the resulting code.

Refs ghostty-org#12293
Related: ghostty-org#3493 (duplicates: ghostty-org#4374, ghostty-org#5091), ghostty-org#7013

Add `macos-menu-key-equivalents`, a macOS-specific setting for disabling
menu key equivalents before they can intercept key events.  It defaults to
true, preserving existing menu behavior unless explicitly disabled.

On macOS, AppKit evaluates menu key equivalents before Ghostty receives
key events.  This means a remap such as `key-remap = command=left_alt`
still leaves `Command+N` captured by the New Window menu item before
Ghostty can turn it into `Alt+N` for keybind and terminal input handling.

Setting `macos-menu-key-equivalents` to false clears those menu shortcuts,
so the key event reaches Ghostty instead of being consumed by AppKit.  That
allows Ghostty to apply `key-remap` first and dispatch the remapped key as
terminal input or a Ghostty keybind.

When disabled, this clears Ghostty-managed menu bindings and known standard
macOS menu items, including dynamic items as their menus are opened.  The
original key equivalents are restored when the option is enabled again.

Document the option and add Swift and Zig config coverage for it.

AI usage: OpenAI Codex helped investigate, implement, test, and refine
this change.  I reviewed and tested the resulting code.
@knu knu requested a review from a team as a code owner May 6, 2026 10:08
@ghostty-bot ghostty-bot Bot added the os/macos label May 6, 2026

@bo2themax bo2themax left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is still a workaround for the issue you mentioned. I believe the rc here is that pre-registered key bindings are not affected by key-remap, while Surface.keyEventIsBinding is using those mappings to query action, which will return null eventually and results in false in performKeyEquivalent.

But tbh, I'm not sure whether they should be remapped at all.

knu added a commit to knu/ghostty that referenced this pull request May 6, 2026
Refs ghostty-org#12293
Related: ghostty-org#3493 (duplicates: ghostty-org#4374, ghostty-org#5091), ghostty-org#7013
Supersedes: ghostty-org#12597

Route key equivalent events with remapped modifiers through the normal key
event path instead of dispatching the original physical shortcut through
AppKit menus.

This lets key-remap apply before Ghostty keybind lookup for shortcuts such
as Cmd+N when command is remapped, while leaving non-remapped menu key
equivalents on the existing AppKit path.

Inspired by: @bo2themax (ghostty-org#12597 (review))

AI usage: OpenAI Codex helped investigate, implement, test, and refine this
change. I reviewed and tested the resulting code.
@knu

knu commented May 6, 2026

Copy link
Copy Markdown
Contributor Author

@bo2themax Thanks, I agree this is better handled at the key event dispatch layer. I've just created #12602.

@knu knu closed this May 6, 2026
@knu knu deleted the macos-menu-key-equivalents branch May 6, 2026 18:33
knu added a commit to knu/ghostty that referenced this pull request May 7, 2026
Refs ghostty-org#12293
Related: ghostty-org#3493 (duplicates: ghostty-org#4374, ghostty-org#5091), ghostty-org#7013
Supersedes: ghostty-org#12597

Apply `key-remap` before keybind lookup and when reporting keybind
triggers for AppKit menu key equivalents.

Previously, menu shortcuts were registered from the configured trigger
without considering modifier remaps. This let AppKit consume the
physical shortcut before Ghostty could match the remapped keybind.

`Config.keyEventIsBinding` now remaps event modifiers before lookup, so
remapped key equivalents match the same keybinds as normal key events.
`CApi.config_trigger_` returns the physical trigger that maps back to the
configured logical modifiers, and leaves triggers unset when no remapped
physical shortcut can produce them.

`RemapSet.unapply` performs the reverse lookup and is checked with
`apply` so ambiguous or impossible remaps do not register incorrect menu
shortcuts.

Inspired by: @bo2themax (ghostty-org#12597 (review))

AI usage: OpenAI Codex helped investigate, implement, test, and refine this
change. I reviewed and tested the resulting code.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants