Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
Classes | Enumerations | Functions | Variables
fl_text_input_plugin.cc File Reference
#include "flutter/shell/platform/linux/fl_text_input_plugin.h"
#include <gtk/gtk.h>
#include "flutter/shell/platform/common/text_editing_delta.h"
#include "flutter/shell/platform/common/text_input_model.h"
#include "flutter/shell/platform/linux/public/flutter_linux/fl_json_method_codec.h"
#include "flutter/shell/platform/linux/public/flutter_linux/fl_method_channel.h"

Go to the source code of this file.

Classes

struct  FlTextInputPluginPrivate
 

Enumerations

enum  FlTextInputType { kFlTextInputTypeText , kFlTextInputTypeMultiline , kFlTextInputTypeNone }
 

Functions

 G_DEFINE_TYPE_WITH_PRIVATE (FlTextInputPlugin, fl_text_input_plugin, G_TYPE_OBJECT) static gboolean finish_method(GObject *object
 
 if (response==nullptr)
 
return fl_method_response_get_result (response, error) !
 
static void update_editing_state_response_cb (GObject *object, GAsyncResult *result, gpointer user_data)
 
static void update_editing_state (FlTextInputPlugin *self)
 
static void update_editing_state_with_delta (FlTextInputPlugin *self, flutter::TextEditingDelta *delta)
 
static void perform_action_response_cb (GObject *object, GAsyncResult *result, gpointer user_data)
 
static void perform_action (FlTextInputPlugin *self)
 
static void im_preedit_start_cb (FlTextInputPlugin *self)
 
static void im_preedit_changed_cb (FlTextInputPlugin *self)
 
static void im_commit_cb (FlTextInputPlugin *self, const gchar *text)
 
static void im_preedit_end_cb (FlTextInputPlugin *self)
 
static gboolean im_retrieve_surrounding_cb (FlTextInputPlugin *self)
 
static gboolean im_delete_surrounding_cb (FlTextInputPlugin *self, gint offset, gint n_chars)
 
static FlMethodResponse * set_client (FlTextInputPlugin *self, FlValue *args)
 
static FlMethodResponse * hide (FlTextInputPlugin *self)
 
static FlMethodResponse * show (FlTextInputPlugin *self)
 
static FlMethodResponse * set_editing_state (FlTextInputPlugin *self, FlValue *args)
 
static FlMethodResponse * clear_client (FlTextInputPlugin *self)
 
static void update_im_cursor_position (FlTextInputPlugin *self)
 
static FlMethodResponse * set_editable_size_and_transform (FlTextInputPlugin *self, FlValue *args)
 
static FlMethodResponse * set_marked_text_rect (FlTextInputPlugin *self, FlValue *args)
 
static void method_call_cb (FlMethodChannel *channel, FlMethodCall *method_call, gpointer user_data)
 
static void fl_text_input_plugin_dispose (GObject *object)
 
static gboolean fl_text_input_plugin_filter_keypress_default (FlTextInputPlugin *self, FlKeyEvent *event)
 
static void fl_text_input_plugin_class_init (FlTextInputPluginClass *klass)
 
static void fl_text_input_plugin_init (FlTextInputPlugin *self)
 
static void init_im_context (FlTextInputPlugin *self, GtkIMContext *im_context)
 
FlTextInputPlugin * fl_text_input_plugin_new (FlBinaryMessenger *messenger, GtkIMContext *im_context, FlTextInputViewDelegate *view_delegate)
 
gboolean fl_text_input_plugin_filter_keypress (FlTextInputPlugin *self, FlKeyEvent *event)
 

Variables

static constexpr char kChannelName [] = "flutter/textinput"
 
static constexpr char kBadArgumentsError [] = "Bad Arguments"
 
static constexpr char kSetClientMethod [] = "TextInput.setClient"
 
static constexpr char kShowMethod [] = "TextInput.show"
 
static constexpr char kSetEditingStateMethod [] = "TextInput.setEditingState"
 
static constexpr char kClearClientMethod [] = "TextInput.clearClient"
 
static constexpr char kHideMethod [] = "TextInput.hide"
 
static constexpr char kUpdateEditingStateMethod []
 
static constexpr char kUpdateEditingStateWithDeltasMethod []
 
static constexpr char kPerformActionMethod [] = "TextInputClient.performAction"
 
static constexpr char kSetEditableSizeAndTransform []
 
static constexpr char kSetMarkedTextRect [] = "TextInput.setMarkedTextRect"
 
static constexpr char kInputActionKey [] = "inputAction"
 
static constexpr char kTextInputTypeKey [] = "inputType"
 
static constexpr char kEnableDeltaModel [] = "enableDeltaModel"
 
static constexpr char kTextInputTypeNameKey [] = "name"
 
static constexpr char kTextKey [] = "text"
 
static constexpr char kSelectionBaseKey [] = "selectionBase"
 
static constexpr char kSelectionExtentKey [] = "selectionExtent"
 
static constexpr char kSelectionAffinityKey [] = "selectionAffinity"
 
static constexpr char kSelectionIsDirectionalKey [] = "selectionIsDirectional"
 
static constexpr char kComposingBaseKey [] = "composingBase"
 
static constexpr char kComposingExtentKey [] = "composingExtent"
 
static constexpr char kTransform [] = "transform"
 
static constexpr char kTextAffinityDownstream [] = "TextAffinity.downstream"
 
static constexpr char kMultilineInputType [] = "TextInputType.multiline"
 
static constexpr char kNoneInputType [] = "TextInputType.none"
 
static constexpr char kNewlineInputAction [] = "TextInputAction.newline"
 
static constexpr int64_t kClientIdUnset = -1
 
GAsyncResult * result
 
GAsyncResult GError ** error
 

Enumeration Type Documentation

◆ FlTextInputType

Enumerator
kFlTextInputTypeText 
kFlTextInputTypeMultiline 
kFlTextInputTypeNone 

Definition at line 54 of file fl_text_input_plugin.cc.

54 {
56 // Send newline when multi-line and enter is pressed.
58 // The input method is not shown at all.
@ kFlTextInputTypeNone
@ kFlTextInputTypeMultiline
@ kFlTextInputTypeText

Function Documentation

◆ clear_client()

static FlMethodResponse * clear_client ( FlTextInputPlugin *  self)
static

Definition at line 468 of file fl_text_input_plugin.cc.

468 {
470 fl_text_input_plugin_get_instance_private(self));
471 priv->client_id = kClientIdUnset;
472
473 return FL_METHOD_RESPONSE(fl_method_success_response_new(nullptr));
474}
G_MODULE_EXPORT FlMethodSuccessResponse * fl_method_success_response_new(FlValue *result)
FlPixelBufferTexturePrivate * priv
static constexpr int64_t kClientIdUnset

◆ fl_method_response_get_result()

return fl_method_response_get_result ( response  ,
error   
)

◆ fl_text_input_plugin_class_init()

static void fl_text_input_plugin_class_init ( FlTextInputPluginClass *  klass)
static

Definition at line 700 of file fl_text_input_plugin.cc.

700 {
701 G_OBJECT_CLASS(klass)->dispose = fl_text_input_plugin_dispose;
702 FL_TEXT_INPUT_PLUGIN_CLASS(klass)->filter_keypress =
704}
static void fl_text_input_plugin_dispose(GObject *object)
static gboolean fl_text_input_plugin_filter_keypress_default(FlTextInputPlugin *self, FlKeyEvent *event)

◆ fl_text_input_plugin_dispose()

static void fl_text_input_plugin_dispose ( GObject *  object)
static

Definition at line 594 of file fl_text_input_plugin.cc.

594 {
595 FlTextInputPlugin* self = FL_TEXT_INPUT_PLUGIN(object);
597 fl_text_input_plugin_get_instance_private(self));
598
599 g_clear_object(&priv->channel);
600 g_clear_pointer(&priv->input_action, g_free);
601 g_clear_object(&priv->im_context);
602 if (priv->text_model != nullptr) {
603 delete priv->text_model;
604 priv->text_model = nullptr;
605 }
606 if (priv->view_delegate != nullptr) {
607 g_object_remove_weak_pointer(
608 G_OBJECT(priv->view_delegate),
609 reinterpret_cast<gpointer*>(&(priv->view_delegate)));
610 priv->view_delegate = nullptr;
611 }
612
613 G_OBJECT_CLASS(fl_text_input_plugin_parent_class)->dispose(object);
614}

◆ fl_text_input_plugin_filter_keypress()

gboolean fl_text_input_plugin_filter_keypress ( FlTextInputPlugin *  plugin,
FlKeyEvent event 
)

fl_text_input_plugin_filter_keypress @plugin: an #FlTextInputPlugin. @event: a FlKeyEvent

Process a Gdk key event.

Returns: TRUE if the event was used.

Definition at line 776 of file fl_text_input_plugin.cc.

777 {
778 g_return_val_if_fail(FL_IS_TEXT_INPUT_PLUGIN(self), FALSE);
779 if (FL_TEXT_INPUT_PLUGIN_GET_CLASS(self)->filter_keypress) {
780 return FL_TEXT_INPUT_PLUGIN_GET_CLASS(self)->filter_keypress(self, event);
781 }
782 return FALSE;
783}
FlKeyEvent * event
return FALSE

◆ fl_text_input_plugin_filter_keypress_default()

static gboolean fl_text_input_plugin_filter_keypress_default ( FlTextInputPlugin *  self,
FlKeyEvent event 
)
static

Definition at line 617 of file fl_text_input_plugin.cc.

619 {
620 g_return_val_if_fail(FL_IS_TEXT_INPUT_PLUGIN(self), false);
621
623 fl_text_input_plugin_get_instance_private(self));
624
625 if (priv->client_id == kClientIdUnset) {
626 return FALSE;
627 }
628
629 if (gtk_im_context_filter_keypress(
630 priv->im_context, reinterpret_cast<GdkEventKey*>(event->origin))) {
631 return TRUE;
632 }
633
634 std::string text_before_change = priv->text_model->GetText();
635 flutter::TextRange selection_before_change = priv->text_model->selection();
636 std::string text = priv->text_model->GetText();
637
638 // Handle the enter/return key.
639 gboolean do_action = FALSE;
640 // Handle navigation keys.
641 gboolean changed = FALSE;
642 if (event->is_press) {
643 switch (event->keyval) {
644 case GDK_KEY_End:
645 case GDK_KEY_KP_End:
646 if (event->state & GDK_SHIFT_MASK) {
647 changed = priv->text_model->SelectToEnd();
648 } else {
649 changed = priv->text_model->MoveCursorToEnd();
650 }
651 break;
652 case GDK_KEY_Return:
653 case GDK_KEY_KP_Enter:
654 case GDK_KEY_ISO_Enter:
655 if (priv->input_type == kFlTextInputTypeMultiline &&
656 strcmp(priv->input_action, kNewlineInputAction) == 0) {
657 priv->text_model->AddCodePoint('\n');
658 text = "\n";
659 changed = TRUE;
660 }
661 do_action = TRUE;
662 break;
663 case GDK_KEY_Home:
664 case GDK_KEY_KP_Home:
665 if (event->state & GDK_SHIFT_MASK) {
666 changed = priv->text_model->SelectToBeginning();
667 } else {
668 changed = priv->text_model->MoveCursorToBeginning();
669 }
670 break;
671 case GDK_KEY_BackSpace:
672 case GDK_KEY_Delete:
673 case GDK_KEY_KP_Delete:
674 case GDK_KEY_Left:
675 case GDK_KEY_KP_Left:
676 case GDK_KEY_Right:
677 case GDK_KEY_KP_Right:
678 // Already handled inside the framework in RenderEditable.
679 break;
680 }
681 }
682
683 if (changed) {
684 if (priv->enable_delta_model) {
686 text_before_change, selection_before_change, text);
688 } else {
690 }
691 }
692 if (do_action) {
694 }
695
696 return changed;
697}
static constexpr char kNewlineInputAction[]
static void update_editing_state(FlTextInputPlugin *self)
static void perform_action(FlTextInputPlugin *self)
static void update_editing_state_with_delta(FlTextInputPlugin *self, flutter::TextEditingDelta *delta)
std::u16string text
GdkEvent * origin
GdkModifierType state
A change in the state of an input field.

◆ fl_text_input_plugin_init()

static void fl_text_input_plugin_init ( FlTextInputPlugin *  self)
static

Definition at line 707 of file fl_text_input_plugin.cc.

707 {
709 fl_text_input_plugin_get_instance_private(self));
710
711 priv->client_id = kClientIdUnset;
712 priv->input_type = kFlTextInputTypeText;
713 priv->text_model = new flutter::TextInputModel();
714}

◆ fl_text_input_plugin_new()

FlTextInputPlugin * fl_text_input_plugin_new ( FlBinaryMessenger *  messenger,
GtkIMContext *  im_context,
FlTextInputViewDelegate *  view_delegate 
)

fl_text_input_plugin_new: @messenger: an #FlBinaryMessenger. @im_context: (allow-none): a #GtkIMContext. @view_delegate: an #FlTextInputViewDelegate.

Creates a new plugin that implements SystemChannels.textInput from the Flutter services library.

Returns: a new #FlTextInputPlugin.

Definition at line 745 of file fl_text_input_plugin.cc.

748 {
749 g_return_val_if_fail(FL_IS_BINARY_MESSENGER(messenger), nullptr);
750 g_return_val_if_fail(GTK_IS_IM_CONTEXT(im_context), nullptr);
751 g_return_val_if_fail(FL_IS_TEXT_INPUT_VIEW_DELEGATE(view_delegate), nullptr);
752
753 FlTextInputPlugin* self = FL_TEXT_INPUT_PLUGIN(
754 g_object_new(fl_text_input_plugin_get_type(), nullptr));
755
756 g_autoptr(FlJsonMethodCodec) codec = fl_json_method_codec_new();
758 fl_text_input_plugin_get_instance_private(self));
759 priv->channel =
760 fl_method_channel_new(messenger, kChannelName, FL_METHOD_CODEC(codec));
762 nullptr);
763
764 init_im_context(self, im_context);
765
766 priv->view_delegate = view_delegate;
768 G_OBJECT(view_delegate),
769 reinterpret_cast<gpointer*>(&(priv->view_delegate)));
770
771 return self;
772}
G_MODULE_EXPORT FlJsonMethodCodec * fl_json_method_codec_new()
G_MODULE_EXPORT FlMethodChannel * fl_method_channel_new(FlBinaryMessenger *messenger, const gchar *name, FlMethodCodec *codec)
G_MODULE_EXPORT void fl_method_channel_set_method_call_handler(FlMethodChannel *self, FlMethodChannelMethodCallHandler handler, gpointer user_data, GDestroyNotify destroy_notify)
static void method_call_cb(FlMethodChannel *channel, FlMethodCall *method_call, gpointer user_data)
static void init_im_context(FlTextInputPlugin *self, GtkIMContext *im_context)
static constexpr char kChannelName[]
g_object_add_weak_pointer(G_OBJECT(self), reinterpret_cast< gpointer * >(&self->engine))

◆ G_DEFINE_TYPE_WITH_PRIVATE()

G_DEFINE_TYPE_WITH_PRIVATE ( FlTextInputPlugin  ,
fl_text_input_plugin  ,
G_TYPE_OBJECT   
)

◆ hide()

static FlMethodResponse * hide ( FlTextInputPlugin *  self)
static

Definition at line 408 of file fl_text_input_plugin.cc.

408 {
410 fl_text_input_plugin_get_instance_private(self));
411 gtk_im_context_focus_out(priv->im_context);
412
413 return FL_METHOD_RESPONSE(fl_method_success_response_new(nullptr));
414}

◆ if()

if ( response  = = nullptr)

Definition at line 110 of file fl_text_input_plugin.cc.

110 {
111 return FALSE;
112 }

◆ im_commit_cb()

static void im_commit_cb ( FlTextInputPlugin *  self,
const gchar *  text 
)
static

Definition at line 291 of file fl_text_input_plugin.cc.

291 {
293 fl_text_input_plugin_get_instance_private(self));
294 std::string text_before_change = priv->text_model->GetText();
295 flutter::TextRange composing_before_change =
296 priv->text_model->composing_range();
297 flutter::TextRange selection_before_change = priv->text_model->selection();
298 gboolean was_composing = priv->text_model->composing();
299
300 priv->text_model->AddText(text);
301 if (priv->text_model->composing()) {
302 priv->text_model->CommitComposing();
303 }
304
305 if (priv->enable_delta_model) {
306 flutter::TextRange replace_range =
307 was_composing ? composing_before_change : selection_before_change;
308 std::unique_ptr<flutter::TextEditingDelta> delta =
309 std::make_unique<flutter::TextEditingDelta>(text_before_change,
310 replace_range, text);
312 } else {
314 }
315}

◆ im_delete_surrounding_cb()

static gboolean im_delete_surrounding_cb ( FlTextInputPlugin *  self,
gint  offset,
gint  n_chars 
)
static

Definition at line 343 of file fl_text_input_plugin.cc.

345 {
347 fl_text_input_plugin_get_instance_private(self));
348
349 std::string text_before_change = priv->text_model->GetText();
350 if (priv->text_model->DeleteSurrounding(offset, n_chars)) {
351 if (priv->enable_delta_model) {
353 text_before_change, priv->text_model->composing_range(),
354 priv->text_model->GetText());
356 } else {
358 }
359 }
360 return TRUE;
361}
Point offset

◆ im_preedit_changed_cb()

static void im_preedit_changed_cb ( FlTextInputPlugin *  self)
static

Definition at line 262 of file fl_text_input_plugin.cc.

262 {
264 fl_text_input_plugin_get_instance_private(self));
265 std::string text_before_change = priv->text_model->GetText();
266 flutter::TextRange composing_before_change =
267 priv->text_model->composing_range();
268 g_autofree gchar* buf = nullptr;
269 gint cursor_offset = 0;
270 gtk_im_context_get_preedit_string(priv->im_context, &buf, nullptr,
271 &cursor_offset);
272 if (priv->text_model->composing()) {
273 cursor_offset += priv->text_model->composing_range().start();
274 } else {
275 cursor_offset += priv->text_model->selection().start();
276 }
277 priv->text_model->UpdateComposingText(buf);
278 priv->text_model->SetSelection(flutter::TextRange(cursor_offset));
279
280 if (priv->enable_delta_model) {
281 std::string text(buf);
283 text_before_change, composing_before_change, text);
285 } else {
287 }
288}

◆ im_preedit_end_cb()

static void im_preedit_end_cb ( FlTextInputPlugin *  self)
static

Definition at line 318 of file fl_text_input_plugin.cc.

318 {
320 fl_text_input_plugin_get_instance_private(self));
321 priv->text_model->EndComposing();
322 if (priv->enable_delta_model) {
324 flutter::TextEditingDelta(priv->text_model->GetText());
326 } else {
328 }
329}

◆ im_preedit_start_cb()

static void im_preedit_start_cb ( FlTextInputPlugin *  self)
static

Definition at line 255 of file fl_text_input_plugin.cc.

255 {
257 fl_text_input_plugin_get_instance_private(self));
258 priv->text_model->BeginComposing();
259}

◆ im_retrieve_surrounding_cb()

static gboolean im_retrieve_surrounding_cb ( FlTextInputPlugin *  self)
static

Definition at line 332 of file fl_text_input_plugin.cc.

332 {
334 fl_text_input_plugin_get_instance_private(self));
335 auto text = priv->text_model->GetText();
336 size_t cursor_offset = priv->text_model->GetCursorOffset();
337 gtk_im_context_set_surrounding(priv->im_context, text.c_str(), -1,
338 cursor_offset);
339 return TRUE;
340}

◆ init_im_context()

static void init_im_context ( FlTextInputPlugin *  self,
GtkIMContext *  im_context 
)
static

Definition at line 716 of file fl_text_input_plugin.cc.

716 {
718 fl_text_input_plugin_get_instance_private(self));
719 priv->im_context = GTK_IM_CONTEXT(g_object_ref(im_context));
720
721 // On Wayland, this call sets up the input method so it can be enabled
722 // immediately when required. Without it, on-screen keyboard's don't come up
723 // the first time a text field is focused.
724 gtk_im_context_focus_out(priv->im_context);
725
726 g_signal_connect_object(priv->im_context, "preedit-start",
727 G_CALLBACK(im_preedit_start_cb), self,
728 G_CONNECT_SWAPPED);
729 g_signal_connect_object(priv->im_context, "preedit-end",
730 G_CALLBACK(im_preedit_end_cb), self,
731 G_CONNECT_SWAPPED);
732 g_signal_connect_object(priv->im_context, "preedit-changed",
733 G_CALLBACK(im_preedit_changed_cb), self,
734 G_CONNECT_SWAPPED);
735 g_signal_connect_object(priv->im_context, "commit", G_CALLBACK(im_commit_cb),
736 self, G_CONNECT_SWAPPED);
737 g_signal_connect_object(priv->im_context, "retrieve-surrounding",
738 G_CALLBACK(im_retrieve_surrounding_cb), self,
739 G_CONNECT_SWAPPED);
740 g_signal_connect_object(priv->im_context, "delete-surrounding",
741 G_CALLBACK(im_delete_surrounding_cb), self,
742 G_CONNECT_SWAPPED);
743}
static void im_preedit_changed_cb(FlTextInputPlugin *self)
static void im_preedit_end_cb(FlTextInputPlugin *self)
static gboolean im_delete_surrounding_cb(FlTextInputPlugin *self, gint offset, gint n_chars)
static void im_preedit_start_cb(FlTextInputPlugin *self)
static void im_commit_cb(FlTextInputPlugin *self, const gchar *text)
static gboolean im_retrieve_surrounding_cb(FlTextInputPlugin *self)

◆ method_call_cb()

static void method_call_cb ( FlMethodChannel *  channel,
FlMethodCall *  method_call,
gpointer  user_data 
)
static

Definition at line 560 of file fl_text_input_plugin.cc.

562 {
563 FlTextInputPlugin* self = FL_TEXT_INPUT_PLUGIN(user_data);
564
565 const gchar* method = fl_method_call_get_name(method_call);
567
568 g_autoptr(FlMethodResponse) response = nullptr;
569 if (strcmp(method, kSetClientMethod) == 0) {
570 response = set_client(self, args);
571 } else if (strcmp(method, kShowMethod) == 0) {
572 response = show(self);
573 } else if (strcmp(method, kSetEditingStateMethod) == 0) {
574 response = set_editing_state(self, args);
575 } else if (strcmp(method, kClearClientMethod) == 0) {
576 response = clear_client(self);
577 } else if (strcmp(method, kHideMethod) == 0) {
578 response = hide(self);
579 } else if (strcmp(method, kSetEditableSizeAndTransform) == 0) {
581 } else if (strcmp(method, kSetMarkedTextRect) == 0) {
582 response = set_marked_text_rect(self, args);
583 } else {
584 response = FL_METHOD_RESPONSE(fl_method_not_implemented_response_new());
585 }
586
587 g_autoptr(GError) error = nullptr;
588 if (!fl_method_call_respond(method_call, response, &error)) {
589 g_warning("Failed to send method call response: %s", error->message);
590 }
591}
G_BEGIN_DECLS G_MODULE_EXPORT FlValue * args
G_MODULE_EXPORT const gchar * fl_method_call_get_name(FlMethodCall *self)
G_MODULE_EXPORT gboolean fl_method_call_respond(FlMethodCall *self, FlMethodResponse *response, GError **error)
G_MODULE_EXPORT FlValue * fl_method_call_get_args(FlMethodCall *self)
G_BEGIN_DECLS G_MODULE_EXPORT FlMethodCall * method_call
G_MODULE_EXPORT FlMethodNotImplementedResponse * fl_method_not_implemented_response_new()
static constexpr char kClearClientMethod[]
static constexpr char kSetEditableSizeAndTransform[]
static constexpr char kSetMarkedTextRect[]
static FlMethodResponse * clear_client(FlTextInputPlugin *self)
static constexpr char kHideMethod[]
static FlMethodResponse * set_client(FlTextInputPlugin *self, FlValue *args)
static constexpr char kSetEditingStateMethod[]
static FlMethodResponse * show(FlTextInputPlugin *self)
static FlMethodResponse * set_marked_text_rect(FlTextInputPlugin *self, FlValue *args)
static FlMethodResponse * set_editable_size_and_transform(FlTextInputPlugin *self, FlValue *args)
static constexpr char kSetClientMethod[]
static constexpr char kShowMethod[]
static FlMethodResponse * hide(FlTextInputPlugin *self)
GAsyncResult GError ** error
static FlMethodResponse * set_editing_state(FlTextInputPlugin *self, FlValue *args)
typedefG_BEGIN_DECLS struct _FlValue FlValue
Definition fl_value.h:42

◆ perform_action()

static void perform_action ( FlTextInputPlugin *  self)
static

Definition at line 238 of file fl_text_input_plugin.cc.

238 {
240 fl_text_input_plugin_get_instance_private(self));
241
242 g_return_if_fail(FL_IS_TEXT_INPUT_PLUGIN(self));
243 g_return_if_fail(priv->client_id != 0);
244 g_return_if_fail(priv->input_action != nullptr);
245
246 g_autoptr(FlValue) args = fl_value_new_list();
249
252}
G_MODULE_EXPORT void fl_method_channel_invoke_method(FlMethodChannel *self, const gchar *method, FlValue *args, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data)
static void perform_action_response_cb(GObject *object, GAsyncResult *result, gpointer user_data)
static constexpr char kPerformActionMethod[]
G_MODULE_EXPORT FlValue * fl_value_new_string(const gchar *value)
Definition fl_value.cc:276
G_MODULE_EXPORT FlValue * fl_value_new_int(int64_t value)
Definition fl_value.cc:262
G_MODULE_EXPORT void fl_value_append_take(FlValue *self, FlValue *value)
Definition fl_value.cc:600
G_MODULE_EXPORT FlValue * fl_value_new_list()
Definition fl_value.cc:349

◆ perform_action_response_cb()

static void perform_action_response_cb ( GObject *  object,
GAsyncResult *  result,
gpointer  user_data 
)
static

Definition at line 228 of file fl_text_input_plugin.cc.

230 {
231 g_autoptr(GError) error = nullptr;
232 if (!finish_method(object, result, &error)) {
233 g_warning("Failed to call %s: %s", kPerformActionMethod, error->message);
234 }
235}
static gboolean finish_method(GObject *object, GAsyncResult *result, GError **error)
GAsyncResult * result

◆ set_client()

static FlMethodResponse * set_client ( FlTextInputPlugin *  self,
FlValue args 
)
static

Definition at line 364 of file fl_text_input_plugin.cc.

364 {
367 return FL_METHOD_RESPONSE(fl_method_error_response_new(
368 kBadArgumentsError, "Expected 2-element list", nullptr));
369 }
371 fl_text_input_plugin_get_instance_private(self));
372
374 FlValue* config_value = fl_value_get_list_value(args, 1);
375 g_free(priv->input_action);
376 FlValue* input_action_value =
378 if (fl_value_get_type(input_action_value) == FL_VALUE_TYPE_STRING) {
379 priv->input_action = g_strdup(fl_value_get_string(input_action_value));
380 }
381
382 FlValue* enable_delta_model_value =
384 gboolean enable_delta_model = fl_value_get_bool(enable_delta_model_value);
385 priv->enable_delta_model = enable_delta_model;
386
387 // Reset the input type, then set only if appropriate.
388 priv->input_type = kFlTextInputTypeText;
389 FlValue* input_type_value =
391 if (fl_value_get_type(input_type_value) == FL_VALUE_TYPE_MAP) {
392 FlValue* input_type_name =
394 if (fl_value_get_type(input_type_name) == FL_VALUE_TYPE_STRING) {
395 const gchar* input_type = fl_value_get_string(input_type_name);
396 if (g_strcmp0(input_type, kMultilineInputType) == 0) {
397 priv->input_type = kFlTextInputTypeMultiline;
398 } else if (g_strcmp0(input_type, kNoneInputType) == 0) {
399 priv->input_type = kFlTextInputTypeNone;
400 }
401 }
402 }
403
404 return FL_METHOD_RESPONSE(fl_method_success_response_new(nullptr));
405}
G_MODULE_EXPORT FlMethodErrorResponse * fl_method_error_response_new(const gchar *code, const gchar *message, FlValue *details)
static constexpr char kEnableDeltaModel[]
static constexpr char kNoneInputType[]
static constexpr char kMultilineInputType[]
static constexpr char kTextInputTypeNameKey[]
static constexpr char kTextInputTypeKey[]
static constexpr char kBadArgumentsError[]
static constexpr char kInputActionKey[]
G_MODULE_EXPORT FlValue * fl_value_lookup_string(FlValue *self, const gchar *key)
Definition fl_value.cc:811
G_MODULE_EXPORT int64_t fl_value_get_int(FlValue *self)
Definition fl_value.cc:668
G_MODULE_EXPORT FlValueType fl_value_get_type(FlValue *self)
Definition fl_value.cc:466
G_MODULE_EXPORT const gchar * fl_value_get_string(FlValue *self)
Definition fl_value.cc:682
G_MODULE_EXPORT FlValue * fl_value_get_list_value(FlValue *self, size_t index)
Definition fl_value.cc:776
G_MODULE_EXPORT bool fl_value_get_bool(FlValue *self)
Definition fl_value.cc:661
G_MODULE_EXPORT size_t fl_value_get_length(FlValue *self)
Definition fl_value.cc:724
@ FL_VALUE_TYPE_STRING
Definition fl_value.h:69
@ FL_VALUE_TYPE_LIST
Definition fl_value.h:74
@ FL_VALUE_TYPE_MAP
Definition fl_value.h:75

◆ set_editable_size_and_transform()

static FlMethodResponse * set_editable_size_and_transform ( FlTextInputPlugin *  self,
FlValue args 
)
static

Definition at line 518 of file fl_text_input_plugin.cc.

520 {
522 size_t transform_len = fl_value_get_length(transform);
523 g_warn_if_fail(transform_len == 16);
524
525 for (size_t i = 0; i < transform_len; ++i) {
528 fl_text_input_plugin_get_instance_private(self));
529 priv->editabletext_transform[i / 4][i % 4] = val;
530 }
532
533 return FL_METHOD_RESPONSE(fl_method_success_response_new(nullptr));
534}
static constexpr char kTransform[]
static void update_im_cursor_position(FlTextInputPlugin *self)
G_MODULE_EXPORT double fl_value_get_float(FlValue *self)
Definition fl_value.cc:675
static SkColor4f transform(SkColor4f c, SkColorSpace *src, SkColorSpace *dst)
Definition p3.cpp:47

◆ set_editing_state()

static FlMethodResponse * set_editing_state ( FlTextInputPlugin *  self,
FlValue args 
)
static

Definition at line 430 of file fl_text_input_plugin.cc.

431 {
433 fl_text_input_plugin_get_instance_private(self));
434 const gchar* text =
436 priv->text_model->SetText(text);
437
438 int64_t selection_base =
440 int64_t selection_extent =
442 // Flutter uses -1/-1 for invalid; translate that to 0/0 for the model.
443 if (selection_base == -1 && selection_extent == -1) {
444 selection_base = selection_extent = 0;
445 }
446
447 priv->text_model->SetText(text);
448 priv->text_model->SetSelection(
449 flutter::TextRange(selection_base, selection_extent));
450
451 int64_t composing_base =
453 int64_t composing_extent =
455 if (composing_base == -1 && composing_extent == -1) {
456 priv->text_model->EndComposing();
457 } else {
458 size_t composing_start = std::min(composing_base, composing_extent);
459 size_t cursor_offset = selection_base - composing_start;
460 priv->text_model->SetComposingRange(
461 flutter::TextRange(composing_base, composing_extent), cursor_offset);
462 }
463
464 return FL_METHOD_RESPONSE(fl_method_success_response_new(nullptr));
465}
static constexpr char kSelectionExtentKey[]
static constexpr char kComposingExtentKey[]
static constexpr char kComposingBaseKey[]
static constexpr char kTextKey[]
static constexpr char kSelectionBaseKey[]

◆ set_marked_text_rect()

static FlMethodResponse * set_marked_text_rect ( FlTextInputPlugin *  self,
FlValue args 
)
static

Definition at line 542 of file fl_text_input_plugin.cc.

543 {
545 fl_text_input_plugin_get_instance_private(self));
546 priv->composing_rect.x =
548 priv->composing_rect.y =
550 priv->composing_rect.width =
552 priv->composing_rect.height =
555
556 return FL_METHOD_RESPONSE(fl_method_success_response_new(nullptr));
557}

◆ show()

static FlMethodResponse * show ( FlTextInputPlugin *  self)
static

Definition at line 417 of file fl_text_input_plugin.cc.

417 {
419 fl_text_input_plugin_get_instance_private(self));
420 if (priv->input_type == kFlTextInputTypeNone) {
421 return hide(self);
422 }
423
424 gtk_im_context_focus_in(priv->im_context);
425
426 return FL_METHOD_RESPONSE(fl_method_success_response_new(nullptr));
427}

◆ update_editing_state()

static void update_editing_state ( FlTextInputPlugin *  self)
static

Definition at line 128 of file fl_text_input_plugin.cc.

128 {
130 fl_text_input_plugin_get_instance_private(self));
131
132 g_autoptr(FlValue) args = fl_value_new_list();
134 g_autoptr(FlValue) value = fl_value_new_map();
135
136 flutter::TextRange selection = priv->text_model->selection();
138 value, kTextKey,
139 fl_value_new_string(priv->text_model->GetText().c_str()));
141 fl_value_new_int(selection.base()));
143 fl_value_new_int(selection.extent()));
144
145 int composing_base = -1;
146 int composing_extent = -1;
147 if (!priv->text_model->composing_range().collapsed()) {
148 composing_base = priv->text_model->composing_range().base();
149 composing_extent = priv->text_model->composing_range().extent();
150 }
152 fl_value_new_int(composing_base));
154 fl_value_new_int(composing_extent));
155
156 // The following keys are not implemented and set to default values.
161
162 fl_value_append(args, value);
163
165 args, nullptr,
167}
size_t base() const
Definition text_range.h:30
size_t extent() const
Definition text_range.h:36
uint8_t value
static constexpr char kSelectionIsDirectionalKey[]
static void update_editing_state_response_cb(GObject *object, GAsyncResult *result, gpointer user_data)
static constexpr char kUpdateEditingStateMethod[]
static constexpr char kTextAffinityDownstream[]
static constexpr char kSelectionAffinityKey[]
G_MODULE_EXPORT FlValue * fl_value_new_map()
Definition fl_value.cc:366
G_MODULE_EXPORT void fl_value_set_string_take(FlValue *self, const gchar *key, FlValue *value)
Definition fl_value.cc:650
G_MODULE_EXPORT void fl_value_append(FlValue *self, FlValue *value)
Definition fl_value.cc:592
G_MODULE_EXPORT FlValue * fl_value_new_bool(bool value)
Definition fl_value.cc:255

◆ update_editing_state_response_cb()

static void update_editing_state_response_cb ( GObject *  object,
GAsyncResult *  result,
gpointer  user_data 
)
static

Definition at line 117 of file fl_text_input_plugin.cc.

119 {
120 g_autoptr(GError) error = nullptr;
121 if (!finish_method(object, result, &error)) {
122 g_warning("Failed to call %s: %s", kUpdateEditingStateMethod,
123 error->message);
124 }
125}

◆ update_editing_state_with_delta()

static void update_editing_state_with_delta ( FlTextInputPlugin *  self,
flutter::TextEditingDelta delta 
)
static

Definition at line 170 of file fl_text_input_plugin.cc.

171 {
173 fl_text_input_plugin_get_instance_private(self));
174
175 g_autoptr(FlValue) args = fl_value_new_list();
177
178 g_autoptr(FlValue) deltaValue = fl_value_new_map();
179 fl_value_set_string_take(deltaValue, "oldText",
180 fl_value_new_string(delta->old_text().c_str()));
181
182 fl_value_set_string_take(deltaValue, "deltaText",
183 fl_value_new_string(delta->delta_text().c_str()));
184
185 fl_value_set_string_take(deltaValue, "deltaStart",
186 fl_value_new_int(delta->delta_start()));
187
188 fl_value_set_string_take(deltaValue, "deltaEnd",
189 fl_value_new_int(delta->delta_end()));
190
191 flutter::TextRange selection = priv->text_model->selection();
192 fl_value_set_string_take(deltaValue, "selectionBase",
193 fl_value_new_int(selection.base()));
194
195 fl_value_set_string_take(deltaValue, "selectionExtent",
196 fl_value_new_int(selection.extent()));
197
198 fl_value_set_string_take(deltaValue, "selectionAffinity",
200
201 fl_value_set_string_take(deltaValue, "selectionIsDirectional",
203
204 int composing_base = -1;
205 int composing_extent = -1;
206 if (!priv->text_model->composing_range().collapsed()) {
207 composing_base = priv->text_model->composing_range().base();
208 composing_extent = priv->text_model->composing_range().extent();
209 }
210 fl_value_set_string_take(deltaValue, "composingBase",
211 fl_value_new_int(composing_base));
212 fl_value_set_string_take(deltaValue, "composingExtent",
213 fl_value_new_int(composing_extent));
214
215 g_autoptr(FlValue) deltas = fl_value_new_list();
216 fl_value_append(deltas, deltaValue);
217 g_autoptr(FlValue) value = fl_value_new_map();
218 fl_value_set_string(value, "deltas", deltas);
219
220 fl_value_append(args, value);
221
225}
static constexpr char kUpdateEditingStateWithDeltasMethod[]
G_MODULE_EXPORT void fl_value_set_string(FlValue *self, const gchar *key, FlValue *value)
Definition fl_value.cc:639

◆ update_im_cursor_position()

static void update_im_cursor_position ( FlTextInputPlugin *  self)
static

Definition at line 484 of file fl_text_input_plugin.cc.

484 {
486 fl_text_input_plugin_get_instance_private(self));
487
488 // Skip update if not composing to avoid setting to position 0.
489 if (!priv->text_model->composing()) {
490 return;
491 }
492
493 // Transform the x, y positions of the cursor from local coordinates to
494 // Flutter view coordinates.
495 gint x = priv->composing_rect.x * priv->editabletext_transform[0][0] +
496 priv->composing_rect.y * priv->editabletext_transform[1][0] +
497 priv->editabletext_transform[3][0] + priv->composing_rect.width;
498 gint y = priv->composing_rect.x * priv->editabletext_transform[0][1] +
499 priv->composing_rect.y * priv->editabletext_transform[1][1] +
500 priv->editabletext_transform[3][1] + priv->composing_rect.height;
501
502 // Transform from Flutter view coordinates to GTK window coordinates.
503 GdkRectangle preedit_rect = {};
505 priv->view_delegate, x, y, &preedit_rect.x, &preedit_rect.y);
506
507 // Set the cursor location in window coordinates so that GTK can position any
508 // system input method windows.
509 gtk_im_context_set_cursor_location(priv->im_context, &preedit_rect);
510}
void fl_text_input_view_delegate_translate_coordinates(FlTextInputViewDelegate *self, gint view_x, gint view_y, gint *window_x, gint *window_y)
double y
double x

Variable Documentation

◆ error

GAsyncResult GError** error
Initial value:
{
g_autoptr(FlMethodResponse) response = fl_method_channel_invoke_method_finish(
FL_METHOD_CHANNEL(object), result, error)
G_MODULE_EXPORT FlMethodResponse * fl_method_channel_invoke_method_finish(FlMethodChannel *self, GAsyncResult *result, GError **error)

Definition at line 107 of file fl_text_input_plugin.cc.

◆ kBadArgumentsError

constexpr char kBadArgumentsError[] = "Bad Arguments"
staticconstexpr

Definition at line 16 of file fl_text_input_plugin.cc.

◆ kChannelName

constexpr char kChannelName[] = "flutter/textinput"
staticconstexpr

Definition at line 14 of file fl_text_input_plugin.cc.

◆ kClearClientMethod

constexpr char kClearClientMethod[] = "TextInput.clearClient"
staticconstexpr

Definition at line 21 of file fl_text_input_plugin.cc.

◆ kClientIdUnset

constexpr int64_t kClientIdUnset = -1
staticconstexpr

Definition at line 52 of file fl_text_input_plugin.cc.

◆ kComposingBaseKey

constexpr char kComposingBaseKey[] = "composingBase"
staticconstexpr

Definition at line 41 of file fl_text_input_plugin.cc.

◆ kComposingExtentKey

constexpr char kComposingExtentKey[] = "composingExtent"
staticconstexpr

Definition at line 42 of file fl_text_input_plugin.cc.

◆ kEnableDeltaModel

constexpr char kEnableDeltaModel[] = "enableDeltaModel"
staticconstexpr

Definition at line 34 of file fl_text_input_plugin.cc.

◆ kHideMethod

constexpr char kHideMethod[] = "TextInput.hide"
staticconstexpr

Definition at line 22 of file fl_text_input_plugin.cc.

◆ kInputActionKey

constexpr char kInputActionKey[] = "inputAction"
staticconstexpr

Definition at line 32 of file fl_text_input_plugin.cc.

◆ kMultilineInputType

constexpr char kMultilineInputType[] = "TextInputType.multiline"
staticconstexpr

Definition at line 47 of file fl_text_input_plugin.cc.

◆ kNewlineInputAction

constexpr char kNewlineInputAction[] = "TextInputAction.newline"
staticconstexpr

Definition at line 50 of file fl_text_input_plugin.cc.

◆ kNoneInputType

constexpr char kNoneInputType[] = "TextInputType.none"
staticconstexpr

Definition at line 48 of file fl_text_input_plugin.cc.

◆ kPerformActionMethod

constexpr char kPerformActionMethod[] = "TextInputClient.performAction"
staticconstexpr

Definition at line 27 of file fl_text_input_plugin.cc.

◆ kSelectionAffinityKey

constexpr char kSelectionAffinityKey[] = "selectionAffinity"
staticconstexpr

Definition at line 39 of file fl_text_input_plugin.cc.

◆ kSelectionBaseKey

constexpr char kSelectionBaseKey[] = "selectionBase"
staticconstexpr

Definition at line 37 of file fl_text_input_plugin.cc.

◆ kSelectionExtentKey

constexpr char kSelectionExtentKey[] = "selectionExtent"
staticconstexpr

Definition at line 38 of file fl_text_input_plugin.cc.

◆ kSelectionIsDirectionalKey

constexpr char kSelectionIsDirectionalKey[] = "selectionIsDirectional"
staticconstexpr

Definition at line 40 of file fl_text_input_plugin.cc.

◆ kSetClientMethod

constexpr char kSetClientMethod[] = "TextInput.setClient"
staticconstexpr

Definition at line 18 of file fl_text_input_plugin.cc.

◆ kSetEditableSizeAndTransform

constexpr char kSetEditableSizeAndTransform[]
staticconstexpr
Initial value:
=
"TextInput.setEditableSizeAndTransform"

Definition at line 28 of file fl_text_input_plugin.cc.

◆ kSetEditingStateMethod

constexpr char kSetEditingStateMethod[] = "TextInput.setEditingState"
staticconstexpr

Definition at line 20 of file fl_text_input_plugin.cc.

◆ kSetMarkedTextRect

constexpr char kSetMarkedTextRect[] = "TextInput.setMarkedTextRect"
staticconstexpr

Definition at line 30 of file fl_text_input_plugin.cc.

◆ kShowMethod

constexpr char kShowMethod[] = "TextInput.show"
staticconstexpr

Definition at line 19 of file fl_text_input_plugin.cc.

◆ kTextAffinityDownstream

constexpr char kTextAffinityDownstream[] = "TextAffinity.downstream"
staticconstexpr

Definition at line 46 of file fl_text_input_plugin.cc.

◆ kTextInputTypeKey

constexpr char kTextInputTypeKey[] = "inputType"
staticconstexpr

Definition at line 33 of file fl_text_input_plugin.cc.

◆ kTextInputTypeNameKey

constexpr char kTextInputTypeNameKey[] = "name"
staticconstexpr

Definition at line 35 of file fl_text_input_plugin.cc.

◆ kTextKey

constexpr char kTextKey[] = "text"
staticconstexpr

Definition at line 36 of file fl_text_input_plugin.cc.

◆ kTransform

constexpr char kTransform[] = "transform"
staticconstexpr

Definition at line 44 of file fl_text_input_plugin.cc.

◆ kUpdateEditingStateMethod

constexpr char kUpdateEditingStateMethod[]
staticconstexpr
Initial value:
=
"TextInputClient.updateEditingState"

Definition at line 23 of file fl_text_input_plugin.cc.

◆ kUpdateEditingStateWithDeltasMethod

constexpr char kUpdateEditingStateWithDeltasMethod[]
staticconstexpr
Initial value:
=
"TextInputClient.updateEditingStateWithDeltas"

Definition at line 25 of file fl_text_input_plugin.cc.

◆ result

GAsyncResult* result

Definition at line 106 of file fl_text_input_plugin.cc.