Skip to content

Commit

Permalink
Fix broken Chinese IME when deleting composition (#5109)
Browse files Browse the repository at this point in the history
## Summary of the Pull Request
This PR fixes an out of bounds access when deleting composition during Chinese IME. What's happening is that we're receiving a CompositionCompleted before receiving the TextUpdate to tell us to delete the last character in the composition. This creates two problems for us:
1. The final character gets sent to the Terminal when it should have been deleted.
2. `_activeTextStart` gets set to `_inputBuffer.length()` when sending the character to the terminal, so when the `TextUpdate` comes right after the `CompositionCompleted` event, `_activeTextStart` is out of sync.

This PR fixes the second issue, by updating `_activeTextStart` during a `TextUpdate` in case we run into this issue. 
The first issue is trickier to resolve since we assume that if the text server api tells us a composition is completed, we should send what we have. It'll be tracked here: #5110.
At the very least, this PR will let users continue to type in Chinese IME without it breaking, but it will still be annoying to see the first letter of your composition reappear after deleting it.

## PR Checklist
* [x] Closes #5054
* [x] CLA signed. If not, go over [here](https://cla.opensource.microsoft.com/microsoft/Terminal) and sign the CLA
* [x] Tests added/passed

## Validation Steps Performed
Play around with Chinese IME deleting and composing, and play around with Korean and Japanese IME to see that it still works as expected.
  • Loading branch information
leonMSFT authored Mar 25, 2020
1 parent c9ac0b7 commit 1e30b53
Showing 1 changed file with 9 additions and 0 deletions.
9 changes: 9 additions & 0 deletions src/cascadia/TerminalControl/TSFInputControl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -300,6 +300,15 @@ namespace winrt::Microsoft::Terminal::TerminalControl::implementation

try
{
// When a user deletes the last character in their current composition, some machines
// will fire a CompositionCompleted before firing a TextUpdating event that deletes the last character.
// The TextUpdating will have a lower StartCaretPosition, so in this scenario, _activeTextStart
// needs to update to be the StartCaretPosition.
// A known issue related to this behavior is that the last character that's deleted from a composition
// will get sent to the terminal before we receive the TextUpdate to delete the character.
// See GH #5054.
_activeTextStart = ::base::ClampMin(_activeTextStart, ::base::ClampedNumeric<size_t>(range.StartCaretPosition));

_inputBuffer = _inputBuffer.replace(
range.StartCaretPosition,
::base::ClampSub<size_t>(range.EndCaretPosition, range.StartCaretPosition),
Expand Down

0 comments on commit 1e30b53

Please sign in to comment.