[Linux, Keyboard] Convert duplicate down events to repeat events (#32261)

diff --git a/shell/platform/linux/fl_key_embedder_responder.cc b/shell/platform/linux/fl_key_embedder_responder.cc
index 14eb6bb..95f9d4a 100644
--- a/shell/platform/linux/fl_key_embedder_responder.cc
+++ b/shell/platform/linux/fl_key_embedder_responder.cc
@@ -752,16 +752,13 @@
   if (is_down_event) {
     if (last_logical_record) {
       // A key has been pressed that has the exact physical key as a currently
-      // pressed one, usually indicating multiple keyboards are pressing keys
-      // with the same physical key, or the up event was lost during a loss of
-      // focus. The down event is ignored.
-      callback(true, user_data);
-      return;
+      // pressed one. This can happen during repeated events.
+      out_event.type = kFlutterKeyEventTypeRepeat;
     } else {
       out_event.type = kFlutterKeyEventTypeDown;
-      character_to_free = event_to_character(event);  // Might be null
-      out_event.character = character_to_free;
     }
+    character_to_free = event_to_character(event);  // Might be null
+    out_event.character = character_to_free;
   } else {  // is_down_event false
     if (!last_logical_record) {
       // The physical key has been released before. It might indicate a missed
diff --git a/shell/platform/linux/fl_key_embedder_responder_test.cc b/shell/platform/linux/fl_key_embedder_responder_test.cc
index 1ff36b2..32eb528 100644
--- a/shell/platform/linux/fl_key_embedder_responder_test.cc
+++ b/shell/platform/linux/fl_key_embedder_responder_test.cc
@@ -953,7 +953,7 @@
   g_object_unref(responder);
 }
 
-TEST(FlKeyEmbedderResponderTest, IgnoreDuplicateDownEvent) {
+TEST(FlKeyEmbedderResponderTest, TurnDuplicateDownEventsToRepeats) {
   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();
@@ -976,24 +976,25 @@
   invoke_record_callback_and_verify(record, TRUE, &user_data);
   g_ptr_array_clear(g_call_records);
 
-  // Press KeyA again (with different logical key, which is not necessari but
-  // for coverage).
-  g_expected_handled = true;  // The empty event is always handled.
+  // Another KeyA down events, which usually means a repeated event.
+  g_expected_handled = false;
   fl_key_responder_handle_event(
       responder,
-      fl_key_event_new_by_mock(102, kPress, GDK_KEY_q, kKeyCodeKeyA, 0,
+      fl_key_event_new_by_mock(102, kPress, GDK_KEY_a, kKeyCodeKeyA, 0,
                                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->physical, 0ull);
-  EXPECT_EQ(record->event->logical, 0ull);
-  EXPECT_STREQ(record->event->character, nullptr);
+  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeRepeat);
+  EXPECT_EQ(record->event->physical, kPhysicalKeyA);
+  EXPECT_EQ(record->event->logical, kLogicalKeyA);
+  EXPECT_STREQ(record->event->character, "a");
   EXPECT_EQ(record->event->synthesized, false);
-  EXPECT_EQ(record->callback, nullptr);
+  EXPECT_NE(record->callback, nullptr);
 
+  invoke_record_callback_and_verify(record, TRUE, &user_data);
   g_ptr_array_clear(g_call_records);
 
   // Release KeyA