20 #define DEBUG_PRINT_LAYOUT
28 fl_keyboard_pending_event,
30 KEYBOARD_PENDING_EVENT,
33 #define FL_TYPE_KEYBOARD_MANAGER_USER_DATA \
34 fl_keyboard_manager_user_data_get_type()
36 fl_keyboard_manager_user_data,
38 KEYBOARD_MANAGER_USER_DATA,
49 constexpr
size_t kLayoutSize = 128;
53 typedef std::array<uint64_t, kLayoutSize> DerivedGroupLayout;
57 typedef std::map<guint8, DerivedGroupLayout> DerivedLayout;
64 } DispatchToResponderLoopContext;
66 bool is_eascii(uint16_t character) {
67 return character < 256;
70 #ifdef DEBUG_PRINT_LAYOUT
72 void debug_format_layout_data(std::string& debug_layout_data,
76 if (keycode % 4 == 0) {
77 debug_layout_data.append(
" ");
80 constexpr
int kBufferSize = 30;
83 buffer[kBufferSize - 1] = 0;
85 snprintf(
buffer, kBufferSize,
"0x%04x, 0x%04x, ", clue1, clue2);
86 debug_layout_data.append(
buffer);
88 if (keycode % 4 == 3) {
89 snprintf(
buffer, kBufferSize,
" // 0x%02x", keycode);
90 debug_layout_data.append(
buffer);
98 const DerivedLayout& layout) {
99 guint8 group =
event->group;
100 guint16 keycode =
event->keycode;
101 if (keycode >= kLayoutSize) {
105 auto found_group_layout = layout.find(group);
106 if (found_group_layout != layout.end()) {
107 return found_group_layout->second[keycode];
145 G_DEFINE_TYPE(FlKeyboardPendingEvent, fl_keyboard_pending_event, G_TYPE_OBJECT)
150 g_return_if_fail(FL_IS_KEYBOARD_PENDING_EVENT(
object));
152 FlKeyboardPendingEvent*
self = FL_KEYBOARD_PENDING_EVENT(
object);
153 if (self->event !=
nullptr) {
156 G_OBJECT_CLASS(fl_keyboard_pending_event_parent_class)->dispose(
object);
160 FlKeyboardPendingEventClass* klass) {
174 static_cast<uint64_t
>(
event->is_press ? GDK_KEY_PRESS : GDK_KEY_RELEASE);
175 guint64 keycode =
static_cast<uint64_t
>(
event->keycode);
176 return (
event->
time & 0xffffffff) | ((
type & 0xffff) << 32) |
177 ((keycode & 0xffff) << 48);
185 std::unique_ptr<FlKeyEvent>
event,
186 uint64_t sequence_id,
188 FlKeyboardPendingEvent*
self = FL_KEYBOARD_PENDING_EVENT(
189 g_object_new(fl_keyboard_pending_event_get_type(),
nullptr));
191 self->event = std::move(
event);
192 self->sequence_id = sequence_id;
193 self->unreplied = to_reply;
194 self->any_handled =
false;
216 fl_keyboard_manager_user_data,
219 static void fl_keyboard_manager_user_data_dispose(GObject*
object) {
220 g_return_if_fail(FL_IS_KEYBOARD_MANAGER_USER_DATA(
object));
221 FlKeyboardManagerUserData*
self = FL_KEYBOARD_MANAGER_USER_DATA(
object);
222 if (self->manager !=
nullptr) {
223 g_object_remove_weak_pointer(G_OBJECT(self->manager),
224 reinterpret_cast<gpointer*
>(&(self->manager)));
225 self->manager =
nullptr;
230 FlKeyboardManagerUserDataClass* klass) {
231 G_OBJECT_CLASS(klass)->dispose = fl_keyboard_manager_user_data_dispose;
235 FlKeyboardManagerUserData*
self) {}
240 uint64_t sequence_id) {
241 FlKeyboardManagerUserData*
self = FL_KEYBOARD_MANAGER_USER_DATA(
242 g_object_new(fl_keyboard_manager_user_data_get_type(),
nullptr));
244 self->manager = manager;
247 g_object_add_weak_pointer(G_OBJECT(manager),
248 reinterpret_cast<gpointer*
>(&(self->manager)));
249 self->sequence_id = sequence_id;
293 std::unique_ptr<std::map<uint64_t, const LayoutGoal*>>
309 self->derived_layout = std::make_unique<DerivedLayout>();
311 self->keycode_to_goals =
312 std::make_unique<std::map<uint16_t, const LayoutGoal*>>();
313 self->logical_to_mandatory_goals =
314 std::make_unique<std::map<uint64_t, const LayoutGoal*>>();
316 (*
self->keycode_to_goals)[goal.keycode] = &goal;
317 if (goal.mandatory) {
318 (*
self->logical_to_mandatory_goals)[goal.logical_key] = &goal;
322 self->responder_list = g_ptr_array_new_with_free_func(g_object_unref);
324 self->pending_responds = g_ptr_array_new();
325 self->pending_redispatches = g_ptr_array_new_with_free_func(g_object_unref);
327 self->last_sequence_id = 1;
333 if (self->view_delegate !=
nullptr) {
336 g_object_remove_weak_pointer(
337 G_OBJECT(self->view_delegate),
338 reinterpret_cast<gpointer*
>(&(self->view_delegate)));
339 self->view_delegate =
nullptr;
342 self->derived_layout.reset();
343 self->keycode_to_goals.reset();
344 self->logical_to_mandatory_goals.reset();
346 g_ptr_array_free(self->responder_list,
TRUE);
347 g_ptr_array_set_free_func(self->pending_responds, g_object_unref);
348 g_ptr_array_free(self->pending_responds,
TRUE);
349 g_ptr_array_free(self->pending_redispatches,
TRUE);
351 G_OBJECT_CLASS(fl_keyboard_manager_parent_class)->dispose(
object);
360 gconstpointer needle,
361 GEqualFunc equal_func,
364 g_return_val_if_fail(haystack != NULL, FALSE);
365 if (equal_func == NULL) {
366 equal_func = g_direct_equal;
368 for (
i = 0;
i < haystack->len;
i++) {
369 if (equal_func(g_ptr_array_index(haystack,
i), needle)) {
370 if (index_ != NULL) {
383 gconstpointer pending,
384 gconstpointer needle_sequence_id) {
385 uint64_t sequence_id = *
reinterpret_cast<const uint64_t*
>(needle_sequence_id);
386 return static_cast<const FlKeyboardPendingEvent*
>(pending)->sequence_id ==
393 gconstpointer needle_hash) {
394 uint64_t hash = *
reinterpret_cast<const uint64_t*
>(needle_hash);
395 return static_cast<const FlKeyboardPendingEvent*
>(pending)->hash == hash;
406 self->pending_redispatches,
static_cast<const uint64_t*
>(&hash),
410 g_ptr_array_remove_index_fast(self->pending_redispatches, result_index);
419 gpointer user_data_ptr) {
420 g_return_if_fail(FL_IS_KEYBOARD_MANAGER_USER_DATA(user_data_ptr));
422 FL_KEYBOARD_MANAGER_USER_DATA(user_data_ptr);
424 g_return_if_fail(self->view_delegate !=
nullptr);
426 guint result_index = -1;
428 self->pending_responds, &
user_data->sequence_id,
430 g_return_if_fail(found);
431 FlKeyboardPendingEvent* pending = FL_KEYBOARD_PENDING_EVENT(
432 g_ptr_array_index(self->pending_responds, result_index));
433 g_return_if_fail(pending !=
nullptr);
434 g_return_if_fail(pending->unreplied > 0);
435 pending->unreplied -= 1;
436 pending->any_handled = pending->any_handled || handled;
438 if (pending->unreplied == 0) {
439 g_object_unref(user_data_ptr);
441 g_ptr_array_remove_index_fast(self->pending_responds, result_index);
442 g_return_if_fail(removed == pending);
443 bool should_redispatch = !pending->any_handled &&
445 self->view_delegate, pending->event.get());
446 if (should_redispatch) {
447 g_ptr_array_add(self->pending_redispatches, pending);
449 std::move(pending->event));
451 g_object_unref(pending);
460 GdkKeymapKey key = {keycode, group, level};
461 constexpr
int kBmpMax = 0xD7FF;
463 return origin < kBmpMax ? origin : 0xFFFF;
469 guint8 group =
event->group;
470 if (self->derived_layout->find(group) != self->derived_layout->end()) {
474 self->keycode_to_goals->end()) {
478 DerivedGroupLayout& layout = (*
self->derived_layout)[group];
482 std::map<uint64_t, const LayoutGoal*> remaining_mandatory_goals =
483 *
self->logical_to_mandatory_goals;
485 #ifdef DEBUG_PRINT_LAYOUT
486 std::string debug_layout_data;
487 for (uint16_t keycode = 0; keycode < 128; keycode += 1) {
488 std::vector<uint16_t> this_key_clues = {
492 debug_format_layout_data(debug_layout_data, keycode, this_key_clues[0],
502 uint16_t keycode = keycode_goal.keycode;
503 std::vector<uint16_t> this_key_clues = {
515 for (uint16_t clue : this_key_clues) {
516 auto matching_goal = remaining_mandatory_goals.find(clue);
517 if (matching_goal != remaining_mandatory_goals.end()) {
519 g_return_if_fail(layout[keycode] == 0);
520 layout[keycode] = clue;
521 remaining_mandatory_goals.erase(matching_goal);
525 bool has_any_eascii =
526 is_eascii(this_key_clues[0]) || is_eascii(this_key_clues[1]);
528 if (layout[keycode] == 0 && !has_any_eascii) {
529 auto found_us_layout =
self->keycode_to_goals->find(keycode);
530 if (found_us_layout != self->keycode_to_goals->end()) {
531 layout[keycode] = found_us_layout->second->logical_key;
537 for (
const auto mandatory_goal_iter : remaining_mandatory_goals) {
538 const LayoutGoal* goal = mandatory_goal_iter.second;
547 GHashTable* pressing_records =
550 g_hash_table_foreach(
553 int64_t physical_key =
reinterpret_cast<int64_t
>(key);
554 int64_t logical_key =
reinterpret_cast<int64_t
>(
value);
572 g_autoptr(FlMethodResponse) response =
nullptr;
579 g_autoptr(GError)
error =
nullptr;
581 g_warning(
"Failed to send method call response: %s",
error->message);
586 FlBinaryMessenger* messenger,
587 FlKeyboardViewDelegate* view_delegate) {
588 g_return_val_if_fail(FL_IS_KEYBOARD_VIEW_DELEGATE(view_delegate),
nullptr);
591 g_object_new(fl_keyboard_manager_get_type(),
nullptr));
593 self->view_delegate = view_delegate;
594 g_object_add_weak_pointer(
595 G_OBJECT(view_delegate),
596 reinterpret_cast<gpointer*
>(&(self->view_delegate)));
600 self->responder_list,
602 [](
const FlutterKeyEvent*
event, FlutterKeyEventCallback
callback,
603 void* callback_user_data,
void* send_key_event_user_data) {
605 FL_KEYBOARD_MANAGER(send_key_event_user_data);
606 g_return_if_fail(self->view_delegate !=
nullptr);
611 g_ptr_array_add(self->responder_list,
616 self->view_delegate, [
self]() { self->derived_layout->clear(); });
629 gpointer foreach_data_ptr) {
630 DispatchToResponderLoopContext* context =
631 reinterpret_cast<DispatchToResponderLoopContext*
>(foreach_data_ptr);
632 FlKeyResponder* responder = FL_KEY_RESPONDER(responder_data);
635 context->user_data, context->specified_logical_key);
640 g_return_val_if_fail(FL_IS_KEYBOARD_MANAGER(
self), FALSE);
641 g_return_val_if_fail(
event !=
nullptr, FALSE);
642 g_return_val_if_fail(self->view_delegate !=
nullptr, FALSE);
652 std::unique_ptr<FlKeyEvent>(
event), ++self->last_sequence_id,
653 self->responder_list->len);
655 g_ptr_array_add(self->pending_responds, pending);
658 DispatchToResponderLoopContext data{
660 .specified_logical_key =
670 g_return_val_if_fail(FL_IS_KEYBOARD_MANAGER(
self), FALSE);
671 return self->pending_responds->len == 0 &&
672 self->pending_redispatches->len == 0;
678 g_return_if_fail(FL_IS_KEYBOARD_MANAGER(
self));
682 FlKeyEmbedderResponder* responder =
683 FL_KEY_EMBEDDER_RESPONDER(g_ptr_array_index(self->responder_list, 0));
689 g_return_val_if_fail(FL_IS_KEYBOARD_MANAGER(
self),
nullptr);
693 FlKeyEmbedderResponder* responder =
694 FL_KEY_EMBEDDER_RESPONDER(g_ptr_array_index(self->responder_list, 0));