Brief description
Key binds that are set to "Unbound" (no key assigned) all activate at the same
time when a key event with scan code 0 arrives. While a Chinese IME is active,
pressing Right Shift produces exactly such an event, so every unbound key bind
fires at once. The cinematic camera (key.smoothCamera) is unbound by default, so
this reproduces on a fresh installation with no setup at all: the cinematic
camera turns itself on.
Steps to reproduce
Launch Minecraft and enter a world. Do not change any key bind.
Switch to a Chinese IME (tested with Microsoft Pinyin).
Press Right Shift (the IME's Chinese/English toggle).
Expected result
Nothing happens. A key bind set to "Unbound" must never activate.
Actual result
The cinematic camera turns on. Every other unbound key bind is triggered at the
same moment. Left Shift does not trigger it (see "Why only Right Shift" below).
Root cause
The IME consumes Right Shift, so Windows delivers it as WM_KEYDOWN/WM_KEYUP with
wParam == VK_PROCESSKEY and lParam == 1. Because lParam carries no real scan
code, the corresponding SDL event has scan code 0 and key code SDLK_UNKNOWN.
Instrumenting KeyboardHandler#keyPress in the vanilla client shows:
key=225 keysym=0x400000e1 mod=0x1 action=1 -> key.keyboard.left.shift (Left Shift, normal)
key=0 keysym=0x0 mod=0x0 action=1 -> key.keyboard.unknown (Right Shift under the IME)
key=0 keysym=0x0 mod=0x0 action=0 -> key.keyboard.unknownInputConstants.UNKNOWN is InputConstants.Type.KEYBOARD.getOrCreate(0), i.e.
value 0 (InputConstants.java:195). InputConstants.getKey(KeyEvent) is
Type.KEYBOARD.getOrCreate(event.key()) (InputConstants.java:197), and
SDLEventHandler.handleKeyEvent builds the event with no filtering
(SDLEventHandler.java:114). A scan-code-0 event therefore resolves to UNKNOWN.
KeyboardHandler#keyPress then calls KeyMapping.set(key, true) and
KeyMapping.click(key) (KeyboardHandler.java:566-567). Both funnel into
forAllKeyMappings -> MAP.get(key) (KeyMapping.java:30, 34, 38), which has no
isUnbound() check. Every KeyMapping registers itself in MAP under its own key,
unbound ones included (the KeyMapping constructor calls registerMapping(this.key);
resetMapping() does the same for all of them), so MAP.get(UNKNOWN) returns every
key bind the player has unbound. All of them get setDown(true) and clickCount++.
Minecraft.java:1909 then consumes that click:
while (this.options.keySmoothCamera.consumeClick()) {
this.options.smoothCamera = !this.options.smoothCamera;
}which is why the cinematic camera turns on.
This is an inconsistency rather than intended behaviour: other entry points in the
same class do consult isUnbound() before touching a key bind.
KeyMapping.java:165 matches(KeyEvent) has "&& !this.isUnbound()"
KeyMapping.java:169 matchesMouse(MouseButtonEvent) has "&& !this.isUnbound()"
KeyMapping.java:173 matches(Key) has "&& !this.isUnbound()"
KeyboardHandler.java:442 keyDebugCrash has "!options.keyDebugCrash.isUnbound() && ..."
set and click are the only path that reaches key binds without checking it.
Why only Right Shift
Only the right Shift is swallowed by the IME and re-sent as VK_PROCESSKEY; the
left Shift's toggle is performed without consuming the key, so it still arrives
as a normal SDL key event (scan code 225) and key binds assigned to it keep
working. The bug itself does not depend on this: any event that resolves to
InputConstants.UNKNOWN fires every unbound key bind, and Right Shift is simply a
reliable way to produce one.
Suggested fix
Ignore the unknown key in the lookup path, for example:
private static void forAllKeyMappings(final InputConstants.Key key, final Consumer<KeyMapping> operation) {
if (key.equals(InputConstants.UNKNOWN)) return;
...
}
Equivalently: early-return in KeyMapping.set / KeyMapping.click, or drop
scan-code-0 events in SDLEventHandler.handleKeyEvent.
Related reports (searched before submitting)
Not the same as MC-306812 ("Inventories with no text fields cause key binds to
conflict with IME input methods"): that report is about the IME staying active
while a GUI is open, which makes normally-bound keys (E, Q, F, 1-9) stop working.
Here no screen is open, the affected key binds are all unbound, and the defect is
that KeyMapping.set/click lack the isUnbound() guard. Possibly related, same SDL
migration area: MC-310984 and MC-310108 (scan code to key mapping differences).
Environment
Windows 10 Pro for Workstations 22H2 (build 19045), Microsoft Pinyin IME. Vanilla Minecraft Java Edition 26.3, no mods. Input backend: SDL 3.4.14 (bundled via LWJGL 3.4.3).
Linked issues
Comments 2
Thank you for your report!
We're tracking this issue in MC-311424, so this ticket is being resolved and linked as a Duplicate.
That ticket has already been resolved as Fixed. Please check the Fix Version/s field in that ticket to see in which version this behavior was or will be fixed.
If you haven't already, please make use of the search feature to see if an issue you are about to report has already been reported.
Quick Links:
📓 Bug Tracker Guidelines – 💬 Community Support – 📧 Mojang Support (Technical Issues) – 📧 Microsoft Support (Account Issues)
📓 Project Summary – ✍️ Feedback and Suggestions – 📖 Game Wiki
The same applies to the Japanese IME.