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,108 @@ 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 (FlKeyEventResponseDataClass* klass) {
103
+ G_OBJECT_CLASS (klass)->dispose = fl_key_event_response_data_dispose;
104
+ }
105
+
106
+ static void fl_key_event_response_data_init (FlKeyEventResponseData* self) {}
107
+
108
+ FlKeyEventResponseData* fl_key_event_response_data_new (FlKeyEventPlugin* plugin, uint64_t id, gpointer user_data) {
109
+ FlKeyEventResponseData* self =
110
+ FL_KEY_EVENT_RESPONSE_DATA (g_object_new (fl_key_event_response_data_get_type (), nullptr ));
111
+
112
+ self->plugin = plugin;
113
+ // Add a weak pointer so we can know if the key event plugin disappeared
114
+ // while the framework was responding.
115
+ g_object_add_weak_pointer (G_OBJECT (plugin),
116
+ reinterpret_cast <gpointer*>(&(self->plugin )));
117
+ self->id = id;
118
+ self->user_data = user_data;
119
+ return self;
120
+ }
121
+
122
+ // Definition of the FlKeyEventPlugin GObject class.
123
+
30
124
struct _FlKeyEventPlugin {
31
125
GObject parent_instance;
32
126
33
127
FlBasicMessageChannel* channel = nullptr ;
34
128
FlTextInputPlugin* text_input_plugin = nullptr ;
35
129
FlKeyEventPluginCallback response_callback = nullptr ;
36
-
37
- std::deque<std::pair<uint64_t , GdkEventKey*>> pendingEvents;
130
+ GPtrArray* pending_events;
38
131
};
39
132
40
133
G_DEFINE_TYPE (FlKeyEventPlugin, fl_key_event_plugin, G_TYPE_OBJECT)
@@ -46,6 +139,7 @@ static void fl_key_event_plugin_dispose(GObject* object) {
46
139
g_object_remove_weak_pointer (
47
140
G_OBJECT (self->text_input_plugin ),
48
141
reinterpret_cast <gpointer*>(&(self->text_input_plugin )));
142
+ g_ptr_array_free (self->pending_events , TRUE );
49
143
50
144
G_OBJECT_CLASS (fl_key_event_plugin_parent_class)->dispose (object);
51
145
}
@@ -78,6 +172,7 @@ FlKeyEventPlugin* fl_key_event_plugin_new(
78
172
reinterpret_cast <gpointer*>(&(self->text_input_plugin )));
79
173
self->text_input_plugin = text_input_plugin;
80
174
175
+ self->pending_events = g_ptr_array_new_with_free_func (g_object_unref);
81
176
return self;
82
177
}
83
178
@@ -92,60 +187,47 @@ uint64_t fl_get_event_id(GdkEventKey* event) {
92
187
}
93
188
94
189
GdkEventKey* fl_find_pending_event (FlKeyEventPlugin* self, uint64_t id) {
95
- if (self->pendingEvents .empty () || self->pendingEvents .front ().first != id) {
190
+ if (self->pending_events ->len == 0 ||
191
+ FL_KEY_EVENT_PAIR (g_ptr_array_index (self->pending_events , 0 ))->id != id) {
96
192
return nullptr ;
97
193
}
98
- return self->pendingEvents .front ().second ;
194
+
195
+ return FL_KEY_EVENT_PAIR (g_ptr_array_index (self->pending_events , 0 ))->event ;
99
196
}
100
197
101
198
void fl_remove_pending_event (FlKeyEventPlugin* self, uint64_t id) {
102
- if (self->pendingEvents .empty () || self->pendingEvents .front ().first != id) {
199
+ if (self->pending_events ->len == 0 ||
200
+ FL_KEY_EVENT_PAIR (g_ptr_array_index (self->pending_events , 0 ))->id != id) {
103
201
g_warning (
104
202
" Tried to remove pending event with id %ld, but the event was out of "
105
203
" order, or is unknown." ,
106
204
id);
107
205
return ;
108
206
}
109
- gdk_event_free (
110
- reinterpret_cast <GdkEvent*>(self->pendingEvents .front ().second ));
111
- self->pendingEvents .pop_front ();
207
+ g_ptr_array_remove_index (self->pending_events , 0 );
112
208
}
113
209
114
210
void fl_add_pending_event (FlKeyEventPlugin* self,
115
211
uint64_t id,
116
212
GdkEventKey* event) {
117
- if (self->pendingEvents . size () > kMaxPendingEvents ) {
213
+ if (self->pending_events -> len > kMaxPendingEvents ) {
118
214
g_warning (
119
- " There are %ld keyboard events that have not yet received a "
215
+ " There are %d keyboard events that have not yet received a "
120
216
" response from the framework. Are responses being sent?" ,
121
- self->pendingEvents . size () );
217
+ self->pending_events -> len );
122
218
}
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));
219
+ g_ptr_array_add (self->pending_events , fl_key_event_pair_new (id, event));
128
220
}
129
221
130
- struct _KeyEventResponseData {
131
- FlKeyEventPlugin* self;
132
- uint64_t id;
133
- gpointer user_data;
134
- };
135
-
136
222
void fl_handle_response (GObject* object,
137
223
GAsyncResult* result,
138
224
gpointer user_data) {
139
- _KeyEventResponseData* data =
140
- reinterpret_cast <_KeyEventResponseData*>(user_data);
225
+ FlKeyEventResponseData* data = FL_KEY_EVENT_RESPONSE_DATA (user_data);
141
226
142
227
// Will also return if the weak pointer has been destroyed.
143
- g_return_if_fail (FL_IS_KEY_EVENT_PLUGIN (data->self ));
228
+ g_return_if_fail (FL_IS_KEY_EVENT_PLUGIN (data->plugin ));
144
229
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 )));
230
+ FlKeyEventPlugin* self = data->plugin ;
149
231
150
232
g_autoptr (GError) error = nullptr ;
151
233
FlBasicMessageChannel* messageChannel = FL_BASIC_MESSAGE_CHANNEL (object);
@@ -154,6 +236,7 @@ void fl_handle_response(GObject* object,
154
236
if (error != nullptr ) {
155
237
g_error (" Unable to retrieve framework response: %s" , error->message );
156
238
g_error_free (error);
239
+ g_object_unref (data);
157
240
return ;
158
241
}
159
242
g_autoptr (FlValue) handled_value = fl_value_lookup_string (message, " handled" );
@@ -193,6 +276,7 @@ void fl_handle_response(GObject* object,
193
276
if (self->response_callback != nullptr ) {
194
277
self->response_callback (object, message, handled, data->user_data );
195
278
}
279
+ g_object_unref (data);
196
280
}
197
281
198
282
bool fl_key_event_plugin_send_key_event (FlKeyEventPlugin* self,
@@ -207,7 +291,8 @@ bool fl_key_event_plugin_send_key_event(FlKeyEventPlugin* self,
207
291
// when we receive a random event that may or may not have been
208
292
// tracked/produced by this code.
209
293
uint64_t id = fl_get_event_id (event);
210
- if (!self->pendingEvents .empty () && self->pendingEvents .front ().first == id) {
294
+ if (self->pending_events ->len != 0 &&
295
+ FL_KEY_EVENT_PAIR (g_ptr_array_index (self->pending_events , 0 ))->id == id) {
211
296
// If the event is at the head of the queue of pending events we've seen,
212
297
// and has the same id, then we know that this is a re-dispatched event, and
213
298
// we shouldn't respond to it, but we should remove it from tracking.
@@ -295,11 +380,7 @@ bool fl_key_event_plugin_send_key_event(FlKeyEventPlugin* self,
295
380
296
381
// Track the event as pending a response from the framework.
297
382
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 )));
383
+ FlKeyEventResponseData* data = fl_key_event_response_data_new (self, id, user_data);
303
384
// Send the message off to the framework for handling (or not).
304
385
fl_basic_message_channel_send (self->channel , message, nullptr ,
305
386
fl_handle_response, data);
0 commit comments