mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
[Linux keyboard] Fix logical keys of up events are not regularized (flutter/engine#29550)
This PR fixes a bug where up events from the embedder responder are not using the logical keys of the down events, breaking the regularization
This commit is contained in:
parent
5f9ea0a1a9
commit
d4d9c2aa4d
@ -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 = logical_key;
|
||||
out_event.logical =
|
||||
last_logical_record != 0 ? last_logical_record : logical_key;
|
||||
out_event.character = nullptr;
|
||||
out_event.synthesized = false;
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user