Fix Windows Korean IME caret position during composition#186353
Fix Windows Korean IME caret position during composition#186353auto-submit[bot] merged 2 commits into
Conversation
|
Thanks for your pull request! It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA). View this failed invocation of the CLA check for more information. For the most up to date status, view the checks section at the bottom of the pull request. |
There was a problem hiding this comment.
Code Review
This pull request introduces a GetCursorPositionForComposition helper function in the Windows platform shell to manage IME composition cursor positions, ensuring they default to the end of the text when an explicit position is missing or invalid. Corresponding unit tests and a regression test were added to verify this behavior. Feedback suggests replacing the long data type with int in the new helper function to comply with the Google C++ Style Guide.
loic-sharma
left a comment
There was a problem hiding this comment.
Thanks for the pull request!
|
@mattkae Could you do the second review for this? |
Renzo-Olivares
left a comment
There was a problem hiding this comment.
LGTM but will defer to current reviewers.
|
The review threads appear resolved and the PR is approved, but Google testing failed with "Engine artifacts not found" while tree-status is broken. Could someone rerun the external testing or advise if there is anything else needed from my side? |
CC: @loic-sharma Also - I left a comment for Loic to read above :) |
mattkae
left a comment
There was a problem hiding this comment.
This looks good, but I am skeptical of the potential side-effects of the int cast. long seems more appropriate longterm there, since that is what the Win32 API returns to us.
Good catch. It looks like the underlying |
|
autosubmit label was removed for flutter/flutter/186353, because The base commit of the PR is older than 7 days and can not be merged. Please merge the latest changes from the main into this branch and resubmit the PR. |
|
@CHOIgoung could you rebase this PR off the latest master commit? Once you do that, I'll rerun tests and get this landed! :) |
7f46b4d to
bc46f13
Compare
|
큰 일 하셨습니다 !!! |
|
감사합니다. 2년이 걸렸네요. |
flutter/flutter@54e199a...701665b 2026-06-02 engine-flutter-autoroll@skia.org Roll Skia from c97e939eb5c9 to 279b17fe9fc1 (16 revisions) (flutter/flutter#187425) 2026-06-02 bdero@google.com [Flutter GPU] Add block-compressed texture format support (BC, ETC2, ASTC LDR) (flutter/flutter#187281) 2026-06-02 bdero@google.com [Impeller] Allow attaching specific texture mip levels and slices (flutter/flutter#187066) 2026-06-02 bdero@google.com [Impeller] Fix GLES command submission status before context is current (flutter/flutter#187293) 2026-06-02 engine-flutter-autoroll@skia.org Roll Dart SDK from 3cdc25e8ffe9 to d39850bf4a01 (9 revisions) (flutter/flutter#187409) 2026-06-01 jason-simmons@users.noreply.github.com [Impeller] Use glVertexAttribDivisor on GLES3 and glVertexAttribDivisorEXT on GLES2 with the extension (flutter/flutter#187313) 2026-06-01 matt.boetger@gmail.com [Android] Add Javadoc documentation to TextInputChannel (flutter/flutter#186018) 2026-06-01 mvincentong@gmail.com Read FLTEnableWideGamut from Dart bundle (flutter/flutter#186509) 2026-06-01 matt.boetger@gmail.com [flutter_tools] Remove obsolete AndroidX console warning during Gradle builds (flutter/flutter#186077) 2026-06-01 kjlubick@users.noreply.github.com [skia] Update gni file list name hsw -> ml3 (flutter/flutter#184892) 2026-06-01 zhongliu88889@gmail.com [web] Always sync slider input attrs regardless of gesture mode (flutter/flutter#187217) 2026-06-01 zhongliu88889@gmail.com [flutter_driver] Don't throw when stderr is unavailable on web (flutter/flutter#187190) 2026-06-01 116356835+AbdeMohlbi@users.noreply.github.com Remove unused code in `FlutterPluginUtils.kt` (flutter/flutter#187012) 2026-06-01 taak140@gmail.com [flutter_tools] Fix `flutter drive --chrome-binary` being ignored on web (flutter/flutter#185481) 2026-06-01 davidmartos96@gmail.com Eager failure when building and no XCode build settings (flutter/flutter#184726) 2026-06-01 goung123@gmail.com Fix Windows Korean IME caret position during composition (flutter/flutter#186353) 2026-06-01 okorohelijah@google.com iOS: update provisioning profile for 2026-2027 cert (flutter/flutter#187280) 2026-06-01 154381524+flutteractionsbot@users.noreply.github.com Sync CHANGELOG.md from stable (flutter/flutter#187380) 2026-06-01 jason-simmons@users.noreply.github.com Reland "Move dart-lang/ai to a top level third party dependency in engine (#187268)" (flutter/flutter#187378) 2026-06-01 stuartmorgan@google.com Add vector_math to Framework triage (flutter/flutter#187389) 2026-06-01 engine-flutter-autoroll@skia.org Roll Packages from e930ced to f5d50ca (4 revisions) (flutter/flutter#187381) 2026-06-01 mr_nadeem_iqbal@yahoo.com [flutter_tools] Reject archive entries that escape into a sibling directory by name prefix (#185794) (flutter/flutter#186647) 2026-06-01 bkonyi@google.com [flutter_tools] Fix widget_preview unawaited async write race condition (flutter/flutter#187177) 2026-06-01 137456488+flutter-pub-roller-bot@users.noreply.github.com Roll pub packages (flutter/flutter#187375) 2026-06-01 engine-flutter-autoroll@skia.org Roll Skia from 0aee4675e0ad to c97e939eb5c9 (7 revisions) (flutter/flutter#187371) 2026-06-01 mr_nadeem_iqbal@yahoo.com docs: Stack.clipBehavior = Clip.none does not extend hit testing (#160787) (flutter/flutter#186643) If this roll has caused a breakage, revert this CL and stop the roller using the controls here: https://autoroll.skia.org/r/flutter-packages Please CC stuartmorgan@google.com,tarrinneal@google.com on the revert to ensure that a human is aware of the problem. To file a bug in Packages: https://github.com/flutter/flutter/issues/new/choose To report a problem with the AutoRoller itself, please file a bug: https://issues.skia.org/issues/new?component=1389291&template=1850622 Documentation for the AutoRoller is here: https://skia.googlesource.com/buildbot/+doc/main/autoroll/README.md
…r#11822) flutter/flutter@54e199a...701665b 2026-06-02 engine-flutter-autoroll@skia.org Roll Skia from c97e939eb5c9 to 279b17fe9fc1 (16 revisions) (flutter/flutter#187425) 2026-06-02 bdero@google.com [Flutter GPU] Add block-compressed texture format support (BC, ETC2, ASTC LDR) (flutter/flutter#187281) 2026-06-02 bdero@google.com [Impeller] Allow attaching specific texture mip levels and slices (flutter/flutter#187066) 2026-06-02 bdero@google.com [Impeller] Fix GLES command submission status before context is current (flutter/flutter#187293) 2026-06-02 engine-flutter-autoroll@skia.org Roll Dart SDK from 3cdc25e8ffe9 to d39850bf4a01 (9 revisions) (flutter/flutter#187409) 2026-06-01 jason-simmons@users.noreply.github.com [Impeller] Use glVertexAttribDivisor on GLES3 and glVertexAttribDivisorEXT on GLES2 with the extension (flutter/flutter#187313) 2026-06-01 matt.boetger@gmail.com [Android] Add Javadoc documentation to TextInputChannel (flutter/flutter#186018) 2026-06-01 mvincentong@gmail.com Read FLTEnableWideGamut from Dart bundle (flutter/flutter#186509) 2026-06-01 matt.boetger@gmail.com [flutter_tools] Remove obsolete AndroidX console warning during Gradle builds (flutter/flutter#186077) 2026-06-01 kjlubick@users.noreply.github.com [skia] Update gni file list name hsw -> ml3 (flutter/flutter#184892) 2026-06-01 zhongliu88889@gmail.com [web] Always sync slider input attrs regardless of gesture mode (flutter/flutter#187217) 2026-06-01 zhongliu88889@gmail.com [flutter_driver] Don't throw when stderr is unavailable on web (flutter/flutter#187190) 2026-06-01 116356835+AbdeMohlbi@users.noreply.github.com Remove unused code in `FlutterPluginUtils.kt` (flutter/flutter#187012) 2026-06-01 taak140@gmail.com [flutter_tools] Fix `flutter drive --chrome-binary` being ignored on web (flutter/flutter#185481) 2026-06-01 davidmartos96@gmail.com Eager failure when building and no XCode build settings (flutter/flutter#184726) 2026-06-01 goung123@gmail.com Fix Windows Korean IME caret position during composition (flutter/flutter#186353) 2026-06-01 okorohelijah@google.com iOS: update provisioning profile for 2026-2027 cert (flutter/flutter#187280) 2026-06-01 154381524+flutteractionsbot@users.noreply.github.com Sync CHANGELOG.md from stable (flutter/flutter#187380) 2026-06-01 jason-simmons@users.noreply.github.com Reland "Move dart-lang/ai to a top level third party dependency in engine (#187268)" (flutter/flutter#187378) 2026-06-01 stuartmorgan@google.com Add vector_math to Framework triage (flutter/flutter#187389) 2026-06-01 engine-flutter-autoroll@skia.org Roll Packages from e930ced to f5d50ca (4 revisions) (flutter/flutter#187381) 2026-06-01 mr_nadeem_iqbal@yahoo.com [flutter_tools] Reject archive entries that escape into a sibling directory by name prefix (#185794) (flutter/flutter#186647) 2026-06-01 bkonyi@google.com [flutter_tools] Fix widget_preview unawaited async write race condition (flutter/flutter#187177) 2026-06-01 137456488+flutter-pub-roller-bot@users.noreply.github.com Roll pub packages (flutter/flutter#187375) 2026-06-01 engine-flutter-autoroll@skia.org Roll Skia from 0aee4675e0ad to c97e939eb5c9 (7 revisions) (flutter/flutter#187371) 2026-06-01 mr_nadeem_iqbal@yahoo.com docs: Stack.clipBehavior = Clip.none does not extend hit testing (#160787) (flutter/flutter#186643) If this roll has caused a breakage, revert this CL and stop the roller using the controls here: https://autoroll.skia.org/r/flutter-packages Please CC stuartmorgan@google.com,tarrinneal@google.com on the revert to ensure that a human is aware of the problem. To file a bug in Packages: https://github.com/flutter/flutter/issues/new/choose To report a problem with the AutoRoller itself, please file a bug: https://issues.skia.org/issues/new?component=1389291&template=1850622 Documentation for the AutoRoller is here: https://skia.googlesource.com/buildbot/+doc/main/autoroll/README.md
) Fixes flutter#140739 ## Summary This fixes a Windows Korean IME caret positioning issue where the caret could appear before the active composing syllable while entering Korean text. The Windows embedder previously queried the IME composing cursor position for every `WM_IME_COMPOSITION` update. However, Microsoft Korean IME can send composition updates with `GCS_COMPSTR` or `GCS_RESULTSTR` without the `GCS_CURSORPOS` flag. In that case, the cursor position is not explicitly part of the message, so querying it can produce a missing or stale cursor value. That stale value can then be converted into Flutter's text selection and place the visual caret before the end of the active composing range. ## Recordings Before this fix, the caret can appear before the active Korean composing syllable:  After this fix, the caret stays at the end of the active composing syllable:  ## Root Cause For Korean input such as `가나달`, the engine receives `WM_IME_COMPOSITION` updates for the active syllable. Local runtime logging showed that Microsoft Korean IME sends composition text updates without `GCS_CURSORPOS`: ```text [IME] OnImeComposition message=271, wparam=45796, lparam=24600, has_result=0, has_comp=1, has_cursor=0 [IME] GCS_CURSORPOS absent; fallback_cursor_pos=1 [IME] composing text="다", text_length=1, compose_change_cursor_pos=1 [IME] ComposeChangeHook input_text="다", input_length=1, cursor_pos=1, before_text="가나", before_selection=(2, 2), before_composing=(2, 2), after_text="가나다", after_selection=(3, 3), after_composing=(2, 3) [IME] SendStateUpdate text="가나다", selection=(3, 3), composing=(2, 3) [IME] OnImeComposition message=271, wparam=45804, lparam=24600, has_result=0, has_comp=1, has_cursor=0 [IME] GCS_CURSORPOS absent; fallback_cursor_pos=1 [IME] composing text="달", text_length=1, compose_change_cursor_pos=1 [IME] ComposeChangeHook input_text="달", input_length=1, cursor_pos=1, before_text="가나다", before_selection=(3, 3), before_composing=(2, 3), after_text="가나달", after_selection=(3, 3), after_composing=(2, 3) [IME] SendStateUpdate text="가나달", selection=(3, 3), composing=(2, 3) ``` In the problematic path, `has_comp=1` but `has_cursor=0`. The composing text is present, but the IME did not provide an explicit composing cursor position. ## Fix This change makes the Windows embedder read the IME composing cursor only when `GCS_CURSORPOS` is present in `lParam`. When `GCS_CURSORPOS` is absent, the embedder falls back to the end of the current composition text. If `GCS_CURSORPOS` is present but returns an out-of-range value, it also falls back to the composition end. This keeps explicit IME cursor positions working for IMEs that provide them, while avoiding stale or missing cursor values for Korean composition updates. ## Validation - Added regression coverage for Korean composition updates without `GCS_CURSORPOS`. - Added coverage that explicit `GCS_CURSORPOS` is still used when present. - Added coverage that out-of-range cursor positions fall back to the composition end. - Ran: ```text flutter_windows_unittests.exe --gtest_filter=MockWindow.OnImeComposition* ``` Result: ```text [==========] Running 7 tests from 1 test suite. [ PASSED ] 7 tests. ``` - Manually verified Korean IME input for `가나달` with a local diagnostic build. The final editing state showed the caret at the end of the composing range: ```text text="가나달", selection=(3, 3), composing=(2, 3) ```
Fixes #140739
Summary
This fixes a Windows Korean IME caret positioning issue where the caret could appear before the active composing syllable while entering Korean text.
The Windows embedder previously queried the IME composing cursor position for every
WM_IME_COMPOSITIONupdate. However, Microsoft Korean IME can send composition updates withGCS_COMPSTRorGCS_RESULTSTRwithout theGCS_CURSORPOSflag. In that case, the cursor position is not explicitly part of the message, so querying it can produce a missing or stale cursor value. That stale value can then be converted into Flutter's text selection and place the visual caret before the end of the active composing range.Recordings
Before this fix, the caret can appear before the active Korean composing syllable:
After this fix, the caret stays at the end of the active composing syllable:
Root Cause
For Korean input such as
가나달, the engine receivesWM_IME_COMPOSITIONupdates for the active syllable. Local runtime logging showed that Microsoft Korean IME sends composition text updates withoutGCS_CURSORPOS:In the problematic path,
has_comp=1buthas_cursor=0. The composing text is present, but the IME did not provide an explicit composing cursor position.Fix
This change makes the Windows embedder read the IME composing cursor only when
GCS_CURSORPOSis present inlParam.When
GCS_CURSORPOSis absent, the embedder falls back to the end of the current composition text. IfGCS_CURSORPOSis present but returns an out-of-range value, it also falls back to the composition end.This keeps explicit IME cursor positions working for IMEs that provide them, while avoiding stale or missing cursor values for Korean composition updates.
Validation
GCS_CURSORPOS.GCS_CURSORPOSis still used when present.Result:
가나달with a local diagnostic build. The final editing state showed the caret at the end of the composing range: