Skip to content

fix: prevent XIM character leak in Xwayland apps under CJK locale#1594

Closed
SHORiN-KiWATA wants to merge 1 commit into
fcitx:masterfrom
SHORiN-KiWATA:fix/xim-leak
Closed

fix: prevent XIM character leak in Xwayland apps under CJK locale#1594
SHORiN-KiWATA wants to merge 1 commit into
fcitx:masterfrom
SHORiN-KiWATA:fix/xim-leak

Conversation

@SHORiN-KiWATA

@SHORiN-KiWATA SHORiN-KiWATA commented Jun 25, 2026

Copy link
Copy Markdown
Contributor

Environment

  • OS: Arch Linux, Linux 7.0
  • Display: Wayland + niri + xwayland-satellite 0.8.1
  • fcitx5: 5.1.20, xcb-imdkit: 1.0.9, libx11: 1.8.13
  • Affected apps: Electron/Xwayland apps (Typora 0.11.18, linuxqq, VS Code)
  • IM engines affected: rime, fcitx5-chinese-addons (pinyin)

Reproduction

  1. Set LC_CTYPE=zh_CN.UTF-8 (apps with LC_CTYPE=en_US.UTF-8 are unaffected)
  2. Launch an Electron app via Xwayland with XIM (XMODIFIERS=@im=fcitx; no GTK_IM_MODULE set)
  3. Activate fcitx5 and type pinyin rapidly
  4. Random key presses bypass the IM and appear as raw ASCII in the document
2026-06-25-195704-REGION

Root Cause

  1. IM engines accept KeyPress events but reject KeyRelease events
  2. The XIM frontend forwards rejected releases back to the client via xcb_im_forward_event
  3. Internally, xcb_im_forward_event sets client->sync = true, causing the next KeyPress to be queued
  4. On the client side, libx11 XIM implementation sets a FABRICATED flag during forward event processing, which should be consumed by a subsequent synthetic key event
  5. Under LC_CTYPE=zh_CN.UTF-8, XIM encoding negotiation selects COMPOUND_TEXT instead of UTF8_STRING, introducing encoding overhead that widens the race window
  6. A real key press arrives before the FABRICATED flag is cleared → XFilterEvent returns NOTFILTERD → the client commits the character directly → leak

LC_CTYPE=en_US.UTF-8 negotiates UTF8_STRING encoding (zero overhead), making the race window too small to trigger.

Fix

In the XIM frontend XCB_XIM_FORWARD_EVENT handler, skip forwarding KeyRelease events of regular printable characters while the IM is composing. These releases serve no purpose for the application — it only needs commit results and preedit state, both already correctly provided by the engine. Avoiding the forward prevents client->sync from being set, eliminating the root trigger of the race condition.

Summary by CodeRabbit

Summary by CodeRabbit

  • Bug Fixes
    • Improved input method key handling by suppressing forwarding of printable character key releases while preedit text is active and no Ctrl/Alt/Super/Shift modifiers are pressed.
    • Kept existing behavior unchanged for other key events, including shortcuts and non-printable keys.

@coderabbitai

coderabbitai Bot commented Jun 25, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 529ec7d6-2b18-4c8b-a8e6-9475b2a0e138

📥 Commits

Reviewing files that changed from the base of the PR and between 65affd3 and 6b49d76.

📒 Files selected for processing (1)
  • src/frontend/xim/xim.cpp
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/frontend/xim/xim.cpp

📝 Walkthrough

Walkthrough

XIMServer::callback now skips forwarding some printable key-release events to the XIM client while preedit text is non-empty and no Ctrl/Alt/Super/Shift modifiers are active. Other key events keep the previous forwarding behavior.

Changes

XIM forwarding behavior

Layer / File(s) Summary
Conditional key-release forwarding
src/frontend/xim/xim.cpp
xcb_im_forward_event(im(), xic, xevent) is now gated so printable key releases are not forwarded during active preedit without modifier keys.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Poem

I hopped through keys with twitchy nose,
and found the preedit’s quiet glow.
✨🐇 Some releases now stay in the burrow,
while others bound along as before.
Soft paws, neat hops, and typing flows!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly describes the main fix: preventing XIM character leakage in Xwayland apps under CJK locales.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Comment @coderabbitai help to get the list of available commands.

Don't forward key release events of regular printable characters
while composing. Forwarding releases triggers a sync race in the XIM
client's FABRICATED flag handling that can cause character leaks when
COMPOUND_TEXT encoding is negotiated (which happens under CJK locales).
@wengxt

wengxt commented Jun 25, 2026

Copy link
Copy Markdown
Member

No, not forwarding release is likely to be wrong in other case. Traditional way to fix the actual issue here is to use fcitx im module.

https://fcitx-im.org/wiki/Using_Fcitx_5_on_Wayland#GTK_IM_MODULE describe how to use wayland protocol for wayland and fcitx im module for X11.

@wengxt wengxt closed this Jun 25, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants