Skip to content

Show input method composition in text fields - #10195

Open
hard25670559 wants to merge 1 commit into
PathOfBuildingCommunity:devfrom
hard25670559:feature/show-ime-composition
Open

Show input method composition in text fields#10195
hard25670559 wants to merge 1 commit into
PathOfBuildingCommunity:devfrom
hard25670559:feature/show-ime-composition

Conversation

@hard25670559

Copy link
Copy Markdown

Description of the problem being solved

Text an input method is still composing is invisible until it is committed, so typing through an IME looks like nothing is happening — no characters, no underline, and the candidate window has no caret to attach itself to. This affects anyone typing Chinese, Japanese or Korean into a build name, note or search field.

This is the application half of the work; the engine half is being submitted to the macOS engine port separately. Related: #5632.

Description of the changes

  • Take the composition state the engine reports through a new OnPreedit callback and hold it on main. It is state rather than an input event, since it is replaced wholesale on every keystroke and discarded when composing ends.
  • Draw it at the caret, underlined to mark it as uncommitted, in EditControl.
  • Report the caret rectangle back so the candidate window can follow the text. A single-line field selects all of its content when focused; that selection collapses to its end once composing starts, since that is where the text will be inserted.

Everything is guarded: SetIMECaretRect is only called if the running engine provides it, and main.imePreedit is nil unless the engine sends a composition. On an engine without IME support this changes nothing.

Steps taken to verify a working solution

Tested on macOS with the system Bopomofo input method and a third-party one:

  • Bopomofo symbols and partially converted text now appear underlined at the caret as they are typed.
  • The candidate window follows the caret instead of sitting in a screen corner.
  • Committing inserts the text at the right place; backspace, arrows and selection behave normally afterwards.
  • With an engine that does not send composition events, behaviour is unchanged.

Text being composed by an input method was invisible until it was
committed, so typing anything through an IME looked like nothing was
happening.

Take the composition state the engine now reports and draw it at the
caret, underlined to mark it as uncommitted, and tell the engine where
that caret is so the candidate window can follow it. A single-line field
selects all of its text when focused; collapse that to the end of the
selection once composing starts, since that is where the text will be
inserted and where the candidate window belongs.
self.sel = nil
end
local viewOriginX, viewOriginY = textX, textY
if self.hasFocus and SetIMECaretRect and not self.lineHeight then

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IME composition is still skipped in multiline editors such as Notes. NotesTab sets lineHeight = 16, so this guard disables caret reporting and the preedit-rendering block below is bypassed. Users therefore still compose blindly in Notes, with no current caret rectangle for the candidate window. Could the multiline draw path receive equivalent preedit rendering and caret positioning?

Native macOS IME behavior was not exercised in this review.

AI-assisted review disclosure: This finding was identified during a review using OpenAI Codex.

end
if SetIMECaretRect then
-- Refine the position now that the composition width is known.
SetIMECaretRect(viewOriginX + textX, viewOriginY + textY, 1, textHeight)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OnPreedit's caret byte offset is stored in main.imePreeditCaret but never read. Draw advances textX by the full preedit before drawing the caret and calling SetIMECaretRect, so an IME caret inside the composition is shown at the end and the candidate window follows the wrong position. Could the preedit be split at that offset and the caret rectangle placed after its prefix?

Native macOS IME behavior was not exercised in this review.

AI-assisted review disclosure: This finding was identified during a review using OpenAI Codex.

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