5
5
#include " flutter/shell/platform/linux/fl_key_event_plugin.h"
6
6
7
7
#include < gtk/gtk.h>
8
- #include < deque>
9
8
10
9
#include " flutter/shell/platform/linux/fl_text_input_plugin.h"
11
10
#include " flutter/shell/platform/linux/public/flutter_linux/fl_basic_message_channel.h"
@@ -27,14 +26,111 @@ static constexpr char kLinuxKeymap[] = "linux";
27
26
28
27
static constexpr uint64_t kMaxPendingEvents = 1000 ;
29
28
29
+ // Declare and define a private pair object to bind the id and the event
30
+ // together.
31
+
32
+ G_BEGIN_DECLS
33
+ G_DECLARE_FINAL_TYPE (FlKeyEventPair,
34
+ fl_key_event_pair,
35
+ FL,
36
+ KEY_EVENT_PAIR,
37
+ GObject);
38
+ G_END_DECLS
39
+
40
+ struct _FlKeyEventPair {
41
+ GObject parent_instance;
42
+
43
+ uint64_t id;
44
+ GdkEventKey* event;
45
+ };
46
+
47
+ G_DEFINE_TYPE (FlKeyEventPair, fl_key_event_pair, G_TYPE_OBJECT)
48
+
49
+ static void fl_key_event_pair_dispose(GObject* object) {
50
+ g_return_if_fail (FL_IS_KEY_EVENT_PAIR (object));
51
+ FlKeyEventPair* self = FL_KEY_EVENT_PAIR (object);
52
+ gdk_event_free (reinterpret_cast <GdkEvent*>(self->event ));
53
+ }
54
+
55
+ static void fl_key_event_pair_class_init (FlKeyEventPairClass* klass) {
56
+ G_OBJECT_CLASS (klass)->dispose = fl_key_event_pair_dispose;
57
+ }
58
+
59
+ static void fl_key_event_pair_init (FlKeyEventPair* self) {}
60
+
61
+ FlKeyEventPair* fl_key_event_pair_new (uint64_t id, GdkEventKey* event) {
62
+ FlKeyEventPair* self =
63
+ FL_KEY_EVENT_PAIR (g_object_new (fl_key_event_pair_get_type (), nullptr ));
64
+
65
+ // Copy the event to preserve refcounts for referenced values (mainly the
66
+ // window).
67
+ GdkEventKey* event_copy = reinterpret_cast <GdkEventKey*>(
68
+ gdk_event_copy (reinterpret_cast <GdkEvent*>(event)));
69
+ self->id = id;
70
+ self->event = event_copy;
71
+ return self;
72
+ }
73
+
74
+ // Declare and define a private class to hold response data from the framework.
75
+
76
+ G_BEGIN_DECLS
77
+ G_DECLARE_FINAL_TYPE (FlKeyEventResponseData,
78
+ fl_key_event_response_data,
79
+ FL,
80
+ KEY_EVENT_RESPONSE_DATA,
81
+ GObject);
82
+ G_END_DECLS
83
+
84
+ struct _FlKeyEventResponseData {
85
+ GObject parent_instance;
86
+
87
+ FlKeyEventPlugin* plugin;
88
+ uint64_t id;
89
+ gpointer user_data;
90
+ };
91
+
92
+ G_DEFINE_TYPE (FlKeyEventResponseData, fl_key_event_response_data, G_TYPE_OBJECT)
93
+
94
+ static void fl_key_event_response_data_dispose(GObject* object) {
95
+ g_return_if_fail (FL_IS_KEY_EVENT_RESPONSE_DATA (object));
96
+ FlKeyEventResponseData* self = FL_KEY_EVENT_RESPONSE_DATA (object);
97
+ // Don't need to weak pointer anymore.
98
+ g_object_remove_weak_pointer (G_OBJECT (self->plugin ),
99
+ reinterpret_cast <gpointer*>(&(self->plugin )));
100
+ }
101
+
102
+ static void fl_key_event_response_data_class_init (
103
+ FlKeyEventResponseDataClass* klass) {
104
+ G_OBJECT_CLASS (klass)->dispose = fl_key_event_response_data_dispose;
105
+ }
106
+
107
+ static void fl_key_event_response_data_init (FlKeyEventResponseData* self) {}
108
+
109
+ FlKeyEventResponseData* fl_key_event_response_data_new (FlKeyEventPlugin* plugin,
110
+ uint64_t id,
111
+ gpointer user_data) {
112
+ FlKeyEventResponseData* self = FL_KEY_EVENT_RESPONSE_DATA (
113
+ g_object_new (fl_key_event_response_data_get_type (), nullptr ));
114
+
115
+ self->plugin = plugin;
116
+ // Add a weak pointer so we can know if the key event plugin disappeared
117
+ // while the framework was responding.
118
+ g_object_add_weak_pointer (G_OBJECT (plugin),
119
+ reinterpret_cast <gpointer*>(&(self->plugin )));
120
+ self->id = id;
121
+ self->user_data = user_data;
122
+ return self;
123
+ }
124
+
125
+ // Definition of the FlKeyEventPlugin GObject class.
126
+
30
127
struct _FlKeyEventPlugin {
31
128
GObject parent_instance;
32
129
33
130
FlBasicMessageChannel* channel = nullptr ;
34
131
FlTextInputPlugin* text_input_plugin = nullptr ;
35
132
FlKeyEventPluginCallback response_callback = nullptr ;
36
-
37
- std::deque<std::pair<uint64_t , GdkEventKey*>> pendingEvents;
133
+ GPtrArray* pending_events;
38
134
};
39
135
40
136
G_DEFINE_TYPE (FlKeyEventPlugin, fl_key_event_plugin, G_TYPE_OBJECT)
@@ -46,6 +142,7 @@ static void fl_key_event_plugin_dispose(GObject* object) {
46
142
g_object_remove_weak_pointer (
47
143
G_OBJECT (self->text_input_plugin ),
48
144
reinterpret_cast <gpointer*>(&(self->text_input_plugin )));
145
+ g_ptr_array_free (self->pending_events , TRUE );
49
146
50
147
G_OBJECT_CLASS (fl_key_event_plugin_parent_class)->dispose (object);
51
148
}
@@ -78,6 +175,7 @@ FlKeyEventPlugin* fl_key_event_plugin_new(
78
175
reinterpret_cast <gpointer*>(&(self->text_input_plugin )));
79
176
self->text_input_plugin = text_input_plugin;
80
177
178
+ self->pending_events = g_ptr_array_new_with_free_func (g_object_unref);
81
179
return self;
82
180
}
83
181
@@ -92,60 +190,48 @@ uint64_t fl_get_event_id(GdkEventKey* event) {
92
190
}
93
191
94
192
GdkEventKey* fl_find_pending_event (FlKeyEventPlugin* self, uint64_t id) {
95
- if (self->pendingEvents .empty () || self->pendingEvents .front ().first != id) {
193
+ if (self->pending_events ->len == 0 ||
194
+ FL_KEY_EVENT_PAIR (g_ptr_array_index (self->pending_events , 0 ))->id != id) {
96
195
return nullptr ;
97
196
}
98
- return self->pendingEvents .front ().second ;
197
+
198
+ return FL_KEY_EVENT_PAIR (g_ptr_array_index (self->pending_events , 0 ))->event ;
99
199
}
100
200
101
201
void fl_remove_pending_event (FlKeyEventPlugin* self, uint64_t id) {
102
- if (self->pendingEvents .empty () || self->pendingEvents .front ().first != id) {
202
+ if (self->pending_events ->len == 0 ||
203
+ FL_KEY_EVENT_PAIR (g_ptr_array_index (self->pending_events , 0 ))->id != id) {
103
204
g_warning (
104
205
" Tried to remove pending event with id %ld, but the event was out of "
105
206
" order, or is unknown." ,
106
207
id);
107
208
return ;
108
209
}
109
- gdk_event_free (
110
- reinterpret_cast <GdkEvent*>(self->pendingEvents .front ().second ));
111
- self->pendingEvents .pop_front ();
210
+ g_ptr_array_remove_index (self->pending_events , 0 );
112
211
}
113
212
114
213
void fl_add_pending_event (FlKeyEventPlugin* self,
115
214
uint64_t id,
116
215
GdkEventKey* event) {
117
- if (self->pendingEvents . size () > kMaxPendingEvents ) {
216
+ if (self->pending_events -> len > kMaxPendingEvents ) {
118
217
g_warning (
119
- " There are %ld keyboard events that have not yet received a "
218
+ " There are %d keyboard events that have not yet received a "
120
219
" response from the framework. Are responses being sent?" ,
121
- self->pendingEvents . size () );
220
+ self->pending_events -> len );
122
221
}
123
- // Copy the event to preserve refcounts for referenced values (mainly the
124
- // window).
125
- GdkEventKey* event_copy = reinterpret_cast <GdkEventKey*>(
126
- gdk_event_copy (reinterpret_cast <GdkEvent*>(event)));
127
- self->pendingEvents .push_back (std::make_pair (id, event_copy));
222
+ g_ptr_array_add (self->pending_events , fl_key_event_pair_new (id, event));
128
223
}
129
224
130
- struct _KeyEventResponseData {
131
- FlKeyEventPlugin* self;
132
- uint64_t id;
133
- gpointer user_data;
134
- };
135
-
136
225
void fl_handle_response (GObject* object,
137
226
GAsyncResult* result,
138
227
gpointer user_data) {
139
- _KeyEventResponseData* data =
140
- reinterpret_cast <_KeyEventResponseData*> (user_data);
228
+ g_autoptr (FlKeyEventResponseData) data =
229
+ FL_KEY_EVENT_RESPONSE_DATA (user_data);
141
230
142
231
// Will also return if the weak pointer has been destroyed.
143
- g_return_if_fail (FL_IS_KEY_EVENT_PLUGIN (data->self ));
232
+ g_return_if_fail (FL_IS_KEY_EVENT_PLUGIN (data->plugin ));
144
233
145
- FlKeyEventPlugin* self = data->self ;
146
- // Don't need to weak pointer anymore.
147
- g_object_remove_weak_pointer (G_OBJECT (self),
148
- reinterpret_cast <gpointer*>(&(data->self )));
234
+ FlKeyEventPlugin* self = data->plugin ;
149
235
150
236
g_autoptr (GError) error = nullptr ;
151
237
FlBasicMessageChannel* messageChannel = FL_BASIC_MESSAGE_CHANNEL (object);
@@ -207,7 +293,8 @@ bool fl_key_event_plugin_send_key_event(FlKeyEventPlugin* self,
207
293
// when we receive a random event that may or may not have been
208
294
// tracked/produced by this code.
209
295
uint64_t id = fl_get_event_id (event);
210
- if (!self->pendingEvents .empty () && self->pendingEvents .front ().first == id) {
296
+ if (self->pending_events ->len != 0 &&
297
+ FL_KEY_EVENT_PAIR (g_ptr_array_index (self->pending_events , 0 ))->id == id) {
211
298
// If the event is at the head of the queue of pending events we've seen,
212
299
// and has the same id, then we know that this is a re-dispatched event, and
213
300
// we shouldn't respond to it, but we should remove it from tracking.
@@ -295,11 +382,8 @@ bool fl_key_event_plugin_send_key_event(FlKeyEventPlugin* self,
295
382
296
383
// Track the event as pending a response from the framework.
297
384
fl_add_pending_event (self, id, event);
298
- _KeyEventResponseData* data = new _KeyEventResponseData{self, id, user_data};
299
- // Add a weak pointer so we can know if the key event plugin disappeared
300
- // while the framework was responding.
301
- g_object_add_weak_pointer (G_OBJECT (self),
302
- reinterpret_cast <gpointer*>(&(data->self )));
385
+ FlKeyEventResponseData* data =
386
+ fl_key_event_response_data_new (self, id, user_data);
303
387
// Send the message off to the framework for handling (or not).
304
388
fl_basic_message_channel_send (self->channel , message, nullptr ,
305
389
fl_handle_response, data);
0 commit comments