gpui_macos: Skip IME for Cmd+key events on non-US layouts#51394
gpui_macos: Skip IME for Cmd+key events on non-US layouts#51394ConradIrwin merged 1 commit intozed-industries:mainfrom
Conversation
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.
|
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'. |
|
@cla-bot check |
|
The cla-bot has been summoned, and re-checked this pull request! |
|
@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). |
|
Thanks for the quick response and the blog post! There's two layers to this problem:
This PR fixes that. After the fix:
|
|
@jamarju the expectation I have is that the Spanish mapping: zed/crates/gpui_macos/src/keyboard.rs Lines 1214 to 1234 in 66d7452 That said, on my system it looks like the comma is not involved
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 |
|
Thanks for merging the PR, @ConradIrwin!
With this PR in, US locale and ES layout, can you try cycling windows using 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 ( If you unbind that action, you should be able to cycle windows while on US locale + ES layout by pressing 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:
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. |
|
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: zed/crates/gpui_macos/src/keyboard.rs Line 1225 in 66d7452 So Let me try and raise a proposal to fix this in a new PR and perhaps we can discuss there. |
…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.

Closes #51297
On non-US layouts, all Cmd+key events are routed through the macOS IME because
key_charis alwaysNonewhen Cmd is held. For certain characters (dead keys like backtick, and non-dead keys like ç), the IME callsinsertText:instead ofdoCommandBySelector:, consuming the event before it reaches GPUI's keybinding system or macOS system shortcuts.This adds
!platformto the IME-path condition inhandle_key_eventso Cmd+key events bypass the IME (except when composing). GPUI handles them if a binding matches, otherwiseperformKeyEquivalent:returnsNOand 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, andcmd-}(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: