diff --git a/shell/platform/linux/fl_key_embedder_responder.cc b/shell/platform/linux/fl_key_embedder_responder.cc index 925c530a71348..100d6189f7b53 100644 --- a/shell/platform/linux/fl_key_embedder_responder.cc +++ b/shell/platform/linux/fl_key_embedder_responder.cc @@ -141,6 +141,7 @@ struct _FlKeyEmbedderResponder { GObject parent_instance; EmbedderSendKeyEvent send_key_event; + void* send_key_event_user_data; // Internal record for states of whether a key is pressed. // @@ -260,11 +261,13 @@ static void initialize_logical_key_to_lock_bit_loop_body(gpointer lock_bit, // Creates a new FlKeyEmbedderResponder instance. FlKeyEmbedderResponder* fl_key_embedder_responder_new( - EmbedderSendKeyEvent send_key_event) { + EmbedderSendKeyEvent send_key_event, + void* send_key_event_user_data) { FlKeyEmbedderResponder* self = FL_KEY_EMBEDDER_RESPONDER( g_object_new(FL_TYPE_EMBEDDER_RESPONDER_USER_DATA, nullptr)); - self->send_key_event = std::move(send_key_event); + self->send_key_event = send_key_event; + self->send_key_event_user_data = send_key_event_user_data; self->pressing_records = g_hash_table_new(g_direct_hash, g_direct_equal); self->mapping_records = g_hash_table_new(g_direct_hash, g_direct_equal); @@ -360,7 +363,8 @@ static void synthesize_simple_event(FlKeyEmbedderResponder* self, out_event.character = nullptr; out_event.synthesized = true; self->sent_any_events = true; - self->send_key_event(&out_event, nullptr, nullptr); + self->send_key_event(&out_event, nullptr, nullptr, + self->send_key_event_user_data); } namespace { @@ -850,7 +854,8 @@ static void fl_key_embedder_responder_handle_event_impl( FlKeyEmbedderUserData* response_data = fl_key_embedder_user_data_new(callback, user_data); self->sent_any_events = true; - self->send_key_event(&out_event, handle_response, response_data); + self->send_key_event(&out_event, handle_response, response_data, + self->send_key_event_user_data); } // Sends a key event to the framework. @@ -865,7 +870,8 @@ static void fl_key_embedder_responder_handle_event( fl_key_embedder_responder_handle_event_impl( responder, event, specified_logical_key, callback, user_data); if (!self->sent_any_events) { - self->send_key_event(&kEmptyEvent, nullptr, nullptr); + self->send_key_event(&kEmptyEvent, nullptr, nullptr, + self->send_key_event_user_data); } } diff --git a/shell/platform/linux/fl_key_embedder_responder.h b/shell/platform/linux/fl_key_embedder_responder.h index 8937f97e2ec13..73c754bf77b4b 100644 --- a/shell/platform/linux/fl_key_embedder_responder.h +++ b/shell/platform/linux/fl_key_embedder_responder.h @@ -15,10 +15,21 @@ constexpr int kMaxConvertedKeyData = 3; -typedef std::function - EmbedderSendKeyEvent; +// The signature of a function that FlKeyEmbedderResponder calls on every key +// event. +// +// The `user_data` is opaque data managed by the object that creates +// FlKeyEmbedderResponder, and is registered along with this callback +// via `fl_key_embedder_responder_new`. +// +// The `callback_user_data` is opaque data managed by FlKeyEmbedderResponder. +// Instances of the EmbedderSendKeyEvent callback are required to invoke +// `callback` with the `callback_user_data` parameter after the `event` has been +// processed. +typedef void (*EmbedderSendKeyEvent)(const FlutterKeyEvent* event, + FlutterKeyEventCallback callback, + void* callback_user_data, + void* send_key_event_user_data); G_BEGIN_DECLS @@ -44,11 +55,16 @@ G_DECLARE_FINAL_TYPE(FlKeyEmbedderResponder, * the event. * * Creates a new #FlKeyEmbedderResponder. + * @send_key_event: a function that is called on every key event. + * @send_key_event_user_data: an opaque pointer that will be sent back as the + * last argument of send_key_event, created and managed by the object that holds + * FlKeyEmbedderResponder. * * Returns: a new #FlKeyEmbedderResponder. */ FlKeyEmbedderResponder* fl_key_embedder_responder_new( - EmbedderSendKeyEvent send_key_event); + EmbedderSendKeyEvent send_key_event, + void* send_key_event_user_data); /** * fl_key_embedder_responder_sync_modifiers_if_needed: diff --git a/shell/platform/linux/fl_key_embedder_responder_test.cc b/shell/platform/linux/fl_key_embedder_responder_test.cc index 6b7d0f1c068e2..c7445c85c5e51 100644 --- a/shell/platform/linux/fl_key_embedder_responder_test.cc +++ b/shell/platform/linux/fl_key_embedder_responder_test.cc @@ -149,14 +149,16 @@ namespace { GPtrArray* g_call_records; } -static EmbedderSendKeyEvent record_calls_in(GPtrArray* records_array) { - return [records_array](const FlutterKeyEvent* event, - FlutterKeyEventCallback callback, void* user_data) { - if (records_array != nullptr) { - g_ptr_array_add(records_array, fl_key_embedder_call_record_new( - event, callback, user_data)); - } - }; +static void record_calls(const FlutterKeyEvent* event, + FlutterKeyEventCallback callback, + void* callback_user_data, + void* send_key_event_user_data) { + GPtrArray* records_array = + reinterpret_cast(send_key_event_user_data); + if (records_array != nullptr) { + g_ptr_array_add(records_array, fl_key_embedder_call_record_new( + event, callback, callback_user_data)); + } } static void clear_g_call_records() { @@ -169,7 +171,7 @@ TEST(FlKeyEmbedderResponderTest, SendKeyEvent) { EXPECT_EQ(g_call_records, nullptr); g_call_records = g_ptr_array_new_with_free_func(g_object_unref); FlKeyResponder* responder = FL_KEY_RESPONDER( - fl_key_embedder_responder_new(record_calls_in(g_call_records))); + fl_key_embedder_responder_new(record_calls, g_call_records)); int user_data = 123; // Arbitrary user data FlKeyEmbedderCallRecord* record; @@ -265,7 +267,7 @@ TEST(FlKeyEmbedderResponderTest, UsesSpecifiedLogicalKey) { EXPECT_EQ(g_call_records, nullptr); g_call_records = g_ptr_array_new_with_free_func(g_object_unref); FlKeyResponder* responder = FL_KEY_RESPONDER( - fl_key_embedder_responder_new(record_calls_in(g_call_records))); + fl_key_embedder_responder_new(record_calls, g_call_records)); int user_data = 123; // Arbitrary user data FlKeyEmbedderCallRecord* record; @@ -300,7 +302,7 @@ TEST(FlKeyEmbedderResponderTest, PressShiftDuringLetterKeyTap) { EXPECT_EQ(g_call_records, nullptr); g_call_records = g_ptr_array_new_with_free_func(g_object_unref); FlKeyResponder* responder = FL_KEY_RESPONDER( - fl_key_embedder_responder_new(record_calls_in(g_call_records))); + fl_key_embedder_responder_new(record_calls, g_call_records)); int user_data = 123; // Arbitrary user data FlKeyEmbedderCallRecord* record; @@ -393,7 +395,7 @@ TEST(FlKeyEmbedderResponderTest, TapNumPadKeysBetweenNumLockEvents) { EXPECT_EQ(g_call_records, nullptr); g_call_records = g_ptr_array_new_with_free_func(g_object_unref); FlKeyResponder* responder = FL_KEY_RESPONDER( - fl_key_embedder_responder_new(record_calls_in(g_call_records))); + fl_key_embedder_responder_new(record_calls, g_call_records)); int user_data = 123; // Arbitrary user data FlKeyEmbedderCallRecord* record; @@ -554,7 +556,7 @@ TEST(FlKeyEmbedderResponderTest, ReleaseShiftKeyBetweenDigitKeyEvents) { EXPECT_EQ(g_call_records, nullptr); g_call_records = g_ptr_array_new_with_free_func(g_object_unref); FlKeyResponder* responder = FL_KEY_RESPONDER( - fl_key_embedder_responder_new(record_calls_in(g_call_records))); + fl_key_embedder_responder_new(record_calls, g_call_records)); int user_data = 123; // Arbitrary user data FlKeyEmbedderCallRecord* record; @@ -649,7 +651,7 @@ TEST(FlKeyEmbedderResponderTest, TapLetterKeysBetweenCapsLockEvents) { EXPECT_EQ(g_call_records, nullptr); g_call_records = g_ptr_array_new_with_free_func(g_object_unref); FlKeyResponder* responder = FL_KEY_RESPONDER( - fl_key_embedder_responder_new(record_calls_in(g_call_records))); + fl_key_embedder_responder_new(record_calls, g_call_records)); int user_data = 123; // Arbitrary user data FlKeyEmbedderCallRecord* record; @@ -810,7 +812,7 @@ TEST(FlKeyEmbedderResponderTest, TapLetterKeysBetweenCapsLockEventsReversed) { EXPECT_EQ(g_call_records, nullptr); g_call_records = g_ptr_array_new_with_free_func(g_object_unref); FlKeyResponder* responder = FL_KEY_RESPONDER( - fl_key_embedder_responder_new(record_calls_in(g_call_records))); + fl_key_embedder_responder_new(record_calls, g_call_records)); int user_data = 123; // Arbitrary user data FlKeyEmbedderCallRecord* record; @@ -967,7 +969,7 @@ TEST(FlKeyEmbedderResponderTest, TurnDuplicateDownEventsToRepeats) { EXPECT_EQ(g_call_records, nullptr); g_call_records = g_ptr_array_new_with_free_func(g_object_unref); FlKeyResponder* responder = FL_KEY_RESPONDER( - fl_key_embedder_responder_new(record_calls_in(g_call_records))); + fl_key_embedder_responder_new(record_calls, g_call_records)); int user_data = 123; // Arbitrary user data FlKeyEmbedderCallRecord* record; @@ -1028,7 +1030,7 @@ TEST(FlKeyEmbedderResponderTest, IgnoreAbruptUpEvent) { EXPECT_EQ(g_call_records, nullptr); g_call_records = g_ptr_array_new_with_free_func(g_object_unref); FlKeyResponder* responder = FL_KEY_RESPONDER( - fl_key_embedder_responder_new(record_calls_in(g_call_records))); + fl_key_embedder_responder_new(record_calls, g_call_records)); int user_data = 123; // Arbitrary user data // Release KeyA before it was even pressed. @@ -1058,7 +1060,7 @@ TEST(FlKeyEmbedderResponderTest, SynthesizeForDesyncPressingStateOnSelfEvents) { EXPECT_EQ(g_call_records, nullptr); g_call_records = g_ptr_array_new_with_free_func(g_object_unref); FlKeyResponder* responder = FL_KEY_RESPONDER( - fl_key_embedder_responder_new(record_calls_in(g_call_records))); + fl_key_embedder_responder_new(record_calls, g_call_records)); int user_data = 123; // Arbitrary user data FlKeyEmbedderCallRecord* record; @@ -1189,7 +1191,7 @@ TEST(FlKeyEmbedderResponderTest, EXPECT_EQ(g_call_records, nullptr); g_call_records = g_ptr_array_new_with_free_func(g_object_unref); FlKeyResponder* responder = FL_KEY_RESPONDER( - fl_key_embedder_responder_new(record_calls_in(g_call_records))); + fl_key_embedder_responder_new(record_calls, g_call_records)); int user_data = 123; // Arbitrary user data FlKeyEmbedderCallRecord* record; @@ -1320,7 +1322,7 @@ TEST(FlKeyEmbedderResponderTest, EXPECT_EQ(g_call_records, nullptr); g_call_records = g_ptr_array_new_with_free_func(g_object_unref); FlKeyResponder* responder = FL_KEY_RESPONDER( - fl_key_embedder_responder_new(record_calls_in(g_call_records))); + fl_key_embedder_responder_new(record_calls, g_call_records)); int user_data = 123; // Arbitrary user data FlKeyEmbedderCallRecord* record; @@ -1388,7 +1390,7 @@ TEST(FlKeyEmbedderResponderTest, SynthesizeForDesyncLockModeOnNonSelfEvents) { EXPECT_EQ(g_call_records, nullptr); g_call_records = g_ptr_array_new_with_free_func(g_object_unref); FlKeyResponder* responder = FL_KEY_RESPONDER( - fl_key_embedder_responder_new(record_calls_in(g_call_records))); + fl_key_embedder_responder_new(record_calls, g_call_records)); int user_data = 123; // Arbitrary user data FlKeyEmbedderCallRecord* record; @@ -1496,7 +1498,7 @@ TEST(FlKeyEmbedderResponderTest, SynthesizeForDesyncLockModeOnSelfEvents) { EXPECT_EQ(g_call_records, nullptr); g_call_records = g_ptr_array_new_with_free_func(g_object_unref); FlKeyResponder* responder = FL_KEY_RESPONDER( - fl_key_embedder_responder_new(record_calls_in(g_call_records))); + fl_key_embedder_responder_new(record_calls, g_call_records)); int user_data = 123; // Arbitrary user data FlKeyEmbedderCallRecord* record; @@ -1595,7 +1597,7 @@ TEST(FlKeyEmbedderResponderTest, SynthesizationOccursOnIgnoredEvents) { EXPECT_EQ(g_call_records, nullptr); g_call_records = g_ptr_array_new_with_free_func(g_object_unref); FlKeyResponder* responder = FL_KEY_RESPONDER( - fl_key_embedder_responder_new(record_calls_in(g_call_records))); + fl_key_embedder_responder_new(record_calls, g_call_records)); int user_data = 123; // Arbitrary user data FlKeyEmbedderCallRecord* record; @@ -1648,7 +1650,7 @@ TEST(FlKeyEmbedderResponderTest, HandlesShiftAltVersusGroupNext) { EXPECT_EQ(g_call_records, nullptr); g_call_records = g_ptr_array_new_with_free_func(g_object_unref); FlKeyResponder* responder = FL_KEY_RESPONDER( - fl_key_embedder_responder_new(record_calls_in(g_call_records))); + fl_key_embedder_responder_new(record_calls, g_call_records)); g_expected_handled = true; guint32 now_time = 1; @@ -1746,7 +1748,7 @@ TEST(FlKeyEmbedderResponderTest, HandlesShiftAltLeftIsMetaLeft) { EXPECT_EQ(g_call_records, nullptr); g_call_records = g_ptr_array_new_with_free_func(g_object_unref); FlKeyResponder* responder = FL_KEY_RESPONDER( - fl_key_embedder_responder_new(record_calls_in(g_call_records))); + fl_key_embedder_responder_new(record_calls, g_call_records)); g_expected_handled = true; guint32 now_time = 1; diff --git a/shell/platform/linux/fl_keyboard_manager.cc b/shell/platform/linux/fl_keyboard_manager.cc index 46f70fa2401d2..2d14293560eac 100644 --- a/shell/platform/linux/fl_keyboard_manager.cc +++ b/shell/platform/linux/fl_keyboard_manager.cc @@ -599,12 +599,15 @@ FlKeyboardManager* fl_keyboard_manager_new( g_ptr_array_add( self->responder_list, FL_KEY_RESPONDER(fl_key_embedder_responder_new( - [self](const FlutterKeyEvent* event, FlutterKeyEventCallback callback, - void* user_data) { + [](const FlutterKeyEvent* event, FlutterKeyEventCallback callback, + void* callback_user_data, void* send_key_event_user_data) { + FlKeyboardManager* self = + FL_KEYBOARD_MANAGER(send_key_event_user_data); g_return_if_fail(self->view_delegate != nullptr); - fl_keyboard_view_delegate_send_key_event(self->view_delegate, event, - callback, user_data); - }))); + fl_keyboard_view_delegate_send_key_event( + self->view_delegate, event, callback, callback_user_data); + }, + self))); g_ptr_array_add(self->responder_list, FL_KEY_RESPONDER(fl_key_channel_responder_new( fl_keyboard_view_delegate_get_messenger(view_delegate))));