-
Notifications
You must be signed in to change notification settings - Fork 6k
Revert text cursor position calculation windows #51164
Revert text cursor position calculation windows #51164
Conversation
…ition when inputting Korean characters (as 3.13.9) - Issue occurred since 3.16.x - flutter/flutter#140739
|
It looks like this pull request may not have tests. Please make sure to add tests before merging. If you need an exemption to this rule, contact "@test-exemption-reviewer" in the #hackers channel in Chat (don't just cc them here, they won't see it! Use Discord!). If you are not sure if you need tests, consider this rule of thumb: the purpose of a test is to make sure someone doesn't accidentally revert the fix. Ask yourself, is there anything in your PR that you feel it is important we not accidentally revert back to how it was before your fix? Reviewers: Read the Tree Hygiene page and make sure this patch meets those guidelines before LGTMing. |
|
@LongCatIsLooong this is related to your changes in #49314, would you be able to review this? |
LongCatIsLooong
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
After reading https://learn.microsoft.com/en-us/windows/win32/api/imm/nf-imm-immgetcompositionstringa it's still not super obvious to me what could have caused the caret to be misplaced.
/cc @cbracken
long TextInputManager::GetComposingCursorPosition() const {
if (window_handle_ == nullptr) {
return false;
}
ImmContext imm_context(window_handle_);
if (imm_context.IsValid()) {
// Read the cursor position within the composing string.
return ImmGetCompositionString(imm_context.get(), GCS_CURSORPOS, nullptr,
0);
}
return -1;
}
This looks a bit suspicious as the documentation says ImmGetCompositionString returns the byte length of the string. Does this always work for UTF16?
| std::string text_before_change = active_model_->GetText(); | ||
| TextRange composing_before_change = active_model_->composing_range(); | ||
| active_model_->AddText(text); | ||
| cursor_pos += active_model_->composing_range().extent(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IIRC cursor_pos is relative to the start of the new composing region. So this does not seem to be right.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
However I suspect the AddText is no longer needed (and neither is text_after_change but that's unrelated to this PR.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is related below:
Use start instead of extent for Windows IME cursor position #45667
Fix macOS text composing #49314
It was applied to solve problems when inputting Japanese and Chinese, but new issues are occurring in Korean.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you by chance have a repro with stack frames (especially the input arguments of this method when the cursor is placed at the wrong location)?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In the case of Korean, cursor_pos is based on the end of the new composing area.
When entering Korean, the text cursor is behind single space. #140739
https://bugs.chromium.org/p/chromium/issues/detail?id=653160

This PR did not pass the unittests below.
- UpdateSelectionWhileComposing (text_input_model_unittests.cc),
- CompositionCursorPos (text_input_plugin_unittest.cc)
So, this PR commits are incomplete and needs improvement.
However, I don't fully understand process of that unittest cases, so I'm checking it further.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@loic-sharma , @LongCatIsLooong When I looked it up, there was no branching with regular expressions in the engine code before.
So I'm not sure if adding regular expressions to check Korean is the right way, but I tried modifying the code to fix the issue.
When I ran the unit tests on the local engine, they all passed, but I am not sure if the difference in clang library version is the cause, but the unit tests failed on Mac and Linux.
Even if the above pull request is not approved, please reexamine to confirm the fix for the Korean issue.
| composing_range_.collapsed() ? selection_ : composing_range_; | ||
| text_.replace(rangeToDelete.start(), rangeToDelete.length(), text); | ||
| composing_range_.set_end(composing_range_.start() + text.length()); | ||
| #if FML_OS_WIN |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My understanding is that this class is meant to be an OS-agnostic abstraction, so having OS dependant logic here seems weird.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Correct - this class is common code used by multiple OSes.
We should avoid #ifdef as much as possible since Flutter is used on many platforms, including some which are not part of our repo -- developers for those embedders can't patch in platform-specific #ifdefs so neither should we. (We'd also need platform specific additional testing etc.)
Instead, we should make the patches in the platform-specific embedder that requires updated behaviour. For the case where all platforms need an update we can put it in the common code.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree that it is not a good idea to include platform branching statements in code in the common area.
| std::string text_before_change = active_model_->GetText(); | ||
| TextRange composing_before_change = active_model_->composing_range(); | ||
| active_model_->AddText(text); | ||
| cursor_pos += active_model_->composing_range().extent(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you by chance have a repro with stack frames (especially the input arguments of this method when the cursor is placed at the wrong location)?
|
Hi @deniz-lee are you planning to follow up on the code review suggestions? If not, could you please close this PR to get it off of our review queue? (Desktop triage) |
|
This pull request executed golden file tests, but it has not been updated in a while (20+ days). Test results from Gold expire after as many days, so this pull request will need to be updated with a fresh commit in order to get results from Gold. |
Reverts the logic for calculating the TextField input text cursor position when inputting Korean characters (3.13.9)
List which issues are fixed by this PR. You must list at least one issue.
However, when entering Korean text, the input cursor is located to the left of the entered character.
Recorded Video about the issue:
Before (origin/main):
https://github.com/flutter/engine/assets/121159478/25d86b34-677c-4bc4-bc5e-b0179f36484c
Modified (origin/revert_text_cursor_position_calculation_windows)
https://github.com/flutter/engine/assets/121159478/7a53799f-7c1d-404b-be33-d4568b9a001c
Pre-launch Checklist
///).