Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.
Closed
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
51 changes: 51 additions & 0 deletions shell/platform/windows/text_input_plugin.cc
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ static constexpr char kClearClientMethod[] = "TextInput.clearClient";
static constexpr char kSetClientMethod[] = "TextInput.setClient";
static constexpr char kShowMethod[] = "TextInput.show";
static constexpr char kHideMethod[] = "TextInput.hide";
static constexpr char kSetMarkedTextRect[] = "TextInput.setMarkedTextRect";
static constexpr char kSetEditableSizeAndTransform[] =
"TextInput.setEditableSizeAndTransform";

static constexpr char kMultilineInputType[] = "TextInputType.multiline";

Expand All @@ -34,6 +37,11 @@ static constexpr char kSelectionBaseKey[] = "selectionBase";
static constexpr char kSelectionExtentKey[] = "selectionExtent";
static constexpr char kSelectionIsDirectionalKey[] = "selectionIsDirectional";
static constexpr char kTextKey[] = "text";
static constexpr char kXKey[] = "x";
static constexpr char kYKey[] = "y";
static constexpr char kWidthKey[] = "width";
static constexpr char kHeightKey[] = "height";
static constexpr char kTransformKey[] = "transform";

static constexpr char kChannelName[] = "flutter/textinput";

Expand Down Expand Up @@ -171,6 +179,49 @@ void TextInputPlugin::HandleMethodCall(
}
active_model_->SetText(text->value.GetString());
active_model_->SetSelection(TextRange(base, extent));
} else if (method.compare(kSetMarkedTextRect) == 0) {
if (!method_call.arguments() || method_call.arguments()->IsNull()) {
result->Error(kBadArgumentError, "Method invoked without args");
return;
}
const rapidjson::Document& args = *method_call.arguments();
auto x = args.FindMember(kXKey);
auto y = args.FindMember(kYKey);
auto width = args.FindMember(kWidthKey);
auto height = args.FindMember(kHeightKey);
if (x == args.MemberEnd() || x->value.IsNull() ||
y == args.MemberEnd() || y->value.IsNull() ||
width == args.MemberEnd() || width->value.IsNull() ||
height == args.MemberEnd() || height->value.IsNull()) {
result->Error(kInternalConsistencyError, "Composing rect values invalid.");
return;
}
compose_rect_.x = x->value.GetDouble();
compose_rect_.y = y->value.GetDouble();
compose_rect_.width = width->value.GetDouble();
compose_rect_.height = height->value.GetDouble();
} else if (method.compare(kSetEditableSizeAndTransform) == 0) {
if (!method_call.arguments() || method_call.arguments()->IsNull()) {
result->Error(kBadArgumentError, "Method invoked without args");
return;
}
const rapidjson::Document& args = *method_call.arguments();
auto transform = args.FindMember(kTransformKey);
if (transform == args.MemberEnd() || transform->value.IsNull() ||
!transform->value.IsArray() || transform->value.Size() != 16) {
result->Error(kInternalConsistencyError, "EditableText transform invalid.");
return;
}
size_t i = 0;
for (auto& entry : transform->value.GetArray()) {
if (entry.IsNull()) {
result->Error(kInternalConsistencyError,
"EditableText transform contains null value.");
return;
}
editabletext_transform_[i / 4][i % 4] = entry.GetDouble();
++i;
}
} else {
result->NotImplemented();
return;
Expand Down
29 changes: 29 additions & 0 deletions shell/platform/windows/text_input_plugin.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,21 @@ namespace flutter {

class FlutterWindowsView;

// A rectangle with a position and extent.
//
// Used to store the current composing rectangle when using multi-step (IME)
// text input.
struct Rect {
Rect() = default;
Rect(const Rect& rect) = default;
Rect& operator=(const Rect& other) = default;

double x;
double y;
double width;
double height;
};

// Implements a text input plugin.
//
// Specifically handles window events within windows.
Expand Down Expand Up @@ -50,6 +65,10 @@ class TextInputPlugin : public KeyboardHookHandler {
const flutter::MethodCall<rapidjson::Document>& method_call,
std::unique_ptr<flutter::MethodResult<rapidjson::Document>> result);

void SetMarkedTextRect(
const flutter::MethodCall<rapidjson::Document>& method_call,
std::unique_ptr<flutter::MethodResult<rapidjson::Document>> result);

// The MethodChannel used for communication with the Flutter engine.
std::unique_ptr<flutter::MethodChannel<rapidjson::Document>> channel_;

Expand All @@ -66,6 +85,16 @@ class TextInputPlugin : public KeyboardHookHandler {
// An action requested by the user on the input client. See available options:
// https://api.flutter.dev/flutter/services/TextInputAction-class.html
std::string input_action_;

// The smallest rect, in local coordinates, of the text in the composing
// range, or of the caret in the case where there is no current composing
// range. This value is updated via `TextInput.setMarkedTextRect` messages
// over the text input channel.
Rect compose_rect_;

// A 4x4 matrix that maps from `EditableText` local coordinates to the
// coordinate system of `PipelineOwner.rootNode`.
double editabletext_transform_[4][4];
};

} // namespace flutter
Expand Down