Flutter Linux Embedder
fl_keyboard_manager.cc File Reference

Go to the source code of this file.

Classes

struct  _FlKeyboardManagerData
 
struct  _FlKeyboardManager
 

Macros

#define DEBUG_PRINT_LAYOUT
 

Functions

 G_DECLARE_FINAL_TYPE (FlKeyboardManagerData, fl_keyboard_manager_data, FL, KEYBOARD_MANAGER_DATA, GObject)
 
static void fl_keyboard_manager_data_dispose (GObject *object)
 
static void fl_keyboard_manager_data_class_init (FlKeyboardManagerDataClass *klass)
 
static void fl_keyboard_manager_data_init (FlKeyboardManagerData *self)
 
static FlKeyboardManagerData * fl_keyboard_manager_data_new (FlKeyboardManager *manager, FlKeyboardPendingEvent *pending)
 
 G_DEFINE_TYPE (FlKeyboardManager, fl_keyboard_manager, G_TYPE_OBJECT)
 
static void keymap_keys_changed_cb (FlKeyboardManager *self)
 
static gboolean g_ptr_array_find_with_equal_func1 (GPtrArray *haystack, gconstpointer needle, GEqualFunc equal_func, guint *index_)
 
static gboolean compare_pending_by_hash (gconstpointer a, gconstpointer b)
 
static bool fl_keyboard_manager_remove_redispatched (FlKeyboardManager *self, uint64_t hash)
 
static void responder_handle_event_callback (FlKeyboardManager *self, FlKeyboardPendingEvent *pending)
 
static void responder_handle_embedder_event_callback (bool handled, gpointer user_data)
 
static void responder_handle_channel_event_cb (GObject *object, GAsyncResult *result, gpointer user_data)
 
static uint16_t convert_key_to_char (FlKeyboardManager *self, guint keycode, gint group, gint level)
 
static void guarantee_layout (FlKeyboardManager *self, FlKeyEvent *event)
 
static void fl_keyboard_manager_dispose (GObject *object)
 
static void fl_keyboard_manager_class_init (FlKeyboardManagerClass *klass)
 
static void fl_keyboard_manager_init (FlKeyboardManager *self)
 
FlKeyboardManager * fl_keyboard_manager_new (FlEngine *engine, FlKeyboardViewDelegate *view_delegate)
 
gboolean fl_keyboard_manager_handle_event (FlKeyboardManager *self, FlKeyEvent *event)
 
gboolean fl_keyboard_manager_is_state_clear (FlKeyboardManager *self)
 
void fl_keyboard_manager_sync_modifier_if_needed (FlKeyboardManager *self, guint state, double event_time)
 
GHashTable * fl_keyboard_manager_get_pressed_state (FlKeyboardManager *self)
 
void fl_keyboard_manager_set_send_key_event_handler (FlKeyboardManager *self, FlKeyboardManagerSendKeyEventHandler send_key_event_handler, gpointer user_data)
 
void fl_keyboard_manager_set_lookup_key_handler (FlKeyboardManager *self, FlKeyboardManagerLookupKeyHandler lookup_key_handler, gpointer user_data)
 
void fl_keyboard_manager_set_redispatch_handler (FlKeyboardManager *self, FlKeyboardManagerRedispatchEventHandler redispatch_handler, gpointer user_data)
 
void fl_keyboard_manager_set_get_pressed_state_handler (FlKeyboardManager *self, FlKeyboardManagerGetPressedStateHandler get_pressed_state_handler, gpointer user_data)
 

Macro Definition Documentation

◆ DEBUG_PRINT_LAYOUT

#define DEBUG_PRINT_LAYOUT

Definition at line 21 of file fl_keyboard_manager.cc.

Function Documentation

◆ compare_pending_by_hash()

static gboolean compare_pending_by_hash ( gconstpointer  a,
gconstpointer  b 
)
static

Definition at line 207 of file fl_keyboard_manager.cc.

207  {
208  FlKeyboardPendingEvent* pending =
209  FL_KEYBOARD_PENDING_EVENT(const_cast<gpointer>(a));
210  uint64_t hash = *reinterpret_cast<const uint64_t*>(b);
211  return fl_keyboard_pending_event_get_hash(pending) == hash;
212 }

References fl_keyboard_pending_event_get_hash().

Referenced by fl_keyboard_manager_remove_redispatched().

◆ convert_key_to_char()

static uint16_t convert_key_to_char ( FlKeyboardManager *  self,
guint  keycode,
gint  group,
gint  level 
)
static

Definition at line 306 of file fl_keyboard_manager.cc.

309  {
310  GdkKeymapKey key = {keycode, group, level};
311  constexpr int kBmpMax = 0xD7FF;
312  guint origin;
313  if (self->lookup_key_handler != nullptr) {
314  origin = self->lookup_key_handler(&key, self->lookup_key_handler_user_data);
315  } else {
316  origin = gdk_keymap_lookup_key(self->keymap, &key);
317  }
318  return origin < kBmpMax ? origin : 0xFFFF;
319 }

Referenced by guarantee_layout().

◆ fl_keyboard_manager_class_init()

static void fl_keyboard_manager_class_init ( FlKeyboardManagerClass *  klass)
static

Definition at line 435 of file fl_keyboard_manager.cc.

435  {
436  G_OBJECT_CLASS(klass)->dispose = fl_keyboard_manager_dispose;
437 }

References fl_keyboard_manager_dispose().

◆ fl_keyboard_manager_data_class_init()

static void fl_keyboard_manager_data_class_init ( FlKeyboardManagerDataClass *  klass)
static

Definition at line 94 of file fl_keyboard_manager.cc.

95  {
96  G_OBJECT_CLASS(klass)->dispose = fl_keyboard_manager_data_dispose;
97 }

References fl_keyboard_manager_data_dispose().

◆ fl_keyboard_manager_data_dispose()

static void fl_keyboard_manager_data_dispose ( GObject *  object)
static

Definition at line 85 of file fl_keyboard_manager.cc.

85  {
86  g_return_if_fail(FL_IS_KEYBOARD_MANAGER_DATA(object));
87  FlKeyboardManagerData* self = FL_KEYBOARD_MANAGER_DATA(object);
88 
89  g_weak_ref_clear(&self->manager);
90 
91  G_OBJECT_CLASS(fl_keyboard_manager_data_parent_class)->dispose(object);
92 }

Referenced by fl_keyboard_manager_data_class_init().

◆ fl_keyboard_manager_data_init()

static void fl_keyboard_manager_data_init ( FlKeyboardManagerData *  self)
static

Definition at line 99 of file fl_keyboard_manager.cc.

99 {}

◆ fl_keyboard_manager_data_new()

static FlKeyboardManagerData* fl_keyboard_manager_data_new ( FlKeyboardManager *  manager,
FlKeyboardPendingEvent *  pending 
)
static

Definition at line 102 of file fl_keyboard_manager.cc.

104  {
105  FlKeyboardManagerData* self = FL_KEYBOARD_MANAGER_DATA(
106  g_object_new(fl_keyboard_manager_data_get_type(), nullptr));
107 
108  g_weak_ref_init(&self->manager, manager);
109  self->pending = FL_KEYBOARD_PENDING_EVENT(g_object_ref(pending));
110  return self;
111 }

Referenced by fl_keyboard_manager_handle_event().

◆ fl_keyboard_manager_dispose()

static void fl_keyboard_manager_dispose ( GObject *  object)
static

Definition at line 409 of file fl_keyboard_manager.cc.

409  {
410  FlKeyboardManager* self = FL_KEYBOARD_MANAGER(object);
411 
412  g_cancellable_cancel(self->cancellable);
413 
414  g_weak_ref_clear(&self->engine);
415  g_weak_ref_clear(&self->view_delegate);
416 
417  self->keycode_to_goals.reset();
418  self->logical_to_mandatory_goals.reset();
419 
420  g_clear_object(&self->key_embedder_responder);
421  g_clear_object(&self->key_channel_responder);
422  g_ptr_array_set_free_func(self->pending_responds, g_object_unref);
423  g_ptr_array_free(self->pending_responds, TRUE);
424  g_ptr_array_free(self->pending_redispatches, TRUE);
425  g_clear_object(&self->derived_layout);
426  if (self->keymap_keys_changed_cb_id != 0) {
427  g_signal_handler_disconnect(self->keymap, self->keymap_keys_changed_cb_id);
428  self->keymap_keys_changed_cb_id = 0;
429  }
430  g_clear_object(&self->cancellable);
431 
432  G_OBJECT_CLASS(fl_keyboard_manager_parent_class)->dispose(object);
433 }

References TRUE.

Referenced by fl_keyboard_manager_class_init().

◆ fl_keyboard_manager_get_pressed_state()

GHashTable* fl_keyboard_manager_get_pressed_state ( FlKeyboardManager *  manager)

fl_keyboard_manager_get_pressed_state: @manager: the #FlKeyboardManager self.

Returns the keyboard pressed state. The hash table contains one entry per pressed keys, mapping from the logical key to the physical key.*

Definition at line 566 of file fl_keyboard_manager.cc.

566  {
567  g_return_val_if_fail(FL_IS_KEYBOARD_MANAGER(self), nullptr);
568  if (self->get_pressed_state_handler != nullptr) {
569  return self->get_pressed_state_handler(
570  self->get_pressed_state_handler_user_data);
571  } else {
573  self->key_embedder_responder);
574  }
575 }

References fl_key_embedder_responder_get_pressed_state().

Referenced by get_keyboard_state().

◆ fl_keyboard_manager_handle_event()

gboolean fl_keyboard_manager_handle_event ( FlKeyboardManager *  manager,
FlKeyEvent *  event 
)

fl_keyboard_manager_handle_event: @manager: the #FlKeyboardManager self. @event: the event to be dispatched. It is usually a wrap of a GdkEventKey. This event will be managed and released by #FlKeyboardManager.

Make the manager process a system key event. This might eventually send messages to the framework, trigger text input effects, or redispatch the event back to the system.

Definition at line 522 of file fl_keyboard_manager.cc.

523  {
524  g_return_val_if_fail(FL_IS_KEYBOARD_MANAGER(self), FALSE);
525  g_return_val_if_fail(event != nullptr, FALSE);
526 
527  guarantee_layout(self, event);
528 
529  uint64_t incoming_hash = fl_key_event_hash(event);
530  if (fl_keyboard_manager_remove_redispatched(self, incoming_hash)) {
531  return FALSE;
532  }
533 
534  FlKeyboardPendingEvent* pending = fl_keyboard_pending_event_new(event);
535 
536  g_ptr_array_add(self->pending_responds, pending);
537  g_autoptr(FlKeyboardManagerData) data =
538  fl_keyboard_manager_data_new(self, pending);
539  uint64_t specified_logical_key = fl_keyboard_layout_get_logical_key(
540  self->derived_layout, fl_key_event_get_group(event),
541  fl_key_event_get_keycode(event));
543  self->key_embedder_responder, event, specified_logical_key,
544  responder_handle_embedder_event_callback, g_object_ref(data));
546  self->key_channel_responder, event, specified_logical_key,
547  self->cancellable, responder_handle_channel_event_cb, g_object_ref(data));
548 
549  return TRUE;
550 }

References fl_key_channel_responder_handle_event(), fl_key_embedder_responder_handle_event(), fl_key_event_get_group(), fl_key_event_get_keycode(), fl_key_event_hash(), fl_keyboard_layout_get_logical_key(), fl_keyboard_manager_data_new(), fl_keyboard_manager_remove_redispatched(), fl_keyboard_pending_event_new(), guarantee_layout(), responder_handle_channel_event_cb(), responder_handle_embedder_event_callback(), and TRUE.

Referenced by fl_view_key_press_event(), and fl_view_key_release_event().

◆ fl_keyboard_manager_init()

static void fl_keyboard_manager_init ( FlKeyboardManager *  self)
static

Definition at line 439 of file fl_keyboard_manager.cc.

439  {
440  self->derived_layout = fl_keyboard_layout_new();
441 
442  self->keycode_to_goals =
443  std::make_unique<std::map<uint16_t, const LayoutGoal*>>();
444  self->logical_to_mandatory_goals =
445  std::make_unique<std::map<uint64_t, const LayoutGoal*>>();
446  for (const LayoutGoal& goal : layout_goals) {
447  (*self->keycode_to_goals)[goal.keycode] = &goal;
448  if (goal.mandatory) {
449  (*self->logical_to_mandatory_goals)[goal.logical_key] = &goal;
450  }
451  }
452 
453  self->pending_responds = g_ptr_array_new();
454  self->pending_redispatches = g_ptr_array_new_with_free_func(g_object_unref);
455 
456  self->keymap = gdk_keymap_get_for_display(gdk_display_get_default());
457  self->keymap_keys_changed_cb_id = g_signal_connect_swapped(
458  self->keymap, "keys-changed", G_CALLBACK(keymap_keys_changed_cb), self);
459  self->cancellable = g_cancellable_new();
460 }

References fl_keyboard_layout_new(), if(), keymap_keys_changed_cb(), and layout_goals.

◆ fl_keyboard_manager_is_state_clear()

gboolean fl_keyboard_manager_is_state_clear ( FlKeyboardManager *  manager)

fl_keyboard_manager_is_state_clear: @manager: the #FlKeyboardManager self.

A debug-only method that queries whether the manager's various states are cleared, i.e. no pending events for redispatching or for responding.

Returns: true if the manager's various states are cleared.

Definition at line 552 of file fl_keyboard_manager.cc.

552  {
553  g_return_val_if_fail(FL_IS_KEYBOARD_MANAGER(self), FALSE);
554  return self->pending_responds->len == 0 &&
555  self->pending_redispatches->len == 0;
556 }

◆ fl_keyboard_manager_new()

FlKeyboardManager* fl_keyboard_manager_new ( FlEngine *  engine,
FlKeyboardViewDelegate *  view_delegate 
)

FlKeyboardManager:

Processes keyboard events and cooperate with TextInputManager.

A keyboard event goes through a few sections, each can choose to handle the event, and only unhandled events can move to the next section:

  • Keyboard: Dispatch to the embedder responder and the channel responder simultaneously. After both responders have responded (asynchronously), the event is considered handled if either responder handles it.
  • Text input: Events are sent to IM filter (usually owned by TextInputManager) and are handled synchronously.
  • Redispatching: Events are inserted back to the system for redispatching. fl_keyboard_manager_new: @engine: an #FlEngine. @view_delegate: An interface that the manager requires to communicate with the platform. Usually implemented by FlView.

Create a new #FlKeyboardManager.

Returns: a new #FlKeyboardManager.

Definition at line 462 of file fl_keyboard_manager.cc.

464  {
465  g_return_val_if_fail(FL_IS_KEYBOARD_VIEW_DELEGATE(view_delegate), nullptr);
466 
467  FlKeyboardManager* self = FL_KEYBOARD_MANAGER(
468  g_object_new(fl_keyboard_manager_get_type(), nullptr));
469 
470  g_weak_ref_init(&self->engine, engine);
471  g_weak_ref_init(&self->view_delegate, view_delegate);
472 
473  self->key_embedder_responder = fl_key_embedder_responder_new(
474  [](const FlutterKeyEvent* event, FlutterKeyEventCallback callback,
475  void* callback_user_data, void* send_key_event_user_data) {
476  FlKeyboardManager* self = FL_KEYBOARD_MANAGER(send_key_event_user_data);
477  if (self->send_key_event_handler != nullptr) {
478  self->send_key_event_handler(event, callback, callback_user_data,
479  self->send_key_event_handler_user_data);
480  } else {
481  g_autoptr(FlEngine) engine = FL_ENGINE(g_weak_ref_get(&self->engine));
482  if (engine != nullptr) {
483  typedef struct {
484  FlutterKeyEventCallback callback;
485  void* callback_user_data;
486  } SendKeyEventData;
487  SendKeyEventData* data = g_new0(SendKeyEventData, 1);
488  data->callback = callback;
489  data->callback_user_data = callback_user_data;
491  engine, event, self->cancellable,
492  [](GObject* object, GAsyncResult* result, gpointer user_data) {
493  g_autofree SendKeyEventData* data =
494  static_cast<SendKeyEventData*>(user_data);
495  gboolean handled = FALSE;
496  g_autoptr(GError) error = nullptr;
497  if (!fl_engine_send_key_event_finish(
498  FL_ENGINE(object), result, &handled, &error)) {
499  if (g_error_matches(error, G_IO_ERROR,
500  G_IO_ERROR_CANCELLED)) {
501  return;
502  }
503 
504  g_warning("Failed to send key event: %s", error->message);
505  }
506 
507  if (data->callback != nullptr) {
508  data->callback(handled, data->callback_user_data);
509  }
510  },
511  data);
512  }
513  }
514  },
515  self);
516  self->key_channel_responder =
518 
519  return self;
520 }

References fl_engine_send_key_event(), fl_key_embedder_responder_new(), if(), and user_data.

Referenced by init_keyboard(), and TEST().

◆ fl_keyboard_manager_remove_redispatched()

static bool fl_keyboard_manager_remove_redispatched ( FlKeyboardManager *  self,
uint64_t  hash 
)
static

Definition at line 218 of file fl_keyboard_manager.cc.

219  {
220  guint result_index;
221  gboolean found = g_ptr_array_find_with_equal_func1(
222  self->pending_redispatches, static_cast<const uint64_t*>(&hash),
223  compare_pending_by_hash, &result_index);
224  if (found) {
225  // The removed object is freed due to `pending_redispatches`'s free_func.
226  g_ptr_array_remove_index_fast(self->pending_redispatches, result_index);
227  return TRUE;
228  } else {
229  return FALSE;
230  }
231 }

References compare_pending_by_hash(), g_ptr_array_find_with_equal_func1(), and TRUE.

Referenced by fl_keyboard_manager_handle_event().

◆ fl_keyboard_manager_set_get_pressed_state_handler()

void fl_keyboard_manager_set_get_pressed_state_handler ( FlKeyboardManager *  manager,
FlKeyboardManagerGetPressedStateHandler  get_pressed_state_handler,
gpointer  user_data 
)

fl_keyboard_manager_set_get_pressed_state_handler: @manager: the #FlKeyboardManager self.

Set the handler for gettting the keyboard state, for testing purposes only.

Definition at line 604 of file fl_keyboard_manager.cc.

607  {
608  g_return_if_fail(FL_IS_KEYBOARD_MANAGER(self));
609  self->get_pressed_state_handler = get_pressed_state_handler;
610  self->get_pressed_state_handler_user_data = user_data;
611 }

References user_data.

Referenced by TEST().

◆ fl_keyboard_manager_set_lookup_key_handler()

void fl_keyboard_manager_set_lookup_key_handler ( FlKeyboardManager *  manager,
FlKeyboardManagerLookupKeyHandler  lookup_key_handler,
gpointer  user_data 
)

fl_keyboard_manager_set_lookup_key_handler: @manager: the #FlKeyboardManager self.

Set the handler for key lookup, for testing purposes only.

Definition at line 586 of file fl_keyboard_manager.cc.

589  {
590  g_return_if_fail(FL_IS_KEYBOARD_MANAGER(self));
591  self->lookup_key_handler = lookup_key_handler;
592  self->lookup_key_handler_user_data = user_data;
593 }

References user_data.

◆ fl_keyboard_manager_set_redispatch_handler()

void fl_keyboard_manager_set_redispatch_handler ( FlKeyboardManager *  manager,
FlKeyboardManagerRedispatchEventHandler  redispatch_handler,
gpointer  user_data 
)

fl_keyboard_manager_set_redispatch_handler: @manager: the #FlKeyboardManager self.

Set the handler for redispatches, for testing purposes only.

Definition at line 595 of file fl_keyboard_manager.cc.

598  {
599  g_return_if_fail(FL_IS_KEYBOARD_MANAGER(self));
600  self->redispatch_handler = redispatch_handler;
601  self->redispatch_handler_user_data = user_data;
602 }

References user_data.

◆ fl_keyboard_manager_set_send_key_event_handler()

void fl_keyboard_manager_set_send_key_event_handler ( FlKeyboardManager *  manager,
FlKeyboardManagerSendKeyEventHandler  send_key_event_handler,
gpointer  user_data 
)

fl_keyboard_manager_set_send_key_event_handler: @manager: the #FlKeyboardManager self.

Set the handler for sending events, for testing purposes only.

Definition at line 577 of file fl_keyboard_manager.cc.

580  {
581  g_return_if_fail(FL_IS_KEYBOARD_MANAGER(self));
582  self->send_key_event_handler = send_key_event_handler;
583  self->send_key_event_handler_user_data = user_data;
584 }

References user_data.

◆ fl_keyboard_manager_sync_modifier_if_needed()

void fl_keyboard_manager_sync_modifier_if_needed ( FlKeyboardManager *  manager,
guint  state,
double  event_time 
)

fl_keyboard_manager_sync_modifier_if_needed: @manager: the #FlKeyboardManager self. @state: the state of the modifiers mask. @event_time: the time attribute of the incoming GDK event.

If needed, synthesize modifier keys up and down event by comparing their current pressing states with the given modifiers mask.

Definition at line 558 of file fl_keyboard_manager.cc.

560  {
561  g_return_if_fail(FL_IS_KEYBOARD_MANAGER(self));
563  self->key_embedder_responder, state, event_time);
564 }

References fl_key_embedder_responder_sync_modifiers_if_needed(), and state.

Referenced by sync_modifier_if_needed().

◆ G_DECLARE_FINAL_TYPE()

G_DECLARE_FINAL_TYPE ( FlKeyboardManagerData  ,
fl_keyboard_manager_data  ,
FL  ,
KEYBOARD_MANAGER_DATA  ,
GObject   
)

◆ G_DEFINE_TYPE()

G_DEFINE_TYPE ( FlKeyboardManager  ,
fl_keyboard_manager  ,
G_TYPE_OBJECT   
)

◆ 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_ 
)
static

Definition at line 185 of file fl_keyboard_manager.cc.

188  {
189  guint i;
190  g_return_val_if_fail(haystack != NULL, FALSE);
191  if (equal_func == NULL) {
192  equal_func = g_direct_equal;
193  }
194  for (i = 0; i < haystack->len; i++) {
195  if (equal_func(g_ptr_array_index(haystack, i), needle)) {
196  if (index_ != NULL) {
197  *index_ = i;
198  }
199  return TRUE;
200  }
201  }
202 
203  return FALSE;
204 }

References i, and TRUE.

Referenced by fl_keyboard_manager_remove_redispatched().

◆ guarantee_layout()

static void guarantee_layout ( FlKeyboardManager *  self,
FlKeyEvent *  event 
)
static

Definition at line 323 of file fl_keyboard_manager.cc.

323  {
324  g_autoptr(FlKeyboardViewDelegate) view_delegate =
325  FL_KEYBOARD_VIEW_DELEGATE(g_weak_ref_get(&self->view_delegate));
326  if (view_delegate == nullptr) {
327  return;
328  }
329 
330  guint8 group = fl_key_event_get_group(event);
331  if (fl_keyboard_layout_has_group(self->derived_layout, group)) {
332  return;
333  }
334  if (self->keycode_to_goals->find(fl_key_event_get_keycode(event)) ==
335  self->keycode_to_goals->end()) {
336  return;
337  }
338 
339  // Clone all mandatory goals. Each goal is removed from this cloned map when
340  // fulfilled, and the remaining ones will be assigned to a default position.
341  std::map<uint64_t, const LayoutGoal*> remaining_mandatory_goals =
342  *self->logical_to_mandatory_goals;
343 
344 #ifdef DEBUG_PRINT_LAYOUT
345  std::string debug_layout_data;
346  for (uint16_t keycode = 0; keycode < 128; keycode += 1) {
347  std::vector<uint16_t> this_key_clues = {
348  convert_key_to_char(self, keycode, group, 0),
349  convert_key_to_char(self, keycode, group, 1), // Shift
350  };
351  debug_format_layout_data(debug_layout_data, keycode, this_key_clues[0],
352  this_key_clues[1]);
353  }
354 #endif
355 
356  // It's important to only traverse layout goals instead of all keycodes.
357  // Some key codes outside of the standard keyboard also gives alpha-numeric
358  // letters, and will therefore take over mandatory goals from standard
359  // keyboard keys if they come first. Example: French keyboard digit 1.
360  for (const LayoutGoal& keycode_goal : layout_goals) {
361  uint16_t keycode = keycode_goal.keycode;
362  std::vector<uint16_t> this_key_clues = {
363  convert_key_to_char(self, keycode, group, 0),
364  convert_key_to_char(self, keycode, group, 1), // Shift
365  };
366 
367  // The logical key should be the first available clue from below:
368  //
369  // - Mandatory goal, if it matches any clue. This ensures that all alnum
370  // keys can be found somewhere.
371  // - US layout, if neither clue of the key is EASCII. This ensures that
372  // there are no non-latin logical keys.
373  // - A value derived on the fly from keycode & keyval.
374  for (uint16_t clue : this_key_clues) {
375  auto matching_goal = remaining_mandatory_goals.find(clue);
376  if (matching_goal != remaining_mandatory_goals.end()) {
377  // Found a key that produces a mandatory char. Use it.
378  g_return_if_fail(fl_keyboard_layout_get_logical_key(
379  self->derived_layout, group, keycode) == 0);
380  fl_keyboard_layout_set_logical_key(self->derived_layout, group, keycode,
381  clue);
382  remaining_mandatory_goals.erase(matching_goal);
383  break;
384  }
385  }
386  bool has_any_eascii =
387  is_eascii(this_key_clues[0]) || is_eascii(this_key_clues[1]);
388  // See if any produced char meets the requirement as a logical key.
389  if (fl_keyboard_layout_get_logical_key(self->derived_layout, group,
390  keycode) == 0 &&
391  !has_any_eascii) {
392  auto found_us_layout = self->keycode_to_goals->find(keycode);
393  if (found_us_layout != self->keycode_to_goals->end()) {
395  self->derived_layout, group, keycode,
396  found_us_layout->second->logical_key);
397  }
398  }
399  }
400 
401  // Ensure all mandatory goals are assigned.
402  for (const auto mandatory_goal_iter : remaining_mandatory_goals) {
403  const LayoutGoal* goal = mandatory_goal_iter.second;
404  fl_keyboard_layout_set_logical_key(self->derived_layout, group,
405  goal->keycode, goal->logical_key);
406  }
407 }

References convert_key_to_char(), fl_key_event_get_group(), fl_key_event_get_keycode(), fl_keyboard_layout_get_logical_key(), fl_keyboard_layout_has_group(), fl_keyboard_layout_set_logical_key(), LayoutGoal::keycode, layout_goals, and LayoutGoal::logical_key.

Referenced by fl_keyboard_manager_handle_event().

◆ keymap_keys_changed_cb()

static void keymap_keys_changed_cb ( FlKeyboardManager *  self)
static

Definition at line 177 of file fl_keyboard_manager.cc.

177  {
178  g_clear_object(&self->derived_layout);
179  self->derived_layout = fl_keyboard_layout_new();
180 }

References fl_keyboard_layout_new().

Referenced by fl_keyboard_manager_init().

◆ responder_handle_channel_event_cb()

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

Definition at line 280 of file fl_keyboard_manager.cc.

282  {
283  g_autoptr(FlKeyboardManagerData) data = FL_KEYBOARD_MANAGER_DATA(user_data);
284 
285  g_autoptr(GError) error = nullptr;
286  gboolean handled;
288  FL_KEY_CHANNEL_RESPONDER(object), result, &handled, &error)) {
289  if (!g_error_matches(error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
290  g_warning("Failed to handle key event in platform: %s", error->message);
291  }
292  return;
293  }
294 
295  g_autoptr(FlKeyboardManager) self =
296  FL_KEYBOARD_MANAGER(g_weak_ref_get(&data->manager));
297  if (self == nullptr) {
298  return;
299  }
300 
301  fl_keyboard_pending_event_mark_channel_replied(data->pending, handled);
302 
303  responder_handle_event_callback(self, data->pending);
304 }

References error, fl_key_channel_responder_handle_event_finish(), fl_keyboard_pending_event_mark_channel_replied(), responder_handle_event_callback(), and user_data.

Referenced by fl_keyboard_manager_handle_event().

◆ responder_handle_embedder_event_callback()

static void responder_handle_embedder_event_callback ( bool  handled,
gpointer  user_data 
)
static

Definition at line 265 of file fl_keyboard_manager.cc.

266  {
267  g_autoptr(FlKeyboardManagerData) data = FL_KEYBOARD_MANAGER_DATA(user_data);
268 
269  fl_keyboard_pending_event_mark_embedder_replied(data->pending, handled);
270 
271  g_autoptr(FlKeyboardManager) self =
272  FL_KEYBOARD_MANAGER(g_weak_ref_get(&data->manager));
273  if (self == nullptr) {
274  return;
275  }
276 
277  responder_handle_event_callback(self, data->pending);
278 }

References fl_keyboard_pending_event_mark_embedder_replied(), responder_handle_event_callback(), and user_data.

Referenced by fl_keyboard_manager_handle_event().

◆ responder_handle_event_callback()

static void responder_handle_event_callback ( FlKeyboardManager *  self,
FlKeyboardPendingEvent *  pending 
)
static

Definition at line 234 of file fl_keyboard_manager.cc.

235  {
236  g_autoptr(FlKeyboardViewDelegate) view_delegate =
237  FL_KEYBOARD_VIEW_DELEGATE(g_weak_ref_get(&self->view_delegate));
238  if (view_delegate == nullptr) {
239  return;
240  }
241 
242  // All responders have replied.
244  g_ptr_array_remove(self->pending_responds, pending);
245  bool should_redispatch =
248  view_delegate, fl_keyboard_pending_event_get_event(pending));
249  if (should_redispatch) {
250  g_ptr_array_add(self->pending_redispatches, g_object_ref(pending));
251  FlKeyEvent* event = fl_keyboard_pending_event_get_event(pending);
252  if (self->redispatch_handler != nullptr) {
253  self->redispatch_handler(event, self->redispatch_handler_user_data);
254  } else {
255  GdkEventType event_type =
256  gdk_event_get_event_type(fl_key_event_get_origin(event));
257  g_return_if_fail(event_type == GDK_KEY_PRESS ||
258  event_type == GDK_KEY_RELEASE);
259  gdk_event_put(fl_key_event_get_origin(event));
260  }
261  }
262  }
263 }

References fl_key_event_get_origin(), fl_keyboard_pending_event_get_any_handled(), fl_keyboard_pending_event_get_event(), fl_keyboard_pending_event_is_complete(), and fl_keyboard_view_delegate_text_filter_key_press().

Referenced by responder_handle_channel_event_cb(), and responder_handle_embedder_event_callback().

fl_keyboard_pending_event_get_hash
uint64_t fl_keyboard_pending_event_get_hash(FlKeyboardPendingEvent *self)
Definition: fl_keyboard_pending_event.cc:73
if
if(end==-1)
Definition: fl_accessible_text_field.cc:42
responder_handle_embedder_event_callback
static void responder_handle_embedder_event_callback(bool handled, gpointer user_data)
Definition: fl_keyboard_manager.cc:265
fl_keyboard_pending_event_get_event
FlKeyEvent * fl_keyboard_pending_event_get_event(FlKeyboardPendingEvent *self)
Definition: fl_keyboard_pending_event.cc:68
fl_key_embedder_responder_handle_event
void fl_key_embedder_responder_handle_event(FlKeyEmbedderResponder *self, FlKeyEvent *event, uint64_t specified_logical_key, FlKeyEmbedderResponderAsyncCallback callback, gpointer user_data)
Definition: fl_key_embedder_responder.cc:835
layout_goals
const std::vector< LayoutGoal > layout_goals
Definition: key_mapping.g.cc:462
guarantee_layout
static void guarantee_layout(FlKeyboardManager *self, FlKeyEvent *event)
Definition: fl_keyboard_manager.cc:323
convert_key_to_char
static uint16_t convert_key_to_char(FlKeyboardManager *self, guint keycode, gint group, gint level)
Definition: fl_keyboard_manager.cc:306
responder_handle_channel_event_cb
static void responder_handle_channel_event_cb(GObject *object, GAsyncResult *result, gpointer user_data)
Definition: fl_keyboard_manager.cc:280
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:867
LayoutGoal
Definition: key_mapping.h:40
responder_handle_event_callback
static void responder_handle_event_callback(FlKeyboardManager *self, FlKeyboardPendingEvent *pending)
Definition: fl_keyboard_manager.cc:234
fl_key_channel_responder_new
FlKeyChannelResponder * fl_key_channel_responder_new(FlBinaryMessenger *messenger)
Definition: fl_key_channel_responder.cc:59
fl_keyboard_pending_event_mark_channel_replied
void fl_keyboard_pending_event_mark_channel_replied(FlKeyboardPendingEvent *self, gboolean handled)
Definition: fl_keyboard_pending_event.cc:86
i
int i
Definition: fl_socket_accessible.cc:18
LayoutGoal::keycode
uint16_t keycode
Definition: key_mapping.h:42
fl_keyboard_manager_dispose
static void fl_keyboard_manager_dispose(GObject *object)
Definition: fl_keyboard_manager.cc:409
keymap_keys_changed_cb
static void keymap_keys_changed_cb(FlKeyboardManager *self)
Definition: fl_keyboard_manager.cc:177
LayoutGoal::logical_key
uint64_t logical_key
Definition: key_mapping.h:45
fl_keyboard_manager_remove_redispatched
static bool fl_keyboard_manager_remove_redispatched(FlKeyboardManager *self, uint64_t hash)
Definition: fl_keyboard_manager.cc:218
fl_engine_get_binary_messenger
G_MODULE_EXPORT FlBinaryMessenger * fl_engine_get_binary_messenger(FlEngine *self)
Definition: fl_engine.cc:1203
fl_engine_send_key_event
void fl_engine_send_key_event(FlEngine *self, const FlutterKeyEvent *event, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data)
Definition: fl_engine.cc:1121
fl_keyboard_layout_get_logical_key
uint64_t fl_keyboard_layout_get_logical_key(FlKeyboardLayout *self, uint8_t group, uint16_t keycode)
Definition: fl_keyboard_layout.cc:65
state
AtkStateType state
Definition: fl_accessible_node.cc:10
fl_key_event_get_origin
GdkEvent * fl_key_event_get_origin(FlKeyEvent *self)
Definition: fl_key_event.cc:109
fl_keyboard_layout_set_logical_key
void fl_keyboard_layout_set_logical_key(FlKeyboardLayout *self, uint8_t group, uint16_t keycode, uint64_t logical_key)
Definition: fl_keyboard_layout.cc:49
compare_pending_by_hash
static gboolean compare_pending_by_hash(gconstpointer a, gconstpointer b)
Definition: fl_keyboard_manager.cc:207
fl_keyboard_pending_event_is_complete
gboolean fl_keyboard_pending_event_is_complete(FlKeyboardPendingEvent *self)
Definition: fl_keyboard_pending_event.cc:100
user_data
G_BEGIN_DECLS G_MODULE_EXPORT FlValue gpointer user_data
Definition: fl_event_channel.h:90
fl_keyboard_pending_event_mark_embedder_replied
void fl_keyboard_pending_event_mark_embedder_replied(FlKeyboardPendingEvent *self, gboolean handled)
Definition: fl_keyboard_pending_event.cc:78
fl_keyboard_pending_event_get_any_handled
gboolean fl_keyboard_pending_event_get_any_handled(FlKeyboardPendingEvent *self)
Definition: fl_keyboard_pending_event.cc:94
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:237
fl_keyboard_manager_data_dispose
static void fl_keyboard_manager_data_dispose(GObject *object)
Definition: fl_keyboard_manager.cc:85
fl_keyboard_layout_new
FlKeyboardLayout * fl_keyboard_layout_new()
Definition: fl_keyboard_layout.cc:40
TRUE
return TRUE
Definition: fl_pixel_buffer_texture_test.cc:53
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_manager.cc:185
fl_key_channel_responder_handle_event
void fl_key_channel_responder_handle_event(FlKeyChannelResponder *self, FlKeyEvent *event, uint64_t specified_logical_key, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data)
Definition: fl_key_channel_responder.cc:71
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:14
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:850
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
fl_keyboard_pending_event_new
FlKeyboardPendingEvent * fl_keyboard_pending_event_new(FlKeyEvent *event)
Definition: fl_keyboard_pending_event.cc:58
fl_key_channel_responder_handle_event_finish
gboolean fl_key_channel_responder_handle_event_finish(FlKeyChannelResponder *self, GAsyncResult *result, gboolean *handled, GError **error)
Definition: fl_key_channel_responder.cc:139
error
const uint8_t uint32_t uint32_t GError ** error
Definition: fl_pixel_buffer_texture_test.cc:40
fl_keyboard_layout_has_group
gboolean fl_keyboard_layout_has_group(FlKeyboardLayout *self, uint8_t group)
Definition: fl_keyboard_layout.cc:45
fl_keyboard_manager_data_new
static FlKeyboardManagerData * fl_keyboard_manager_data_new(FlKeyboardManager *manager, FlKeyboardPendingEvent *pending)
Definition: fl_keyboard_manager.cc:102