Skip to content
Search

Alacritty:KoreanImeOrder

lastmod 2026-10-23created 2026-10-231 edits

How to fix the character order getting swapped when typing with ibus-hangul Dubeolsik on X11

Overview

A record of investigating the problem where the character order gets swapped when typing with ibus-hangul Dubeolsik in Alacritty (X11). (Investigated: 2026-10-23)

Conclusion: not yet fixed. Both the latest Alacritty stable release 0.17.0 and master (54214706) use winit 0.30.13, and the winit issue identified as the cause, #4777, is still open with no fix PR.

Environment

Item

Version

OS

Ubuntu 24.04.5 LTS, X11 session

Alacritty

0.16.1 (installed), master 54214706 (build for reproduction)

winit

0.30.12 (0.16.1), 0.30.13 (0.17.0, master)

Input method

ibus 1.5.29 + ibus-hangul 1.5.5, connected via XIM (XMODIFIERS=@im=ibus, ibus-x11)

libX11

1.8.7

Symptoms

A character still being composed is shown with an underline cursor, and a finished character with a box (block) cursor.

  • Space gets attached in front of the character being composed.
    • 조합이 완료되지 않았음에도 불구하고 → 조합 이완료되 지않았음에도 불구하 고
    • 같다. → 같.다, 이미 → 이 미
  • During composition it suddenly switches to the completed state (box cursor), and the following character moves ahead.
    • 조합완료 → 조완합 료
    • 이상하게 → 이하상게

Reproduction

Reproduced in an environment isolated from the user's desktop.

  • Started a virtual X server (Xvfb), a separate D-Bus session, and a separate ibus-daemon (--xim).
  • ibus-hangul was isolated with the GSettings keyfile backend and started in Hangul mode.
  • The ibus, ibus-hangul, and libX11 versions are the same as on the user's system.
  • Ran stty raw -echo; cat > out.txt in Alacritty, typed Dubeolsik keys with xdotool, and compared the bytes actually received.
  • Event order was recorded with alacritty --print-events.

Reproduced results:

  • 조합 이완료되지 않았음에도…, …불구하 고, 조합완 료: Space attached in front of the composed character
  • 조합완료잇 ㅏㅇ하게, 조합완료이 상하 게: composition is cut off midway and later keys are processed first

Event log

When Space is pressed during composition, ibus-hangul commits the composed character and sends Space back to the app via XIM as an unhandled key (forward).

Normal

Ime(Preedit("", None))
Ime(Commit("지"))
KeyboardInput { logical_key: Named(Space), text: Some(" "), state: Pressed }

Failure

Ime(Preedit("이", Some((3, 3))))
Ime(Preedit("", Some((0, 0))))
Ime(Preedit("", None))
KeyboardInput { logical_key: Named(Space), text: Some(" "), state: Pressed }
Ime(Preedit("", None))
Ime(Commit("이"))

The composed character is cleared first (Preedit(""), at which point the underline cursor changes to a box cursor), Space arrives first, and the committed character comes in late.

When composition is cut off, Space goes back into the input method late, so the input method processes ㅇ ㅣ ㅅ first and only then receives Space.

Ime(Commit("료"))
Ime(Preedit("이", Some((3, 3))))
Ime(Preedit("잇", Some((3, 3))))
Ime(Commit("잇"))
KeyboardInput { logical_key: Named(Space), ... }
Ime(Preedit("ㅏ", Some((3, 3))))
Ime(Commit("ㅏ"))

Experiments to confirm the cause

Made comparison builds that only toggle IME position updates (set_ime_cursor_area) on and off, and repeated the same input. The "ibus briefly stalls" case briefly stopped and resumed the test ibus-x11 with SIGSTOP/SIGCONT, simulating a load situation where queued keys are processed all at once.

Condition

Normal input

ibus briefly stalls

Original behavior (IME position updates on)

7 failures in 20 runs

5 failures in 9 runs

Only IME position updates off

0 in 20 runs

0 in 9 runs

Original behavior + libX11 1.8.12

7 failures in 12 runs

The IME position update alone makes the symptom appear and disappear.

Cause

  1. Alacritty tells the IME the cursor position every time it draws the screen.
    • alacritty/src/display/mod.rs:1141, alacritty/src/display/mod.rs:1215
    • alacritty/src/display/window.rs:450 (update_ime_position → set_ime_cursor_area)
  2. winit sends this request with XSetICValues right after handling the next X event, and waits synchronously for the input method's response.
    • winit-0.30.13/src/platform_impl/linux/x11/event_processor.rs:87 (IME request handling loop)
    • winit-0.30.13/src/platform_impl/linux/x11/ime/context.rs:368 (XSetICValues)
  3. In a terminal the cursor moves with every character, so this wait happens on every keystroke. winit skips it when the position is the same, but the position changes every time so that has no effect.
  4. The commit string (XIM_COMMIT) and the forwarded key (XIM_FORWARD_EVENT) that arrive during the wait are each inserted at the front of the event queue by libX11 with XPutBackEvent. As a result the order is reversed or the key goes back into the input method late.

The libX11 internal path in step 4 is inferred from reading the source (modules/im/ximcp/imDefLkup.c). That "IME position updates are the cause" was confirmed by the experiment above. The mechanism is the same as winit #4777 (reported as a Vietnamese fcitx5 case).

  • ibus: The XIM key order fix client/x11: Fix Key typing order is included in ibus 1.5.29. The symptom occurs on this version too, so it is not the cause.
  • ibus-hangul: The Space order problem during composition (#42, ibus #1847) is worked around with the forward_key_event approach. This problem is that forwarded key getting jumbled on the client (winit/libX11) side.
  • GNOME Wayland: The Hangul/space order problem in GNOME 45 mutter (ibus-hangul #118) was fixed by mutter MR 3536. It takes a different path from X11 + Alacritty.
  • libX11: The XIM key order getting jumbled during fast typing (libX11 #198, MR 246) was fixed in 1.8.10. Ubuntu 24.04 ships 1.8.7, but building 1.8.12 and applying it only to Alacritty left the symptom unchanged. Upgrading libX11 does not fix it.

Fix status

Target

Status

winit #4777

Open, 0 comments, no related PR (filed 2026-10-19)

winit master

No related fix (checked up to the 2026-10-21 commit)

Alacritty 0.17.0

Uses winit 0.30.13, no related fix in the changelog

Alacritty master 54214706

Reproduced with a local build

The root fix has to be made in winit. The direction proposed in #4777 is to send IME position requests only when no X events remain to be processed (XPending = 0).

Workarounds

Turn off IME position updates (confirmed effective in the reproduction environment)

If you build Alacritty with the change below, it skips IME position updates only when the environment variable is set. Since Alacritty draws the composed character itself, the only thing you effectively lose is the position of the Hanja conversion candidate window.

// alacritty/src/display/window.rs
pub fn update_ime_position(&self, point: Point<usize>, size: &SizeInfo) {
    if std::env::var_os("ALACRITTY_NO_IME_SPOT").is_some() {
        return;
    }
    // ...
}
ALACRITTY_NO_IME_SPOT=1 alacritty

The comparison build made during the investigation is in a temporary path (/tmp/claude-1000/-home-zer0-Projects-alacritty/fcd0ab99-44d7-4831-87d3-1923a4bc58c3/scratchpad/alacritty-nospot/target/release/alacritty) and may be deleted later.

Other (effect unverified)

  • Use a Wayland session: winit uses the text-input protocol instead of XIM, so this path can be avoided.
  • Use a GTK terminal: gnome-terminal and others use the ibus module directly without going through XIM.
  • Restart ibus with IBUS_ENABLE_SYNC_MODE=0: This was the fix for an earlier XIM order problem, but it can freeze Java apps, and it is not certain whether it works for this problem.

See also

Favorite site

author Zer0 sitemap