From 83ee03c4e16883c84036ed885c9e695dcb1b3ad5 Mon Sep 17 00:00:00 2001 From: schectman Date: Mon, 11 Sep 2023 16:43:51 -0400 Subject: [PATCH 1/3] Use start instead of extent --- shell/platform/windows/text_input_plugin.cc | 2 +- .../windows/text_input_plugin_unittest.cc | 58 ++++++++++++++++++- 2 files changed, 58 insertions(+), 2 deletions(-) diff --git a/shell/platform/windows/text_input_plugin.cc b/shell/platform/windows/text_input_plugin.cc index 340092e3edb79..08c0007a4d083 100644 --- a/shell/platform/windows/text_input_plugin.cc +++ b/shell/platform/windows/text_input_plugin.cc @@ -196,7 +196,7 @@ void TextInputPlugin::ComposeChangeHook(const std::u16string& text, 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(); + cursor_pos += active_model_->composing_range().start(); active_model_->UpdateComposingText(text); active_model_->SetSelection(TextRange(cursor_pos, cursor_pos)); std::string text_after_change = active_model_->GetText(); diff --git a/shell/platform/windows/text_input_plugin_unittest.cc b/shell/platform/windows/text_input_plugin_unittest.cc index 7d4705096441d..dca36014c216a 100644 --- a/shell/platform/windows/text_input_plugin_unittest.cc +++ b/shell/platform/windows/text_input_plugin_unittest.cc @@ -36,6 +36,8 @@ static constexpr char kSelectionAffinityKey[] = "selectionAffinity"; static constexpr char kSelectionIsDirectionalKey[] = "selectionIsDirectional"; static constexpr char kComposingBaseKey[] = "composingBase"; static constexpr char kComposingExtentKey[] = "composingExtent"; +static constexpr char kUpdateEditingStateMethod[] = + "TextInputClient.updateEditingState"; static std::unique_ptr> CreateResponse(bool handled) { auto response_doc = @@ -243,7 +245,7 @@ TEST(TextInputPluginTest, VerifyInputActionNewlineInsertNewLine) { // Editing state should have been updated. auto encoded_arguments = EncodedEditingState("\n", TextRange(1)); auto update_state_message = codec.EncodeMethodCall( - {"TextInputClient.updateEditingState", std::move(encoded_arguments)}); + {kUpdateEditingStateMethod, std::move(encoded_arguments)}); EXPECT_TRUE(std::equal(update_state_message->begin(), update_state_message->end(), @@ -366,6 +368,60 @@ TEST(TextInputPluginTest, TextEditingWorksWithDeltaModel) { // Passes if it did not crash } +TEST(TextInputPluginTest, CompositionCursorPos) { + int selection_base = -1; + TestBinaryMessenger messenger([&](const std::string& channel, + const uint8_t* message, size_t size, + BinaryReply reply) { + auto method = JsonMethodCodec::GetInstance().DecodeMethodCall( + std::vector(message, message + size)); + if (method->method_name() == kUpdateEditingStateMethod) { + const auto& args = *method->arguments(); + const auto& editing_state = args[1]; + auto base = editing_state.FindMember(kSelectionBaseKey); + ASSERT_NE(base, editing_state.MemberEnd()); + ASSERT_TRUE(base->value.IsInt()); + selection_base = base->value.GetInt(); + } + }); + MockTextInputPluginDelegate delegate; + + TextInputPlugin plugin(&messenger, &delegate); + + auto args = std::make_unique(rapidjson::kArrayType); + auto& allocator = args->GetAllocator(); + args->PushBack(123, allocator); // client_id + rapidjson::Value client_config(rapidjson::kObjectType); + args->PushBack(client_config, allocator); + auto encoded = JsonMethodCodec::GetInstance().EncodeMethodCall( + MethodCall(kSetClientMethod, std::move(args))); + EXPECT_TRUE(messenger.SimulateEngineMessage( + kChannelName, encoded->data(), encoded->size(), + [](const uint8_t* reply, size_t reply_size) {})); + + plugin.ComposeBeginHook(); + EXPECT_EQ(selection_base, 0); + plugin.ComposeChangeHook(u"abc", 3); + EXPECT_EQ(selection_base, 3); + + plugin.ComposeCommitHook(); + plugin.ComposeEndHook(); + EXPECT_EQ(selection_base, 3); + + plugin.ComposeBeginHook(); + plugin.ComposeChangeHook(u"1", 1); + EXPECT_EQ(selection_base, 4); + + plugin.ComposeChangeHook(u"12", 2); + EXPECT_EQ(selection_base, 5); + + plugin.ComposeChangeHook(u"12", 1); + EXPECT_EQ(selection_base, 4); + + plugin.ComposeChangeHook(u"12", 2); + EXPECT_EQ(selection_base, 5); +} + TEST(TextInputPluginTest, TransformCursorRect) { // A position of `EditableText`. double view_x = 100; From 68d5462ce77141fa0c43323a2d926c87fadc0bf0 Mon Sep 17 00:00:00 2001 From: schectman Date: Tue, 12 Sep 2023 12:18:52 -0400 Subject: [PATCH 2/3] Feedback --- shell/platform/windows/text_input_plugin_unittest.cc | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/shell/platform/windows/text_input_plugin_unittest.cc b/shell/platform/windows/text_input_plugin_unittest.cc index dca36014c216a..fcb288ffb426d 100644 --- a/shell/platform/windows/text_input_plugin_unittest.cc +++ b/shell/platform/windows/text_input_plugin_unittest.cc @@ -368,6 +368,7 @@ TEST(TextInputPluginTest, TextEditingWorksWithDeltaModel) { // Passes if it did not crash } +// Regression test for https://github.com/flutter/flutter/issues/123749 TEST(TextInputPluginTest, CompositionCursorPos) { int selection_base = -1; TestBinaryMessenger messenger([&](const std::string& channel, @@ -379,9 +380,13 @@ TEST(TextInputPluginTest, CompositionCursorPos) { const auto& args = *method->arguments(); const auto& editing_state = args[1]; auto base = editing_state.FindMember(kSelectionBaseKey); + auto extent = editing_state.FindMember(kSelectionExtentKey); ASSERT_NE(base, editing_state.MemberEnd()); ASSERT_TRUE(base->value.IsInt()); + ASSERT_NE(extent, editing_state.MemberEnd()); + ASSERT_TRUE(extent->value.IsInt()); selection_base = base->value.GetInt(); + EXPECT_EQ(selection_extent, 0); } }); MockTextInputPluginDelegate delegate; From 6811e608d4d0a265237354e237167499b6fcdf1b Mon Sep 17 00:00:00 2001 From: schectman Date: Tue, 12 Sep 2023 12:49:15 -0400 Subject: [PATCH 3/3] Unit test feedback --- shell/platform/windows/text_input_plugin_unittest.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shell/platform/windows/text_input_plugin_unittest.cc b/shell/platform/windows/text_input_plugin_unittest.cc index fcb288ffb426d..a99e0149aa286 100644 --- a/shell/platform/windows/text_input_plugin_unittest.cc +++ b/shell/platform/windows/text_input_plugin_unittest.cc @@ -386,7 +386,7 @@ TEST(TextInputPluginTest, CompositionCursorPos) { ASSERT_NE(extent, editing_state.MemberEnd()); ASSERT_TRUE(extent->value.IsInt()); selection_base = base->value.GetInt(); - EXPECT_EQ(selection_extent, 0); + EXPECT_EQ(extent->value.GetInt(), selection_base); } }); MockTextInputPluginDelegate delegate;