Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion shell/platform/windows/text_input_plugin.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down
63 changes: 62 additions & 1 deletion shell/platform/windows/text_input_plugin_unittest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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<std::vector<uint8_t>> CreateResponse(bool handled) {
auto response_doc =
Expand Down Expand Up @@ -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)});
Copy link
Member

@cbracken cbracken Sep 12, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for cleaning this up while you're in here!


EXPECT_TRUE(std::equal(update_state_message->begin(),
update_state_message->end(),
Expand Down Expand Up @@ -366,6 +368,65 @@ 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,
const uint8_t* message, size_t size,
BinaryReply reply) {
auto method = JsonMethodCodec::GetInstance().DecodeMethodCall(
std::vector<uint8_t>(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);
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(extent->value.GetInt(), selection_base);
}
});
MockTextInputPluginDelegate delegate;

TextInputPlugin plugin(&messenger, &delegate);

auto args = std::make_unique<rapidjson::Document>(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<rapidjson::Document>(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;
Expand Down