13
13
#include " flutter/shell/platform/linux/fl_key_channel_responder.h"
14
14
#include " flutter/shell/platform/linux/fl_key_embedder_responder.h"
15
15
#include " flutter/shell/platform/linux/fl_keyboard_layout.h"
16
- #include " flutter/shell/platform/linux/fl_keyboard_pending_event.h"
17
16
#include " flutter/shell/platform/linux/key_mapping.h"
18
17
19
18
// Turn on this flag to print complete layout data when switching IMEs. The data
@@ -53,6 +52,35 @@ void debug_format_layout_data(std::string& debug_layout_data,
53
52
54
53
} // namespace
55
54
55
+ typedef struct {
56
+ // Event being handled.
57
+ FlKeyEvent* event;
58
+
59
+ // TRUE if the embedder has responded.
60
+ gboolean embedder_responded;
61
+
62
+ // TRUE if the channel has responded.
63
+ gboolean channel_responded;
64
+
65
+ // TRUE if this event is to be redispatched;
66
+ gboolean redispatch;
67
+
68
+ // TRUE if either the embedder of channel handled this event (or both).
69
+ gboolean handled;
70
+ } HandleEventData;
71
+
72
+ static HandleEventData* handle_event_data_new (FlKeyEvent* event) {
73
+ HandleEventData* data =
74
+ static_cast <HandleEventData*>(g_new0 (HandleEventData, 1 ));
75
+ data->event = FL_KEY_EVENT (g_object_ref (event));
76
+ return data;
77
+ }
78
+
79
+ static void handle_event_data_free (HandleEventData* data) {
80
+ g_object_unref (data->event );
81
+ g_free (data);
82
+ }
83
+
56
84
struct _FlKeyboardManager {
57
85
GObject parent_instance;
58
86
@@ -66,26 +94,14 @@ struct _FlKeyboardManager {
66
94
FlKeyboardManagerLookupKeyHandler lookup_key_handler;
67
95
gpointer lookup_key_handler_user_data;
68
96
69
- FlKeyboardManagerRedispatchEventHandler redispatch_handler;
70
- gpointer redispatch_handler_user_data;
71
-
72
97
FlKeyboardManagerGetPressedStateHandler get_pressed_state_handler;
73
98
gpointer get_pressed_state_handler_user_data;
74
99
75
100
FlKeyEmbedderResponder* key_embedder_responder;
76
101
77
102
FlKeyChannelResponder* key_channel_responder;
78
103
79
- // An array of #FlKeyboardPendingEvent.
80
- //
81
- // Its elements are *not* unreferenced when removed. When FlKeyboardManager is
82
- // disposed, this array will be set with a free_func so that the elements are
83
- // unreferenced when removed.
84
- GPtrArray* pending_responds;
85
-
86
- // An array of #FlKeyboardPendingEvent.
87
- //
88
- // Its elements are unreferenced when removed.
104
+ // Events in the process of being redispatched.
89
105
GPtrArray* pending_redispatches;
90
106
91
107
// Record the derived layout.
@@ -120,88 +136,44 @@ static void keymap_keys_changed_cb(FlKeyboardManager* self) {
120
136
self->derived_layout = fl_keyboard_layout_new ();
121
137
}
122
138
123
- // This is an exact copy of g_ptr_array_find_with_equal_func. Somehow CI
124
- // reports that can not find symbol g_ptr_array_find_with_equal_func, despite
125
- // the fact that it runs well locally.
126
- static gboolean g_ptr_array_find_with_equal_func1 (GPtrArray* haystack,
127
- gconstpointer needle,
128
- GEqualFunc equal_func,
129
- guint* index_) {
130
- guint i;
131
- g_return_val_if_fail (haystack != NULL , FALSE );
132
- if (equal_func == NULL ) {
133
- equal_func = g_direct_equal;
134
- }
135
- for (i = 0 ; i < haystack->len ; i++) {
136
- if (equal_func (g_ptr_array_index (haystack, i), needle)) {
137
- if (index_ != NULL ) {
138
- *index_ = i;
139
- }
140
- return TRUE ;
141
- }
142
- }
143
-
144
- return FALSE ;
145
- }
146
-
147
- // Compare a #FlKeyboardPendingEvent with the given hash.
148
- static gboolean compare_pending_by_hash (gconstpointer a, gconstpointer b) {
149
- FlKeyboardPendingEvent* pending =
150
- FL_KEYBOARD_PENDING_EVENT (const_cast <gpointer>(a));
151
- uint64_t hash = *reinterpret_cast <const uint64_t *>(b);
152
- return fl_keyboard_pending_event_get_hash (pending) == hash;
153
- }
139
+ static void complete_handle_event (FlKeyboardManager* self, GTask* task) {
140
+ HandleEventData* data =
141
+ static_cast <HandleEventData*>(g_task_get_task_data (task));
154
142
155
- // The callback used by a responder after the event was dispatched.
156
- static void responder_handle_event_callback (FlKeyboardManager* self,
157
- FlKeyboardPendingEvent* pending) {
158
- g_autoptr (FlKeyboardViewDelegate) view_delegate =
159
- FL_KEYBOARD_VIEW_DELEGATE (g_weak_ref_get (&self->view_delegate ));
160
- if (view_delegate == nullptr ) {
143
+ // Waiting for responses.
144
+ if (!data->embedder_responded || !data->channel_responded ) {
161
145
return ;
162
146
}
163
147
164
- // All responders have replied.
165
- if (fl_keyboard_pending_event_is_complete (pending)) {
166
- g_ptr_array_remove (self->pending_responds , pending);
167
- bool should_redispatch =
168
- !fl_keyboard_pending_event_get_any_handled (pending) &&
169
- !fl_keyboard_view_delegate_text_filter_key_press (
170
- view_delegate, fl_keyboard_pending_event_get_event (pending));
171
- if (should_redispatch) {
172
- g_ptr_array_add (self->pending_redispatches , g_object_ref (pending));
173
- FlKeyEvent* event = fl_keyboard_pending_event_get_event (pending);
174
- if (self->redispatch_handler != nullptr ) {
175
- self->redispatch_handler (event, self->redispatch_handler_user_data );
176
- } else {
177
- GdkEventType event_type =
178
- gdk_event_get_event_type (fl_key_event_get_origin (event));
179
- g_return_if_fail (event_type == GDK_KEY_PRESS ||
180
- event_type == GDK_KEY_RELEASE);
181
- gdk_event_put (fl_key_event_get_origin (event));
182
- }
148
+ // Redispatch if needed.
149
+ if (!data->handled ) {
150
+ gboolean filtered = FALSE ;
151
+ g_autoptr (FlKeyboardViewDelegate) view_delegate =
152
+ FL_KEYBOARD_VIEW_DELEGATE (g_weak_ref_get (&self->view_delegate ));
153
+ if (view_delegate != nullptr ) {
154
+ filtered = fl_keyboard_view_delegate_text_filter_key_press (view_delegate,
155
+ data->event );
156
+ }
157
+ data->redispatch = !filtered;
158
+ if (data->redispatch ) {
159
+ g_ptr_array_add (self->pending_redispatches , g_object_ref (data->event ));
183
160
}
184
161
}
185
- }
186
162
187
- static void complete_handle_event (FlKeyboardManager* self, GTask* task) {
188
- FlKeyboardPendingEvent* pending =
189
- FL_KEYBOARD_PENDING_EVENT (g_task_get_task_data (task));
190
-
191
- if (fl_keyboard_pending_event_is_complete (pending)) {
192
- g_task_return_boolean (task, TRUE );
193
- }
163
+ g_task_return_boolean (task, TRUE );
194
164
}
195
165
196
166
static void responder_handle_embedder_event_callback (bool handled,
197
167
gpointer user_data) {
198
168
g_autoptr (GTask) task = G_TASK (user_data);
199
169
FlKeyboardManager* self = FL_KEYBOARD_MANAGER (g_task_get_source_object (task));
200
170
201
- FlKeyboardPendingEvent* pending =
202
- FL_KEYBOARD_PENDING_EVENT (g_task_get_task_data (task));
203
- fl_keyboard_pending_event_mark_embedder_replied (pending, handled);
204
- responder_handle_event_callback (self, pending);
171
+ HandleEventData* data =
172
+ static_cast <HandleEventData*>(g_task_get_task_data (G_TASK (task)));
173
+ data->embedder_responded = TRUE ;
174
+ if (handled) {
175
+ data->handled = TRUE ;
176
+ }
205
177
206
178
complete_handle_event (self, task);
207
179
}
@@ -212,6 +184,10 @@ static void responder_handle_channel_event_cb(GObject* object,
212
184
g_autoptr (GTask) task = G_TASK (user_data);
213
185
FlKeyboardManager* self = FL_KEYBOARD_MANAGER (g_task_get_source_object (task));
214
186
187
+ HandleEventData* data =
188
+ static_cast <HandleEventData*>(g_task_get_task_data (G_TASK (task)));
189
+ data->channel_responded = TRUE ;
190
+
215
191
g_autoptr (GError) error = nullptr ;
216
192
gboolean handled;
217
193
if (!fl_key_channel_responder_handle_event_finish (
@@ -221,11 +197,9 @@ static void responder_handle_channel_event_cb(GObject* object,
221
197
}
222
198
handled = FALSE ;
223
199
}
224
-
225
- FlKeyboardPendingEvent* pending =
226
- FL_KEYBOARD_PENDING_EVENT (g_task_get_task_data (task));
227
- fl_keyboard_pending_event_mark_channel_replied (pending, handled);
228
- responder_handle_event_callback (self, pending);
200
+ if (handled) {
201
+ data->handled = TRUE ;
202
+ }
229
203
230
204
complete_handle_event (self, task);
231
205
}
@@ -346,8 +320,6 @@ static void fl_keyboard_manager_dispose(GObject* object) {
346
320
347
321
g_clear_object (&self->key_embedder_responder );
348
322
g_clear_object (&self->key_channel_responder );
349
- g_ptr_array_set_free_func (self->pending_responds , g_object_unref);
350
- g_ptr_array_free (self->pending_responds , TRUE );
351
323
g_ptr_array_free (self->pending_redispatches , TRUE );
352
324
g_clear_object (&self->derived_layout );
353
325
if (self->keymap_keys_changed_cb_id != 0 ) {
@@ -377,7 +349,6 @@ static void fl_keyboard_manager_init(FlKeyboardManager* self) {
377
349
}
378
350
}
379
351
380
- self->pending_responds = g_ptr_array_new ();
381
352
self->pending_redispatches = g_ptr_array_new_with_free_func (g_object_unref);
382
353
383
354
self->keymap = gdk_keymap_get_for_display (gdk_display_get_default ());
@@ -450,19 +421,21 @@ gboolean fl_keyboard_manager_is_redispatched(FlKeyboardManager* self,
450
421
FlKeyEvent* event) {
451
422
g_return_val_if_fail (FL_IS_KEYBOARD_MANAGER (self), FALSE );
452
423
453
- uint64_t hash = fl_key_event_hash (event);
454
-
455
- guint result_index ;
456
- gboolean found = g_ptr_array_find_with_equal_func1 (
457
- self-> pending_redispatches , static_cast < const uint64_t *>(&hash),
458
- compare_pending_by_hash, &result_index );
459
- if (found) {
460
- // The removed object is freed due to `pending_redispatches`'s free_func.
461
- g_ptr_array_remove_index_fast (self-> pending_redispatches , result_index);
462
- return TRUE ;
463
- } else {
464
- return FALSE ;
424
+ guint32 time = fl_key_event_get_time (event);
425
+ gboolean is_press = !! fl_key_event_get_is_press (event);
426
+ guint16 keycode = fl_key_event_get_keycode (event) ;
427
+ for (guint i = 0 ; i < self-> pending_redispatches -> len ; i++) {
428
+ FlKeyEvent* e =
429
+ FL_KEY_EVENT ( g_ptr_array_index (self-> pending_redispatches , i) );
430
+ if (fl_key_event_get_time (e) == time &&
431
+ !! fl_key_event_get_is_press (e) == is_press &&
432
+ fl_key_event_get_keycode (e) == keycode) {
433
+ g_ptr_array_remove_index (self-> pending_redispatches , i) ;
434
+ return TRUE ;
435
+ }
465
436
}
437
+
438
+ return FALSE ;
466
439
}
467
440
468
441
void fl_keyboard_manager_handle_event (FlKeyboardManager* self,
@@ -477,9 +450,9 @@ void fl_keyboard_manager_handle_event(FlKeyboardManager* self,
477
450
478
451
guarantee_layout (self, event);
479
452
480
- FlKeyboardPendingEvent* pending = fl_keyboard_pending_event_new (event);
481
- g_ptr_array_add (self-> pending_responds , pending);
482
- g_task_set_task_data (task, g_object_ref (pending), g_object_unref );
453
+ g_task_set_task_data (
454
+ task, handle_event_data_new (event),
455
+ reinterpret_cast <GDestroyNotify>(handle_event_data_free) );
483
456
484
457
uint64_t specified_logical_key = fl_keyboard_layout_get_logical_key (
485
458
self->derived_layout , fl_key_event_get_group (event),
@@ -492,18 +465,21 @@ void fl_keyboard_manager_handle_event(FlKeyboardManager* self,
492
465
self->cancellable , responder_handle_channel_event_cb, g_object_ref (task));
493
466
}
494
467
495
- gboolean fl_keyboard_manager_handle_event_finish (FlKeyboardManager* self,
496
- GAsyncResult* result,
497
- GError** error) {
468
+ gboolean fl_keyboard_manager_handle_event_finish (
469
+ FlKeyboardManager* self,
470
+ GAsyncResult* result,
471
+ FlKeyEvent** redispatched_event,
472
+ GError** error) {
498
473
g_return_val_if_fail (FL_IS_KEYBOARD_MANAGER (self), FALSE );
499
474
g_return_val_if_fail (g_task_is_valid (result, self), FALSE );
500
- return g_task_propagate_boolean (G_TASK (result), error);
501
- }
502
475
503
- gboolean fl_keyboard_manager_is_state_clear (FlKeyboardManager* self) {
504
- g_return_val_if_fail (FL_IS_KEYBOARD_MANAGER (self), FALSE );
505
- return self->pending_responds ->len == 0 &&
506
- self->pending_redispatches ->len == 0 ;
476
+ HandleEventData* data =
477
+ static_cast <HandleEventData*>(g_task_get_task_data (G_TASK (result)));
478
+ if (redispatched_event != nullptr && data->redispatch ) {
479
+ *redispatched_event = FL_KEY_EVENT (g_object_ref (data->event ));
480
+ }
481
+
482
+ return g_task_propagate_boolean (G_TASK (result), error);
507
483
}
508
484
509
485
void fl_keyboard_manager_sync_modifier_if_needed (FlKeyboardManager* self,
@@ -543,15 +519,6 @@ void fl_keyboard_manager_set_lookup_key_handler(
543
519
self->lookup_key_handler_user_data = user_data;
544
520
}
545
521
546
- void fl_keyboard_manager_set_redispatch_handler (
547
- FlKeyboardManager* self,
548
- FlKeyboardManagerRedispatchEventHandler redispatch_handler,
549
- gpointer user_data) {
550
- g_return_if_fail (FL_IS_KEYBOARD_MANAGER (self));
551
- self->redispatch_handler = redispatch_handler;
552
- self->redispatch_handler_user_data = user_data;
553
- }
554
-
555
522
void fl_keyboard_manager_set_get_pressed_state_handler (
556
523
FlKeyboardManager* self,
557
524
FlKeyboardManagerGetPressedStateHandler get_pressed_state_handler,
0 commit comments