Skip to content

gpui_macos: Skip IME for Cmd+key events on non-US layouts#51394

Merged
ConradIrwin merged 1 commit intozed-industries:mainfrom
jamarju:fix-cmd-key-ime-bypass
Mar 13, 2026
Merged

gpui_macos: Skip IME for Cmd+key events on non-US layouts#51394
ConradIrwin merged 1 commit intozed-industries:mainfrom
jamarju:fix-cmd-key-ime-bypass

Conversation

@jamarju
Copy link
Copy Markdown
Contributor

@jamarju jamarju commented Mar 12, 2026

Closes #51297

On non-US layouts, all Cmd+key events are routed through the macOS IME because key_char is always None when Cmd is held. For certain characters (dead keys like backtick, and non-dead keys like ç), the IME calls insertText: instead of doCommandBySelector:, consuming the event before it reaches GPUI's keybinding system or macOS system shortcuts.

This adds !platform to the IME-path condition in handle_key_event so Cmd+key events bypass the IME (except when composing). GPUI handles them if a binding matches, otherwise performKeyEquivalent: returns NO and macOS handles them.

This won't fully fix Cmd+backtick window cycling by itself because Zed's key_equivalents system maps default keybindings onto the physical backtick key on various layouts. For example, cmd-' (ToggleSelectedDiffHunks) maps to the backtick key on Spanish, cmd-= (IncreaseBufferFontSize) on Scandinavian layouts, cmd-" (ExpandAllDiffHunks) on German/Portuguese/Swiss, and cmd-} (ActivateNextItem) on Spanish-ISO. These Zed bindings shadow the backtick key and consume the event before macOS can cycle windows. I'd appreciate guidance on the preferred approach to resolve these keybinding conflicts -- IMO, Zed's default shortcuts should not be interfering with Cmd+backtick for any layout.

Release Notes:

  • Fixed Cmd+key shortcuts being consumed by the IME on non-US keyboard layouts, preventing Zed keybindings and macOS system shortcuts from working with special characters.

When Cmd is held, key_char is always None, causing all Cmd+key events
to be routed through the macOS IME. On non-QWERTY layouts, the IME
consumes certain characters (dead keys like backtick, and non-dead
keys like ç) by calling insertText: instead of doCommandBySelector:,
preventing the events from reaching GPUI's keybinding system or macOS
system shortcuts like window cycling.

Add !platform to the IME-path condition so Cmd+key events bypass the
IME entirely (except when composing). This lets GPUI handle them if a
binding matches, or return NO from performKeyEquivalent: so macOS can
handle them.

Release Notes:

- Fixed Cmd+key shortcuts being consumed by the IME on non-QWERTY
  keyboard layouts (e.g. Spanish, German QWERTZ), preventing macOS
  system shortcuts and Zed keybindings from working with special
  characters.
@cla-bot
Copy link
Copy Markdown

cla-bot bot commented Mar 12, 2026

We require contributors to sign our Contributor License Agreement, and we don't have @jamarju on file. You can sign our CLA at https://zed.dev/cla. Once you've signed, post a comment here that says '@cla-bot check'.

@zed-community-bot zed-community-bot bot added the first contribution the author's first pull request to Zed. NOTE: the label application is automated via github actions label Mar 12, 2026
@jamarju
Copy link
Copy Markdown
Contributor Author

jamarju commented Mar 12, 2026

@cla-bot check

@cla-bot cla-bot bot added the cla-signed The user has signed the Contributor License Agreement label Mar 12, 2026
@cla-bot
Copy link
Copy Markdown

cla-bot bot commented Mar 12, 2026

The cla-bot has been summoned, and re-checked this pull request!

@ConradIrwin
Copy link
Copy Markdown
Member

@jamarju thanks!

The way that rebinding is supposed to work is that builtin bindings are moved out of the way (so nothing should be moved over the top of the layout equivalent version of cmd-backtick). Can you clarify more which layouts this is not working for?

https://zed.dev/blog/keyboard-localization explains how I think it should work (but very willing to believe it's buggy).

@jamarju
Copy link
Copy Markdown
Contributor Author

jamarju commented Mar 13, 2026

Thanks for the quick response and the blog post!

There's two layers to this problem:

  1. Let me clarify what's happening on Spanish layout before this PR:
  • Cmd+backtick inserts a backtick character into the editor instead of window cycling.
  • Cmd+´ inserts a ´ character, but that combo is mapped to editor::ToggleLineNumbers, so it should be toggling line numbers instead.

This PR fixes that. After the fix:

  • Cmd+backtick no longer inserts characters (but it doesn't yet cycle windows, that's problem layer 2)
  • Cmd+´ now correctly toggles line numbers
  1. Cmd+backtick still doesn't cycle windows after the fix because the backtick key on Spanish is at the QWERTY ' position, and cmd-' is bound to ToggleSelectedDiffHunks. Disabling that binding confirms it: window cycling starts working. This PR doesn't address this issue, hence my question on what would be your best course of action here.

@ConradIrwin ConradIrwin merged commit fe7fa37 into zed-industries:main Mar 13, 2026
39 checks passed
@ConradIrwin
Copy link
Copy Markdown
Member

@jamarju the expectation I have is that the Spanish mapping:

"com.apple.keylayout.Spanish" => &[
('!', '¡'),
('"', '¨'),
('.', 'ç'),
('/', '.'),
(':', 'º'),
(';', '´'),
('<', '¿'),
('>', 'Ç'),
('@', '!'),
('[', 'ñ'),
('\'', '`'),
('\\', '\''),
(']', ';'),
('^', '/'),
('`', '<'),
('{', 'Ñ'),
('|', '"'),
('}', ':'),
('~', '>'),
],
should move the shortcuts out of the way of the window shortcuts.

That said, on my system it looks like the comma is not involved

  • cmd-' for ToggleLineNumbers is being re-mapped to cmd-`
  • cmd-` (the window cycling shortcut) would be mapped to cmd-< (because that's in the equivalent position on the Spanish keyboard) – but we don't actually intercept this one I don't think, just rely on the OS (though I might be wrong...)
Screenshot 2026-03-13 at 12 36 25

I also know that the OS-level window cycling shortcuts don't localize when you switch the keyboard layout (I think they're tied to your locale); so maybe we should actually be intercepting them ourselves for people who switch layouts. For me, using the US locale, I haven't figured out how to cycle windows if I change my keyboard layout to Spanish

@jamarju
Copy link
Copy Markdown
Contributor Author

jamarju commented Mar 14, 2026

Thanks for merging the PR, @ConradIrwin!

For me, using the US locale, I haven't figured out how to cycle windows if I change my keyboard layout to Spanish

With this PR in, US locale and ES layout, can you try cycling windows using cmd+[ in Finder and Zed?

If that works in Finder but not Zed, then you have reproduced problem 2 I explained above: while on ES layout, cmd+' is remapped to cmd+backtick and there's an action (editor: toggle selected diff hunks) that in US layout is mapped to cmd+' but becomes cmd+backtick in ES, thus shadowing macOS cycle windows shortcut.

If you unbind that action, you should be able to cycle windows while on US locale + ES layout by pressing cmd+[ (ie. cmd + the key physically labelled with [ in your US keyboard, which produces a backtick while on ES layout). I tested this myself by dusting an external US keyboard I had around and switching my locale to US.

So I believe the remaining issue here is that certain shortcuts are remapped into cmd+backtick. cmd+' is one offender here for Spanish layouts, but there are more:

US key Zed binding Layouts affected (count)
' cmd-' editor::ToggleSelectedDiffHunks Spanish, Spanish-ISO (2)
" cmd-" editor::ExpandAllDiffHunks German, Austrian, Brazilian, Portuguese, Swiss... (8)
= cmd-= zed::IncreaseBufferFontSize Danish, Finnish, Norwegian, Swedish... (13)
\ cmd-\ pane::SplitRight French, Belgian, ABC-AZERTY (4)

That's the list of X to backtick mappings where X is bound to some action in Zed by default.

I think the best course of action would be to MOVE these actions to some other combo.

This is of course going to disrupt people having any of these in their muscle memory already. But I can't think of any other solution.

@jamarju
Copy link
Copy Markdown
Contributor Author

jamarju commented Mar 14, 2026

On second thought there's another, much more sensible option, which is to change the mapping in keyboard.rs only for problematic layouts. Eg. for the Spanish one, replace this one line:

So ' gets mapped to something else. Ie. make sure nothing's remapped to backtick on any layout.

Let me try and raise a proposal to fix this in a new PR and perhaps we can discuss there.

tommyming pushed a commit to tommyming/zed that referenced this pull request Mar 15, 2026
…dustries#51394)

Closes zed-industries#51297

On non-QWERTY layouts, all Cmd+key events are routed through the macOS
IME because `key_char` is always `None` when Cmd is held. For certain
characters (dead keys like backtick, and non-dead keys like ç), the IME
calls `insertText:` instead of `doCommandBySelector:`, consuming the
event before it reaches GPUI's keybinding system or macOS system
shortcuts.

This adds `!platform` to the IME-path condition in `handle_key_event` so
Cmd+key events bypass the IME (except when composing). GPUI handles them
if a binding matches, otherwise `performKeyEquivalent:` returns `NO` and
macOS handles them.

**This won't fully fix Cmd+backtick window cycling by itself** because
Zed's key_equivalents system maps default keybindings onto the physical
backtick key on various layouts. For example, `cmd-'`
(ToggleSelectedDiffHunks) maps to the backtick key on Spanish, `cmd-=`
(IncreaseBufferFontSize) on Scandinavian layouts, `cmd-"`
(ExpandAllDiffHunks) on German/Portuguese/Swiss, and `cmd-}`
(ActivateNextItem) on Spanish-ISO. These Zed bindings shadow the
backtick key and consume the event before macOS can cycle windows. I'd
appreciate guidance on the preferred approach to resolve these
keybinding conflicts -- IMO, Zed's default shortcuts should not be
interfering with Cmd+backtick for any layout.

Release Notes:

- Fixed Cmd+key shortcuts being consumed by the IME on non-QWERTY
keyboard layouts, preventing Zed keybindings and macOS system shortcuts
from working with special characters.
@jamarju jamarju deleted the fix-cmd-key-ime-bypass branch March 15, 2026 14:31
@jamarju jamarju changed the title gpui_macos: Skip IME for Cmd+key events on non-QWERTY layouts gpui_macos: Skip IME for Cmd+key events on non-US layouts Mar 15, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

cla-signed The user has signed the Contributor License Agreement first contribution the author's first pull request to Zed. NOTE: the label application is automated via github actions

Projects

None yet

Development

Successfully merging this pull request may close these issues.

cmd+backtick does not cycle windows on keyboards where backtick is a dead key

2 participants