| Index: ui/base/ime/win/tsf_text_store.cc
|
| diff --git a/ui/base/ime/win/tsf_text_store.cc b/ui/base/ime/win/tsf_text_store.cc
|
| index fb842bc42d58f653ebdf6449f11e44e1b1836607..3d7f3290cb9f8b43a0e6e8d7554b4e55ce81e758 100644
|
| --- a/ui/base/ime/win/tsf_text_store.cc
|
| +++ b/ui/base/ime/win/tsf_text_store.cc
|
| @@ -831,6 +831,76 @@ void TSFTextStore::RemoveFocusedTextInputClient(
|
| }
|
| }
|
|
|
| +bool TSFTextStore::CancelComposition() {
|
| + // There is an on-going document lock. We must not edit the text!
|
| + if (!edit_flag_)
|
| + return false;
|
| +
|
| + if (string_buffer_.empty())
|
| + return true;
|
| +
|
| + // Unlike ImmNotifyIME(NI_COMPOSITIONSTR, CPS_CANCEL, 0) in IMM32, TSF does
|
| + // not have a dedicated method to cancel composition. However, CUAS actually
|
| + // has a protocol conversion from CPS_CANCEL into TSF operations. According
|
| + // to the observations on Windows 7, TIPs are expected to cancel composition
|
| + // when an on-going composition text is replaced with an empty string. So
|
| + // we use the same operation to cancel composition here to minimize the risk
|
| + // of potential compatibility issues.
|
| +
|
| + const size_t previous_buffer_size = string_buffer_.size();
|
| + string_buffer_.clear();
|
| + committed_size_ = 0;
|
| + selection_.set_start(0);
|
| + selection_.set_end(0);
|
| + if (text_store_acp_sink_mask_ & TS_AS_SEL_CHANGE)
|
| + text_store_acp_sink_->OnSelectionChange();
|
| + if (text_store_acp_sink_mask_ & TS_AS_LAYOUT_CHANGE)
|
| + text_store_acp_sink_->OnLayoutChange(TS_LC_CHANGE, 0);
|
| + if (text_store_acp_sink_mask_ & TS_AS_TEXT_CHANGE) {
|
| + TS_TEXTCHANGE textChange = {};
|
| + textChange.acpStart = 0;
|
| + textChange.acpOldEnd = previous_buffer_size;
|
| + textChange.acpNewEnd = 0;
|
| + text_store_acp_sink_->OnTextChange(0, &textChange);
|
| + }
|
| + return true;
|
| +}
|
| +
|
| +bool TSFTextStore::ConfirmComposition() {
|
| + // There is an on-going document lock. We must not edit the text!
|
| + if (!edit_flag_)
|
| + return false;
|
| +
|
| + if (string_buffer_.empty())
|
| + return true;
|
| +
|
| + // See the comment in TSFTextStore::CancelComposition.
|
| + // This logic is based on the observation about how to emulate
|
| + // ImmNotifyIME(NI_COMPOSITIONSTR, CPS_COMPLETE, 0) by CUAS.
|
| +
|
| + const string16& composition_text = string_buffer_.substr(committed_size_);
|
| + if (!composition_text.empty())
|
| + text_input_client_->InsertText(composition_text);
|
| +
|
| + const size_t previous_buffer_size = string_buffer_.size();
|
| + string_buffer_.clear();
|
| + committed_size_ = 0;
|
| + selection_.set_start(0);
|
| + selection_.set_end(0);
|
| + if (text_store_acp_sink_mask_ & TS_AS_SEL_CHANGE)
|
| + text_store_acp_sink_->OnSelectionChange();
|
| + if (text_store_acp_sink_mask_ & TS_AS_LAYOUT_CHANGE)
|
| + text_store_acp_sink_->OnLayoutChange(TS_LC_CHANGE, 0);
|
| + if (text_store_acp_sink_mask_ & TS_AS_TEXT_CHANGE) {
|
| + TS_TEXTCHANGE textChange = {};
|
| + textChange.acpStart = 0;
|
| + textChange.acpOldEnd = previous_buffer_size;
|
| + textChange.acpNewEnd = 0;
|
| + text_store_acp_sink_->OnTextChange(0, &textChange);
|
| + }
|
| + return true;
|
| +}
|
| +
|
| void TSFTextStore::SendOnLayoutChange() {
|
| if (text_store_acp_sink_ && (text_store_acp_sink_mask_ & TS_AS_LAYOUT_CHANGE))
|
| text_store_acp_sink_->OnLayoutChange(TS_LC_CHANGE, 0);
|
|
|