40 const std::string action_string) {
42 return fuchsia::ui::input::InputMethodAction::NEWLINE;
44 return fuchsia::ui::input::InputMethodAction::DONE;
46 return fuchsia::ui::input::InputMethodAction::GO;
48 return fuchsia::ui::input::InputMethodAction::NEXT;
50 return fuchsia::ui::input::InputMethodAction::PREVIOUS;
52 return fuchsia::ui::input::InputMethodAction::NONE;
54 return fuchsia::ui::input::InputMethodAction::SEARCH;
56 return fuchsia::ui::input::InputMethodAction::SEND;
58 return fuchsia::ui::input::InputMethodAction::UNSPECIFIED;
62 FML_VLOG(1) <<
"unexpected action_string: " << action_string;
64 return fuchsia::ui::input::InputMethodAction::DONE;
69 fuchsia::ui::input::InputMethodAction
action) {
70 if (
action == fuchsia::ui::input::InputMethodAction::NEWLINE) {
72 }
else if (
action == fuchsia::ui::input::InputMethodAction::DONE) {
74 }
else if (
action == fuchsia::ui::input::InputMethodAction::GO) {
76 }
else if (
action == fuchsia::ui::input::InputMethodAction::NEXT) {
78 }
else if (
action == fuchsia::ui::input::InputMethodAction::PREVIOUS) {
80 }
else if (
action == fuchsia::ui::input::InputMethodAction::NONE) {
82 }
else if (
action == fuchsia::ui::input::InputMethodAction::SEARCH) {
84 }
else if (
action == fuchsia::ui::input::InputMethodAction::SEND) {
86 }
else if (
action == fuchsia::ui::input::InputMethodAction::UNSPECIFIED) {
91 FML_VLOG(1) <<
"unexpected action: " <<
static_cast<uint32_t
>(
action);
114 fuchsia::ui::views::ViewRef view_ref,
115 fuchsia::ui::input::ImeServiceHandle ime_service,
116 fuchsia::ui::input3::KeyboardHandle keyboard,
117 std::function<
void(std::unique_ptr<flutter::PlatformMessage>)>
119 : dispatch_callback_(dispatch_callback),
121 text_sync_service_(ime_service.Bind()),
122 keyboard_listener_binding_(this),
132 keyboard_->AddListener(std::move(view_ref),
133 keyboard_listener_binding_.NewBinding(), [] {});
166 fuchsia::ui::input::TextInputState state,
167 std::unique_ptr<fuchsia::ui::input::InputEvent> input_event) {
168 rapidjson::Document document;
169 auto&
allocator = document.GetAllocator();
170 rapidjson::Value encoded_state(rapidjson::kObjectType);
171 encoded_state.AddMember(
"text", state.text,
allocator);
172 encoded_state.AddMember(
"selectionBase", state.selection.base,
allocator);
173 encoded_state.AddMember(
"selectionExtent", state.selection.extent,
allocator);
174 switch (state.selection.affinity) {
175 case fuchsia::ui::input::TextAffinity::UPSTREAM:
176 encoded_state.AddMember(
"selectionAffinity",
177 rapidjson::Value(
"TextAffinity.upstream"),
180 case fuchsia::ui::input::TextAffinity::DOWNSTREAM:
181 encoded_state.AddMember(
"selectionAffinity",
182 rapidjson::Value(
"TextAffinity.downstream"),
186 encoded_state.AddMember(
"selectionIsDirectional",
true,
allocator);
187 encoded_state.AddMember(
"composingBase", state.composing.start,
allocator);
188 encoded_state.AddMember(
"composingExtent", state.composing.end,
allocator);
190 rapidjson::Value
args(rapidjson::kArrayType);
194 document.SetObject();
195 document.AddMember(
"method",
196 rapidjson::Value(
"TextInputClient.updateEditingState"),
200 rapidjson::StringBuffer buffer;
201 rapidjson::Writer<rapidjson::StringBuffer> writer(buffer);
202 document.Accept(writer);
204 const uint8_t* data =
reinterpret_cast<const uint8_t*
>(buffer.GetString());
205 dispatch_callback_(std::make_unique<flutter::PlatformMessage>(
210 last_text_state_ = std::move(state);
215 rapidjson::Document document;
216 auto&
allocator = document.GetAllocator();
218 rapidjson::Value
args(rapidjson::kArrayType);
222 args.PushBack(rapidjson::Value{}.SetString(action_string.c_str(),
223 action_string.length()),
226 document.SetObject();
228 "method", rapidjson::Value(
"TextInputClient.performAction"),
allocator);
231 rapidjson::StringBuffer buffer;
232 rapidjson::Writer<rapidjson::StringBuffer> writer(buffer);
233 document.Accept(writer);
235 const uint8_t* data =
reinterpret_cast<const uint8_t*
>(buffer.GetString());
236 dispatch_callback_(std::make_unique<flutter::PlatformMessage>(
245 std::unique_ptr<flutter::PlatformMessage>
message) {
247 const auto& data =
message->data();
249 rapidjson::Document document;
250 document.Parse(
reinterpret_cast<const char*
>(data.GetMapping()),
252 if (document.HasParseError() || !document.IsObject()) {
255 auto root = document.GetObject();
256 auto method = root.FindMember(
"method");
257 if (method == root.MemberEnd() || !method->value.IsString()) {
261 if (method->value ==
"TextInput.show") {
263 text_sync_service_->ShowKeyboard();
265 }
else if (method->value ==
"TextInput.hide") {
267 text_sync_service_->HideKeyboard();
269 }
else if (method->value ==
"TextInput.setClient") {
299 current_text_input_client_ = 0;
301 auto args = root.FindMember(
"args");
302 if (
args == root.MemberEnd() || !
args->value.IsArray() ||
303 args->value.Size() != 2)
305 const auto& configuration =
args->value[1];
306 if (!configuration.IsObject()) {
310 current_text_input_client_ =
args->value[0].GetInt();
312 auto initial_text_input_state = fuchsia::ui::input::TextInputState{};
313 initial_text_input_state.text =
"";
314 last_text_state_ = std::move(initial_text_input_state);
316 const auto configuration_object = configuration.GetObject();
321 if (!action_object.IsString()) {
324 const auto action_string =
325 std::string(action_object.GetString(), action_object.GetStringLength());
327 }
else if (method->value ==
"TextInput.setEditingState") {
329 auto args_it = root.FindMember(
"args");
330 if (args_it == root.MemberEnd() || !args_it->value.IsObject()) {
333 const auto&
args = args_it->value;
334 fuchsia::ui::input::TextInputState state;
337 auto text =
args.FindMember(
"text");
338 if (
text !=
args.MemberEnd() &&
text->value.IsString()) {
339 state.text =
text->value.GetString();
341 auto selection_base =
args.FindMember(
"selectionBase");
342 if (selection_base !=
args.MemberEnd() && selection_base->value.IsInt()) {
343 state.selection.base = selection_base->value.GetInt();
345 auto selection_extent =
args.FindMember(
"selectionExtent");
346 if (selection_extent !=
args.MemberEnd() &&
347 selection_extent->value.IsInt()) {
348 state.selection.extent = selection_extent->value.GetInt();
350 auto selection_affinity =
args.FindMember(
"selectionAffinity");
351 if (selection_affinity !=
args.MemberEnd() &&
352 selection_affinity->value.IsString() &&
353 selection_affinity->value ==
"TextAffinity.upstream") {
354 state.selection.affinity = fuchsia::ui::input::TextAffinity::UPSTREAM;
356 state.selection.affinity = fuchsia::ui::input::TextAffinity::DOWNSTREAM;
360 auto composing_base =
args.FindMember(
"composingBase");
361 if (composing_base !=
args.MemberEnd() && composing_base->value.IsInt()) {
362 state.composing.start = composing_base->value.GetInt();
364 auto composing_extent =
args.FindMember(
"composingExtent");
365 if (composing_extent !=
args.MemberEnd() &&
366 composing_extent->value.IsInt()) {
367 state.composing.end = composing_extent->value.GetInt();
369 ime_->SetState(std::move(state));
371 }
else if (method->value ==
"TextInput.clearClient") {
372 current_text_input_client_ = 0;
373 last_text_state_ = std::nullopt;
374 requested_text_action_ = std::nullopt;
376 }
else if (method->value ==
"TextInput.setCaretRect" ||
377 method->value ==
"TextInput.setEditableSizeAndTransform" ||
378 method->value ==
"TextInput.setMarkedTextRect" ||
379 method->value ==
"TextInput.setStyle") {
388 << method->value.GetString();
397 fuchsia::ui::input3::KeyboardListener::OnKeyEventCallback
callback) {
398 const char*
type =
nullptr;
400 case fuchsia::ui::input3::KeyEventType::PRESSED:
403 case fuchsia::ui::input3::KeyEventType::RELEASED:
406 case fuchsia::ui::input3::KeyEventType::SYNC:
410 case fuchsia::ui::input3::KeyEventType::CANCEL:
418 if (
type ==
nullptr) {
419 FML_VLOG(1) <<
"Unknown key event phase.";
420 callback(fuchsia::ui::input3::KeyEventStatus::NOT_HANDLED);
425 rapidjson::Document document;
426 auto&
allocator = document.GetAllocator();
427 document.SetObject();
429 document.AddMember(
"keymap", rapidjson::Value(
"fuchsia"),
allocator);
430 document.AddMember(
"hidUsage", keyboard_translator_.
LastHIDUsage(),
432 document.AddMember(
"codePoint", keyboard_translator_.
LastCodePoint(),
435 rapidjson::StringBuffer buffer;
436 rapidjson::Writer<rapidjson::StringBuffer> writer(buffer);
437 document.Accept(writer);
439 const uint8_t* data =
reinterpret_cast<const uint8_t*
>(buffer.GetString());
440 dispatch_callback_(std::make_unique<flutter::PlatformMessage>(
445 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.