Skip to content

Added: Show IME composing text (e.g. Hangul) preview on terminal - #5215

Closed
sng2c wants to merge 1 commit into
termux:masterfrom
sng2c:master
Closed

Added: Show IME composing text (e.g. Hangul) preview on terminal#5215
sng2c wants to merge 1 commit into
termux:masterfrom
sng2c:master

Conversation

@sng2c

@sng2c sng2c commented Jul 29, 2026

Copy link
Copy Markdown

Hello Termux maintainers,

Thank you for your continued work on this project. I'd like to kindly submit this contribution for your review.

Problem

When using an IME (e.g. Korean/Hangul input), the in-progress composition (e.g. ㄱ → 가 → 간) was invisible in the terminal until committed, because the terminal only renders text echoed back from the pty. Additionally,
pressing non-composing keys (arrows, ESC, Tab from extra-keys or hardware keyboard) mid-composition caused the preview to follow the cursor unexpectedly.

Solution

  • Overrode InputConnection.setComposingText() to capture composing text and render it as a preview overlay at the cursor position via a new TerminalRenderer.renderComposingText(), reusing the existing mTextPaint and
    drawTextRun path (consistent font, width scaling, bold/italic/colors/dim).
  • On non-modifier key press in onKeyDown(), composing code points are written directly to the pty, the local Editable is cleared, and the IME state is reset via invalidateInput (API 33+) / restartInput to prevent
    duplication on the next input.

Changed files

  • TerminalRenderer.java — composing text overlay rendering (+74)
  • TerminalView.java — IME composing capture and finalization on key events (+138/-1)

Although this was developed and tested primarily with Korean (Hangul) input, the implementation relies on the standard Android InputConnection composing text API, which is shared across all CJK IMEs (Chinese, Japanese,
Korean). I believe this should work correctly for Chinese and Japanese input methods as well.

I would greatly appreciate your feedback and any suggestions for improvement. Please feel free to request changes if anything does not align with the project's conventions.

Thank you for your time and consideration.

…n-composing keys

The terminal only renders text that is committed and echoed back by the
program in the pty, so in-progress IME composition (e.g. ㄱ → 가 → 간) was
not visible until commit, and the preview followed the cursor when a
non-composing key (arrows/ESC/Tab from extra-keys or hardware keyboard)
was pressed mid-composition.

- Override InputConnection.setComposingText() to capture the composing
  text and draw it as a preview overlay at the cursor via a new
  TerminalRenderer.renderComposingText(), reusing the same mTextPaint
  and drawTextRun path as normal rendering (same font family/fallback,
  width scaling and cell text style: bold/italic/colors/dim).
- Finalize composing on non-modifier keys in onKeyDown(): write the
  composing code points to the pty directly, clear the local Editable,
  and reset the IME via invalidateInput (API 33+) / restartInput so it
  drops its composing buffer (avoids duplication on the next input).
@sng2c

sng2c commented Jul 29, 2026

Copy link
Copy Markdown
Author
Screen_Recording_20260729_112045_Termux(1)

Greetings in Korean. :-)

@sng2c

sng2c commented Jul 29, 2026

Copy link
Copy Markdown
Author
Screen_Recording_20260729_112750_Termux(2)

Greetings in Korean speech.

@sng2c

sng2c commented Jul 29, 2026

Copy link
Copy Markdown
Author

@robertkirkman

Copy link
Copy Markdown
Member

Does it work also with Bluetooth connected CJK keyboard?

image

@robertkirkman

Copy link
Copy Markdown
Member

Is this different, and does it also work with this?

image

@robertkirkman

robertkirkman commented Jul 30, 2026

Copy link
Copy Markdown
Member

I looked for common issues with CJK IME implementations in other terminal emulators on desktop PC, in order to try to understand what it should look like ideally.

Here is a discussion I found comparing the implementations of ghostty and GNOME terminal.

They said that in ghostty, there is a problem that the cursor is not visible or movable during the preview, but in GNOME terminal that problem does not happen.

Could you check that thread and compare this PR to it, and let me know whether this makes Termux more like GNOME terminal, or more like ghostty?

@sng2c

sng2c commented Jul 30, 2026

Copy link
Copy Markdown
Author

I looked for common issues with CJK IME implementations in other terminal emulators on desktop PC, in order to try to understand what it should look like ideally.

Here is a discussion I found comparing the implementations of ghostty and GNOME terminal.

They said that in ghostty, there is a problem that the cursor is not visible or movable during the preview, but in GNOME terminal that problem does not happen.

Could you check that thread and compare this PR to it, and let me know whether this makes Termux more like GNOME terminal, or more like ghostty?

So this is about a special case: cursor movement within the IME composing buffer.

Thank you — that's a case I hadn't considered.

If anything, I was hoping for a result closer to GNOME Terminal. However, this PR forces a commit whenever an arrow key is pressed, so even if the virtual keyboard supports moving inside the buffer, the composition could end
up being committed.

I think I need to revisit this and work toward a more fundamental implementation.

Also, regarding IME input from a physical keyboard: it seems hardware input needs to be routed through the IME as well, so that should probably be handled separately.

I think it's best to withdraw this PR. Shall I improve it and submit it again?

@sng2c

sng2c commented Jul 30, 2026

Copy link
Copy Markdown
Author

I think I need to revisit this and work toward a more fundamental implementation. :-)

@sng2c sng2c closed this Jul 30, 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