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 |
| 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 ( |
| 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.
-
조합이 완료되지 않았음에도 불구하고→조합 이완료되 지않았음에도 불구하 고 -
같다.→같.다,이미→이 미
-
-
조합완료→조완합 료 -
이상하게→이하상게
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.txtin Alacritty, typed Dubeolsik keys withxdotool, 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
- 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)
-
- winit sends this request with
XSetICValuesright 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)
-
- 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.
- 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 withXPutBackEvent. 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).
Related problems already fixed (separate from this symptom)
- 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 | 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;
}
// ...
}
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
- winit #4777 – X11/XIM: moving the IME cursor area while an input method forwards keys garbles text
- libX11 MR 246 – Fix XIM key order (#198)
- ibus 497f0c7 – client/x11: Fix Key typing order
- ibus #1847 – korean: emitting a space in an incorrect order with X11 applications
- ibus-hangul #42 – Hangul and space order gets swapped
- ibus-hangul #118 – GNOME 45 Wayland order problem
- Alacritty CHANGELOG