Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
chore: cherry-pick c20afc96e36f57 from chromium (#24059)
- Loading branch information
1 parent
f7c4199
commit b0cbf49
Showing
2 changed files
with
143 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
142 changes: 142 additions & 0 deletions
142
patches/chromium/allow_ime_to_insert_zero_length_composition_string.patch
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,142 @@ | ||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 | ||
From: Siye Liu <siliu@microsoft.com> | ||
Date: Mon, 8 Jun 2020 21:19:00 +0000 | ||
Subject: Allow IME to insert zero-length composition string. | ||
|
||
Some IMEs and Windows OS dictation will either insert zero-length text | ||
or delete existing composition text to commit active composition. | ||
Therefore, we should allow IMEs to cancel composition by committing zero | ||
length text. | ||
|
||
Bug: 1091069 | ||
Change-Id: I99cb213dc2ba1965abfa88ccf6858b89bd7e82df | ||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2233234 | ||
Commit-Queue: Siye Liu <siliu@microsoft.com> | ||
Reviewed-by: Yohei Yukawa <yukawa@chromium.org> | ||
Cr-Commit-Position: refs/heads/master@{#776198} | ||
|
||
diff --git a/ui/base/ime/win/tsf_text_store.cc b/ui/base/ime/win/tsf_text_store.cc | ||
index 2a8cde4995fc41305847fd995654e3a012f68e1d..31174ba0eb0559aa461cfba1689d9ef627914e71 100644 | ||
--- a/ui/base/ime/win/tsf_text_store.cc | ||
+++ b/ui/base/ime/win/tsf_text_store.cc | ||
@@ -647,9 +647,7 @@ HRESULT TSFTextStore::RequestLock(DWORD lock_flags, HRESULT* result) { | ||
// 3. User commits current composition text. | ||
if (((new_composition_start > last_composition_start && | ||
text_input_client_->HasCompositionText()) || | ||
- (wparam_keydown_fired_ == 0 && !has_composition_range_ && | ||
- !text_input_client_->HasCompositionText()) || | ||
- (wparam_keydown_fired_ != 0 && !has_composition_range_)) && | ||
+ !has_composition_range_) && | ||
text_input_client_) { | ||
CommitTextAndEndCompositionIfAny(last_composition_start, | ||
new_composition_start); | ||
@@ -1355,8 +1353,11 @@ void TSFTextStore::CommitTextAndEndCompositionIfAny(size_t old_size, | ||
: new_committed_string_size); | ||
// TODO(crbug.com/978678): Unify the behavior of | ||
// |TextInputClient::InsertText(text)| for the empty text. | ||
- if (!new_committed_string.empty()) | ||
+ if (!new_committed_string.empty()) { | ||
text_input_client_->InsertText(new_committed_string); | ||
+ } else { | ||
+ text_input_client_->ClearCompositionText(); | ||
+ } | ||
// Notify accessibility about this committed composition | ||
text_input_client_->SetActiveCompositionForAccessibility( | ||
replace_text_range_, new_committed_string, | ||
diff --git a/ui/base/ime/win/tsf_text_store_unittest.cc b/ui/base/ime/win/tsf_text_store_unittest.cc | ||
index 081809d75a1fbbedbcbc722302d4d915eabc46d4..4e81d7c1012f86712f1bba2bfe4037ed1ef79772 100644 | ||
--- a/ui/base/ime/win/tsf_text_store_unittest.cc | ||
+++ b/ui/base/ime/win/tsf_text_store_unittest.cc | ||
@@ -3394,5 +3394,92 @@ TEST_F(TSFTextStoreTest, RegressionTest7) { | ||
EXPECT_EQ(S_OK, result); | ||
} | ||
|
||
+// regression tests for crbug.com/1091069. | ||
+// We should allow inserting empty compositon string to cancel composition. | ||
+class RegressionTest8Callback : public TSFTextStoreTestCallback { | ||
+ public: | ||
+ explicit RegressionTest8Callback(TSFTextStore* text_store) | ||
+ : TSFTextStoreTestCallback(text_store) {} | ||
+ | ||
+ HRESULT LockGranted1(DWORD flags) { | ||
+ SetTextTest(0, 0, L"bbbb", S_OK); | ||
+ SetSelectionTest(0, 4, S_OK); | ||
+ | ||
+ text_spans()->clear(); | ||
+ ImeTextSpan text_span_1; | ||
+ text_span_1.start_offset = 0; | ||
+ text_span_1.end_offset = 4; | ||
+ text_span_1.underline_color = SK_ColorBLACK; | ||
+ text_span_1.thickness = ImeTextSpan::Thickness::kThin; | ||
+ text_span_1.background_color = SK_ColorTRANSPARENT; | ||
+ text_spans()->push_back(text_span_1); | ||
+ | ||
+ *edit_flag() = true; | ||
+ *composition_start() = 0; | ||
+ composition_range()->set_start(0); | ||
+ composition_range()->set_end(4); | ||
+ *has_composition_range() = true; | ||
+ | ||
+ text_store_->OnKeyTraceDown(65u, 1966081u); | ||
+ return S_OK; | ||
+ } | ||
+ | ||
+ void SetCompositionText1(const ui::CompositionText& composition) { | ||
+ EXPECT_EQ(L"bbbb", composition.text); | ||
+ EXPECT_EQ(0u, composition.selection.start()); | ||
+ EXPECT_EQ(4u, composition.selection.end()); | ||
+ ASSERT_EQ(1u, composition.ime_text_spans.size()); | ||
+ EXPECT_EQ(0u, composition.ime_text_spans[0].start_offset); | ||
+ EXPECT_EQ(4u, composition.ime_text_spans[0].end_offset); | ||
+ SetHasCompositionText(true); | ||
+ } | ||
+ | ||
+ HRESULT LockGranted2(DWORD flags) { | ||
+ GetTextTest(0, -1, L"bbbb", 4); | ||
+ SetTextTest(0, 4, L"", S_OK); | ||
+ | ||
+ text_spans()->clear(); | ||
+ *edit_flag() = true; | ||
+ *composition_start() = 0; | ||
+ composition_range()->set_start(0); | ||
+ composition_range()->set_end(0); | ||
+ | ||
+ *has_composition_range() = false; | ||
+ text_store_->OnKeyTraceUp(65u, 1966081u); | ||
+ return S_OK; | ||
+ } | ||
+ | ||
+ void ClearCompositionText2() { EXPECT_EQ(false, *has_composition_range()); } | ||
+ | ||
+ private: | ||
+ DISALLOW_COPY_AND_ASSIGN(RegressionTest8Callback); | ||
+}; | ||
+ | ||
+TEST_F(TSFTextStoreTest, RegressionTest8) { | ||
+ RegressionTest8Callback callback(text_store_.get()); | ||
+ EXPECT_CALL(text_input_client_, SetCompositionText(_)) | ||
+ .WillOnce( | ||
+ Invoke(&callback, &RegressionTest8Callback::SetCompositionText1)); | ||
+ | ||
+ EXPECT_CALL(text_input_client_, ClearCompositionText()) | ||
+ .WillOnce( | ||
+ Invoke(&callback, &RegressionTest8Callback::ClearCompositionText2)); | ||
+ | ||
+ EXPECT_CALL(*sink_, OnLockGranted(_)) | ||
+ .WillOnce(Invoke(&callback, &RegressionTest8Callback::LockGranted1)) | ||
+ .WillOnce(Invoke(&callback, &RegressionTest8Callback::LockGranted2)); | ||
+ | ||
+ ON_CALL(text_input_client_, HasCompositionText()) | ||
+ .WillByDefault( | ||
+ Invoke(&callback, &TSFTextStoreTestCallback::HasCompositionText)); | ||
+ | ||
+ HRESULT result = kInvalidResult; | ||
+ EXPECT_EQ(S_OK, text_store_->RequestLock(TS_LF_READWRITE, &result)); | ||
+ EXPECT_EQ(S_OK, result); | ||
+ result = kInvalidResult; | ||
+ EXPECT_EQ(S_OK, text_store_->RequestLock(TS_LF_READWRITE, &result)); | ||
+ EXPECT_EQ(S_OK, result); | ||
+} | ||
+ | ||
} // namespace | ||
} // namespace ui |