Flutter Linux Embedder
fl_keyboard_handler.cc
Go to the documentation of this file.
1 // Copyright 2013 The Flutter Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
6 
7 #include <array>
8 #include <cinttypes>
9 #include <memory>
10 #include <string>
11 
18 
19 // Turn on this flag to print complete layout data when switching IMEs. The data
20 // is used in unit tests.
21 #define DEBUG_PRINT_LAYOUT
22 
23 static constexpr char kChannelName[] = "flutter/keyboard";
24 static constexpr char kGetKeyboardStateMethod[] = "getKeyboardState";
25 
26 /* Declarations of private classes */
27 
28 #define FL_TYPE_KEYBOARD_HANDLER_USER_DATA \
29  fl_keyboard_handler_user_data_get_type()
30 G_DECLARE_FINAL_TYPE(FlKeyboardHandlerUserData,
31  fl_keyboard_handler_user_data,
32  FL,
33  KEYBOARD_HANDLER_USER_DATA,
34  GObject);
35 
36 /* End declarations */
37 
38 namespace {
39 
40 // The maxiumum keycode in a derived layout.
41 //
42 // Although X supports higher keycodes, Flutter only cares about standard keys,
43 // which are below this.
44 constexpr size_t kLayoutSize = 128;
45 // Describes the derived layout of a keyboard group.
46 //
47 // Maps from keycode to logical key. Value being 0 stands for empty.
48 typedef std::array<uint64_t, kLayoutSize> DerivedGroupLayout;
49 // Describes the derived layout of the entire keyboard.
50 //
51 // Maps from group ID to group layout.
52 typedef std::map<guint8, DerivedGroupLayout> DerivedLayout;
53 
54 // Context variables for the foreach call used to dispatch events to responders.
55 typedef struct {
56  FlKeyEvent* event;
57  uint64_t specified_logical_key;
58  FlKeyboardHandlerUserData* user_data;
59 } DispatchToResponderLoopContext;
60 
61 bool is_eascii(uint16_t character) {
62  return character < 256;
63 }
64 
65 #ifdef DEBUG_PRINT_LAYOUT
66 // Prints layout entries that will be parsed by `MockLayoutData`.
67 void debug_format_layout_data(std::string& debug_layout_data,
68  uint16_t keycode,
69  uint16_t clue1,
70  uint16_t clue2) {
71  if (keycode % 4 == 0) {
72  debug_layout_data.append(" ");
73  }
74 
75  constexpr int kBufferSize = 30;
76  char buffer[kBufferSize];
77  buffer[0] = 0;
78  buffer[kBufferSize - 1] = 0;
79 
80  snprintf(buffer, kBufferSize, "0x%04x, 0x%04x, ", clue1, clue2);
81  debug_layout_data.append(buffer);
82 
83  if (keycode % 4 == 3) {
84  snprintf(buffer, kBufferSize, " // 0x%02x", keycode);
85  debug_layout_data.append(buffer);
86  }
87 }
88 #endif
89 
90 } // namespace
91 
92 static uint64_t get_logical_key_from_layout(FlKeyEvent* event,
93  const DerivedLayout& layout) {
94  guint8 group = fl_key_event_get_group(event);
95  guint16 keycode = fl_key_event_get_keycode(event);
96  if (keycode >= kLayoutSize) {
97  return 0;
98  }
99 
100  auto found_group_layout = layout.find(group);
101  if (found_group_layout != layout.end()) {
102  return found_group_layout->second[keycode];
103  }
104  return 0;
105 }
106 
107 /* Define FlKeyboardHandlerUserData */
108 
109 /**
110  * FlKeyboardHandlerUserData:
111  * The user_data used when #FlKeyboardHandler sends event to
112  * responders.
113  */
114 
117 
118  // A weak reference to the owner handler.
119  FlKeyboardHandler* handler;
120  uint64_t sequence_id;
121 };
122 
123 G_DEFINE_TYPE(FlKeyboardHandlerUserData,
124  fl_keyboard_handler_user_data,
125  G_TYPE_OBJECT)
126 
127 static void fl_keyboard_handler_user_data_dispose(GObject* object) {
128  g_return_if_fail(FL_IS_KEYBOARD_HANDLER_USER_DATA(object));
129  FlKeyboardHandlerUserData* self = FL_KEYBOARD_HANDLER_USER_DATA(object);
130  if (self->handler != nullptr) {
131  g_object_remove_weak_pointer(G_OBJECT(self->handler),
132  reinterpret_cast<gpointer*>(&(self->handler)));
133  self->handler = nullptr;
134  }
135 }
136 
138  FlKeyboardHandlerUserDataClass* klass) {
139  G_OBJECT_CLASS(klass)->dispose = fl_keyboard_handler_user_data_dispose;
140 }
141 
143  FlKeyboardHandlerUserData* self) {}
144 
145 // Creates a new FlKeyboardHandlerUserData private class with all information.
146 static FlKeyboardHandlerUserData* fl_keyboard_handler_user_data_new(
147  FlKeyboardHandler* handler,
148  uint64_t sequence_id) {
149  FlKeyboardHandlerUserData* self = FL_KEYBOARD_HANDLER_USER_DATA(
150  g_object_new(fl_keyboard_handler_user_data_get_type(), nullptr));
151 
152  self->handler = handler;
153  // Add a weak pointer so we can know if the key event responder disappeared
154  // while the framework was responding.
155  g_object_add_weak_pointer(G_OBJECT(handler),
156  reinterpret_cast<gpointer*>(&(self->handler)));
157  self->sequence_id = sequence_id;
158  return self;
159 }
160 
161 /* Define FlKeyboardHandler */
162 
165 
166  FlKeyboardViewDelegate* view_delegate;
167 
168  // An array of #FlKeyResponder. Elements are added with
169  // #fl_keyboard_handler_add_responder immediately after initialization and are
170  // automatically released on dispose.
171  GPtrArray* responder_list;
172 
173  // An array of #FlKeyboardPendingEvent.
174  //
175  // Its elements are *not* unreferenced when removed. When FlKeyboardHandler is
176  // disposed, this array will be set with a free_func so that the elements are
177  // unreferenced when removed.
178  GPtrArray* pending_responds;
179 
180  // An array of #FlKeyboardPendingEvent.
181  //
182  // Its elements are unreferenced when removed.
184 
185  // The last sequence ID used. Increased by 1 by every use.
187 
188  // Record the derived layout.
189  //
190  // It is cleared when the platform reports a layout switch. Each entry,
191  // which corresponds to a group, is only initialized on the arrival of the
192  // first event for that group that has a goal keycode.
193  std::unique_ptr<DerivedLayout> derived_layout;
194  // A static map from keycodes to all layout goals.
195  //
196  // It is set up when the handler is initialized and is not changed ever after.
197  std::unique_ptr<std::map<uint16_t, const LayoutGoal*>> keycode_to_goals;
198  // A static map from logical keys to all mandatory layout goals.
199  //
200  // It is set up when the handler is initialized and is not changed ever after.
201  std::unique_ptr<std::map<uint64_t, const LayoutGoal*>>
203 
204  // The channel used by the framework to query the keyboard pressed state.
205  FlMethodChannel* channel;
206 };
207 
208 G_DEFINE_TYPE(FlKeyboardHandler, fl_keyboard_handler, G_TYPE_OBJECT);
209 
210 // This is an exact copy of g_ptr_array_find_with_equal_func. Somehow CI
211 // reports that can not find symbol g_ptr_array_find_with_equal_func, despite
212 // the fact that it runs well locally.
213 static gboolean g_ptr_array_find_with_equal_func1(GPtrArray* haystack,
214  gconstpointer needle,
215  GEqualFunc equal_func,
216  guint* index_) {
217  guint i;
218  g_return_val_if_fail(haystack != NULL, FALSE);
219  if (equal_func == NULL) {
220  equal_func = g_direct_equal;
221  }
222  for (i = 0; i < haystack->len; i++) {
223  if (equal_func(g_ptr_array_index(haystack, i), needle)) {
224  if (index_ != NULL) {
225  *index_ = i;
226  }
227  return TRUE;
228  }
229  }
230 
231  return FALSE;
232 }
233 
234 // Compare a #FlKeyboardPendingEvent with the given sequence_id.
235 static gboolean compare_pending_by_sequence_id(gconstpointer a,
236  gconstpointer b) {
237  FlKeyboardPendingEvent* pending =
238  FL_KEYBOARD_PENDING_EVENT(const_cast<gpointer>(a));
239  uint64_t sequence_id = *reinterpret_cast<const uint64_t*>(b);
240  return fl_keyboard_pending_event_get_sequence_id(pending) == sequence_id;
241 }
242 
243 // Compare a #FlKeyboardPendingEvent with the given hash.
244 static gboolean compare_pending_by_hash(gconstpointer a, gconstpointer b) {
245  FlKeyboardPendingEvent* pending =
246  FL_KEYBOARD_PENDING_EVENT(const_cast<gpointer>(a));
247  uint64_t hash = *reinterpret_cast<const uint64_t*>(b);
248  return fl_keyboard_pending_event_get_hash(pending) == hash;
249 }
250 
251 // Try to remove a pending event from `pending_redispatches` with the target
252 // hash.
253 //
254 // Returns true if the event is found and removed.
255 static bool fl_keyboard_handler_remove_redispatched(FlKeyboardHandler* self,
256  uint64_t hash) {
257  guint result_index;
258  gboolean found = g_ptr_array_find_with_equal_func1(
259  self->pending_redispatches, static_cast<const uint64_t*>(&hash),
260  compare_pending_by_hash, &result_index);
261  if (found) {
262  // The removed object is freed due to `pending_redispatches`'s free_func.
263  g_ptr_array_remove_index_fast(self->pending_redispatches, result_index);
264  return TRUE;
265  } else {
266  return FALSE;
267  }
268 }
269 
270 // The callback used by a responder after the event was dispatched.
271 static void responder_handle_event_callback(bool handled,
272  gpointer user_data_ptr) {
273  g_return_if_fail(FL_IS_KEYBOARD_HANDLER_USER_DATA(user_data_ptr));
274  FlKeyboardHandlerUserData* user_data =
275  FL_KEYBOARD_HANDLER_USER_DATA(user_data_ptr);
276  FlKeyboardHandler* self = user_data->handler;
277  g_return_if_fail(self->view_delegate != nullptr);
278 
279  guint result_index = -1;
280  gboolean found = g_ptr_array_find_with_equal_func1(
281  self->pending_responds, &user_data->sequence_id,
282  compare_pending_by_sequence_id, &result_index);
283  g_return_if_fail(found);
284  FlKeyboardPendingEvent* pending = FL_KEYBOARD_PENDING_EVENT(
285  g_ptr_array_index(self->pending_responds, result_index));
286  g_return_if_fail(pending != nullptr);
287  fl_keyboard_pending_event_mark_replied(pending, handled);
288  // All responders have replied.
290  g_object_unref(user_data_ptr);
291  gpointer removed =
292  g_ptr_array_remove_index_fast(self->pending_responds, result_index);
293  g_return_if_fail(removed == pending);
294  bool should_redispatch =
297  self->view_delegate, fl_keyboard_pending_event_get_event(pending));
298  if (should_redispatch) {
299  g_ptr_array_add(self->pending_redispatches, pending);
301  self->view_delegate,
302  FL_KEY_EVENT(fl_keyboard_pending_event_get_event(pending)));
303  } else {
304  g_object_unref(pending);
305  }
306  }
307 }
308 
309 static uint16_t convert_key_to_char(FlKeyboardViewDelegate* view_delegate,
310  guint keycode,
311  gint group,
312  gint level) {
313  GdkKeymapKey key = {keycode, group, level};
314  constexpr int kBmpMax = 0xD7FF;
315  guint origin = fl_keyboard_view_delegate_lookup_key(view_delegate, &key);
316  return origin < kBmpMax ? origin : 0xFFFF;
317 }
318 
319 // Make sure that Flutter has derived the layout for the group of the event,
320 // if the event contains a goal keycode.
321 static void guarantee_layout(FlKeyboardHandler* self, FlKeyEvent* event) {
322  guint8 group = fl_key_event_get_group(event);
323  if (self->derived_layout->find(group) != self->derived_layout->end()) {
324  return;
325  }
326  if (self->keycode_to_goals->find(fl_key_event_get_keycode(event)) ==
327  self->keycode_to_goals->end()) {
328  return;
329  }
330 
331  DerivedGroupLayout& layout = (*self->derived_layout)[group];
332 
333  // Clone all mandatory goals. Each goal is removed from this cloned map when
334  // fulfilled, and the remaining ones will be assigned to a default position.
335  std::map<uint64_t, const LayoutGoal*> remaining_mandatory_goals =
336  *self->logical_to_mandatory_goals;
337 
338 #ifdef DEBUG_PRINT_LAYOUT
339  std::string debug_layout_data;
340  for (uint16_t keycode = 0; keycode < 128; keycode += 1) {
341  std::vector<uint16_t> this_key_clues = {
342  convert_key_to_char(self->view_delegate, keycode, group, 0),
343  convert_key_to_char(self->view_delegate, keycode, group, 1), // Shift
344  };
345  debug_format_layout_data(debug_layout_data, keycode, this_key_clues[0],
346  this_key_clues[1]);
347  }
348 #endif
349 
350  // It's important to only traverse layout goals instead of all keycodes.
351  // Some key codes outside of the standard keyboard also gives alpha-numeric
352  // letters, and will therefore take over mandatory goals from standard
353  // keyboard keys if they come first. Example: French keyboard digit 1.
354  for (const LayoutGoal& keycode_goal : layout_goals) {
355  uint16_t keycode = keycode_goal.keycode;
356  std::vector<uint16_t> this_key_clues = {
357  convert_key_to_char(self->view_delegate, keycode, group, 0),
358  convert_key_to_char(self->view_delegate, keycode, group, 1), // Shift
359  };
360 
361  // The logical key should be the first available clue from below:
362  //
363  // - Mandatory goal, if it matches any clue. This ensures that all alnum
364  // keys can be found somewhere.
365  // - US layout, if neither clue of the key is EASCII. This ensures that
366  // there are no non-latin logical keys.
367  // - A value derived on the fly from keycode & keyval.
368  for (uint16_t clue : this_key_clues) {
369  auto matching_goal = remaining_mandatory_goals.find(clue);
370  if (matching_goal != remaining_mandatory_goals.end()) {
371  // Found a key that produces a mandatory char. Use it.
372  g_return_if_fail(layout[keycode] == 0);
373  layout[keycode] = clue;
374  remaining_mandatory_goals.erase(matching_goal);
375  break;
376  }
377  }
378  bool has_any_eascii =
379  is_eascii(this_key_clues[0]) || is_eascii(this_key_clues[1]);
380  // See if any produced char meets the requirement as a logical key.
381  if (layout[keycode] == 0 && !has_any_eascii) {
382  auto found_us_layout = self->keycode_to_goals->find(keycode);
383  if (found_us_layout != self->keycode_to_goals->end()) {
384  layout[keycode] = found_us_layout->second->logical_key;
385  }
386  }
387  }
388 
389  // Ensure all mandatory goals are assigned.
390  for (const auto mandatory_goal_iter : remaining_mandatory_goals) {
391  const LayoutGoal* goal = mandatory_goal_iter.second;
392  layout[goal->keycode] = goal->logical_key;
393  }
394 }
395 
396 // Returns the keyboard pressed state.
397 static FlMethodResponse* get_keyboard_state(FlKeyboardHandler* self) {
398  g_autoptr(FlValue) result = fl_value_new_map();
399 
400  GHashTable* pressing_records =
402 
403  g_hash_table_foreach(
404  pressing_records,
405  [](gpointer key, gpointer value, gpointer user_data) {
406  int64_t physical_key = reinterpret_cast<int64_t>(key);
407  int64_t logical_key = reinterpret_cast<int64_t>(value);
408  FlValue* fl_value_map = reinterpret_cast<FlValue*>(user_data);
409 
410  fl_value_set_take(fl_value_map, fl_value_new_int(physical_key),
411  fl_value_new_int(logical_key));
412  },
413  result);
414  return FL_METHOD_RESPONSE(fl_method_success_response_new(result));
415 }
416 
417 // Called when a method call on flutter/keyboard is received from Flutter.
418 static void method_call_handler(FlMethodChannel* channel,
419  FlMethodCall* method_call,
420  gpointer user_data) {
421  FlKeyboardHandler* self = FL_KEYBOARD_HANDLER(user_data);
422 
423  const gchar* method = fl_method_call_get_name(method_call);
424 
425  g_autoptr(FlMethodResponse) response = nullptr;
426  if (strcmp(method, kGetKeyboardStateMethod) == 0) {
427  response = get_keyboard_state(self);
428  } else {
429  response = FL_METHOD_RESPONSE(fl_method_not_implemented_response_new());
430  }
431 
432  g_autoptr(GError) error = nullptr;
433  if (!fl_method_call_respond(method_call, response, &error)) {
434  g_warning("Failed to send method call response: %s", error->message);
435  }
436 }
437 
438 // The loop body to dispatch an event to a responder.
439 static void dispatch_to_responder(gpointer responder_data,
440  gpointer foreach_data_ptr) {
441  DispatchToResponderLoopContext* context =
442  reinterpret_cast<DispatchToResponderLoopContext*>(foreach_data_ptr);
443  FlKeyResponder* responder = FL_KEY_RESPONDER(responder_data);
445  responder, context->event, responder_handle_event_callback,
446  context->user_data, context->specified_logical_key);
447 }
448 
449 static void fl_keyboard_handler_dispose(GObject* object) {
450  FlKeyboardHandler* self = FL_KEYBOARD_HANDLER(object);
451 
452  if (self->view_delegate != nullptr) {
454  nullptr);
455  g_object_remove_weak_pointer(
456  G_OBJECT(self->view_delegate),
457  reinterpret_cast<gpointer*>(&(self->view_delegate)));
458  self->view_delegate = nullptr;
459  }
460 
461  self->derived_layout.reset();
462  self->keycode_to_goals.reset();
463  self->logical_to_mandatory_goals.reset();
464 
465  g_ptr_array_free(self->responder_list, TRUE);
466  g_ptr_array_set_free_func(self->pending_responds, g_object_unref);
467  g_ptr_array_free(self->pending_responds, TRUE);
468  g_ptr_array_free(self->pending_redispatches, TRUE);
469 
470  G_OBJECT_CLASS(fl_keyboard_handler_parent_class)->dispose(object);
471 }
472 
473 static void fl_keyboard_handler_class_init(FlKeyboardHandlerClass* klass) {
474  G_OBJECT_CLASS(klass)->dispose = fl_keyboard_handler_dispose;
475 }
476 
477 static void fl_keyboard_handler_init(FlKeyboardHandler* self) {
478  self->derived_layout = std::make_unique<DerivedLayout>();
479 
480  self->keycode_to_goals =
481  std::make_unique<std::map<uint16_t, const LayoutGoal*>>();
482  self->logical_to_mandatory_goals =
483  std::make_unique<std::map<uint64_t, const LayoutGoal*>>();
484  for (const LayoutGoal& goal : layout_goals) {
485  (*self->keycode_to_goals)[goal.keycode] = &goal;
486  if (goal.mandatory) {
487  (*self->logical_to_mandatory_goals)[goal.logical_key] = &goal;
488  }
489  }
490 
491  self->responder_list = g_ptr_array_new_with_free_func(g_object_unref);
492 
493  self->pending_responds = g_ptr_array_new();
494  self->pending_redispatches = g_ptr_array_new_with_free_func(g_object_unref);
495 
496  self->last_sequence_id = 1;
497 }
498 
499 FlKeyboardHandler* fl_keyboard_handler_new(
500  FlBinaryMessenger* messenger,
501  FlKeyboardViewDelegate* view_delegate) {
502  g_return_val_if_fail(FL_IS_KEYBOARD_VIEW_DELEGATE(view_delegate), nullptr);
503 
504  FlKeyboardHandler* self = FL_KEYBOARD_HANDLER(
505  g_object_new(fl_keyboard_handler_get_type(), nullptr));
506 
507  self->view_delegate = view_delegate;
508  g_object_add_weak_pointer(
509  G_OBJECT(view_delegate),
510  reinterpret_cast<gpointer*>(&(self->view_delegate)));
511 
512  // The embedder responder must be added before the channel responder.
513  g_ptr_array_add(
514  self->responder_list,
515  FL_KEY_RESPONDER(fl_key_embedder_responder_new(
516  [](const FlutterKeyEvent* event, FlutterKeyEventCallback callback,
517  void* callback_user_data, void* send_key_event_user_data) {
518  FlKeyboardHandler* self =
519  FL_KEYBOARD_HANDLER(send_key_event_user_data);
520  g_return_if_fail(self->view_delegate != nullptr);
522  self->view_delegate, event, callback, callback_user_data);
523  },
524  self)));
525  g_ptr_array_add(self->responder_list,
526  FL_KEY_RESPONDER(fl_key_channel_responder_new(
527  fl_keyboard_view_delegate_get_messenger(view_delegate))));
528 
530  self->view_delegate, [self]() { self->derived_layout->clear(); });
531 
532  // Setup the flutter/keyboard channel.
533  g_autoptr(FlStandardMethodCodec) codec = fl_standard_method_codec_new();
534  self->channel =
535  fl_method_channel_new(messenger, kChannelName, FL_METHOD_CODEC(codec));
537  self, nullptr);
538  return self;
539 }
540 
541 gboolean fl_keyboard_handler_handle_event(FlKeyboardHandler* self,
542  FlKeyEvent* event) {
543  g_return_val_if_fail(FL_IS_KEYBOARD_HANDLER(self), FALSE);
544  g_return_val_if_fail(event != nullptr, FALSE);
545  g_return_val_if_fail(self->view_delegate != nullptr, FALSE);
546 
547  guarantee_layout(self, event);
548 
549  uint64_t incoming_hash = fl_key_event_hash(event);
550  if (fl_keyboard_handler_remove_redispatched(self, incoming_hash)) {
551  return FALSE;
552  }
553 
554  FlKeyboardPendingEvent* pending = fl_keyboard_pending_event_new(
555  event, ++self->last_sequence_id, self->responder_list->len);
556 
557  g_ptr_array_add(self->pending_responds, pending);
558  FlKeyboardHandlerUserData* user_data = fl_keyboard_handler_user_data_new(
560  DispatchToResponderLoopContext data{
561  .event = event,
562  .specified_logical_key =
563  get_logical_key_from_layout(event, *self->derived_layout),
564  .user_data = user_data,
565  };
566  g_ptr_array_foreach(self->responder_list, dispatch_to_responder, &data);
567 
568  return TRUE;
569 }
570 
571 gboolean fl_keyboard_handler_is_state_clear(FlKeyboardHandler* self) {
572  g_return_val_if_fail(FL_IS_KEYBOARD_HANDLER(self), FALSE);
573  return self->pending_responds->len == 0 &&
574  self->pending_redispatches->len == 0;
575 }
576 
577 void fl_keyboard_handler_sync_modifier_if_needed(FlKeyboardHandler* self,
578  guint state,
579  double event_time) {
580  g_return_if_fail(FL_IS_KEYBOARD_HANDLER(self));
581 
582  // The embedder responder is the first element in
583  // FlKeyboardHandler.responder_list.
584  FlKeyEmbedderResponder* responder =
585  FL_KEY_EMBEDDER_RESPONDER(g_ptr_array_index(self->responder_list, 0));
587  event_time);
588 }
589 
590 GHashTable* fl_keyboard_handler_get_pressed_state(FlKeyboardHandler* self) {
591  g_return_val_if_fail(FL_IS_KEYBOARD_HANDLER(self), nullptr);
592 
593  // The embedder responder is the first element in
594  // FlKeyboardHandler.responder_list.
595  FlKeyEmbedderResponder* responder =
596  FL_KEY_EMBEDDER_RESPONDER(g_ptr_array_index(self->responder_list, 0));
598 }
fl_keyboard_pending_event_get_hash
uint64_t fl_keyboard_pending_event_get_hash(FlKeyboardPendingEvent *self)
Definition: fl_keyboard_pending_event.cc:81
fl_keyboard_handler_handle_event
gboolean fl_keyboard_handler_handle_event(FlKeyboardHandler *self, FlKeyEvent *event)
Definition: fl_keyboard_handler.cc:541
if
if(end==-1)
Definition: fl_accessible_text_field.cc:42
fl_keyboard_view_delegate_redispatch_event
void fl_keyboard_view_delegate_redispatch_event(FlKeyboardViewDelegate *self, FlKeyEvent *event)
Definition: fl_keyboard_view_delegate.cc:42
event
FlKeyEvent * event
Definition: fl_key_channel_responder.cc:118
get_keyboard_state
static FlMethodResponse * get_keyboard_state(FlKeyboardHandler *self)
Definition: fl_keyboard_handler.cc:397
fl_keyboard_pending_event_get_event
FlKeyEvent * fl_keyboard_pending_event_get_event(FlKeyboardPendingEvent *self)
Definition: fl_keyboard_pending_event.cc:70
layout_goals
const std::vector< LayoutGoal > layout_goals
Definition: key_mapping.g.cc:462
kChannelName
static constexpr char kChannelName[]
Definition: fl_keyboard_handler.cc:23
_FlKeyboardHandler::derived_layout
std::unique_ptr< DerivedLayout > derived_layout
Definition: fl_keyboard_handler.cc:193
fl_method_channel_new
G_MODULE_EXPORT FlMethodChannel * fl_method_channel_new(FlBinaryMessenger *messenger, const gchar *name, FlMethodCodec *codec)
Definition: fl_method_channel.cc:112
fl_key_event_get_group
guint8 fl_key_event_get_group(FlKeyEvent *self)
Definition: fl_key_event.cc:104
fl_key_embedder_responder_get_pressed_state
GHashTable * fl_key_embedder_responder_get_pressed_state(FlKeyEmbedderResponder *self)
Definition: fl_key_embedder_responder.cc:896
fl_keyboard_view_delegate_subscribe_to_layout_change
void fl_keyboard_view_delegate_subscribe_to_layout_change(FlKeyboardViewDelegate *self, KeyboardLayoutNotifier notifier)
Definition: fl_keyboard_view_delegate.cc:51
LayoutGoal
Definition: key_mapping.h:40
fl_keyboard_handler_user_data_class_init
static void fl_keyboard_handler_user_data_class_init(FlKeyboardHandlerUserDataClass *klass)
Definition: fl_keyboard_handler.cc:137
fl_method_not_implemented_response_new
G_MODULE_EXPORT FlMethodNotImplementedResponse * fl_method_not_implemented_response_new()
Definition: fl_method_response.cc:179
fl_standard_method_codec_new
G_MODULE_EXPORT FlStandardMethodCodec * fl_standard_method_codec_new()
Definition: fl_standard_method_codec.cc:291
_FlKeyboardHandler::pending_responds
GPtrArray * pending_responds
Definition: fl_keyboard_handler.cc:178
_FlKeyboardHandlerUserData
Definition: fl_keyboard_handler.cc:115
fl_keyboard_handler_get_pressed_state
GHashTable * fl_keyboard_handler_get_pressed_state(FlKeyboardHandler *self)
Definition: fl_keyboard_handler.cc:590
fl_key_embedder_responder.h
fl_method_channel.h
i
int i
Definition: fl_socket_accessible.cc:18
FlValue
typedefG_BEGIN_DECLS struct _FlValue FlValue
Definition: fl_value.h:42
fl_keyboard_handler_user_data_new
static FlKeyboardHandlerUserData * fl_keyboard_handler_user_data_new(FlKeyboardHandler *handler, uint64_t sequence_id)
Definition: fl_keyboard_handler.cc:146
LayoutGoal::keycode
uint16_t keycode
Definition: key_mapping.h:42
LayoutGoal::logical_key
uint64_t logical_key
Definition: key_mapping.h:45
user_data
FlKeyEvent uint64_t FlKeyResponderAsyncCallback gpointer user_data
Definition: fl_key_channel_responder.cc:121
fl_value_set_take
G_MODULE_EXPORT void fl_value_set_take(FlValue *self, FlValue *key, FlValue *value)
Definition: fl_value.cc:618
_FlKeyboardHandlerUserData::sequence_id
uint64_t sequence_id
Definition: fl_keyboard_handler.cc:120
_FlKeyboardHandlerUserData::handler
FlKeyboardHandler * handler
Definition: fl_keyboard_handler.cc:119
fl_value_new_int
G_MODULE_EXPORT FlValue * fl_value_new_int(int64_t value)
Definition: fl_value.cc:262
convert_key_to_char
static uint16_t convert_key_to_char(FlKeyboardViewDelegate *view_delegate, guint keycode, gint group, gint level)
Definition: fl_keyboard_handler.cc:309
fl_method_success_response_new
G_MODULE_EXPORT FlMethodSuccessResponse * fl_method_success_response_new(FlValue *result)
Definition: fl_method_response.cc:126
state
AtkStateType state
Definition: fl_accessible_node.cc:10
fl_key_channel_responder_new
FlKeyChannelResponder * fl_key_channel_responder_new(FlBinaryMessenger *messenger, FlKeyChannelResponderMock *mock)
Definition: fl_key_channel_responder.cc:186
g_ptr_array_find_with_equal_func1
static gboolean g_ptr_array_find_with_equal_func1(GPtrArray *haystack, gconstpointer needle, GEqualFunc equal_func, guint *index_)
Definition: fl_keyboard_handler.cc:213
fl_keyboard_pending_event_get_sequence_id
uint64_t fl_keyboard_pending_event_get_sequence_id(FlKeyboardPendingEvent *self)
Definition: fl_keyboard_pending_event.cc:75
fl_keyboard_handler.h
fl_keyboard_view_delegate_lookup_key
guint fl_keyboard_view_delegate_lookup_key(FlKeyboardViewDelegate *self, const GdkKeymapKey *key)
Definition: fl_keyboard_view_delegate.cc:60
fl_keyboard_pending_event_is_complete
gboolean fl_keyboard_pending_event_is_complete(FlKeyboardPendingEvent *self)
Definition: fl_keyboard_pending_event.cc:102
kGetKeyboardStateMethod
static constexpr char kGetKeyboardStateMethod[]
Definition: fl_keyboard_handler.cc:24
fl_keyboard_pending_event_get_any_handled
gboolean fl_keyboard_pending_event_get_any_handled(FlKeyboardPendingEvent *self)
Definition: fl_keyboard_pending_event.cc:96
fl_key_embedder_responder_new
FlKeyEmbedderResponder * fl_key_embedder_responder_new(EmbedderSendKeyEvent send_key_event, void *send_key_event_user_data)
Definition: fl_key_embedder_responder.cc:263
fl_method_call_respond
G_MODULE_EXPORT gboolean fl_method_call_respond(FlMethodCall *self, FlMethodResponse *response, GError **error)
Definition: fl_method_call.cc:77
fl_value_new_map
G_MODULE_EXPORT FlValue * fl_value_new_map()
Definition: fl_value.cc:366
guarantee_layout
static void guarantee_layout(FlKeyboardHandler *self, FlKeyEvent *event)
Definition: fl_keyboard_handler.cc:321
method_call
G_BEGIN_DECLS G_MODULE_EXPORT FlMethodCall * method_call
Definition: fl_method_channel.h:120
fl_key_responder_handle_event
void fl_key_responder_handle_event(FlKeyResponder *self, FlKeyEvent *event, FlKeyResponderAsyncCallback callback, gpointer user_data, uint64_t specified_logical_key)
Definition: fl_key_responder.cc:11
fl_keyboard_handler_remove_redispatched
static bool fl_keyboard_handler_remove_redispatched(FlKeyboardHandler *self, uint64_t hash)
Definition: fl_keyboard_handler.cc:255
fl_keyboard_pending_event_mark_replied
void fl_keyboard_pending_event_mark_replied(FlKeyboardPendingEvent *self, gboolean handled)
Definition: fl_keyboard_pending_event.cc:86
_FlKeyboardHandler::parent_instance
GObject parent_instance
Definition: fl_keyboard_handler.cc:164
fl_method_call_get_name
const G_MODULE_EXPORT gchar * fl_method_call_get_name(FlMethodCall *self)
Definition: fl_method_call.cc:67
key_mapping.h
fl_keyboard_handler_is_state_clear
gboolean fl_keyboard_handler_is_state_clear(FlKeyboardHandler *self)
Definition: fl_keyboard_handler.cc:571
TRUE
return TRUE
Definition: fl_pixel_buffer_texture_test.cc:53
_FlKeyboardHandler::keycode_to_goals
std::unique_ptr< std::map< uint16_t, const LayoutGoal * > > keycode_to_goals
Definition: fl_keyboard_handler.cc:197
responder_handle_event_callback
static void responder_handle_event_callback(bool handled, gpointer user_data_ptr)
Definition: fl_keyboard_handler.cc:271
fl_keyboard_handler_user_data_init
static void fl_keyboard_handler_user_data_init(FlKeyboardHandlerUserData *self)
Definition: fl_keyboard_handler.cc:142
_FlKeyboardHandler::logical_to_mandatory_goals
std::unique_ptr< std::map< uint64_t, const LayoutGoal * > > logical_to_mandatory_goals
Definition: fl_keyboard_handler.cc:202
fl_keyboard_view_delegate_text_filter_key_press
gboolean fl_keyboard_view_delegate_text_filter_key_press(FlKeyboardViewDelegate *self, FlKeyEvent *event)
Definition: fl_keyboard_view_delegate.cc:25
fl_key_embedder_responder_sync_modifiers_if_needed
void fl_key_embedder_responder_sync_modifiers_if_needed(FlKeyEmbedderResponder *responder, guint state, double event_time)
Definition: fl_key_embedder_responder.cc:879
_FlKeyboardHandlerUserData::parent_instance
GObject parent_instance
Definition: fl_keyboard_handler.cc:116
FL
FL
Definition: fl_binary_messenger.cc:27
method_call_handler
static void method_call_handler(FlMethodChannel *channel, FlMethodCall *method_call, gpointer user_data)
Definition: fl_keyboard_handler.cc:418
fl_standard_method_codec.h
fl_method_channel_set_method_call_handler
G_MODULE_EXPORT void fl_method_channel_set_method_call_handler(FlMethodChannel *self, FlMethodChannelMethodCallHandler handler, gpointer user_data, GDestroyNotify destroy_notify)
Definition: fl_method_channel.cc:134
result
GAsyncResult * result
Definition: fl_text_input_handler.cc:106
fl_key_event_hash
uint64_t fl_key_event_hash(FlKeyEvent *self)
Definition: fl_key_event.cc:114
fl_key_event_get_keycode
guint16 fl_key_event_get_keycode(FlKeyEvent *self)
Definition: fl_key_event.cc:89
compare_pending_by_hash
static gboolean compare_pending_by_hash(gconstpointer a, gconstpointer b)
Definition: fl_keyboard_handler.cc:244
error
const uint8_t uint32_t uint32_t GError ** error
Definition: fl_pixel_buffer_texture_test.cc:40
fl_keyboard_handler_sync_modifier_if_needed
void fl_keyboard_handler_sync_modifier_if_needed(FlKeyboardHandler *self, guint state, double event_time)
Definition: fl_keyboard_handler.cc:577
_FlKeyboardHandler::channel
FlMethodChannel * channel
Definition: fl_keyboard_handler.cc:205
fl_keyboard_view_delegate_get_messenger
FlBinaryMessenger * fl_keyboard_view_delegate_get_messenger(FlKeyboardViewDelegate *self)
Definition: fl_keyboard_view_delegate.cc:35
compare_pending_by_sequence_id
static gboolean compare_pending_by_sequence_id(gconstpointer a, gconstpointer b)
Definition: fl_keyboard_handler.cc:235
fl_keyboard_handler_class_init
static void fl_keyboard_handler_class_init(FlKeyboardHandlerClass *klass)
Definition: fl_keyboard_handler.cc:473
buffer
static const uint8_t buffer[]
Definition: fl_pixel_buffer_texture_test.cc:44
fl_keyboard_handler_init
static void fl_keyboard_handler_init(FlKeyboardHandler *self)
Definition: fl_keyboard_handler.cc:477
specified_logical_key
FlKeyEvent uint64_t specified_logical_key
Definition: fl_key_channel_responder.cc:119
fl_keyboard_pending_event_new
FlKeyboardPendingEvent * fl_keyboard_pending_event_new(FlKeyEvent *event, uint64_t sequence_id, size_t to_reply)
Definition: fl_keyboard_pending_event.cc:55
fl_keyboard_pending_event.h
callback
FlKeyEvent uint64_t FlKeyResponderAsyncCallback callback
Definition: fl_key_channel_responder.cc:120
_FlKeyboardHandler::view_delegate
FlKeyboardViewDelegate * view_delegate
Definition: fl_keyboard_handler.cc:166
fl_key_channel_responder.h
dispatch_to_responder
static void dispatch_to_responder(gpointer responder_data, gpointer foreach_data_ptr)
Definition: fl_keyboard_handler.cc:439
_FlKeyboardHandler::last_sequence_id
uint64_t last_sequence_id
Definition: fl_keyboard_handler.cc:186
fl_keyboard_view_delegate_send_key_event
void fl_keyboard_view_delegate_send_key_event(FlKeyboardViewDelegate *self, const FlutterKeyEvent *event, FlutterKeyEventCallback callback, void *user_data)
Definition: fl_keyboard_view_delegate.cc:14
fl_keyboard_view_delegate_get_keyboard_state
GHashTable * fl_keyboard_view_delegate_get_keyboard_state(FlKeyboardViewDelegate *self)
Definition: fl_keyboard_view_delegate.cc:67
get_logical_key_from_layout
static uint64_t get_logical_key_from_layout(FlKeyEvent *event, const DerivedLayout &layout)
Definition: fl_keyboard_handler.cc:92
value
uint8_t value
Definition: fl_standard_message_codec.cc:36
fl_keyboard_handler_new
FlKeyboardHandler * fl_keyboard_handler_new(FlBinaryMessenger *messenger, FlKeyboardViewDelegate *view_delegate)
Definition: fl_keyboard_handler.cc:499
G_DECLARE_FINAL_TYPE
G_DECLARE_FINAL_TYPE(FlKeyboardHandlerUserData, fl_keyboard_handler_user_data, FL, KEYBOARD_HANDLER_USER_DATA, GObject)
_FlKeyboardHandler::pending_redispatches
GPtrArray * pending_redispatches
Definition: fl_keyboard_handler.cc:183
_FlKeyboardHandler
Definition: fl_keyboard_handler.cc:163
_FlKeyboardHandler::responder_list
GPtrArray * responder_list
Definition: fl_keyboard_handler.cc:171
G_DEFINE_TYPE
G_DEFINE_TYPE(FlKeyboardHandlerUserData, fl_keyboard_handler_user_data, G_TYPE_OBJECT) static void fl_keyboard_handler_user_data_dispose(GObject *object)
Definition: fl_keyboard_handler.cc:123
fl_keyboard_handler_dispose
static void fl_keyboard_handler_dispose(GObject *object)
Definition: fl_keyboard_handler.cc:449