Skip to content

macOS: the key-press events of arrow keys are incorrectly suppressed during dead key composition #4537

@umajho

Description

@umajho

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:
Image
(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:
Image


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

Image

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:

Image

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    B - bugDang, that shouldn't have happenedDS - appkitAffects the AppKit/macOS backend

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions