| Flutter Linux Embedder |

fl_keyboard_manager.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
5 #include "flutter/shell/platform/linux/fl_keyboard_manager.h"
6
7 #include <array>
8 #include <cinttypes>
9 #include <memory>
10 #include <string>
11
12 #include "flutter/shell/platform/linux/fl_engine_private.h"
13 #include "flutter/shell/platform/linux/fl_key_channel_responder.h"
14 #include "flutter/shell/platform/linux/fl_key_embedder_responder.h"
15 #include "flutter/shell/platform/linux/fl_keyboard_layout.h"
16 #include "flutter/shell/platform/linux/fl_keyboard_pending_event.h"
17 #include "flutter/shell/platform/linux/key_mapping.h"
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 /* Declarations of private classes */
24
25 G_DECLARE_FINAL_TYPE(FlKeyboardManagerData,
26 fl_keyboard_manager_data,
27 FL,
28 KEYBOARD_MANAGER_DATA,
29 GObject);
30
31 /* End declarations */
32
33 namespace {
34
35 static bool is_eascii(uint16_t character) {
36 return character < 256;
37 }
38
39 #ifdef DEBUG_PRINT_LAYOUT
40 // Prints layout entries that will be parsed by `MockLayoutData`.
41 void debug_format_layout_data(std::string& debug_layout_data,
42 uint16_t keycode,
43 uint16_t clue1,
44 uint16_t clue2) {
45 if (keycode % 4 == 0) {
46 debug_layout_data.append(" ");
47 }
48
49 constexpr int kBufferSize = 30;
50 char buffer[kBufferSize];
51 buffer[0] = 0;
52 buffer[kBufferSize - 1] = 0;
53
54 snprintf(buffer, kBufferSize, "0x%04x, 0x%04x, ", clue1, clue2);
55 debug_layout_data.append(buffer);
56
57 if (keycode % 4 == 3) {
58 snprintf(buffer, kBufferSize, " // 0x%02x", keycode);
59 debug_layout_data.append(buffer);
60 }
61 }
62 #endif
63
64 } // namespace
65
66 /* Define FlKeyboardManagerData */
67
68 /**
69 * FlKeyboardManagerData:
70 * The user_data used when #FlKeyboardManager sends event to
71 * responders.
72 */
73
74 struct _FlKeyboardManagerData {
75 GObject parent_instance;
76
77 // The owner manager.
78 GWeakRef manager;
79
80 FlKeyboardPendingEvent* pending;
81 };
82
83 G_DEFINE_TYPE(FlKeyboardManagerData, fl_keyboard_manager_data, G_TYPE_OBJECT)
84
85 static void fl_keyboard_manager_data_dispose(GObject* object) {
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 }
93
94 static void fl_keyboard_manager_data_class_init(
95 FlKeyboardManagerDataClass* klass) {
96 G_OBJECT_CLASS(klass)->dispose = fl_keyboard_manager_data_dispose;
97 }
98
99 static void fl_keyboard_manager_data_init(FlKeyboardManagerData* self) {}
100
101 // Creates a new FlKeyboardManagerData private class with all information.
102 static FlKeyboardManagerData* fl_keyboard_manager_data_new(
103 FlKeyboardManager* manager,
104 FlKeyboardPendingEvent* pending) {
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 }
112
113 /* Define FlKeyboardManager */
114
115 struct _FlKeyboardManager {
116 GObject parent_instance;
117
118 GWeakRef engine;
119
120 GWeakRef view_delegate;
121
122 FlKeyboardManagerSendKeyEventHandler send_key_event_handler;
123 gpointer send_key_event_handler_user_data;
124
125 FlKeyboardManagerLookupKeyHandler lookup_key_handler;
126 gpointer lookup_key_handler_user_data;
127
128 FlKeyboardManagerRedispatchEventHandler redispatch_handler;
129 gpointer redispatch_handler_user_data;
130
131 FlKeyboardManagerGetPressedStateHandler get_pressed_state_handler;
132 gpointer get_pressed_state_handler_user_data;
133
134 FlKeyEmbedderResponder* key_embedder_responder;
135
136 FlKeyChannelResponder* key_channel_responder;
137
138 // An array of #FlKeyboardPendingEvent.
139 //
140 // Its elements are *not* unreferenced when removed. When FlKeyboardManager is
141 // disposed, this array will be set with a free_func so that the elements are
142 // unreferenced when removed.
143 GPtrArray* pending_responds;
144
145 // An array of #FlKeyboardPendingEvent.
146 //
147 // Its elements are unreferenced when removed.
148 GPtrArray* pending_redispatches;
149
150 // Record the derived layout.
151 //
152 // It is cleared when the platform reports a layout switch. Each entry,
153 // which corresponds to a group, is only initialized on the arrival of the
154 // first event for that group that has a goal keycode.
155 FlKeyboardLayout* derived_layout;
156
157 // A static map from keycodes to all layout goals.
158 //
159 // It is set up when the manager is initialized and is not changed ever after.
160 std::unique_ptr<std::map<uint16_t, const LayoutGoal*>> keycode_to_goals;
161
162 // A static map from logical keys to all mandatory layout goals.
163 //
164 // It is set up when the manager is initialized and is not changed ever after.
165 std::unique_ptr<std::map<uint64_t, const LayoutGoal*>>
166 logical_to_mandatory_goals;
167
168 GdkKeymap* keymap;
169 gulong keymap_keys_changed_cb_id; // Signal connection ID for
170 // keymap-keys-changed
171
172 GCancellable* cancellable;
173 };
174
175 G_DEFINE_TYPE(FlKeyboardManager, fl_keyboard_manager, G_TYPE_OBJECT);
176
177 static void keymap_keys_changed_cb(FlKeyboardManager* self) {
178 g_clear_object(&self->derived_layout);
179 self->derived_layout = fl_keyboard_layout_new();
180 }
181
182 // This is an exact copy of g_ptr_array_find_with_equal_func. Somehow CI
183 // reports that can not find symbol g_ptr_array_find_with_equal_func, despite
184 // the fact that it runs well locally.
185 static gboolean g_ptr_array_find_with_equal_func1(GPtrArray* haystack,
186 gconstpointer needle,
187 GEqualFunc equal_func,
188 guint* index_) {
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 }
205
206 // Compare a #FlKeyboardPendingEvent with the given hash.
207 static gboolean compare_pending_by_hash(gconstpointer a, gconstpointer b) {
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 }
213
214 // Try to remove a pending event from `pending_redispatches` with the target
215 // hash.
216 //
217 // Returns true if the event is found and removed.
218 static bool fl_keyboard_manager_remove_redispatched(FlKeyboardManager* self,
219 uint64_t hash) {
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 }
232
233 // The callback used by a responder after the event was dispatched.
234 static void responder_handle_event_callback(FlKeyboardManager* self,
235 FlKeyboardPendingEvent* pending) {
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.
243 if (fl_keyboard_pending_event_is_complete(pending)) {
244 g_ptr_array_remove(self->pending_responds, pending);
245 bool should_redispatch =
246 !fl_keyboard_pending_event_get_any_handled(pending) &&
247 !fl_keyboard_view_delegate_text_filter_key_press(
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 }
264
265 static void responder_handle_embedder_event_callback(bool handled,
266 gpointer user_data) {
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 }
279
280 static void responder_handle_channel_event_cb(GObject* object,
281 GAsyncResult* result,
282 gpointer user_data) {
283 g_autoptr(FlKeyboardManagerData) data = FL_KEYBOARD_MANAGER_DATA(user_data);
284
285 g_autoptr(GError) error = nullptr;
286 gboolean handled;
287 if (!fl_key_channel_responder_handle_event_finish(
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 }
305
306 static uint16_t convert_key_to_char(FlKeyboardManager* self,
307 guint keycode,
308 gint group,
309 gint level) {
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 }
320
321 // Make sure that Flutter has derived the layout for the group of the event,
322 // if the event contains a goal keycode.
323 static void guarantee_layout(FlKeyboardManager* self, FlKeyEvent* event) {
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()) {
394 fl_keyboard_layout_set_logical_key(
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 }
408
409 static void fl_keyboard_manager_dispose(GObject* object) {
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 }
434
435 static void fl_keyboard_manager_class_init(FlKeyboardManagerClass* klass) {
436 G_OBJECT_CLASS(klass)->dispose = fl_keyboard_manager_dispose;
437 }
438
439 static void fl_keyboard_manager_init(FlKeyboardManager* self) {
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 }
461
462 FlKeyboardManager* fl_keyboard_manager_new(
463 FlEngine* engine,
464 FlKeyboardViewDelegate* view_delegate) {
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;
490 fl_engine_send_key_event(
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 =
517 fl_key_channel_responder_new(fl_engine_get_binary_messenger(engine));
518
519 return self;
520 }
521
522 gboolean fl_keyboard_manager_handle_event(FlKeyboardManager* self,
523 FlKeyEvent* event) {
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));
542 fl_key_embedder_responder_handle_event(
543 self->key_embedder_responder, event, specified_logical_key,
544 responder_handle_embedder_event_callback, g_object_ref(data));
545 fl_key_channel_responder_handle_event(
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 }
551
552 gboolean fl_keyboard_manager_is_state_clear(FlKeyboardManager* self) {
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 }
557
558 void fl_keyboard_manager_sync_modifier_if_needed(FlKeyboardManager* self,
559 guint state,
560 double event_time) {
561 g_return_if_fail(FL_IS_KEYBOARD_MANAGER(self));
562 fl_key_embedder_responder_sync_modifiers_if_needed(
563 self->key_embedder_responder, state, event_time);
564 }
565
566 GHashTable* fl_keyboard_manager_get_pressed_state(FlKeyboardManager* self) {
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 {
572 return fl_key_embedder_responder_get_pressed_state(
573 self->key_embedder_responder);
574 }
575 }
576
577 void fl_keyboard_manager_set_send_key_event_handler(
578 FlKeyboardManager* self,
579 FlKeyboardManagerSendKeyEventHandler send_key_event_handler,
580 gpointer user_data) {
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 }
585
586 void fl_keyboard_manager_set_lookup_key_handler(
587 FlKeyboardManager* self,
588 FlKeyboardManagerLookupKeyHandler lookup_key_handler,
589 gpointer user_data) {
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 }
594
595 void fl_keyboard_manager_set_redispatch_handler(
596 FlKeyboardManager* self,
597 FlKeyboardManagerRedispatchEventHandler redispatch_handler,
598 gpointer user_data) {
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 }
603
604 void fl_keyboard_manager_set_get_pressed_state_handler(
605 FlKeyboardManager* self,
606 FlKeyboardManagerGetPressedStateHandler get_pressed_state_handler,
607 gpointer user_data) {
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 }
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
_FlKeyboardManager::pending_redispatches
GPtrArray * pending_redispatches
Definition: fl_keyboard_manager.cc:148
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
fl_keyboard_manager_set_redispatch_handler
void fl_keyboard_manager_set_redispatch_handler(FlKeyboardManager *self, FlKeyboardManagerRedispatchEventHandler redispatch_handler, gpointer user_data)
Definition: fl_keyboard_manager.cc:595
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
_FlKeyboardManager::keymap_keys_changed_cb_id
gulong keymap_keys_changed_cb_id
Definition: fl_keyboard_manager.cc:169
LayoutGoal
Definition: key_mapping.h:40
_FlKeyboardManager::redispatch_handler
FlKeyboardManagerRedispatchEventHandler redispatch_handler
Definition: fl_keyboard_manager.cc:128
responder_handle_event_callback
static void responder_handle_event_callback(FlKeyboardManager *self, FlKeyboardPendingEvent *pending)
Definition: fl_keyboard_manager.cc:234
_FlKeyboardManager::pending_responds
GPtrArray * pending_responds
Definition: fl_keyboard_manager.cc:143
fl_keyboard_manager.h
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
_FlKeyboardManager::redispatch_handler_user_data
gpointer redispatch_handler_user_data
Definition: fl_keyboard_manager.cc:129
FlKeyboardManagerGetPressedStateHandler
GHashTable *(* FlKeyboardManagerGetPressedStateHandler)(gpointer user_data)
Definition: fl_keyboard_manager.h:142
fl_key_embedder_responder.h
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
_FlKeyboardManager::lookup_key_handler_user_data
gpointer lookup_key_handler_user_data
Definition: fl_keyboard_manager.cc:126
_FlKeyboardManager::get_pressed_state_handler_user_data
gpointer get_pressed_state_handler_user_data
Definition: fl_keyboard_manager.cc:132
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_manager_is_state_clear
gboolean fl_keyboard_manager_is_state_clear(FlKeyboardManager *self)
Definition: fl_keyboard_manager.cc:552
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
FlKeyboardManagerSendKeyEventHandler
void(* FlKeyboardManagerSendKeyEventHandler)(const FlutterKeyEvent *event, FlutterKeyEventCallback callback, void *callback_user_data, gpointer user_data)
Definition: fl_keyboard_manager.h:97
_FlKeyboardManager::parent_instance
GObject parent_instance
Definition: fl_keyboard_manager.cc:116
fl_keyboard_manager_data_class_init
static void fl_keyboard_manager_data_class_init(FlKeyboardManagerDataClass *klass)
Definition: fl_keyboard_manager.cc:94
fl_key_event_get_origin
GdkEvent * fl_key_event_get_origin(FlKeyEvent *self)
Definition: fl_key_event.cc:109
_FlKeyboardManagerData
Definition: fl_keyboard_manager.cc:74
_FlKeyboardManager::send_key_event_handler
FlKeyboardManagerSendKeyEventHandler send_key_event_handler
Definition: fl_keyboard_manager.cc:122
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
_FlKeyboardManager::get_pressed_state_handler
FlKeyboardManagerGetPressedStateHandler get_pressed_state_handler
Definition: fl_keyboard_manager.cc:131
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
_FlKeyboardManager::send_key_event_handler_user_data
gpointer send_key_event_handler_user_data
Definition: fl_keyboard_manager.cc:123
fl_keyboard_manager_handle_event
gboolean fl_keyboard_manager_handle_event(FlKeyboardManager *self, FlKeyEvent *event)
Definition: fl_keyboard_manager.cc:522
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
_FlKeyboardManagerData::parent_instance
GObject parent_instance
Definition: fl_keyboard_manager.cc:75
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
_FlKeyboardManagerData::pending
FlKeyboardPendingEvent * pending
Definition: fl_keyboard_manager.cc:80
fl_keyboard_manager_data_dispose
static void fl_keyboard_manager_data_dispose(GObject *object)
Definition: fl_keyboard_manager.cc:85
fl_keyboard_manager_init
static void fl_keyboard_manager_init(FlKeyboardManager *self)
Definition: fl_keyboard_manager.cc:439
_FlKeyboardManager::keymap
GdkKeymap * keymap
Definition: fl_keyboard_manager.cc:168
FlKeyboardManagerRedispatchEventHandler
void(* FlKeyboardManagerRedispatchEventHandler)(FlKeyEvent *event, gpointer user_data)
Definition: fl_keyboard_manager.h:128
_FlKeyboardManager::view_delegate
GWeakRef view_delegate
Definition: fl_keyboard_manager.cc:120
_FlKeyboardManager::key_embedder_responder
FlKeyEmbedderResponder * key_embedder_responder
Definition: fl_keyboard_manager.cc:134
fl_keyboard_manager_set_lookup_key_handler
void fl_keyboard_manager_set_lookup_key_handler(FlKeyboardManager *self, FlKeyboardManagerLookupKeyHandler lookup_key_handler, gpointer user_data)
Definition: fl_keyboard_manager.cc:586
fl_keyboard_layout_new
FlKeyboardLayout * fl_keyboard_layout_new()
Definition: fl_keyboard_layout.cc:40
fl_engine_private.h
key_mapping.h
fl_keyboard_layout.h
TRUE
return TRUE
Definition: fl_pixel_buffer_texture_test.cc:53
G_DECLARE_FINAL_TYPE
G_DECLARE_FINAL_TYPE(FlKeyboardManagerData, fl_keyboard_manager_data, FL, KEYBOARD_MANAGER_DATA, GObject)
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
G_DEFINE_TYPE
G_DEFINE_TYPE(FlKeyboardManager, fl_keyboard_manager, G_TYPE_OBJECT)
FL
FL
Definition: fl_binary_messenger.cc:27
fl_keyboard_manager_sync_modifier_if_needed
void fl_keyboard_manager_sync_modifier_if_needed(FlKeyboardManager *self, guint state, double event_time)
Definition: fl_keyboard_manager.cc:558
fl_keyboard_manager_class_init
static void fl_keyboard_manager_class_init(FlKeyboardManagerClass *klass)
Definition: fl_keyboard_manager.cc:435
fl_keyboard_manager_set_get_pressed_state_handler
void fl_keyboard_manager_set_get_pressed_state_handler(FlKeyboardManager *self, FlKeyboardManagerGetPressedStateHandler get_pressed_state_handler, gpointer user_data)
Definition: fl_keyboard_manager.cc:604
fl_keyboard_manager_get_pressed_state
GHashTable * fl_keyboard_manager_get_pressed_state(FlKeyboardManager *self)
Definition: fl_keyboard_manager.cc:566
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
_FlKeyboardManager::cancellable
GCancellable * cancellable
Definition: fl_keyboard_manager.cc:172
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
_FlKeyboardManager::derived_layout
FlKeyboardLayout * derived_layout
Definition: fl_keyboard_manager.cc:155
fl_keyboard_layout_has_group
gboolean fl_keyboard_layout_has_group(FlKeyboardLayout *self, uint8_t group)
Definition: fl_keyboard_layout.cc:45
buffer
static const uint8_t buffer[]
Definition: fl_pixel_buffer_texture_test.cc:44
fl_keyboard_pending_event.h
fl_keyboard_manager_data_new
static FlKeyboardManagerData * fl_keyboard_manager_data_new(FlKeyboardManager *manager, FlKeyboardPendingEvent *pending)
Definition: fl_keyboard_manager.cc:102
fl_keyboard_manager_set_send_key_event_handler
void fl_keyboard_manager_set_send_key_event_handler(FlKeyboardManager *self, FlKeyboardManagerSendKeyEventHandler send_key_event_handler, gpointer user_data)
Definition: fl_keyboard_manager.cc:577
fl_key_channel_responder.h
_FlKeyboardManager
Definition: fl_keyboard_manager.cc:115
_FlKeyboardManager::keycode_to_goals
std::unique_ptr< std::map< uint16_t, const LayoutGoal * > > keycode_to_goals
Definition: fl_keyboard_manager.cc:160
fl_keyboard_manager_new
FlKeyboardManager * fl_keyboard_manager_new(FlEngine *engine, FlKeyboardViewDelegate *view_delegate)
Definition: fl_keyboard_manager.cc:462
_FlKeyboardManager::key_channel_responder
FlKeyChannelResponder * key_channel_responder
Definition: fl_keyboard_manager.cc:136
_FlKeyboardManagerData::manager
GWeakRef manager
Definition: fl_keyboard_manager.cc:78
_FlKeyboardManager::lookup_key_handler
FlKeyboardManagerLookupKeyHandler lookup_key_handler
Definition: fl_keyboard_manager.cc:125
_FlKeyboardManager::logical_to_mandatory_goals
std::unique_ptr< std::map< uint64_t, const LayoutGoal * > > logical_to_mandatory_goals
Definition: fl_keyboard_manager.cc:166
_FlKeyboardManager::engine
GWeakRef engine
Definition: fl_keyboard_manager.cc:118
fl_keyboard_manager_data_init
static void fl_keyboard_manager_data_init(FlKeyboardManagerData *self)
Definition: fl_keyboard_manager.cc:99
FlKeyboardManagerLookupKeyHandler
guint(* FlKeyboardManagerLookupKeyHandler)(const GdkKeymapKey *key, gpointer user_data)
Definition: fl_keyboard_manager.h:114