From be848480ea0099e24ad7023c8d73f8259f2a35cd Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Fri, 5 Nov 2021 04:47:09 -0700 Subject: [PATCH 1/2] Impl --- .../linux/fl_key_embedder_responder.cc | 2 +- .../linux/fl_key_embedder_responder_test.cc | 99 +++++++++++++++++++ 2 files changed, 100 insertions(+), 1 deletion(-) diff --git a/shell/platform/linux/fl_key_embedder_responder.cc b/shell/platform/linux/fl_key_embedder_responder.cc index 982273ffb746e..b34ea72677ada 100644 --- a/shell/platform/linux/fl_key_embedder_responder.cc +++ b/shell/platform/linux/fl_key_embedder_responder.cc @@ -714,7 +714,7 @@ static void fl_key_embedder_responder_handle_event_impl( out_event.struct_size = sizeof(out_event); out_event.timestamp = timestamp; out_event.physical = physical_key; - out_event.logical = logical_key; + out_event.logical = last_logical_record != 0 ? last_logical_record : logical_key; out_event.character = nullptr; out_event.synthesized = false; diff --git a/shell/platform/linux/fl_key_embedder_responder_test.cc b/shell/platform/linux/fl_key_embedder_responder_test.cc index 48d2681f0dac3..824f39857d5fe 100644 --- a/shell/platform/linux/fl_key_embedder_responder_test.cc +++ b/shell/platform/linux/fl_key_embedder_responder_test.cc @@ -19,7 +19,9 @@ constexpr gboolean kPress = TRUE; constexpr gboolean kIsModifier = TRUE; constexpr gboolean kIsNotModifier = FALSE; +constexpr guint16 kKeyCodeDigit1 = 0x0au; constexpr guint16 kKeyCodeKeyA = 0x26u; +constexpr guint16 kKeyCodeShiftLeft = 0x32u; constexpr guint16 kKeyCodeShiftRight = 0x3Eu; constexpr guint16 kKeyCodeNumpad1 = 0x57u; constexpr guint16 kKeyCodeNumLock = 0x4Du; @@ -527,6 +529,103 @@ TEST(FlKeyEmbedderResponderTest, TapNumPadKeysBetweenNumLockEvents) { g_object_unref(responder); } +// Press or release digit 1 between presses/releases of Shift. +// +// GTK will change the virtual key during a key tap, and the embedder +// should regularize it. +TEST(FlKeyEmbedderResponderTest, ReleaseShiftKeyBetweenDigitKeyEvents) { + EXPECT_EQ(g_call_records, nullptr); + g_call_records = g_ptr_array_new_with_free_func(g_object_unref); + FlEngine* engine = make_mock_engine_with_records(); + FlKeyResponder* responder = + FL_KEY_RESPONDER(fl_key_embedder_responder_new(engine)); + int user_data = 123; // Arbitrary user data + + FlKeyEmbedderCallRecord* record; + + guint state = 0; + + // Press shift left + fl_key_responder_handle_event( + responder, + fl_key_event_new_by_mock(101, kPress, GDK_KEY_Shift_L, kKeyCodeShiftLeft, state, + kIsModifier), + verify_response_handled, &user_data); + + EXPECT_EQ(g_call_records->len, 1u); + record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 0)); + EXPECT_EQ(record->event->type, kFlutterKeyEventTypeDown); + EXPECT_EQ(record->event->physical, kPhysicalShiftLeft); + EXPECT_EQ(record->event->logical, kLogicalShiftLeft); + EXPECT_STREQ(record->event->character, nullptr); + EXPECT_EQ(record->event->synthesized, false); + + invoke_record_callback_and_verify(record, TRUE, &user_data); + g_ptr_array_clear(g_call_records); + + state = GDK_SHIFT_MASK; + + // Press digit 1, which is '!' on a US keyboard + fl_key_responder_handle_event( + responder, + fl_key_event_new_by_mock(102, kPress, GDK_KEY_exclam, kKeyCodeDigit1, + state, kIsNotModifier), + verify_response_handled, &user_data); + + EXPECT_EQ(g_call_records->len, 1u); + record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 0)); + EXPECT_EQ(record->event->type, kFlutterKeyEventTypeDown); + EXPECT_EQ(record->event->physical, kPhysicalDigit1); + EXPECT_EQ(record->event->logical, kLogicalExclamation); + EXPECT_STREQ(record->event->character, "!"); + EXPECT_EQ(record->event->synthesized, false); + + invoke_record_callback_and_verify(record, TRUE, &user_data); + g_ptr_array_clear(g_call_records); + + // Release shift + fl_key_responder_handle_event( + responder, + fl_key_event_new_by_mock(103, kRelease, GDK_KEY_Shift_L, kKeyCodeShiftLeft, + state, kIsModifier), + verify_response_handled, &user_data); + + EXPECT_EQ(g_call_records->len, 1u); + record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 0)); + EXPECT_EQ(record->event->type, kFlutterKeyEventTypeUp); + EXPECT_EQ(record->event->physical, kPhysicalShiftLeft); + EXPECT_EQ(record->event->logical, kLogicalShiftLeft); + EXPECT_STREQ(record->event->character, nullptr); + EXPECT_EQ(record->event->synthesized, false); + + invoke_record_callback_and_verify(record, TRUE, &user_data); + g_ptr_array_clear(g_call_records); + + state = 0; + + // Release digit 1, which is "1" because shift has been released. + fl_key_responder_handle_event( + responder, + fl_key_event_new_by_mock(104, kRelease, GDK_KEY_1, kKeyCodeDigit1, + state, kIsNotModifier), + verify_response_handled, &user_data); + + EXPECT_EQ(g_call_records->len, 1u); + record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 0)); + EXPECT_EQ(record->event->type, kFlutterKeyEventTypeUp); + EXPECT_EQ(record->event->physical, kPhysicalDigit1); + EXPECT_EQ(record->event->logical, kLogicalExclamation); // Important + EXPECT_STREQ(record->event->character, nullptr); + EXPECT_EQ(record->event->synthesized, false); + + invoke_record_callback_and_verify(record, TRUE, &user_data); + g_ptr_array_clear(g_call_records); + + clear_g_call_records(); + g_object_unref(engine); + g_object_unref(responder); +} + // Press or release letter key between presses/releases of CapsLock. // // This tests interaction between lock keys and non-lock keys in cases that do From 41bfd4ed04532587101c9f3319636eeb88bd46ee Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Fri, 5 Nov 2021 04:49:01 -0700 Subject: [PATCH 2/2] Format --- shell/platform/linux/fl_key_embedder_responder.cc | 3 ++- .../linux/fl_key_embedder_responder_test.cc | 14 +++++++------- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/shell/platform/linux/fl_key_embedder_responder.cc b/shell/platform/linux/fl_key_embedder_responder.cc index b34ea72677ada..cdb46b73cbc35 100644 --- a/shell/platform/linux/fl_key_embedder_responder.cc +++ b/shell/platform/linux/fl_key_embedder_responder.cc @@ -714,7 +714,8 @@ static void fl_key_embedder_responder_handle_event_impl( out_event.struct_size = sizeof(out_event); out_event.timestamp = timestamp; out_event.physical = physical_key; - out_event.logical = last_logical_record != 0 ? last_logical_record : logical_key; + out_event.logical = + last_logical_record != 0 ? last_logical_record : logical_key; out_event.character = nullptr; out_event.synthesized = false; diff --git a/shell/platform/linux/fl_key_embedder_responder_test.cc b/shell/platform/linux/fl_key_embedder_responder_test.cc index 824f39857d5fe..0fae15d0a1275 100644 --- a/shell/platform/linux/fl_key_embedder_responder_test.cc +++ b/shell/platform/linux/fl_key_embedder_responder_test.cc @@ -548,8 +548,8 @@ TEST(FlKeyEmbedderResponderTest, ReleaseShiftKeyBetweenDigitKeyEvents) { // Press shift left fl_key_responder_handle_event( responder, - fl_key_event_new_by_mock(101, kPress, GDK_KEY_Shift_L, kKeyCodeShiftLeft, state, - kIsModifier), + fl_key_event_new_by_mock(101, kPress, GDK_KEY_Shift_L, kKeyCodeShiftLeft, + state, kIsModifier), verify_response_handled, &user_data); EXPECT_EQ(g_call_records->len, 1u); @@ -586,8 +586,8 @@ TEST(FlKeyEmbedderResponderTest, ReleaseShiftKeyBetweenDigitKeyEvents) { // Release shift fl_key_responder_handle_event( responder, - fl_key_event_new_by_mock(103, kRelease, GDK_KEY_Shift_L, kKeyCodeShiftLeft, - state, kIsModifier), + fl_key_event_new_by_mock(103, kRelease, GDK_KEY_Shift_L, + kKeyCodeShiftLeft, state, kIsModifier), verify_response_handled, &user_data); EXPECT_EQ(g_call_records->len, 1u); @@ -606,15 +606,15 @@ TEST(FlKeyEmbedderResponderTest, ReleaseShiftKeyBetweenDigitKeyEvents) { // Release digit 1, which is "1" because shift has been released. fl_key_responder_handle_event( responder, - fl_key_event_new_by_mock(104, kRelease, GDK_KEY_1, kKeyCodeDigit1, - state, kIsNotModifier), + fl_key_event_new_by_mock(104, kRelease, GDK_KEY_1, kKeyCodeDigit1, state, + kIsNotModifier), verify_response_handled, &user_data); EXPECT_EQ(g_call_records->len, 1u); record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 0)); EXPECT_EQ(record->event->type, kFlutterKeyEventTypeUp); EXPECT_EQ(record->event->physical, kPhysicalDigit1); - EXPECT_EQ(record->event->logical, kLogicalExclamation); // Important + EXPECT_EQ(record->event->logical, kLogicalExclamation); // Important EXPECT_STREQ(record->event->character, nullptr); EXPECT_EQ(record->event->synthesized, false);