Description
While composing with dead keys, users should be able to move the cursor with arrow keys even if the composition has not yet been finalized, similar to how it works for typical Korean IMEs.
Working case: (builtin 2-Set Korean IME) in an Electron app:

(First-party Apps don't display the underline indicating composition for Korean unless the Hanja candidate window is open. A third-party app is used here for clarity.)
Working case: dead key composition (English U.S. (QWERTY)) in an Electron app:

For Korean IMEs, downstream programs can also implement this correctly, because key-press events of arrow keys are emitted by winit in such case:

KeyboardInput[Pressed ] logical=Named(F2) physical=Code(F2)
window.set_ime_allowed(true)
KeyboardInput[Released] logical=Named(F2) physical=Code(F2)
2026-03-20 15:54:12.805 winit-ime-repro[10004:285524236] error messaging the mach port for IMKCFRunLoopWakeUpReliable
KeyboardInput[Pressed ] logical=Character("ㅁ") physical=Code(KeyA)
KeyboardInput[Released] logical=Character("ㅁ") physical=Code(KeyA)
KeyboardInput[Pressed ] logical=Named(Backspace) physical=Code(Backspace)
KeyboardInput[Released] logical=Named(Backspace) physical=Code(Backspace)
# The logs above are irrelevant. “ㅁ” and Backspace are for working around #3095.
IME Enabled
IME Preedit("ㅎ", Some((3, 3)))
IME Preedit("ㅎ", Some((3, 3)))
IME Preedit("", None)
IME Commit("ㅎ")
IME Preedit("", None)
KeyboardInput[Pressed ] logical=Named(ArrowLeft) physical=Code(ArrowLeft)
KeyboardInput[Released] logical=Named(ArrowLeft) physical=Code(ArrowLeft)
In contrast, during dead key composition, downstream programs are out of luck, because winit suppresses key-press events of those arrow keys:

KeyboardInput[Pressed ] logical=Named(F2) physical=Code(F2)
window.set_ime_allowed(true)
KeyboardInput[Released] logical=Named(F2) physical=Code(F2)
# The logs above are irrelevant.
KeyboardInput[Pressed ] logical=Named(Alt) physical=Code(AltLeft)
IME Enabled
IME Preedit("˜", Some((2, 2)))
KeyboardInput[Released] logical=Named(Alt) physical=Code(AltLeft)
IME Preedit("", None)
IME Commit("˜")
KeyboardInput[Released] logical=Named(ArrowLeft) physical=Code(ArrowLeft)
The key-release event of the left arrow is there due to another bug (#4526).
Reproduction
https://gist.github.com/umajho/5f42a9cfe49ecfe61d4a9753796d00f2
macOS version
ProductName: macOS
ProductVersion: 15.7.3
BuildVersion: 24G419
Winit version
0.30.13
Description
While composing with dead keys, users should be able to move the cursor with arrow keys even if the composition has not yet been finalized, similar to how it works for typical Korean IMEs.
Working case: (builtin 2-Set Korean IME) in an Electron app:

(First-party Apps don't display the underline indicating composition for Korean unless the Hanja candidate window is open. A third-party app is used here for clarity.)
Working case: dead key composition (English U.S. (QWERTY)) in an Electron app:

For Korean IMEs, downstream programs can also implement this correctly, because key-press events of arrow keys are emitted by
winitin such case:In contrast, during dead key composition, downstream programs are out of luck, because
winitsuppresses key-press events of those arrow keys:The key-release event of the left arrow is there due to another bug (#4526).
Reproduction
https://gist.github.com/umajho/5f42a9cfe49ecfe61d4a9753796d00f2
macOS version
Winit version
0.30.13