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,64 @@ static constexpr char kLinuxKeymap[] = "linux";
2726
2827static 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+
34+ G_DECLARE_FINAL_TYPE (FlKeyEventPair,
35+ fl_key_event_pair,
36+ FL,
37+ KEY_EVENT_PAIR,
38+ GObject);
39+
40+ FlKeyEventPair* fl_key_event_pair_new (uint64_t id, GdkEventKey* event);
41+
42+ G_END_DECLS
43+
44+ struct _FlKeyEventPair {
45+ GObject parent_instance;
46+
47+ uint64_t id;
48+ GdkEventKey* event;
49+ };
50+
51+ G_DEFINE_TYPE (FlKeyEventPair, fl_key_event_pair, G_TYPE_OBJECT)
52+
53+ static void fl_key_event_pair_dispose(GObject* object) {
54+ g_return_if_fail (FL_IS_KEY_EVENT_PAIR (object));
55+ FlKeyEventPair* self = FL_KEY_EVENT_PAIR (object);
56+ gdk_event_free (reinterpret_cast <GdkEvent*>(self->event ));
57+ }
58+
59+ static void fl_key_event_pair_class_init (FlKeyEventPairClass* klass) {
60+ G_OBJECT_CLASS (klass)->dispose = fl_key_event_pair_dispose;
61+ }
62+
63+ static void fl_key_event_pair_init (FlKeyEventPair* self) {}
64+
65+ FlKeyEventPair* fl_key_event_pair_new (uint64_t id, GdkEventKey* event) {
66+ FlKeyEventPair* self =
67+ FL_KEY_EVENT_PAIR (g_object_new (fl_key_event_pair_get_type (), nullptr ));
68+
69+ // Copy the event to preserve refcounts for referenced values (mainly the
70+ // window).
71+ GdkEventKey* event_copy = reinterpret_cast <GdkEventKey*>(
72+ gdk_event_copy (reinterpret_cast <GdkEvent*>(event)));
73+ self->id = id;
74+ self->event = event_copy;
75+ return self;
76+ }
77+
78+ // Definition of the FlKeyEventPlugin GObject class.
79+
3080struct _FlKeyEventPlugin {
3181 GObject parent_instance;
3282
3383 FlBasicMessageChannel* channel = nullptr ;
3484 FlTextInputPlugin* text_input_plugin = nullptr ;
3585 FlKeyEventPluginCallback response_callback = nullptr ;
36-
37- std::deque<std::pair<uint64_t , GdkEventKey*>> pendingEvents;
86+ GPtrArray* pending_events;
3887};
3988
4089G_DEFINE_TYPE (FlKeyEventPlugin, fl_key_event_plugin, G_TYPE_OBJECT)
@@ -46,6 +95,7 @@ static void fl_key_event_plugin_dispose(GObject* object) {
4695 g_object_remove_weak_pointer (
4796 G_OBJECT (self->text_input_plugin ),
4897 reinterpret_cast <gpointer*>(&(self->text_input_plugin )));
98+ g_ptr_array_free (self->pending_events , TRUE );
4999
50100 G_OBJECT_CLASS (fl_key_event_plugin_parent_class)->dispose (object);
51101}
@@ -78,6 +128,7 @@ FlKeyEventPlugin* fl_key_event_plugin_new(
78128 reinterpret_cast <gpointer*>(&(self->text_input_plugin )));
79129 self->text_input_plugin = text_input_plugin;
80130
131+ self->pending_events = g_ptr_array_new_with_free_func (g_object_unref);
81132 return self;
82133}
83134
@@ -92,39 +143,36 @@ uint64_t fl_get_event_id(GdkEventKey* event) {
92143}
93144
94145GdkEventKey* fl_find_pending_event (FlKeyEventPlugin* self, uint64_t id) {
95- if (self->pendingEvents .empty () || self->pendingEvents .front ().first != id) {
146+ if (self->pending_events ->len == 0 ||
147+ FL_KEY_EVENT_PAIR (g_ptr_array_index (self->pending_events , 0 ))->id != id) {
96148 return nullptr ;
97149 }
98- return self->pendingEvents .front ().second ;
150+
151+ return FL_KEY_EVENT_PAIR (g_ptr_array_index (self->pending_events , 0 ))->event ;
99152}
100153
101154void fl_remove_pending_event (FlKeyEventPlugin* self, uint64_t id) {
102- if (self->pendingEvents .empty () || self->pendingEvents .front ().first != id) {
155+ if (self->pending_events ->len == 0 ||
156+ FL_KEY_EVENT_PAIR (g_ptr_array_index (self->pending_events , 0 ))->id != id) {
103157 g_warning (
104158 " Tried to remove pending event with id %ld, but the event was out of "
105159 " order, or is unknown." ,
106160 id);
107161 return ;
108162 }
109- gdk_event_free (
110- reinterpret_cast <GdkEvent*>(self->pendingEvents .front ().second ));
111- self->pendingEvents .pop_front ();
163+ g_ptr_array_remove_index (self->pending_events , 0 );
112164}
113165
114166void fl_add_pending_event (FlKeyEventPlugin* self,
115167 uint64_t id,
116168 GdkEventKey* event) {
117- if (self->pendingEvents . size () > kMaxPendingEvents ) {
169+ if (self->pending_events -> len > kMaxPendingEvents ) {
118170 g_warning (
119- " There are %ld keyboard events that have not yet received a "
171+ " There are %d keyboard events that have not yet received a "
120172 " response from the framework. Are responses being sent?" ,
121- self->pendingEvents . size () );
173+ self->pending_events -> len );
122174 }
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));
175+ g_ptr_array_add (self->pending_events , fl_key_event_pair_new (id, event));
128176}
129177
130178struct _KeyEventResponseData {
@@ -154,6 +202,7 @@ void fl_handle_response(GObject* object,
154202 if (error != nullptr ) {
155203 g_error (" Unable to retrieve framework response: %s" , error->message );
156204 g_error_free (error);
205+ delete data;
157206 return ;
158207 }
159208 g_autoptr (FlValue) handled_value = fl_value_lookup_string (message, " handled" );
@@ -193,6 +242,7 @@ void fl_handle_response(GObject* object,
193242 if (self->response_callback != nullptr ) {
194243 self->response_callback (object, message, handled, data->user_data );
195244 }
245+ delete data;
196246}
197247
198248bool fl_key_event_plugin_send_key_event (FlKeyEventPlugin* self,
@@ -207,7 +257,8 @@ bool fl_key_event_plugin_send_key_event(FlKeyEventPlugin* self,
207257 // when we receive a random event that may or may not have been
208258 // tracked/produced by this code.
209259 uint64_t id = fl_get_event_id (event);
210- if (!self->pendingEvents .empty () && self->pendingEvents .front ().first == id) {
260+ if (self->pending_events ->len != 0 &&
261+ FL_KEY_EVENT_PAIR (g_ptr_array_index (self->pending_events , 0 ))->id == id) {
211262 // If the event is at the head of the queue of pending events we've seen,
212263 // and has the same id, then we know that this is a re-dispatched event, and
213264 // we shouldn't respond to it, but we should remove it from tracking.
0 commit comments