Flutter Linux Embedder
fl_text_input_handler.cc File Reference

Go to the source code of this file.

Classes

struct  _FlTextInputHandler
 

Functions

static void update_editing_state_response_cb (GObject *object, GAsyncResult *result, gpointer user_data)
 
static void update_editing_state_with_deltas_response_cb (GObject *object, GAsyncResult *result, gpointer user_data)
 
static void update_editing_state (FlTextInputHandler *self)
 
static void update_editing_state_with_delta (FlTextInputHandler *self, flutter::TextEditingDelta *delta)
 
static void perform_action_response_cb (GObject *object, GAsyncResult *result, gpointer user_data)
 
static void perform_action (FlTextInputHandler *self)
 
static void im_preedit_start_cb (FlTextInputHandler *self)
 
static void im_preedit_changed_cb (FlTextInputHandler *self)
 
static void im_commit_cb (FlTextInputHandler *self, const gchar *text)
 
static void im_preedit_end_cb (FlTextInputHandler *self)
 
static gboolean im_retrieve_surrounding_cb (FlTextInputHandler *self)
 
static gboolean im_delete_surrounding_cb (FlTextInputHandler *self, gint offset, gint n_chars)
 
static void set_client (int64_t client_id, gpointer user_data)
 
static void configure (const gchar *input_action, gboolean enable_delta_model, FlTextInputType input_type, GtkInputPurpose im_purpose, GtkInputHints im_hints, gpointer user_data)
 
static void hide (gpointer user_data)
 
static void show (gpointer user_data)
 
static void set_editing_state (const gchar *text, int64_t selection_base, int64_t selection_extent, int64_t composing_base, int64_t composing_extent, gpointer user_data)
 
static void clear_client (gpointer user_data)
 
static void update_im_cursor_position (FlTextInputHandler *self)
 
static void set_editable_size_and_transform (double *transform, gpointer user_data)
 
static void set_marked_text_rect (double x, double y, double width, double height, gpointer user_data)
 
static void fl_text_input_handler_dispose (GObject *object)
 
static void fl_text_input_handler_class_init (FlTextInputHandlerClass *klass)
 
static void fl_text_input_handler_init (FlTextInputHandler *self)
 
FlTextInputHandler * fl_text_input_handler_new (FlBinaryMessenger *messenger)
 
GtkIMContext * fl_text_input_handler_get_im_context (FlTextInputHandler *self)
 
void fl_text_input_handler_set_widget (FlTextInputHandler *self, GtkWidget *widget)
 
GtkWidget * fl_text_input_handler_get_widget (FlTextInputHandler *self)
 
gboolean fl_text_input_handler_filter_keypress (FlTextInputHandler *self, FlKeyEvent *event)
 

Variables

static constexpr char kNewlineInputAction [] = "TextInputAction.newline"
 
static constexpr char kInputPurposeImProperty [] = "input-purpose"
 
static constexpr char kInputHintsImProperty [] = "input-hints"
 
static constexpr int64_t kClientIdUnset = -1
 
static FlTextInputChannelVTable text_input_vtable
 

Function Documentation

◆ clear_client()

static void clear_client ( gpointer  user_data)
static

Definition at line 320 of file fl_text_input_handler.cc.

320  {
321  FlTextInputHandler* self = FL_TEXT_INPUT_HANDLER(user_data);
322  self->client_id = kClientIdUnset;
323 }
const char FlTextDirection FlAssertiveness gpointer user_data
static constexpr int64_t kClientIdUnset

References kClientIdUnset, and user_data.

◆ configure()

static void configure ( const gchar *  input_action,
gboolean  enable_delta_model,
FlTextInputType  input_type,
GtkInputPurpose  im_purpose,
GtkInputHints  im_hints,
gpointer  user_data 
)
static

Definition at line 251 of file fl_text_input_handler.cc.

256  {
257  FlTextInputHandler* self = FL_TEXT_INPUT_HANDLER(user_data);
258 
259  g_free(self->input_action);
260  self->input_action = g_strdup(input_action);
261  self->enable_delta_model = enable_delta_model;
262  self->input_type = input_type;
263 
264  g_object_set(G_OBJECT(self->im_context), kInputPurposeImProperty, im_purpose,
265  nullptr);
266  g_object_set(G_OBJECT(self->im_context), kInputHintsImProperty, im_hints,
267  nullptr);
268 }
static constexpr char kInputHintsImProperty[]
static constexpr char kInputPurposeImProperty[]

References kInputHintsImProperty, kInputPurposeImProperty, and user_data.

◆ fl_text_input_handler_class_init()

static void fl_text_input_handler_class_init ( FlTextInputHandlerClass *  klass)
static

Definition at line 414 of file fl_text_input_handler.cc.

414  {
415  G_OBJECT_CLASS(klass)->dispose = fl_text_input_handler_dispose;
416 }
static void fl_text_input_handler_dispose(GObject *object)

References fl_text_input_handler_dispose().

◆ fl_text_input_handler_dispose()

static void fl_text_input_handler_dispose ( GObject *  object)
static

Definition at line 396 of file fl_text_input_handler.cc.

396  {
397  FlTextInputHandler* self = FL_TEXT_INPUT_HANDLER(object);
398 
399  g_cancellable_cancel(self->cancellable);
400 
401  g_clear_object(&self->channel);
402  g_clear_pointer(&self->input_action, g_free);
403  g_clear_object(&self->im_context);
404  if (self->text_model != nullptr) {
405  delete self->text_model;
406  self->text_model = nullptr;
407  }
408  g_clear_object(&self->cancellable);
409 
410  G_OBJECT_CLASS(fl_text_input_handler_parent_class)->dispose(object);
411 }

Referenced by fl_text_input_handler_class_init().

◆ fl_text_input_handler_filter_keypress()

gboolean fl_text_input_handler_filter_keypress ( FlTextInputHandler *  handler,
FlKeyEvent *  event 
)

fl_text_input_handler_filter_keypress @handler: an #FlTextInputHandler. @event: a #FlKeyEvent

Process a key event.

Returns: TRUE if the event was used.

Definition at line 492 of file fl_text_input_handler.cc.

493  {
494  g_return_val_if_fail(FL_IS_TEXT_INPUT_HANDLER(self), FALSE);
495 
496  if (self->client_id == kClientIdUnset) {
497  return FALSE;
498  }
499 
500  if (gtk_im_context_filter_keypress(
501  self->im_context,
502  reinterpret_cast<GdkEventKey*>(fl_key_event_get_origin(event)))) {
503  return TRUE;
504  }
505 
506  std::string text_before_change = self->text_model->GetText();
507  flutter::TextRange selection_before_change = self->text_model->selection();
508  std::string text = self->text_model->GetText();
509 
510  // Handle the enter/return key.
511  gboolean do_action = FALSE;
512  // Handle navigation keys.
513  gboolean changed = FALSE;
514  if (fl_key_event_get_is_press(event)) {
515  switch (fl_key_event_get_keyval(event)) {
516  case GDK_KEY_End:
517  case GDK_KEY_KP_End:
518  if (fl_key_event_get_state(event) & GDK_SHIFT_MASK) {
519  changed = self->text_model->SelectToEnd();
520  } else {
521  changed = self->text_model->MoveCursorToEnd();
522  }
523  break;
524  case GDK_KEY_Return:
525  case GDK_KEY_KP_Enter:
526  case GDK_KEY_ISO_Enter:
527  if (self->input_type == FL_TEXT_INPUT_TYPE_MULTILINE &&
528  strcmp(self->input_action, kNewlineInputAction) == 0) {
529  self->text_model->AddCodePoint('\n');
530  text = "\n";
531  changed = TRUE;
532  }
533  do_action = TRUE;
534  break;
535  case GDK_KEY_Home:
536  case GDK_KEY_KP_Home:
537  if (fl_key_event_get_state(event) & GDK_SHIFT_MASK) {
538  changed = self->text_model->SelectToBeginning();
539  } else {
540  changed = self->text_model->MoveCursorToBeginning();
541  }
542  break;
543  case GDK_KEY_BackSpace:
544  case GDK_KEY_Delete:
545  case GDK_KEY_KP_Delete:
546  case GDK_KEY_Left:
547  case GDK_KEY_KP_Left:
548  case GDK_KEY_Right:
549  case GDK_KEY_KP_Right:
550  // Already handled inside the framework in RenderEditable.
551  break;
552  }
553  }
554 
555  if (changed) {
556  if (self->enable_delta_model) {
558  text_before_change, selection_before_change, text);
559  update_editing_state_with_delta(self, &delta);
560  } else {
561  update_editing_state(self);
562  }
563  }
564  if (do_action) {
565  perform_action(self);
566  }
567 
568  return changed;
569 }
return TRUE
GdkEvent * fl_key_event_get_origin(FlKeyEvent *self)
gboolean fl_key_event_get_is_press(FlKeyEvent *self)
Definition: fl_key_event.cc:84
GdkModifierType fl_key_event_get_state(FlKeyEvent *self)
Definition: fl_key_event.cc:99
guint fl_key_event_get_keyval(FlKeyEvent *self)
Definition: fl_key_event.cc:94
@ FL_TEXT_INPUT_TYPE_MULTILINE
static void update_editing_state(FlTextInputHandler *self)
static void update_editing_state_with_delta(FlTextInputHandler *self, flutter::TextEditingDelta *delta)
static constexpr char kNewlineInputAction[]
static void perform_action(FlTextInputHandler *self)
A change in the state of an input field.

References fl_key_event_get_is_press(), fl_key_event_get_keyval(), fl_key_event_get_origin(), fl_key_event_get_state(), FL_TEXT_INPUT_TYPE_MULTILINE, kClientIdUnset, kNewlineInputAction, perform_action(), TRUE, update_editing_state(), and update_editing_state_with_delta().

Referenced by handle_key_event(), and send_key_event().

◆ fl_text_input_handler_get_im_context()

GtkIMContext* fl_text_input_handler_get_im_context ( FlTextInputHandler *  handler)

fl_text_input_handler_get_im_context: @handler: an #FlTextInputHandler.

Get the IM context that is being used. Provided for testing purposes.

Returns: a #GtkIMContext.

Definition at line 474 of file fl_text_input_handler.cc.

474  {
475  g_return_val_if_fail(FL_IS_TEXT_INPUT_HANDLER(self), nullptr);
476  return self->im_context;
477 }

Referenced by TEST().

◆ fl_text_input_handler_get_widget()

GtkWidget* fl_text_input_handler_get_widget ( FlTextInputHandler *  handler)

fl_text_input_handler_get_widget: @handler: an #FlTextInputHandler.

Get the widget that has input focus.

Returns: a #GtkWidget or NULL if none active.

Definition at line 487 of file fl_text_input_handler.cc.

487  {
488  g_return_val_if_fail(FL_IS_TEXT_INPUT_HANDLER(self), nullptr);
489  return self->widget;
490 }

Referenced by setup_keyboard().

◆ fl_text_input_handler_init()

static void fl_text_input_handler_init ( FlTextInputHandler *  self)
static

Definition at line 419 of file fl_text_input_handler.cc.

419  {
420  self->client_id = kClientIdUnset;
421  self->input_type = FL_TEXT_INPUT_TYPE_TEXT;
422  self->text_model = new flutter::TextInputModel();
423  self->cancellable = g_cancellable_new();
424 }
@ FL_TEXT_INPUT_TYPE_TEXT

References FL_TEXT_INPUT_TYPE_TEXT, and kClientIdUnset.

◆ fl_text_input_handler_new()

FlTextInputHandler* fl_text_input_handler_new ( FlBinaryMessenger *  messenger)

FlTextInputHandler:

#FlTextInputHandler is a handler that implements the shell side of SystemChannels.textInput from the Flutter services library. fl_text_input_handler_new: @messenger: an #FlBinaryMessenger.

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

Returns: a new #FlTextInputHandler.

Definition at line 437 of file fl_text_input_handler.cc.

437  {
438  g_return_val_if_fail(FL_IS_BINARY_MESSENGER(messenger), nullptr);
439 
440  FlTextInputHandler* self = FL_TEXT_INPUT_HANDLER(
441  g_object_new(fl_text_input_handler_get_type(), nullptr));
442 
443  self->channel =
444  fl_text_input_channel_new(messenger, &text_input_vtable, self);
445 
446  self->im_context = GTK_IM_CONTEXT(gtk_im_multicontext_new());
447 
448  // On Wayland, this call sets up the input method so it can be enabled
449  // immediately when required. Without it, on-screen keyboard's don't come up
450  // the first time a text field is focused.
451  gtk_im_context_focus_out(self->im_context);
452 
453  g_signal_connect_object(self->im_context, "preedit-start",
454  G_CALLBACK(im_preedit_start_cb), self,
455  G_CONNECT_SWAPPED);
456  g_signal_connect_object(self->im_context, "preedit-end",
457  G_CALLBACK(im_preedit_end_cb), self,
458  G_CONNECT_SWAPPED);
459  g_signal_connect_object(self->im_context, "preedit-changed",
460  G_CALLBACK(im_preedit_changed_cb), self,
461  G_CONNECT_SWAPPED);
462  g_signal_connect_object(self->im_context, "commit", G_CALLBACK(im_commit_cb),
463  self, G_CONNECT_SWAPPED);
464  g_signal_connect_object(self->im_context, "retrieve-surrounding",
465  G_CALLBACK(im_retrieve_surrounding_cb), self,
466  G_CONNECT_SWAPPED);
467  g_signal_connect_object(self->im_context, "delete-surrounding",
468  G_CALLBACK(im_delete_surrounding_cb), self,
469  G_CONNECT_SWAPPED);
470 
471  return self;
472 }
FlTextInputChannel * fl_text_input_channel_new(FlBinaryMessenger *messenger, FlTextInputChannelVTable *vtable, gpointer user_data)
static gboolean im_delete_surrounding_cb(FlTextInputHandler *self, gint offset, gint n_chars)
static void im_preedit_end_cb(FlTextInputHandler *self)
static gboolean im_retrieve_surrounding_cb(FlTextInputHandler *self)
static void im_preedit_start_cb(FlTextInputHandler *self)
static FlTextInputChannelVTable text_input_vtable
static void im_commit_cb(FlTextInputHandler *self, const gchar *text)
static void im_preedit_changed_cb(FlTextInputHandler *self)

References fl_text_input_channel_new(), im_commit_cb(), im_delete_surrounding_cb(), im_preedit_changed_cb(), im_preedit_end_cb(), im_preedit_start_cb(), im_retrieve_surrounding_cb(), and text_input_vtable.

Referenced by setup_keyboard(), and TEST().

◆ fl_text_input_handler_set_widget()

void fl_text_input_handler_set_widget ( FlTextInputHandler *  handler,
GtkWidget *  widget 
)

fl_text_input_handler_set_widget: @handler: an #FlTextInputHandler. @widget: the widget with keyboard focus.

Set the widget that has input focus.

Definition at line 479 of file fl_text_input_handler.cc.

480  {
481  g_return_if_fail(FL_IS_TEXT_INPUT_HANDLER(self));
482  self->widget = widget;
483  gtk_im_context_set_client_window(self->im_context,
484  gtk_widget_get_window(self->widget));
485 }

Referenced by fl_view_focus_in_event(), and setup_keyboard().

◆ hide()

static void hide ( gpointer  user_data)
static

Definition at line 271 of file fl_text_input_handler.cc.

271  {
272  FlTextInputHandler* self = FL_TEXT_INPUT_HANDLER(user_data);
273 
274  gtk_im_context_focus_out(self->im_context);
275 }

References user_data.

Referenced by show().

◆ im_commit_cb()

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

Definition at line 180 of file fl_text_input_handler.cc.

180  {
181  std::string text_before_change = self->text_model->GetText();
182  flutter::TextRange composing_before_change =
183  self->text_model->composing_range();
184  flutter::TextRange selection_before_change = self->text_model->selection();
185  gboolean was_composing = self->text_model->composing();
186 
187  self->text_model->AddText(text);
188  if (self->text_model->composing()) {
189  self->text_model->CommitComposing();
190  }
191 
192  if (self->enable_delta_model) {
193  flutter::TextRange replace_range =
194  was_composing ? composing_before_change : selection_before_change;
195  std::unique_ptr<flutter::TextEditingDelta> delta =
196  std::make_unique<flutter::TextEditingDelta>(text_before_change,
197  replace_range, text);
198  update_editing_state_with_delta(self, delta.get());
199  } else {
200  update_editing_state(self);
201  }
202 }

References update_editing_state(), and update_editing_state_with_delta().

Referenced by fl_text_input_handler_new().

◆ im_delete_surrounding_cb()

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

Definition at line 226 of file fl_text_input_handler.cc.

228  {
229  std::string text_before_change = self->text_model->GetText();
230  if (self->text_model->DeleteSurrounding(offset, n_chars)) {
231  if (self->enable_delta_model) {
233  text_before_change, self->text_model->composing_range(),
234  self->text_model->GetText());
235  update_editing_state_with_delta(self, &delta);
236  } else {
237  update_editing_state(self);
238  }
239  }
240  return TRUE;
241 }

References TRUE, update_editing_state(), and update_editing_state_with_delta().

Referenced by fl_text_input_handler_new().

◆ im_preedit_changed_cb()

static void im_preedit_changed_cb ( FlTextInputHandler *  self)
static

Definition at line 153 of file fl_text_input_handler.cc.

153  {
154  std::string text_before_change = self->text_model->GetText();
155  flutter::TextRange composing_before_change =
156  self->text_model->composing_range();
157  g_autofree gchar* buf = nullptr;
158  gint cursor_offset = 0;
159  gtk_im_context_get_preedit_string(self->im_context, &buf, nullptr,
160  &cursor_offset);
161  if (self->text_model->composing()) {
162  cursor_offset += self->text_model->composing_range().start();
163  } else {
164  cursor_offset += self->text_model->selection().start();
165  }
166  self->text_model->UpdateComposingText(buf);
167  self->text_model->SetSelection(flutter::TextRange(cursor_offset));
168 
169  if (self->enable_delta_model) {
170  std::string text(buf);
172  text_before_change, composing_before_change, text);
173  update_editing_state_with_delta(self, &delta);
174  } else {
175  update_editing_state(self);
176  }
177 }

References update_editing_state(), and update_editing_state_with_delta().

Referenced by fl_text_input_handler_new().

◆ im_preedit_end_cb()

static void im_preedit_end_cb ( FlTextInputHandler *  self)
static

Definition at line 205 of file fl_text_input_handler.cc.

205  {
206  self->text_model->EndComposing();
207  if (self->enable_delta_model) {
209  flutter::TextEditingDelta(self->text_model->GetText());
210  update_editing_state_with_delta(self, &delta);
211  } else {
212  update_editing_state(self);
213  }
214 }

References update_editing_state(), and update_editing_state_with_delta().

Referenced by fl_text_input_handler_new().

◆ im_preedit_start_cb()

static void im_preedit_start_cb ( FlTextInputHandler *  self)
static

Definition at line 148 of file fl_text_input_handler.cc.

148  {
149  self->text_model->BeginComposing();
150 }

Referenced by fl_text_input_handler_new().

◆ im_retrieve_surrounding_cb()

static gboolean im_retrieve_surrounding_cb ( FlTextInputHandler *  self)
static

Definition at line 217 of file fl_text_input_handler.cc.

217  {
218  auto text = self->text_model->GetText();
219  size_t cursor_offset = self->text_model->GetCursorOffset();
220  gtk_im_context_set_surrounding(self->im_context, text.c_str(), -1,
221  cursor_offset);
222  return TRUE;
223 }

References TRUE.

Referenced by fl_text_input_handler_new().

◆ perform_action()

static void perform_action ( FlTextInputHandler *  self)
static

Definition at line 137 of file fl_text_input_handler.cc.

137  {
138  g_return_if_fail(FL_IS_TEXT_INPUT_HANDLER(self));
139  g_return_if_fail(self->client_id != 0);
140  g_return_if_fail(self->input_action != nullptr);
141 
142  fl_text_input_channel_perform_action(self->channel, self->client_id,
143  self->input_action, self->cancellable,
145 }
void fl_text_input_channel_perform_action(FlTextInputChannel *self, int64_t client_id, const gchar *input_action, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data)
static void perform_action_response_cb(GObject *object, GAsyncResult *result, gpointer user_data)

References fl_text_input_channel_perform_action(), and perform_action_response_cb().

Referenced by fl_text_input_handler_filter_keypress().

◆ perform_action_response_cb()

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

Definition at line 125 of file fl_text_input_handler.cc.

127  {
128  g_autoptr(GError) error = nullptr;
129  if (!fl_text_input_channel_perform_action_finish(object, result, &error)) {
130  if (!g_error_matches(error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
131  g_warning("Failed to perform action: %s", error->message);
132  }
133  }
134 }
g_autoptr(FlEngine) engine
const uint8_t uint32_t uint32_t GError ** error
gboolean fl_text_input_channel_perform_action_finish(GObject *object, GAsyncResult *result, GError **error)

References error, fl_text_input_channel_perform_action_finish(), and g_autoptr().

Referenced by perform_action().

◆ set_client()

static void set_client ( int64_t  client_id,
gpointer  user_data 
)
static

Definition at line 244 of file fl_text_input_handler.cc.

244  {
245  FlTextInputHandler* self = FL_TEXT_INPUT_HANDLER(user_data);
246 
247  self->client_id = client_id;
248 }

References user_data.

◆ set_editable_size_and_transform()

static void set_editable_size_and_transform ( double *  transform,
gpointer  user_data 
)
static

Definition at line 365 of file fl_text_input_handler.cc.

366  {
367  FlTextInputHandler* self = FL_TEXT_INPUT_HANDLER(user_data);
368 
369  for (size_t i = 0; i < 16; i++) {
370  self->editabletext_transform[i / 4][i % 4] = transform[i];
371  }
373 }
static void update_im_cursor_position(FlTextInputHandler *self)

References i, update_im_cursor_position(), and user_data.

◆ set_editing_state()

static void set_editing_state ( const gchar *  text,
int64_t  selection_base,
int64_t  selection_extent,
int64_t  composing_base,
int64_t  composing_extent,
gpointer  user_data 
)
static

Definition at line 290 of file fl_text_input_handler.cc.

295  {
296  FlTextInputHandler* self = FL_TEXT_INPUT_HANDLER(user_data);
297 
298  self->text_model->SetText(text);
299 
300  // Flutter uses -1/-1 for invalid; translate that to 0/0 for the model.
301  if (selection_base == -1 && selection_extent == -1) {
302  selection_base = selection_extent = 0;
303  }
304 
305  self->text_model->SetText(text);
306  self->text_model->SetSelection(
307  flutter::TextRange(selection_base, selection_extent));
308 
309  if (composing_base == -1 && composing_extent == -1) {
310  self->text_model->EndComposing();
311  } else {
312  size_t composing_start = std::min(composing_base, composing_extent);
313  size_t cursor_offset = selection_base - composing_start;
314  self->text_model->SetComposingRange(
315  flutter::TextRange(composing_base, composing_extent), cursor_offset);
316  }
317 }

References user_data.

◆ set_marked_text_rect()

static void set_marked_text_rect ( double  x,
double  y,
double  width,
double  height,
gpointer  user_data 
)
static

Definition at line 381 of file fl_text_input_handler.cc.

385  {
386  FlTextInputHandler* self = FL_TEXT_INPUT_HANDLER(user_data);
387 
388  self->composing_rect.x = x;
389  self->composing_rect.y = y;
390  self->composing_rect.width = width;
391  self->composing_rect.height = height;
393 }
self height
self width

References height, update_im_cursor_position(), user_data, and width.

◆ show()

static void show ( gpointer  user_data)
static

Definition at line 278 of file fl_text_input_handler.cc.

278  {
279  FlTextInputHandler* self = FL_TEXT_INPUT_HANDLER(user_data);
280 
281  if (self->input_type == FL_TEXT_INPUT_TYPE_NONE) {
282  hide(user_data);
283  return;
284  }
285 
286  gtk_im_context_focus_in(self->im_context);
287 }
@ FL_TEXT_INPUT_TYPE_NONE
static void hide(gpointer user_data)

References FL_TEXT_INPUT_TYPE_NONE, hide(), and user_data.

◆ update_editing_state()

static void update_editing_state ( FlTextInputHandler *  self)
static

Definition at line 91 of file fl_text_input_handler.cc.

91  {
92  int composing_base = -1;
93  int composing_extent = -1;
94  if (!self->text_model->composing_range().collapsed()) {
95  composing_base = self->text_model->composing_range().base();
96  composing_extent = self->text_model->composing_range().extent();
97  }
98  flutter::TextRange selection = self->text_model->selection();
100  self->channel, self->client_id, self->text_model->GetText().c_str(),
101  selection.base(), selection.extent(), FL_TEXT_AFFINITY_DOWNSTREAM, FALSE,
102  composing_base, composing_extent, self->cancellable,
104 }
size_t base() const
Definition: text_range.h:30
size_t extent() const
Definition: text_range.h:36
void fl_text_input_channel_update_editing_state(FlTextInputChannel *self, int64_t client_id, const gchar *text, int64_t selection_base, int64_t selection_extent, FlTextAffinity selection_affinity, gboolean selection_is_directional, int64_t composing_base, int64_t composing_extent, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data)
@ FL_TEXT_AFFINITY_DOWNSTREAM
static void update_editing_state_response_cb(GObject *object, GAsyncResult *result, gpointer user_data)

References flutter::TextRange::base(), flutter::TextRange::extent(), FL_TEXT_AFFINITY_DOWNSTREAM, fl_text_input_channel_update_editing_state(), and update_editing_state_response_cb().

Referenced by fl_text_input_handler_filter_keypress(), im_commit_cb(), im_delete_surrounding_cb(), im_preedit_changed_cb(), and im_preedit_end_cb().

◆ update_editing_state_response_cb()

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

Definition at line 63 of file fl_text_input_handler.cc.

65  {
66  g_autoptr(GError) error = nullptr;
68  &error)) {
69  if (!g_error_matches(error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
70  g_warning("Failed to update editing state: %s", error->message);
71  }
72  }
73 }
gboolean fl_text_input_channel_update_editing_state_finish(GObject *object, GAsyncResult *result, GError **error)

References error, fl_text_input_channel_update_editing_state_finish(), and g_autoptr().

Referenced by update_editing_state().

◆ update_editing_state_with_delta()

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

Definition at line 107 of file fl_text_input_handler.cc.

108  {
109  flutter::TextRange selection = self->text_model->selection();
110  int composing_base = -1;
111  int composing_extent = -1;
112  if (!self->text_model->composing_range().collapsed()) {
113  composing_base = self->text_model->composing_range().base();
114  composing_extent = self->text_model->composing_range().extent();
115  }
117  self->channel, self->client_id, delta->old_text().c_str(),
118  delta->delta_text().c_str(), delta->delta_start(), delta->delta_end(),
119  selection.base(), selection.extent(), FL_TEXT_AFFINITY_DOWNSTREAM, FALSE,
120  composing_base, composing_extent, self->cancellable,
122 }
void fl_text_input_channel_update_editing_state_with_deltas(FlTextInputChannel *self, int64_t client_id, const gchar *old_text, const gchar *delta_text, int64_t delta_start, int64_t delta_end, int64_t selection_base, int64_t selection_extent, FlTextAffinity selection_affinity, gboolean selection_is_directional, int64_t composing_base, int64_t composing_extent, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data)
static void update_editing_state_with_deltas_response_cb(GObject *object, GAsyncResult *result, gpointer user_data)
std::string delta_text() const
int delta_start() const
Get the delta_start_ value.
int delta_end() const
Get the delta_end_ value.
std::string old_text() const

References flutter::TextRange::base(), flutter::TextEditingDelta::delta_end(), flutter::TextEditingDelta::delta_start(), flutter::TextEditingDelta::delta_text(), flutter::TextRange::extent(), FL_TEXT_AFFINITY_DOWNSTREAM, fl_text_input_channel_update_editing_state_with_deltas(), flutter::TextEditingDelta::old_text(), and update_editing_state_with_deltas_response_cb().

Referenced by fl_text_input_handler_filter_keypress(), im_commit_cb(), im_delete_surrounding_cb(), im_preedit_changed_cb(), and im_preedit_end_cb().

◆ update_editing_state_with_deltas_response_cb()

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

Definition at line 77 of file fl_text_input_handler.cc.

79  {
80  g_autoptr(GError) error = nullptr;
82  object, result, &error)) {
83  if (!g_error_matches(error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
84  g_warning("Failed to update editing state with deltas: %s",
85  error->message);
86  }
87  }
88 }
gboolean fl_text_input_channel_update_editing_state_with_deltas_finish(GObject *object, GAsyncResult *result, GError **error)

References error, fl_text_input_channel_update_editing_state_with_deltas_finish(), and g_autoptr().

Referenced by update_editing_state_with_delta().

◆ update_im_cursor_position()

static void update_im_cursor_position ( FlTextInputHandler *  self)
static

Definition at line 333 of file fl_text_input_handler.cc.

333  {
334  // Skip update if not composing to avoid setting to position 0.
335  if (!self->text_model->composing()) {
336  return;
337  }
338 
339  // Transform the x, y positions of the cursor from local coordinates to
340  // Flutter view coordinates.
341  gint x = self->composing_rect.x * self->editabletext_transform[0][0] +
342  self->composing_rect.y * self->editabletext_transform[1][0] +
343  self->editabletext_transform[3][0] + self->composing_rect.width;
344  gint y = self->composing_rect.x * self->editabletext_transform[0][1] +
345  self->composing_rect.y * self->editabletext_transform[1][1] +
346  self->editabletext_transform[3][1] + self->composing_rect.height;
347 
348  // Transform from Flutter view coordinates to GTK window coordinates.
349  GdkRectangle preedit_rect = {};
350  gtk_widget_translate_coordinates(self->widget,
351  gtk_widget_get_toplevel(self->widget), x, y,
352  &preedit_rect.x, &preedit_rect.y);
353 
354  // Set the cursor location in window coordinates so that GTK can position
355  // any system input method windows.
356  gtk_im_context_set_cursor_location(self->im_context, &preedit_rect);
357 }

Referenced by set_editable_size_and_transform(), and set_marked_text_rect().

Variable Documentation

◆ kClientIdUnset

constexpr int64_t kClientIdUnset = -1
staticconstexpr

◆ kInputHintsImProperty

constexpr char kInputHintsImProperty[] = "input-hints"
staticconstexpr

Definition at line 15 of file fl_text_input_handler.cc.

Referenced by configure().

◆ kInputPurposeImProperty

constexpr char kInputPurposeImProperty[] = "input-purpose"
staticconstexpr

Definition at line 14 of file fl_text_input_handler.cc.

Referenced by configure().

◆ kNewlineInputAction

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

Definition at line 13 of file fl_text_input_handler.cc.

Referenced by fl_text_input_handler_filter_keypress().

◆ text_input_vtable

FlTextInputChannelVTable text_input_vtable
static
Initial value:
= {
.set_client = set_client,
.configure = configure,
.hide = hide,
.show = show,
.set_editing_state = set_editing_state,
.clear_client = clear_client,
.set_editable_size_and_transform = set_editable_size_and_transform,
.set_marked_text_rect = set_marked_text_rect,
}
static void show(gpointer user_data)
static void set_marked_text_rect(double x, double y, double width, double height, gpointer user_data)
static void clear_client(gpointer user_data)
static void set_editable_size_and_transform(double *transform, gpointer user_data)
static void set_client(int64_t client_id, gpointer user_data)
static void set_editing_state(const gchar *text, int64_t selection_base, int64_t selection_extent, int64_t composing_base, int64_t composing_extent, gpointer user_data)
static void configure(const gchar *input_action, gboolean enable_delta_model, FlTextInputType input_type, GtkInputPurpose im_purpose, GtkInputHints im_hints, gpointer user_data)

Definition at line 426 of file fl_text_input_handler.cc.

Referenced by fl_text_input_handler_new().