[BUG] Desktop: zoom shortcuts bound to physical US key positions — wrong keys on non-US (Norwegian) layout
Preflight Checklist
- [x] I have searched existing issues and this hasn't been reported yet
- [x] This is a single bug report (please file separate reports for different bugs)
- [x] I am using the latest version of Claude Code
What's Wrong?
In the Claude Desktop app, the zoom keyboard shortcuts are bound to physical key positions (US layout) rather than to the character each key produces. On a Norwegian keyboard the symbols +, - and \ sit on different physical keys than on a US keyboard, so the shortcuts land on the wrong keys:
| Key I press (Norwegian label) | Physical event.code (US position) | Action that fires | Result |
|---|---|---|---|
| Ctrl + + (top row, right of 0) | Minus | Zoom Out | text gets smaller |
| Ctrl + - (bottom row, left of right-Shift) | Slash | Zoom Out (via menu accelerator) | text gets smaller |
| Ctrl + \ (top row, right of +) | Equal | Zoom In | text gets bigger (only way to zoom in!) |
| Ctrl + 0 | Digit0 | Reset | works |
So neither of the two keys a user naturally reaches for (+ / -) zooms in. The only working zoom-in shortcut is Ctrl+\, which I found by accident.
Root cause is in the packaged app (resources/app.asar → .vite/build/index.chunk-*.js). A before-input-event handler switches on the physical event.code:
webContents.on("before-input-event", (_, v) => {
if (v.type === "keyDown" && v.control && !v.alt && !v.meta)
switch (v.code) { // physical position, layout-independent
case "Equal": case "NumpadAdd": zoomIn(); break;
case "Minus": case "NumpadSubtract": zoomOut(); break;
case "Digit0": case "Numpad0": resetZoom(); break;
}
});
The View-menu accelerators resolve the same way via US keycodes (CmdOrCtrl+- → VKEY_OEM_MINUS = physical Minus key; CmdOrCtrl+= / CmdOrCtrl+Plus → VKEY_OEM_PLUS = physical Equal key). Both mechanisms key off physical position, not the printed/typed character.
This affects any layout where + / - / = aren't in their US positions (Norwegian, Swedish, Danish, German, French, …).
What Should Happen?
Ctrl + the key labeled +/= should zoom in, and Ctrl + the key labeled - should zoom out, based on the character the key actually produces on the active layout — matching browser behavior.
Error Messages/Logs
N/A — no error is produced; the shortcuts simply map to the wrong keys.
Verified from the shipped bundle:
resources/app.asar → .vite/build/index.chunk-BWcZBYrW.js
- before-input-event handler switches on event.code (Equal/Minus/Digit0)
- View-menu accelerators: CmdOrCtrl+Plus, CmdOrCtrl+=, CmdOrCtrl+-, num add/sub/0
Steps to Reproduce
- Set the OS keyboard layout to Norwegian (or any non-US layout where
+/-are not in the US physical positions). On GNOME/Wayland,gsettings get org.gnome.desktop.input-sources sources→[('xkb', 'no')]. - Open the Claude Desktop app.
- Press
Ctrl++(the key right of0) → text shrinks (expected: zoom in). - Press
Ctrl+-(bottom row, left of right-Shift) → text shrinks / no zoom-in (expected: zoom out). - Press
Ctrl+\(the key right of+) → text grows — this is the only working zoom-in.
Note: on a Norwegian keyboard, + is on DOM code Minus, \ is on DOM code Equal, and - is on DOM code Slash — which is exactly why the physical-code bindings mismatch the labels.
Claude Model
Opus
Is this a regression?
I don't know
Last Working Version
_No response_
Claude Code Version
Claude Desktop 1.21459.0 (Electron 42.5.1, Chromium 148) (terminal version: 2.1.211 (Claude Code))
Platform
Anthropic API
Operating System
Ubuntu/Debian Linux
Terminal/Shell
Other
Additional Information
- Keyboard layout: Norwegian, GNOME input source
('xkb', 'no'); from/usr/share/X11/xkb/symbols/no:<AE11>=+(codeMinus),<AE12>=\(codeEqual),<AB10>=-(codeSlash). - Same class of problem as #61340 (international layouts don't support all Desktop shortcuts — includes
Ctrl-\), which was auto-closed as stale rather than fixed. Also related: #62449 (detached-window zoom /Cmd+/-), #71758 (zoom step size). - Workaround today: zoom in with
Ctrl+\, zoom out withCtrl++, reset withCtrl+0; numpad+/-/0also work.
OS version
Ubuntu 26.04 LTS, Wayland/GNOME
Suggested fixes
- Match the produced character (
event.key) in addition toevent.codein thebefore-input-eventhandler, so the shortcut follows the printed symbol on every layout:
``js``
webContents.on("before-input-event", (_, v) => {
if (v.type !== "keyDown" || !v.control || v.alt || v.meta) return;
const k = v.key;
if (v.code === "Equal" || v.code === "NumpadAdd" || k === "+" || k === "=") { _.preventDefault(); zoomIn(); }
else if (v.code === "Minus" || v.code === "NumpadSubtract" || k === "-") { _.preventDefault(); zoomOut(); }
else if (v.code === "Digit0" || v.code === "Numpad0" || k === "0") { _.preventDefault(); resetZoom(); }
});
- Use Electron's built-in zoom menu roles (
zoomIn,zoomOut,resetZoom) instead of hardcoded accelerators — they handle+/-/=across layouts and platforms and keep a single source of truth. - Remove the redundant path. Zoom is currently handled both by the
before-input-eventhandler and by the View-menu accelerators. These can disagree per layout (e.g. the Norwegian+key matches "Zoom Out" by physical code but "Zoom In" by the+character), which can produce inconsistent / order-dependent behavior. Keep one mechanism. - Make the shortcuts user-configurable (relates to #16141) as a general remedy for non-US layouts.
This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗