Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit d073df7

Browse files
committed
Review Changes: convert from std::deque to GPtrArray
1 parent 49ca75d commit d073df7

File tree

1 file changed

+120
-36
lines changed

1 file changed

+120
-36
lines changed

shell/platform/linux/fl_key_event_plugin.cc

Lines changed: 120 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
#include "flutter/shell/platform/linux/fl_key_event_plugin.h"
66

77
#include <gtk/gtk.h>
8-
#include <deque>
98

109
#include "flutter/shell/platform/linux/fl_text_input_plugin.h"
1110
#include "flutter/shell/platform/linux/public/flutter_linux/fl_basic_message_channel.h"
@@ -27,14 +26,111 @@ static constexpr char kLinuxKeymap[] = "linux";
2726

2827
static constexpr uint64_t kMaxPendingEvents = 1000;
2928

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+
30127
struct _FlKeyEventPlugin {
31128
GObject parent_instance;
32129

33130
FlBasicMessageChannel* channel = nullptr;
34131
FlTextInputPlugin* text_input_plugin = nullptr;
35132
FlKeyEventPluginCallback response_callback = nullptr;
36-
37-
std::deque<std::pair<uint64_t, GdkEventKey*>> pendingEvents;
133+
GPtrArray* pending_events;
38134
};
39135

40136
G_DEFINE_TYPE(FlKeyEventPlugin, fl_key_event_plugin, G_TYPE_OBJECT)
@@ -46,6 +142,7 @@ static void fl_key_event_plugin_dispose(GObject* object) {
46142
g_object_remove_weak_pointer(
47143
G_OBJECT(self->text_input_plugin),
48144
reinterpret_cast<gpointer*>(&(self->text_input_plugin)));
145+
g_ptr_array_free(self->pending_events, TRUE);
49146

50147
G_OBJECT_CLASS(fl_key_event_plugin_parent_class)->dispose(object);
51148
}
@@ -78,6 +175,7 @@ FlKeyEventPlugin* fl_key_event_plugin_new(
78175
reinterpret_cast<gpointer*>(&(self->text_input_plugin)));
79176
self->text_input_plugin = text_input_plugin;
80177

178+
self->pending_events = g_ptr_array_new_with_free_func(g_object_unref);
81179
return self;
82180
}
83181

@@ -92,60 +190,48 @@ uint64_t fl_get_event_id(GdkEventKey* event) {
92190
}
93191

94192
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) {
96195
return nullptr;
97196
}
98-
return self->pendingEvents.front().second;
197+
198+
return FL_KEY_EVENT_PAIR(g_ptr_array_index(self->pending_events, 0))->event;
99199
}
100200

101201
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) {
103204
g_warning(
104205
"Tried to remove pending event with id %ld, but the event was out of "
105206
"order, or is unknown.",
106207
id);
107208
return;
108209
}
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);
112211
}
113212

114213
void fl_add_pending_event(FlKeyEventPlugin* self,
115214
uint64_t id,
116215
GdkEventKey* event) {
117-
if (self->pendingEvents.size() > kMaxPendingEvents) {
216+
if (self->pending_events->len > kMaxPendingEvents) {
118217
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 "
120219
"response from the framework. Are responses being sent?",
121-
self->pendingEvents.size());
220+
self->pending_events->len);
122221
}
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));
128223
}
129224

130-
struct _KeyEventResponseData {
131-
FlKeyEventPlugin* self;
132-
uint64_t id;
133-
gpointer user_data;
134-
};
135-
136225
void fl_handle_response(GObject* object,
137226
GAsyncResult* result,
138227
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);
141230

142231
// 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));
144233

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;
149235

150236
g_autoptr(GError) error = nullptr;
151237
FlBasicMessageChannel* messageChannel = FL_BASIC_MESSAGE_CHANNEL(object);
@@ -207,7 +293,8 @@ bool fl_key_event_plugin_send_key_event(FlKeyEventPlugin* self,
207293
// when we receive a random event that may or may not have been
208294
// tracked/produced by this code.
209295
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) {
211298
// If the event is at the head of the queue of pending events we've seen,
212299
// and has the same id, then we know that this is a re-dispatched event, and
213300
// 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,
295382

296383
// Track the event as pending a response from the framework.
297384
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);
303387
// Send the message off to the framework for handling (or not).
304388
fl_basic_message_channel_send(self->channel, message, nullptr,
305389
fl_handle_response, data);

0 commit comments

Comments
 (0)