| Flutter Linux Embedder |

Classes | Macros | Functions | Variables
fl_keyboard_handler.cc File Reference
`#include "flutter/shell/platform/linux/fl_keyboard_handler.h"`
`#include <array>`
`#include <cinttypes>`
`#include <memory>`
`#include <string>`
`#include "flutter/shell/platform/linux/fl_key_channel_responder.h"`
`#include "flutter/shell/platform/linux/fl_key_embedder_responder.h"`
`#include "flutter/shell/platform/linux/fl_keyboard_pending_event.h"`
`#include "flutter/shell/platform/linux/key_mapping.h"`
`#include "flutter/shell/platform/linux/public/flutter_linux/fl_method_channel.h"`
`#include "flutter/shell/platform/linux/public/flutter_linux/fl_standard_method_codec.h"`

Go to the source code of this file.

## Classes
struct | _FlKeyboardHandlerUserData
struct | _FlKeyboardHandler

## Macros
#define | DEBUG_PRINT_LAYOUT
#define | FL_TYPE_KEYBOARD_HANDLER_USER_DATA fl_keyboard_handler_user_data_get_type()

## Functions
| G_DECLARE_FINAL_TYPE (FlKeyboardHandlerUserData, fl_keyboard_handler_user_data, FL, KEYBOARD_HANDLER_USER_DATA, GObject)
static uint64_t | get_logical_key_from_layout (FlKeyEvent *event, const DerivedLayout &layout)
| G_DEFINE_TYPE (FlKeyboardHandlerUserData, fl_keyboard_handler_user_data, G_TYPE_OBJECT) static void fl_keyboard_handler_user_data_dispose(GObject *object)
static void | fl_keyboard_handler_user_data_class_init (FlKeyboardHandlerUserDataClass *klass)
static void | fl_keyboard_handler_user_data_init (FlKeyboardHandlerUserData *self)
static FlKeyboardHandlerUserData * | fl_keyboard_handler_user_data_new (FlKeyboardHandler *handler, uint64_t sequence_id)
| G_DEFINE_TYPE (FlKeyboardHandler, fl_keyboard_handler, G_TYPE_OBJECT)
static gboolean | g_ptr_array_find_with_equal_func1 (GPtrArray *haystack, gconstpointer needle, GEqualFunc equal_func, guint *index_)
static gboolean | compare_pending_by_sequence_id (gconstpointer a, gconstpointer b)
static gboolean | compare_pending_by_hash (gconstpointer a, gconstpointer b)
static bool | fl_keyboard_handler_remove_redispatched (FlKeyboardHandler *self, uint64_t hash)
static void | responder_handle_event_callback (bool handled, gpointer user_data_ptr)
static uint16_t | convert_key_to_char (FlKeyboardViewDelegate *view_delegate, guint keycode, gint group, gint level)
static void | guarantee_layout (FlKeyboardHandler *self, FlKeyEvent *event)
static FlMethodResponse * | get_keyboard_state (FlKeyboardHandler *self)
static void | method_call_handler (FlMethodChannel *channel, FlMethodCall *method_call, gpointer user_data)
static void | dispatch_to_responder (gpointer responder_data, gpointer foreach_data_ptr)
static void | fl_keyboard_handler_dispose (GObject *object)
static void | fl_keyboard_handler_class_init (FlKeyboardHandlerClass *klass)
static void | fl_keyboard_handler_init (FlKeyboardHandler *self)
FlKeyboardHandler * | fl_keyboard_handler_new (FlBinaryMessenger *messenger, FlKeyboardViewDelegate *view_delegate)
gboolean | fl_keyboard_handler_handle_event (FlKeyboardHandler *self, FlKeyEvent *event)
gboolean | fl_keyboard_handler_is_state_clear (FlKeyboardHandler *self)
void | fl_keyboard_handler_sync_modifier_if_needed (FlKeyboardHandler *self, guint state, double event_time)
GHashTable * | fl_keyboard_handler_get_pressed_state (FlKeyboardHandler *self)

## Variables
static constexpr char | kChannelName [] = "flutter/keyboard"
static constexpr char | kGetKeyboardStateMethod [] = "getKeyboardState"

## Macro Definition Documentation

## ◆ DEBUG_PRINT_LAYOUT

#define DEBUG_PRINT_LAYOUT

Definition at line 21 of file fl_keyboard_handler.cc.

## ◆ FL_TYPE_KEYBOARD_HANDLER_USER_DATA

#define FL_TYPE_KEYBOARD_HANDLER_USER_DATA fl_keyboard_handler_user_data_get_type()

Definition at line 28 of file fl_keyboard_handler.cc.

## Function Documentation

## ◆ compare_pending_by_hash()

static gboolean compare_pending_by_hash | ( | gconstpointer | a,
|  | gconstpointer | b
| ) |  |
| static

Definition at line 244 of file fl_keyboard_handler.cc.

244 {
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 }

References fl_keyboard_pending_event_get_hash().

Referenced by fl_keyboard_handler_remove_redispatched().

## ◆ compare_pending_by_sequence_id()

static gboolean compare_pending_by_sequence_id | ( | gconstpointer | a,
|  | gconstpointer | b
| ) |  |
| static

Definition at line 235 of file fl_keyboard_handler.cc.

236 {
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 }

References fl_keyboard_pending_event_get_sequence_id().

Referenced by responder_handle_event_callback().

## ◆ convert_key_to_char()

static uint16_t convert_key_to_char | ( | FlKeyboardViewDelegate * | view_delegate,
|  | guint | keycode,
|  | gint | group,
|  | gint | level
| ) |  |
| static

Definition at line 309 of file fl_keyboard_handler.cc.

312 {
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 }

References fl_keyboard_view_delegate_lookup_key().

Referenced by guarantee_layout().

## ◆ dispatch_to_responder()

static void dispatch_to_responder | ( | gpointer | responder_data,
|  | gpointer | foreach_data_ptr
| ) |  |
| static

Definition at line 439 of file fl_keyboard_handler.cc.

440 {
441 DispatchToResponderLoopContext* context =
442 reinterpret_cast<DispatchToResponderLoopContext*>(foreach_data_ptr);
443 FlKeyResponder* responder = FL_KEY_RESPONDER(responder_data);
444 fl_key_responder_handle_event(
445 responder, context->event, responder_handle_event_callback,
446 context->user_data, context->specified_logical_key);
447 }

References fl_key_responder_handle_event(), and responder_handle_event_callback().

Referenced by fl_keyboard_handler_handle_event().

## ◆ fl_keyboard_handler_class_init()

static void fl_keyboard_handler_class_init | ( | FlKeyboardHandlerClass * | klass | ) |
| static

Definition at line 473 of file fl_keyboard_handler.cc.

473 {
474 G_OBJECT_CLASS(klass)->dispose = fl_keyboard_handler_dispose;
475 }

References fl_keyboard_handler_dispose().

## ◆ fl_keyboard_handler_dispose()

static void fl_keyboard_handler_dispose | ( | GObject * | object | ) |
| static

Definition at line 449 of file fl_keyboard_handler.cc.

449 {
450 FlKeyboardHandler* self = FL_KEYBOARD_HANDLER(object);
451
452 if (self->view_delegate != nullptr) {
453 fl_keyboard_view_delegate_subscribe_to_layout_change(self->view_delegate,
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 }

References fl_keyboard_view_delegate_subscribe_to_layout_change(), and TRUE.

Referenced by fl_keyboard_handler_class_init().

## ◆ fl_keyboard_handler_get_pressed_state()

GHashTable* fl_keyboard_handler_get_pressed_state | ( | FlKeyboardHandler * | handler | ) |

fl_keyboard_handler_get_pressed_state: @handler: the #FlKeyboardHandler 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 590 of file fl_keyboard_handler.cc.

590 {
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));
597 return fl_key_embedder_responder_get_pressed_state(responder);
598 }

References fl_key_embedder_responder_get_pressed_state().

Referenced by fl_view_get_keyboard_state().

## ◆ fl_keyboard_handler_handle_event()

gboolean fl_keyboard_handler_handle_event | ( | FlKeyboardHandler * | handler,
|  | FlKeyEvent * | event
| ) |  |

fl_keyboard_handler_handle_event: @handler: the #FlKeyboardHandler self. @event: the event to be dispatched. It is usually a wrap of a GdkEventKey. This event will be managed and released by #FlKeyboardHandler.

Make the handler 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 541 of file fl_keyboard_handler.cc.

542 {
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(
559 self, fl_keyboard_pending_event_get_sequence_id(pending));
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 }

References dispatch_to_responder(), event, fl_key_event_hash(), fl_keyboard_handler_remove_redispatched(), fl_keyboard_handler_user_data_new(), fl_keyboard_pending_event_get_sequence_id(), fl_keyboard_pending_event_new(), get_logical_key_from_layout(), guarantee_layout(), TRUE, and user_data.

Referenced by fl_view_key_press_event(), and fl_view_key_release_event().

## ◆ fl_keyboard_handler_init()

static void fl_keyboard_handler_init | ( | FlKeyboardHandler * | self | ) |
| static

Definition at line 477 of file fl_keyboard_handler.cc.

477 {
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 }

References if(), and layout_goals.

## ◆ fl_keyboard_handler_is_state_clear()

gboolean fl_keyboard_handler_is_state_clear | ( | FlKeyboardHandler * | handler | ) |

fl_keyboard_handler_is_state_clear: @handler: the #FlKeyboardHandler self.

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

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

Definition at line 571 of file fl_keyboard_handler.cc.

571 {
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 }

## ◆ fl_keyboard_handler_new()

FlKeyboardHandler* fl_keyboard_handler_new | ( | FlBinaryMessenger * | messenger,
|  | FlKeyboardViewDelegate * | view_delegate
| ) |  |

FlKeyboardHandler:

Processes keyboard events and cooperate with `TextInputHandler`.

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 `TextInputHandler`) and are handled synchronously.
- Redispatching: Events are inserted back to the system for redispatching. fl_keyboard_handler_new: @view_delegate: An interface that the handler requires to communicate with the platform. Usually implemented by FlView.

Create a new #FlKeyboardHandler.

Returns: a new #FlKeyboardHandler.

Definition at line 499 of file fl_keyboard_handler.cc.

501 {
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);
521 fl_keyboard_view_delegate_send_key_event(
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
529 fl_keyboard_view_delegate_subscribe_to_layout_change(
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));
536 fl_method_channel_set_method_call_handler(self->channel, method_call_handler,
537 self, nullptr);
538 return self;
539 }

References callback, event, fl_key_channel_responder_new(), fl_key_embedder_responder_new(), fl_keyboard_view_delegate_get_messenger(), fl_keyboard_view_delegate_send_key_event(), fl_keyboard_view_delegate_subscribe_to_layout_change(), fl_method_channel_new(), fl_method_channel_set_method_call_handler(), fl_standard_method_codec_new(), kChannelName, and method_call_handler().

Referenced by init_keyboard().

## ◆ fl_keyboard_handler_remove_redispatched()

static bool fl_keyboard_handler_remove_redispatched | ( | FlKeyboardHandler * | self,
|  | uint64_t | hash
| ) |  |
| static

Definition at line 255 of file fl_keyboard_handler.cc.

256 {
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 }

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

Referenced by fl_keyboard_handler_handle_event().

## ◆ fl_keyboard_handler_sync_modifier_if_needed()

void fl_keyboard_handler_sync_modifier_if_needed | ( | FlKeyboardHandler * | handler,
|  | guint | state,
|  | double | event_time
| ) |  |

fl_keyboard_handler_sync_modifier_if_needed: @handler: the #FlKeyboardHandler 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 577 of file fl_keyboard_handler.cc.

579 {
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));
586 fl_key_embedder_responder_sync_modifiers_if_needed(responder, state,
587 event_time);
588 }

References fl_key_embedder_responder_sync_modifiers_if_needed(), and state.

Referenced by motion_notify_event_cb(), and send_pointer_button_event().

## ◆ fl_keyboard_handler_user_data_class_init()

static void fl_keyboard_handler_user_data_class_init | ( | FlKeyboardHandlerUserDataClass * | klass | ) |
| static

Definition at line 137 of file fl_keyboard_handler.cc.

138 {
139 G_OBJECT_CLASS(klass)->dispose = fl_keyboard_handler_user_data_dispose;
140 }

## ◆ fl_keyboard_handler_user_data_init()

static void fl_keyboard_handler_user_data_init | ( | FlKeyboardHandlerUserData * | self | ) |
| static

Definition at line 142 of file fl_keyboard_handler.cc.

143 {}

## ◆ fl_keyboard_handler_user_data_new()

static FlKeyboardHandlerUserData* fl_keyboard_handler_user_data_new | ( | FlKeyboardHandler * | handler,
|  | uint64_t | sequence_id
| ) |  |
| static

Definition at line 146 of file fl_keyboard_handler.cc.

148 {
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 }

Referenced by fl_keyboard_handler_handle_event().

## ◆ G_DECLARE_FINAL_TYPE()

G_DECLARE_FINAL_TYPE | ( | FlKeyboardHandlerUserData | ,
|  | fl_keyboard_handler_user_data | ,
|  | FL | ,
|  | KEYBOARD_HANDLER_USER_DATA | ,
|  | GObject |
| ) |  |

## ◆ G_DEFINE_TYPE() [1/2]

G_DEFINE_TYPE | ( | FlKeyboardHandler | ,
|  | fl_keyboard_handler | ,
|  | G_TYPE_OBJECT |
| ) |  |

## ◆ G_DEFINE_TYPE() [2/2]

G_DEFINE_TYPE | ( | FlKeyboardHandlerUserData | ,
|  | fl_keyboard_handler_user_data | ,
|  | G_TYPE_OBJECT |
| ) |  |

Definition at line 123 of file fl_keyboard_handler.cc.

127 {
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 }

## ◆ 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 213 of file fl_keyboard_handler.cc.

216 {
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 }

References i, and TRUE.

Referenced by fl_keyboard_handler_remove_redispatched(), and responder_handle_event_callback().

## ◆ get_keyboard_state()

static FlMethodResponse* get_keyboard_state | ( | FlKeyboardHandler * | self | ) |
| static

Definition at line 397 of file fl_keyboard_handler.cc.

397 {
398 g_autoptr(FlValue) result = fl_value_new_map();
399
400 GHashTable* pressing_records =
401 fl_keyboard_view_delegate_get_keyboard_state(self->view_delegate);
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 }

References fl_keyboard_view_delegate_get_keyboard_state(), fl_method_success_response_new(), fl_value_new_int(), fl_value_new_map(), fl_value_set_take(), result, user_data, and value.

Referenced by method_call_handler().

## ◆ get_logical_key_from_layout()

static uint64_t get_logical_key_from_layout | ( | FlKeyEvent * | event,
|  | const DerivedLayout & | layout
| ) |  |
| static

Definition at line 92 of file fl_keyboard_handler.cc.

93 {
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 }

References event, fl_key_event_get_group(), and fl_key_event_get_keycode().

Referenced by fl_keyboard_handler_handle_event().

## ◆ guarantee_layout()

static void guarantee_layout | ( | FlKeyboardHandler * | self,
|  | FlKeyEvent * | event
| ) |  |
| static

Definition at line 321 of file fl_keyboard_handler.cc.

321 {
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 }

References convert_key_to_char(), event, fl_key_event_get_group(), fl_key_event_get_keycode(), LayoutGoal::keycode, layout_goals, and LayoutGoal::logical_key.

Referenced by fl_keyboard_handler_handle_event().

## ◆ method_call_handler()

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

Definition at line 418 of file fl_keyboard_handler.cc.

420 {
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 }

References error, fl_method_call_get_name(), fl_method_call_respond(), fl_method_not_implemented_response_new(), get_keyboard_state(), kGetKeyboardStateMethod, method_call, and user_data.

Referenced by fl_keyboard_handler_new().

## ◆ responder_handle_event_callback()

static void responder_handle_event_callback | ( | bool | handled,
|  | gpointer | user_data_ptr
| ) |  |
| static

Definition at line 271 of file fl_keyboard_handler.cc.

272 {
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.
289 if (fl_keyboard_pending_event_is_complete(pending)) {
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 =
295 !fl_keyboard_pending_event_get_any_handled(pending) &&
296 !fl_keyboard_view_delegate_text_filter_key_press(
297 self->view_delegate, fl_keyboard_pending_event_get_event(pending));
298 if (should_redispatch) {
299 g_ptr_array_add(self->pending_redispatches, pending);
300 fl_keyboard_view_delegate_redispatch_event(
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 }

References compare_pending_by_sequence_id(), fl_keyboard_pending_event_get_any_handled(), fl_keyboard_pending_event_get_event(), fl_keyboard_pending_event_is_complete(), fl_keyboard_pending_event_mark_replied(), fl_keyboard_view_delegate_redispatch_event(), fl_keyboard_view_delegate_text_filter_key_press(), g_ptr_array_find_with_equal_func1(), and user_data.

Referenced by dispatch_to_responder().

## Variable Documentation

## ◆ kChannelName

constexpr char kChannelName[] = "flutter/keyboard"
| static constexpr

Definition at line 23 of file fl_keyboard_handler.cc.

Referenced by fl_keyboard_handler_new().

## ◆ kGetKeyboardStateMethod

constexpr char kGetKeyboardStateMethod[] = "getKeyboardState"
| static constexpr

Definition at line 24 of file fl_keyboard_handler.cc.

Referenced by method_call_handler().

fl_keyboard_pending_event_get_hash
uint64_t fl_keyboard_pending_event_get_hash(FlKeyboardPendingEvent *self)
Definition: fl_keyboard_pending_event.cc:81
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
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_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
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
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_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
fl_method_call_get_name
const G_MODULE_EXPORT gchar * fl_method_call_get_name(FlMethodCall *self)
Definition: fl_method_call.cc:67
TRUE
return TRUE
Definition: fl_pixel_buffer_texture_test.cc:53
responder_handle_event_callback
static void responder_handle_event_callback(bool handled, gpointer user_data_ptr)
Definition: fl_keyboard_handler.cc:271
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
method_call_handler
static void method_call_handler(FlMethodChannel *channel, FlMethodCall *method_call, gpointer user_data)
Definition: fl_keyboard_handler.cc:418
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_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_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
callback
FlKeyEvent uint64_t FlKeyResponderAsyncCallback callback
Definition: fl_key_channel_responder.cc:120
dispatch_to_responder
static void dispatch_to_responder(gpointer responder_data, gpointer foreach_data_ptr)
Definition: fl_keyboard_handler.cc:439
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_dispose
static void fl_keyboard_handler_dispose(GObject *object)
Definition: fl_keyboard_handler.cc:449