42 const std::string action_string) {
44 return fuchsia::ui::input::InputMethodAction::NEWLINE;
46 return fuchsia::ui::input::InputMethodAction::DONE;
48 return fuchsia::ui::input::InputMethodAction::GO;
50 return fuchsia::ui::input::InputMethodAction::NEXT;
52 return fuchsia::ui::input::InputMethodAction::PREVIOUS;
54 return fuchsia::ui::input::InputMethodAction::NONE;
56 return fuchsia::ui::input::InputMethodAction::SEARCH;
58 return fuchsia::ui::input::InputMethodAction::SEND;
60 return fuchsia::ui::input::InputMethodAction::UNSPECIFIED;
64 FML_VLOG(1) <<
"unexpected action_string: " << action_string;
66 return fuchsia::ui::input::InputMethodAction::DONE;
71 fuchsia::ui::input::InputMethodAction
action) {
72 if (
action == fuchsia::ui::input::InputMethodAction::NEWLINE) {
74 }
else if (
action == fuchsia::ui::input::InputMethodAction::DONE) {
76 }
else if (
action == fuchsia::ui::input::InputMethodAction::GO) {
78 }
else if (
action == fuchsia::ui::input::InputMethodAction::NEXT) {
80 }
else if (
action == fuchsia::ui::input::InputMethodAction::PREVIOUS) {
82 }
else if (
action == fuchsia::ui::input::InputMethodAction::NONE) {
84 }
else if (
action == fuchsia::ui::input::InputMethodAction::SEARCH) {
86 }
else if (
action == fuchsia::ui::input::InputMethodAction::SEND) {
88 }
else if (
action == fuchsia::ui::input::InputMethodAction::UNSPECIFIED) {
93 FML_VLOG(1) <<
"unexpected action: " <<
static_cast<uint32_t
>(
action);
116 fuchsia::ui::views::ViewRef view_ref,
117 fuchsia::ui::input::ImeServiceHandle ime_service,
118 fuchsia::ui::input3::KeyboardHandle keyboard,
119 std::function<
void(std::unique_ptr<flutter::PlatformMessage>)>
121 : dispatch_callback_(dispatch_callback),
123 text_sync_service_(ime_service.Bind()),
124 keyboard_listener_binding_(this),
134 keyboard_->AddListener(std::move(view_ref),
135 keyboard_listener_binding_.NewBinding(), [] {});
168 fuchsia::ui::input::TextInputState
state,
169 std::unique_ptr<fuchsia::ui::input::InputEvent> input_event) {
170 rapidjson::Document document;
171 auto& allocator = document.GetAllocator();
172 rapidjson::Value encoded_state(rapidjson::kObjectType);
173 encoded_state.AddMember(
"text",
state.text, allocator);
174 encoded_state.AddMember(
"selectionBase",
state.selection.base, allocator);
175 encoded_state.AddMember(
"selectionExtent",
state.selection.extent, allocator);
176 switch (
state.selection.affinity) {
177 case fuchsia::ui::input::TextAffinity::UPSTREAM:
178 encoded_state.AddMember(
"selectionAffinity",
179 rapidjson::Value(
"TextAffinity.upstream"),
182 case fuchsia::ui::input::TextAffinity::DOWNSTREAM:
183 encoded_state.AddMember(
"selectionAffinity",
184 rapidjson::Value(
"TextAffinity.downstream"),
188 encoded_state.AddMember(
"selectionIsDirectional",
true, allocator);
189 encoded_state.AddMember(
"composingBase",
state.composing.start, allocator);
190 encoded_state.AddMember(
"composingExtent",
state.composing.end, allocator);
192 rapidjson::Value
args(rapidjson::kArrayType);
193 args.PushBack(current_text_input_client_, allocator);
194 args.PushBack(encoded_state, allocator);
196 document.SetObject();
197 document.AddMember(
"method",
198 rapidjson::Value(
"TextInputClient.updateEditingState"),
200 document.AddMember(
"args",
args, allocator);
202 rapidjson::StringBuffer
buffer;
203 rapidjson::Writer<rapidjson::StringBuffer> writer(
buffer);
204 document.Accept(writer);
206 const uint8_t* data =
reinterpret_cast<const uint8_t*
>(
buffer.GetString());
207 dispatch_callback_(std::make_unique<flutter::PlatformMessage>(
212 last_text_state_ = std::move(
state);
217 rapidjson::Document document;
218 auto& allocator = document.GetAllocator();
220 rapidjson::Value
args(rapidjson::kArrayType);
221 args.PushBack(current_text_input_client_, allocator);
224 args.PushBack(rapidjson::Value{}.SetString(action_string.c_str(),
225 action_string.length()),
228 document.SetObject();
230 "method", rapidjson::Value(
"TextInputClient.performAction"), allocator);
231 document.AddMember(
"args",
args, allocator);
233 rapidjson::StringBuffer
buffer;
234 rapidjson::Writer<rapidjson::StringBuffer> writer(
buffer);
235 document.Accept(writer);
237 const uint8_t* data =
reinterpret_cast<const uint8_t*
>(
buffer.GetString());
238 dispatch_callback_(std::make_unique<flutter::PlatformMessage>(
247 std::unique_ptr<flutter::PlatformMessage>
message) {
249 const auto& data =
message->data();
251 rapidjson::Document document;
252 document.Parse(
reinterpret_cast<const char*
>(data.GetMapping()),
254 if (document.HasParseError() || !document.IsObject()) {
257 auto root = document.GetObject();
258 auto method = root.FindMember(
"method");
259 if (method == root.MemberEnd() || !method->value.IsString()) {
263 if (method->value ==
"TextInput.show") {
265 text_sync_service_->ShowKeyboard();
267 }
else if (method->value ==
"TextInput.hide") {
269 text_sync_service_->HideKeyboard();
271 }
else if (method->value ==
"TextInput.setClient") {
301 current_text_input_client_ = 0;
303 auto args = root.FindMember(
"args");
304 if (
args == root.MemberEnd() || !
args->value.IsArray() ||
305 args->value.Size() != 2)
307 const auto& configuration =
args->value[1];
308 if (!configuration.IsObject()) {
312 current_text_input_client_ =
args->value[0].GetInt();
314 auto initial_text_input_state = fuchsia::ui::input::TextInputState{};
315 initial_text_input_state.text =
"";
316 last_text_state_ = std::move(initial_text_input_state);
318 const auto configuration_object = configuration.GetObject();
323 if (!action_object.IsString()) {
326 const auto action_string =
327 std::string(action_object.GetString(), action_object.GetStringLength());
329 }
else if (method->value ==
"TextInput.setEditingState") {
331 auto args_it = root.FindMember(
"args");
332 if (args_it == root.MemberEnd() || !args_it->value.IsObject()) {
335 const auto&
args = args_it->value;
336 fuchsia::ui::input::TextInputState
state;
339 auto text =
args.FindMember(
"text");
340 if (
text !=
args.MemberEnd() &&
text->value.IsString()) {
343 auto selection_base =
args.FindMember(
"selectionBase");
344 if (selection_base !=
args.MemberEnd() && selection_base->value.IsInt()) {
345 state.selection.base = selection_base->value.GetInt();
347 auto selection_extent =
args.FindMember(
"selectionExtent");
348 if (selection_extent !=
args.MemberEnd() &&
349 selection_extent->value.IsInt()) {
350 state.selection.extent = selection_extent->value.GetInt();
352 auto selection_affinity =
args.FindMember(
"selectionAffinity");
353 if (selection_affinity !=
args.MemberEnd() &&
354 selection_affinity->value.IsString() &&
355 selection_affinity->value ==
"TextAffinity.upstream") {
356 state.selection.affinity = fuchsia::ui::input::TextAffinity::UPSTREAM;
358 state.selection.affinity = fuchsia::ui::input::TextAffinity::DOWNSTREAM;
362 auto composing_base =
args.FindMember(
"composingBase");
363 if (composing_base !=
args.MemberEnd() && composing_base->value.IsInt()) {
364 state.composing.start = composing_base->value.GetInt();
366 auto composing_extent =
args.FindMember(
"composingExtent");
367 if (composing_extent !=
args.MemberEnd() &&
368 composing_extent->value.IsInt()) {
369 state.composing.end = composing_extent->value.GetInt();
371 ime_->SetState(std::move(
state));
373 }
else if (method->value ==
"TextInput.clearClient") {
374 current_text_input_client_ = 0;
375 last_text_state_ = std::nullopt;
376 requested_text_action_ = std::nullopt;
378 }
else if (method->value ==
"TextInput.setCaretRect" ||
379 method->value ==
"TextInput.setEditableSizeAndTransform" ||
380 method->value ==
"TextInput.setMarkedTextRect" ||
381 method->value ==
"TextInput.setStyle") {
390 << method->value.GetString();
399 fuchsia::ui::input3::KeyboardListener::OnKeyEventCallback
callback) {
400 const char*
type =
nullptr;
402 case fuchsia::ui::input3::KeyEventType::PRESSED:
405 case fuchsia::ui::input3::KeyEventType::RELEASED:
408 case fuchsia::ui::input3::KeyEventType::SYNC:
412 case fuchsia::ui::input3::KeyEventType::CANCEL:
420 if (
type ==
nullptr) {
421 FML_VLOG(1) <<
"Unknown key event phase.";
422 callback(fuchsia::ui::input3::KeyEventStatus::NOT_HANDLED);
427 rapidjson::Document document;
428 auto& allocator = document.GetAllocator();
429 document.SetObject();
430 document.AddMember(
"type", rapidjson::Value(
type, strlen(
type)), allocator);
431 document.AddMember(
"keymap", rapidjson::Value(
"fuchsia"), allocator);
432 document.AddMember(
"hidUsage", keyboard_translator_.
LastHIDUsage(),
434 document.AddMember(
"codePoint", keyboard_translator_.
LastCodePoint(),
436 document.AddMember(
"modifiers", keyboard_translator_.
Modifiers(), allocator);
437 rapidjson::StringBuffer
buffer;
438 rapidjson::Writer<rapidjson::StringBuffer> writer(
buffer);
439 document.Accept(writer);
441 const uint8_t* data =
reinterpret_cast<const uint8_t*
>(
buffer.GetString());
442 dispatch_callback_(std::make_unique<flutter::PlatformMessage>(
447 callback(fuchsia::ui::input3::KeyEventStatus::HANDLED);
void DidUpdateState(fuchsia::ui::input::TextInputState state, std::unique_ptr< fuchsia::ui::input::InputEvent > event) override
void OnKeyEvent(fuchsia::ui::input3::KeyEvent key_event, fuchsia::ui::input3::KeyboardListener::OnKeyEventCallback callback) override
void OnAction(fuchsia::ui::input::InputMethodAction action) override
TextDelegate(fuchsia::ui::views::ViewRef view_ref, fuchsia::ui::input::ImeServiceHandle ime_service, fuchsia::ui::input3::KeyboardHandle keyboard, std::function< void(std::unique_ptr< flutter::PlatformMessage >)> dispatch_callback)
bool HandleFlutterTextInputChannelPlatformMessage(std::unique_ptr< flutter::PlatformMessage > message)
Channel handler for kTextInputChannel.
static const uint8_t buffer[]