Skip to content

Respect IME preedit cursor position on Win32 - #21632

Merged
MrJul merged 1 commit into
AvaloniaUI:masterfrom
gotoh:fix/windows-ime-preedit-cursor
Jun 24, 2026
Merged

MrJul merged 1 commit into
AvaloniaUI:masterfrom
gotoh:fix/windows-ime-preedit-cursor

Conversation

@gotoh

@gotoh gotoh commented Jun 23, 2026 •

Copy link
Copy Markdown
Contributor

What does the pull request do?

This PR fixes Win32 IME preedit caret handling in Imm32InputMethod.

When IMM32 reports GCS_CURSORPOS, Avalonia now forwards that caret position to TextInputMethodClient.SetPreeditText, so the visual caret in the preedit string stays in sync with the actual IME composition cursor.

The change is limited to the Win32 IMM32 path and does not modify the higher-level text input model or platform-independent preedit behavior.

What is the current behavior?

On Windows, Avalonia updates the preedit text content, but it does not track the caret position inside the active composition string.

As a result, when editing an in-progress IME composition, the logical caret can move inside the composition string while the visual preedit caret remains stale, typically staying at the end.

What is the updated/expected behavior with this PR?

Avalonia now updates the preedit caret position together with the preedit text on the Win32 IMM32 path.

This makes the caret follow IME cursor movement correctly when editing an active composition string, including cases where the user returns from conversion to composition editing and moves the caret within the preedit text.

Manual verification was done with Japanese IME on Windows 10/11 using samples/ControlCatalog.Desktop (TextBox page), including both Google IME and Microsoft IME.

Before After
before after

How was the solution implemented (if it's not obvious)?

  • cached the current Win32 composition cursor position in Imm32InputMethod
  • propagated GCS_CURSORPOS updates to TextInputMethodClient.SetPreeditText
  • cleared cached cursor state on reset, composition start/end, result commit, and client changes
  • avoided reapplying stale cursor state when GCS_RESULTSTR and GCS_CURSORPOS are reported together without a new GCS_COMPSTR

Checklist

Breaking changes

None.

Obsoletions / Deprecations

None.

Fixed issues

Fixes #10933

Likely fixes #21618 as well, since the reported symptom matches this Win32 IMM32 caret synchronization issue. However, my manual verification for this PR was performed with Japanese IMEs (Google IME and Microsoft IME), not with a Chinese IME specifically.

@MrJul MrJul added bug os-windows backport-candidate-12.0.x Consider this PR for backporting to 12.0 branch labels Jun 23, 2026
@avaloniaui-bot

Copy link
Copy Markdown

You can test this PR using the following package version. 12.1.999-cibuild0066768-alpha. (feed url: https://nuget-feed-all.avaloniaui.net/v3/index.json) [PRBUILDID]

@cla-avalonia

cla-avalonia commented Jun 23, 2026 •

Copy link
Copy Markdown
Collaborator
  • All contributors have signed the CLA.

@gotoh

gotoh commented Jun 23, 2026

Copy link
Copy Markdown
Contributor Author

@cla-avalonia agree

@gotoh
gotoh marked this pull request as ready for review June 23, 2026 08:52
@avaloniaui-bot

Copy link
Copy Markdown

You can test this PR using the following package version. 12.1.999-cibuild0066770-alpha. (feed url: https://nuget-feed-all.avaloniaui.net/v3/index.json) [PRBUILDID]

@gotoh
gotoh force-pushed the fix/windows-ime-preedit-cursor branch from 398da5f to 63a772c Compare June 23, 2026 10:02
@avaloniaui-bot

Copy link
Copy Markdown

You can test this PR using the following package version. 12.1.999-cibuild0066796-alpha. (feed url: https://nuget-feed-all.avaloniaui.net/v3/index.json) [PRBUILDID]

@gotoh
gotoh force-pushed the fix/windows-ime-preedit-cursor branch from 63a772c to c39499b Compare June 24, 2026 00:23
@avaloniaui-bot

Copy link
Copy Markdown

You can test this PR using the following package version. 12.1.999-cibuild0066838-alpha. (feed url: https://nuget-feed-all.avaloniaui.net/v3/index.json) [PRBUILDID]

@MrJul MrJul left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Tested with both Japanese and Chinese IME (MS Pinyin). Moving the caret works as advertised.
LGTM!

@MrJul
MrJul added this pull request to the merge queue Jun 24, 2026
@github-merge-queue
github-merge-queue Bot removed this pull request from the merge queue due to failed status checks Jun 24, 2026
@MrJul
MrJul added this pull request to the merge queue Jun 24, 2026
@github-merge-queue
github-merge-queue Bot removed this pull request from the merge queue due to failed status checks Jun 24, 2026
@MrJul
MrJul added this pull request to the merge queue Jun 24, 2026
Merged via the queue into AvaloniaUI:master with commit bdc8314 Jun 24, 2026
11 checks passed
@love-linger

Copy link
Copy Markdown
Contributor

Can this PR backport to 11.3.x branch?

@MrJul

MrJul commented Jun 24, 2026

Copy link
Copy Markdown
Member

Can this PR backport to 11.3.x branch?

No, 11.3 won't receive any new updates (unless it's a security fix). If you have an enterprise support agreement, you can contact the team to request additional fixes.

@Warm-winter

Copy link
Copy Markdown

@gotoh Thanks, using the test version can resolve the issue.

@MrJul MrJul removed the backport-candidate-12.0.x Consider this PR for backporting to 12.0 branch label Jul 9, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

6 participants