From 37da36ab161de512a784ce677cded1f82c46fbe7 Mon Sep 17 00:00:00 2001 From: Maksim Lin Date: Wed, 26 Aug 2020 03:51:02 +1000 Subject: [PATCH] send newline char when input type is multiline (flutter/engine#20660) --- .../platform/linux/fl_text_input_plugin.cc | 31 ++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/engine/src/flutter/shell/platform/linux/fl_text_input_plugin.cc b/engine/src/flutter/shell/platform/linux/fl_text_input_plugin.cc index 89580fa798b..53de080db26 100644 --- a/engine/src/flutter/shell/platform/linux/fl_text_input_plugin.cc +++ b/engine/src/flutter/shell/platform/linux/fl_text_input_plugin.cc @@ -24,6 +24,8 @@ static constexpr char kUpdateEditingStateMethod[] = static constexpr char kPerformActionMethod[] = "TextInputClient.performAction"; static constexpr char kInputActionKey[] = "inputAction"; +static constexpr char kTextInputTypeKey[] = "inputType"; +static constexpr char kTextInputTypeNameKey[] = "name"; static constexpr char kTextKey[] = "text"; static constexpr char kSelectionBaseKey[] = "selectionBase"; static constexpr char kSelectionExtentKey[] = "selectionExtent"; @@ -33,6 +35,7 @@ static constexpr char kComposingBaseKey[] = "composingBase"; static constexpr char kComposingExtentKey[] = "composingExtent"; static constexpr char kTextAffinityDownstream[] = "TextAffinity.downstream"; +static constexpr char kMultilineInputType[] = "TextInputType.multiline"; static constexpr int64_t kClientIdUnset = -1; @@ -47,6 +50,9 @@ struct _FlTextInputPlugin { // Input action to perform when enter pressed. gchar* input_action; + // Send newline when multi-line and enter is pressed. + gboolean input_multiline; + // Input method. GtkIMContext* im_context; @@ -175,6 +181,19 @@ static FlMethodResponse* set_client(FlTextInputPlugin* self, FlValue* args) { self->input_action = g_strdup(fl_value_get_string(input_action_value)); } + // Clear the multiline flag, then set it only if the field is multiline. + self->input_multiline = FALSE; + FlValue* input_type_value = + fl_value_lookup(config_value, fl_value_new_string(kTextInputTypeKey)); + if (fl_value_get_type(input_type_value) == FL_VALUE_TYPE_MAP) { + FlValue* input_type_name = fl_value_lookup( + input_type_value, fl_value_new_string(kTextInputTypeNameKey)); + if (fl_value_equal(input_type_name, + fl_value_new_string(kMultilineInputType))) { + self->input_multiline = TRUE; + } + } + return FL_METHOD_RESPONSE(fl_method_success_response_new(nullptr)); } @@ -269,6 +288,7 @@ static void fl_text_input_plugin_class_init(FlTextInputPluginClass* klass) { static void fl_text_input_plugin_init(FlTextInputPlugin* self) { self->client_id = kClientIdUnset; self->im_context = gtk_im_multicontext_new(); + self->input_multiline = FALSE; g_signal_connect_object(self->im_context, "commit", G_CALLBACK(im_commit_cb), self, G_CONNECT_SWAPPED); g_signal_connect_object(self->im_context, "retrieve-surrounding", @@ -307,6 +327,8 @@ gboolean fl_text_input_plugin_filter_keypress(FlTextInputPlugin* self, return TRUE; } + // Handle the enter/return key. + gboolean do_action = FALSE; // Handle navigation keys. gboolean changed = FALSE; if (event->type == GDK_KEY_PRESS) { @@ -325,7 +347,11 @@ gboolean fl_text_input_plugin_filter_keypress(FlTextInputPlugin* self, case GDK_KEY_Return: case GDK_KEY_KP_Enter: case GDK_KEY_ISO_Enter: - perform_action(self); + if (self->input_multiline == TRUE) { + self->text_model->AddCodePoint('\n'); + changed = TRUE; + } + do_action = TRUE; break; case GDK_KEY_Home: case GDK_KEY_KP_Home: @@ -345,6 +371,9 @@ gboolean fl_text_input_plugin_filter_keypress(FlTextInputPlugin* self, if (changed) { update_editing_state(self); } + if (do_action) { + perform_action(self); + } return FALSE; }