21 #define DEBUG_PRINT_LAYOUT
28 #define FL_TYPE_KEYBOARD_HANDLER_USER_DATA \
29 fl_keyboard_handler_user_data_get_type()
31 fl_keyboard_handler_user_data,
33 KEYBOARD_HANDLER_USER_DATA,
44 constexpr
size_t kLayoutSize = 128;
48 typedef std::array<uint64_t, kLayoutSize> DerivedGroupLayout;
52 typedef std::map<guint8, DerivedGroupLayout> DerivedLayout;
59 } DispatchToResponderLoopContext;
61 bool is_eascii(uint16_t character) {
62 return character < 256;
65 #ifdef DEBUG_PRINT_LAYOUT
67 void debug_format_layout_data(std::string& debug_layout_data,
71 if (keycode % 4 == 0) {
72 debug_layout_data.append(
" ");
75 constexpr
int kBufferSize = 30;
78 buffer[kBufferSize - 1] = 0;
80 snprintf(
buffer, kBufferSize,
"0x%04x, 0x%04x, ", clue1, clue2);
81 debug_layout_data.append(
buffer);
83 if (keycode % 4 == 3) {
84 snprintf(
buffer, kBufferSize,
" // 0x%02x", keycode);
85 debug_layout_data.append(
buffer);
93 const DerivedLayout& layout) {
96 if (keycode >= kLayoutSize) {
100 auto found_group_layout = layout.find(group);
101 if (found_group_layout != layout.end()) {
102 return found_group_layout->second[keycode];
124 fl_keyboard_handler_user_data,
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;
138 FlKeyboardHandlerUserDataClass* klass) {
139 G_OBJECT_CLASS(klass)->dispose = fl_keyboard_handler_user_data_dispose;
143 FlKeyboardHandlerUserData*
self) {}
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));
152 self->handler = handler;
155 g_object_add_weak_pointer(G_OBJECT(handler),
156 reinterpret_cast<gpointer*
>(&(self->handler)));
157 self->sequence_id = sequence_id;
201 std::unique_ptr<std::map<uint64_t, const LayoutGoal*>>
208 G_DEFINE_TYPE(FlKeyboardHandler, fl_keyboard_handler, G_TYPE_OBJECT);
214 gconstpointer needle,
215 GEqualFunc equal_func,
218 g_return_val_if_fail(haystack != NULL, FALSE);
219 if (equal_func == NULL) {
220 equal_func = g_direct_equal;
222 for (
i = 0;
i < haystack->len;
i++) {
223 if (equal_func(g_ptr_array_index(haystack,
i), needle)) {
224 if (index_ != NULL) {
237 FlKeyboardPendingEvent* pending =
238 FL_KEYBOARD_PENDING_EVENT(
const_cast<gpointer
>(a));
239 uint64_t sequence_id = *
reinterpret_cast<const uint64_t*
>(b);
245 FlKeyboardPendingEvent* pending =
246 FL_KEYBOARD_PENDING_EVENT(
const_cast<gpointer
>(a));
247 uint64_t hash = *
reinterpret_cast<const uint64_t*
>(b);
259 self->pending_redispatches,
static_cast<const uint64_t*
>(&hash),
263 g_ptr_array_remove_index_fast(self->pending_redispatches, result_index);
272 gpointer user_data_ptr) {
273 g_return_if_fail(FL_IS_KEYBOARD_HANDLER_USER_DATA(user_data_ptr));
275 FL_KEYBOARD_HANDLER_USER_DATA(user_data_ptr);
276 FlKeyboardHandler*
self =
user_data->handler;
277 g_return_if_fail(self->view_delegate !=
nullptr);
279 guint result_index = -1;
281 self->pending_responds, &
user_data->sequence_id,
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);
290 g_object_unref(user_data_ptr);
292 g_ptr_array_remove_index_fast(self->pending_responds, result_index);
293 g_return_if_fail(removed == pending);
294 bool should_redispatch =
298 if (should_redispatch) {
299 g_ptr_array_add(self->pending_redispatches, pending);
304 g_object_unref(pending);
313 GdkKeymapKey key = {keycode, group, level};
314 constexpr
int kBmpMax = 0xD7FF;
316 return origin < kBmpMax ? origin : 0xFFFF;
323 if (self->derived_layout->find(group) != self->derived_layout->end()) {
327 self->keycode_to_goals->end()) {
331 DerivedGroupLayout& layout = (*
self->derived_layout)[group];
335 std::map<uint64_t, const LayoutGoal*> remaining_mandatory_goals =
336 *
self->logical_to_mandatory_goals;
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 = {
345 debug_format_layout_data(debug_layout_data, keycode, this_key_clues[0],
355 uint16_t keycode = keycode_goal.keycode;
356 std::vector<uint16_t> this_key_clues = {
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()) {
372 g_return_if_fail(layout[keycode] == 0);
373 layout[keycode] = clue;
374 remaining_mandatory_goals.erase(matching_goal);
378 bool has_any_eascii =
379 is_eascii(this_key_clues[0]) || is_eascii(this_key_clues[1]);
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;
390 for (
const auto mandatory_goal_iter : remaining_mandatory_goals) {
391 const LayoutGoal* goal = mandatory_goal_iter.second;
400 GHashTable* pressing_records =
403 g_hash_table_foreach(
406 int64_t physical_key =
reinterpret_cast<int64_t
>(key);
407 int64_t logical_key =
reinterpret_cast<int64_t
>(
value);
421 FlKeyboardHandler*
self = FL_KEYBOARD_HANDLER(
user_data);
425 g_autoptr(FlMethodResponse) response =
nullptr;
432 g_autoptr(GError)
error =
nullptr;
434 g_warning(
"Failed to send method call response: %s",
error->message);
440 gpointer foreach_data_ptr) {
441 DispatchToResponderLoopContext* context =
442 reinterpret_cast<DispatchToResponderLoopContext*
>(foreach_data_ptr);
443 FlKeyResponder* responder = FL_KEY_RESPONDER(responder_data);
446 context->user_data, context->specified_logical_key);
450 FlKeyboardHandler*
self = FL_KEYBOARD_HANDLER(
object);
452 if (self->view_delegate !=
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;
461 self->derived_layout.reset();
462 self->keycode_to_goals.reset();
463 self->logical_to_mandatory_goals.reset();
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);
470 G_OBJECT_CLASS(fl_keyboard_handler_parent_class)->dispose(
object);
478 self->derived_layout = std::make_unique<DerivedLayout>();
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*>>();
485 (*
self->keycode_to_goals)[goal.keycode] = &goal;
486 if (goal.mandatory) {
487 (*
self->logical_to_mandatory_goals)[goal.logical_key] = &goal;
491 self->responder_list = g_ptr_array_new_with_free_func(g_object_unref);
493 self->pending_responds = g_ptr_array_new();
494 self->pending_redispatches = g_ptr_array_new_with_free_func(g_object_unref);
496 self->last_sequence_id = 1;
500 FlBinaryMessenger* messenger,
501 FlKeyboardViewDelegate* view_delegate) {
502 g_return_val_if_fail(FL_IS_KEYBOARD_VIEW_DELEGATE(view_delegate),
nullptr);
504 FlKeyboardHandler*
self = FL_KEYBOARD_HANDLER(
505 g_object_new(fl_keyboard_handler_get_type(),
nullptr));
507 self->view_delegate = view_delegate;
508 g_object_add_weak_pointer(
509 G_OBJECT(view_delegate),
510 reinterpret_cast<gpointer*
>(&(self->view_delegate)));
514 self->responder_list,
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);
525 g_ptr_array_add(self->responder_list,
530 self->view_delegate, [
self]() { self->derived_layout->clear(); });
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);
555 event, ++self->last_sequence_id, self->responder_list->len);
557 g_ptr_array_add(self->pending_responds, pending);
560 DispatchToResponderLoopContext data{
562 .specified_logical_key =
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;
580 g_return_if_fail(FL_IS_KEYBOARD_HANDLER(
self));
584 FlKeyEmbedderResponder* responder =
585 FL_KEY_EMBEDDER_RESPONDER(g_ptr_array_index(self->responder_list, 0));
591 g_return_val_if_fail(FL_IS_KEYBOARD_HANDLER(
self),
nullptr);
595 FlKeyEmbedderResponder* responder =
596 FL_KEY_EMBEDDER_RESPONDER(g_ptr_array_index(self->responder_list, 0));