rioterm: render the IME composition inline at the cursor - #1849
Merged
Merged
Conversation
ISC_SHOWUICOMPOSITIONWINDOW lives in lparam; masking wparam meant the OS floating composition window was never actually suppressed. Same fix as upstream winit. Only correct to ship together with inline preedit rendering: without it this would remove the only visible composition UI on Windows.
Single-row wezterm-style block anchored at the cursor: slides left at the right edge, keeps the tail (where the caret lives) when wider than the row, and never wraps or silently truncates. Text is laid out and shaped per grapheme cluster so ZWJ emoji and combining marks hold together. The caret renders as a thick underline in the text color on composition cells (a beam there would be cursor-on-cursor, invisible) and as a beam past the end where the normal background is behind it. Ime state moves from Context to Screen: the platform IME composes into the focused view, one composition per window, so per-context state could go stale on a background split — keep painting, and swallow keys on refocus through the preedit gate. Window-level state makes that unrepresentable. The overlay is also never built over scrollback, where the cursor row is off-viewport and the anchor would lie. The composition row (and the row it just left) is force-rebuilt every frame while composing, so cursor-only damage or an ended composition can't leave stale block cells. Composition runs use their own run-cache namespace, and the block fill resolves the cursor color the same way the cursor-block uniforms do, OSC 12 included.
This was referenced Aug 10, 2026
torabit
added a commit
to torabit/dotfiles
that referenced
this pull request
Aug 24, 2026
rio 0.5.26 には IME の未確定文字列を描画するコードが無い。rio-window は Windows から composition string を取得して Ime::Preedit を送出し rioterm も それを保持するが、描画側は先頭 1 文字を renderable_content.cursor.content へ 代入するだけで、そのフィールドはどこからも読まれない。一方 rio-window は WM_IME_COMPOSITION で DefWindowProc を呼ばず OS 側の描画を抑止している。 結果、自前でも OS でも描かれず、確定するまで何も見えない。 メンテナ自身の実装 PR raphamorim/rio#1849 が CI 全 green のまま未マージで main と衝突している。それを v0.5.26 へ移植したブランチを torabit/rio の torabit/fix/ime-preedit-inline に置き、マージされるまで自前でビルドする。 msvc ではなく windows-gnu を狙うのは、Windows 側に Visual Studio Build Tools を入れず WSL の mingw-w64 だけで済ませるため。rio の CI も MSYS2 で通っている。 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
raphamorim
force-pushed
the
preedit-v2
branch
from
September 5, 2026 21:30
64fcc80 to
b781c24
Compare
This was referenced Sep 6, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
From-scratch replacement for the approach in #1557/#1846 (closed), designed around everything the deep review of those branches surfaced. rioterm currently renders no composition preview at all — a dead key
'or Japanese romaji shows nothing until commit.Design
cursor_begin = -1, Windows, while paging through candidates) draws nothing, honoring rio-window'sPreeditcontract.Imemoved fromContexttoScreen: the platform IME composes into the focused view — one composition per window — so per-context state could go stale on a background split, keep painting a frozen block, and swallow Enter/Ctrl-C on refocus through the preedit key gate. Window-level state makes the whole class unrepresentable.Ime::Disabledmid-composition (input-source switch) damages and repaints like thePreeditarm.Also included (deliberately coupled): the Windows
WM_IME_SETCONTEXTfix — the fork maskedISC_SHOWUICOMPOSITIONWINDOWoff wParam, but the flag lives in lParam (upstream winit fixed this), so the OS floating composition window was never actually suppressed. With inline rendering in place, suppressing it is now correct; shipping the fix alone would have removed Windows' only visible composition UI.Testing
cargo test -p rioterm— 183 passing, including 10 new layout tests (wide clusters, ZWJ emoji, slide-left, tail cropping, caret snapping, degenerate input). Clippy and fmt clean.Manual checklist for real IMEs:
'+e→ inverted'preview at the cursor, thenécommits