Flutter Linux Embedder
fl_key_embedder_responder_test.cc File Reference
#include "flutter/shell/platform/linux/fl_key_embedder_responder.h"
#include "gtest/gtest.h"
#include "flutter/shell/platform/embedder/test_utils/key_codes.g.h"
#include "flutter/shell/platform/embedder/test_utils/proc_table_replacement.h"
#include "flutter/shell/platform/linux/fl_binary_messenger_private.h"
#include "flutter/shell/platform/linux/fl_engine_private.h"
#include "flutter/shell/platform/linux/testing/fl_test.h"

Go to the source code of this file.

Classes

struct  _FlKeyEmbedderCallRecord
 

Functions

static void clear_records (GPtrArray *array)
 
 G_DECLARE_FINAL_TYPE (FlKeyEmbedderCallRecord, fl_key_embedder_call_record, FL, KEY_EMBEDDER_CALL_RECORD, GObject)
 
 G_DEFINE_TYPE (FlKeyEmbedderCallRecord, fl_key_embedder_call_record, G_TYPE_OBJECT) static void fl_key_embedder_call_record_init(FlKeyEmbedderCallRecord *self)
 
static void fl_key_embedder_call_record_dispose (GObject *object)
 
static void fl_key_embedder_call_record_class_init (FlKeyEmbedderCallRecordClass *klass)
 
static FlKeyEmbedderCallRecord * fl_key_embedder_call_record_new (const FlutterKeyEvent *event, FlutterKeyEventCallback callback, gpointer user_data)
 
static void verify_response_handled (bool handled, gpointer user_data)
 
static void invoke_record_callback_and_verify (FlKeyEmbedderCallRecord *record, bool expected_handled, void *expected_user_data)
 
static void record_calls (const FlutterKeyEvent *event, FlutterKeyEventCallback callback, void *callback_user_data, void *send_key_event_user_data)
 
 TEST (FlKeyEmbedderResponderTest, SendKeyEvent)
 
 TEST (FlKeyEmbedderResponderTest, UsesSpecifiedLogicalKey)
 
 TEST (FlKeyEmbedderResponderTest, PressShiftDuringLetterKeyTap)
 
 TEST (FlKeyEmbedderResponderTest, TapNumPadKeysBetweenNumLockEvents)
 
 TEST (FlKeyEmbedderResponderTest, ReleaseShiftKeyBetweenDigitKeyEvents)
 
 TEST (FlKeyEmbedderResponderTest, TapLetterKeysBetweenCapsLockEvents)
 
 TEST (FlKeyEmbedderResponderTest, TapLetterKeysBetweenCapsLockEventsReversed)
 
 TEST (FlKeyEmbedderResponderTest, TurnDuplicateDownEventsToRepeats)
 
 TEST (FlKeyEmbedderResponderTest, IgnoreAbruptUpEvent)
 
 TEST (FlKeyEmbedderResponderTest, SynthesizeForDesyncPressingStateOnSelfEvents)
 
 TEST (FlKeyEmbedderResponderTest, SynthesizeForDesyncPressingStateOnNonSelfEvents)
 
 TEST (FlKeyEmbedderResponderTest, SynthesizeForDesyncPressingStateOnRemappedEvents)
 
 TEST (FlKeyEmbedderResponderTest, SynthesizeForDesyncLockModeOnNonSelfEvents)
 
 TEST (FlKeyEmbedderResponderTest, SynthesizeForDesyncLockModeOnSelfEvents)
 
 TEST (FlKeyEmbedderResponderTest, SynthesizationOccursOnIgnoredEvents)
 
 TEST (FlKeyEmbedderResponderTest, HandlesShiftAltVersusGroupNext)
 
 TEST (FlKeyEmbedderResponderTest, HandlesShiftAltLeftIsMetaLeft)
 

Variables

static gboolean g_expected_handled
 
static gpointer g_expected_user_data
 

Function Documentation

◆ clear_records()

static void clear_records ( GPtrArray *  array)
static

Definition at line 34 of file fl_key_embedder_responder_test.cc.

34  {
35  g_ptr_array_remove_range(array, 0, array->len);
36 }

Referenced by TEST().

◆ fl_key_embedder_call_record_class_init()

static void fl_key_embedder_call_record_class_init ( FlKeyEmbedderCallRecordClass *  klass)
static

Definition at line 71 of file fl_key_embedder_responder_test.cc.

72  {
73  G_OBJECT_CLASS(klass)->dispose = fl_key_embedder_call_record_dispose;
74 }

References fl_key_embedder_call_record_dispose().

◆ fl_key_embedder_call_record_dispose()

static void fl_key_embedder_call_record_dispose ( GObject *  object)
static

Definition at line 59 of file fl_key_embedder_responder_test.cc.

59  {
60  g_return_if_fail(FL_IS_KEY_EMBEDDER_CALL_RECORD(object));
61 
62  FlKeyEmbedderCallRecord* self = FL_KEY_EMBEDDER_CALL_RECORD(object);
63  if (self->event != nullptr) {
64  g_free(const_cast<char*>(self->event->character));
65  g_free(self->event);
66  }
67  G_OBJECT_CLASS(fl_key_embedder_call_record_parent_class)->dispose(object);
68 }

Referenced by fl_key_embedder_call_record_class_init().

◆ fl_key_embedder_call_record_new()

static FlKeyEmbedderCallRecord* fl_key_embedder_call_record_new ( const FlutterKeyEvent *  event,
FlutterKeyEventCallback  callback,
gpointer  user_data 
)
static

Definition at line 76 of file fl_key_embedder_responder_test.cc.

79  {
80  g_return_val_if_fail(event != nullptr, nullptr);
81 
82  FlKeyEmbedderCallRecord* self = FL_KEY_EMBEDDER_CALL_RECORD(
83  g_object_new(fl_key_embedder_call_record_get_type(), nullptr));
84 
85  FlutterKeyEvent* clone_event = g_new(FlutterKeyEvent, 1);
86  *clone_event = *event;
87  if (event->character != nullptr) {
88  size_t character_length = strlen(event->character);
89  char* clone_character = g_new(char, character_length + 1);
90  strncpy(clone_character, event->character, character_length + 1);
91  clone_event->character = clone_character;
92  }
93  self->event = clone_event;
94  self->callback = callback;
95  self->user_data = user_data;
96 
97  return self;
98 }

References user_data.

Referenced by record_calls().

◆ G_DECLARE_FINAL_TYPE()

G_DECLARE_FINAL_TYPE ( FlKeyEmbedderCallRecord  ,
fl_key_embedder_call_record  ,
FL  ,
KEY_EMBEDDER_CALL_RECORD  ,
GObject   
)

◆ G_DEFINE_TYPE()

G_DEFINE_TYPE ( FlKeyEmbedderCallRecord  ,
fl_key_embedder_call_record  ,
G_TYPE_OBJECT   
)

Definition at line 52 of file fl_key_embedder_responder_test.cc.

56  {}

◆ invoke_record_callback_and_verify()

static void invoke_record_callback_and_verify ( FlKeyEmbedderCallRecord *  record,
bool  expected_handled,
void *  expected_user_data 
)
static

Definition at line 107 of file fl_key_embedder_responder_test.cc.

109  {
110  g_return_if_fail(record->callback != nullptr);
111  g_expected_handled = expected_handled;
112  g_expected_user_data = expected_user_data;
113  record->callback(expected_handled, record->user_data);
114 }

References g_expected_handled, and g_expected_user_data.

Referenced by TEST().

◆ record_calls()

static void record_calls ( const FlutterKeyEvent *  event,
FlutterKeyEventCallback  callback,
void *  callback_user_data,
void *  send_key_event_user_data 
)
static

Definition at line 116 of file fl_key_embedder_responder_test.cc.

119  {
120  GPtrArray* records_array =
121  reinterpret_cast<GPtrArray*>(send_key_event_user_data);
122  if (records_array != nullptr) {
123  g_ptr_array_add(records_array, fl_key_embedder_call_record_new(
124  event, callback, callback_user_data));
125  }
126 }

References fl_key_embedder_call_record_new().

Referenced by TEST().

◆ TEST() [1/17]

TEST ( FlKeyEmbedderResponderTest  ,
HandlesShiftAltLeftIsMetaLeft   
)

Definition at line 1595 of file fl_key_embedder_responder_test.cc.

1595  {
1596  g_autoptr(GPtrArray) call_records =
1597  g_ptr_array_new_with_free_func(g_object_unref);
1598  g_autoptr(FlKeyEmbedderResponder) responder =
1600 
1601  g_expected_handled = true;
1602  guint32 now_time = 1;
1603  // A convenient shorthand to simulate events.
1604  auto send_key_event = [responder, &now_time](bool is_press, guint keyval,
1605  guint16 keycode,
1606  GdkModifierType state) {
1607  now_time += 1;
1608  int user_data = 123; // Arbitrary user data
1609  g_autoptr(FlKeyEvent) event =
1610  fl_key_event_new(now_time, is_press, keycode, keyval, state, 0);
1611  fl_key_embedder_responder_handle_event(responder, event, 0,
1613  };
1614 
1615  // ShiftLeft + AltLeft
1616  send_key_event(kPress, GDK_KEY_Shift_L, kKeyCodeShiftLeft,
1617  GDK_MODIFIER_RESERVED_25_MASK);
1618  EXPECT_EQ(call_records->len, 1u);
1619  FlKeyEmbedderCallRecord* record =
1620  FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(call_records, 0));
1621  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeDown);
1622  EXPECT_EQ(record->event->physical, kPhysicalShiftLeft);
1623  EXPECT_EQ(record->event->logical, kLogicalShiftLeft);
1624  EXPECT_EQ(record->event->synthesized, false);
1625 
1626  send_key_event(kPress, GDK_KEY_Meta_L, kKeyCodeAltLeft,
1627  static_cast<GdkModifierType>(GDK_SHIFT_MASK |
1628  GDK_MODIFIER_RESERVED_25_MASK));
1629  EXPECT_EQ(call_records->len, 2u);
1630  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(call_records, 1));
1631  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeDown);
1632  EXPECT_EQ(record->event->physical, kPhysicalMetaLeft);
1633  EXPECT_EQ(record->event->logical, kLogicalMetaLeft);
1634  EXPECT_EQ(record->event->synthesized, false);
1635 
1636  send_key_event(kRelease, GDK_KEY_Meta_L, kKeyCodeAltLeft,
1637  static_cast<GdkModifierType>(GDK_MODIFIER_RESERVED_13_MASK |
1638  GDK_MODIFIER_RESERVED_25_MASK));
1639  send_key_event(kRelease, GDK_KEY_Shift_L, kKeyCodeShiftLeft,
1640  GDK_MODIFIER_RESERVED_25_MASK);
1641  clear_records(call_records);
1642 
1643  // ShiftRight + AltLeft
1644  send_key_event(kPress, GDK_KEY_Shift_R, kKeyCodeShiftRight,
1645  GDK_MODIFIER_RESERVED_25_MASK);
1646  EXPECT_EQ(call_records->len, 1u);
1647  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(call_records, 0));
1648  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeDown);
1649  EXPECT_EQ(record->event->physical, kPhysicalShiftRight);
1650  EXPECT_EQ(record->event->logical, kLogicalShiftRight);
1651  EXPECT_EQ(record->event->synthesized, false);
1652 
1653  send_key_event(kPress, GDK_KEY_Meta_L, kKeyCodeAltLeft,
1654  static_cast<GdkModifierType>(GDK_SHIFT_MASK |
1655  GDK_MODIFIER_RESERVED_25_MASK));
1656  EXPECT_EQ(call_records->len, 2u);
1657  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(call_records, 1));
1658  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeDown);
1659  EXPECT_EQ(record->event->physical, kPhysicalMetaLeft);
1660  EXPECT_EQ(record->event->logical, kLogicalMetaLeft);
1661  EXPECT_EQ(record->event->synthesized, false);
1662 }

References clear_records(), fl_key_embedder_responder_handle_event(), fl_key_embedder_responder_new(), fl_key_event_new(), g_expected_handled, record_calls(), send_key_event(), state, user_data, and verify_response_handled().

◆ TEST() [2/17]

TEST ( FlKeyEmbedderResponderTest  ,
HandlesShiftAltVersusGroupNext   
)

Definition at line 1491 of file fl_key_embedder_responder_test.cc.

1491  {
1492  g_autoptr(GPtrArray) call_records =
1493  g_ptr_array_new_with_free_func(g_object_unref);
1494  g_autoptr(FlKeyEmbedderResponder) responder =
1496 
1497  g_expected_handled = true;
1498  guint32 now_time = 1;
1499  // A convenient shorthand to simulate events.
1500  auto send_key_event = [responder, &now_time](bool is_press, guint keyval,
1501  guint16 keycode,
1502  GdkModifierType state) {
1503  now_time += 1;
1504  int user_data = 123; // Arbitrary user data
1505  g_autoptr(FlKeyEvent) event =
1506  fl_key_event_new(now_time, is_press, keycode, keyval, state, 0);
1507  fl_key_embedder_responder_handle_event(responder, event, 0,
1509  };
1510 
1511  send_key_event(kPress, GDK_KEY_Shift_L, kKeyCodeShiftLeft,
1512  GDK_MODIFIER_RESERVED_25_MASK);
1513  EXPECT_EQ(call_records->len, 1u);
1514  FlKeyEmbedderCallRecord* record =
1515  FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(call_records, 0));
1516  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeDown);
1517  EXPECT_EQ(record->event->physical, kPhysicalShiftLeft);
1518  EXPECT_EQ(record->event->logical, kLogicalShiftLeft);
1519  EXPECT_EQ(record->event->synthesized, false);
1520 
1521  send_key_event(kPress, GDK_KEY_Meta_R, kKeyCodeAltRight,
1522  static_cast<GdkModifierType>(GDK_SHIFT_MASK |
1523  GDK_MODIFIER_RESERVED_25_MASK));
1524  EXPECT_EQ(call_records->len, 2u);
1525  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(call_records, 1));
1526  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeDown);
1527  EXPECT_EQ(record->event->physical, kPhysicalAltRight);
1528  EXPECT_EQ(record->event->logical, kLogicalMetaRight);
1529  EXPECT_EQ(record->event->synthesized, false);
1530 
1531  send_key_event(kRelease, GDK_KEY_ISO_Next_Group, kKeyCodeShiftLeft,
1532  static_cast<GdkModifierType>(GDK_SHIFT_MASK | GDK_MOD1_MASK |
1533  GDK_MODIFIER_RESERVED_25_MASK));
1534  EXPECT_EQ(call_records->len, 5u);
1535  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(call_records, 2));
1536  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeDown);
1537  EXPECT_EQ(record->event->physical, kPhysicalAltLeft);
1538  EXPECT_EQ(record->event->logical, kLogicalAltLeft);
1539  EXPECT_EQ(record->event->synthesized, true);
1540 
1541  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(call_records, 3));
1542  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeUp);
1543  EXPECT_EQ(record->event->physical, kPhysicalAltRight);
1544  EXPECT_EQ(record->event->logical, kLogicalMetaRight);
1545  EXPECT_EQ(record->event->synthesized, true);
1546 
1547  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(call_records, 4));
1548  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeUp);
1549  EXPECT_EQ(record->event->physical, kPhysicalShiftLeft);
1550  EXPECT_EQ(record->event->logical, kLogicalShiftLeft);
1551  EXPECT_EQ(record->event->synthesized, false);
1552 
1553  send_key_event(kPress, GDK_KEY_ISO_Next_Group, kKeyCodeShiftLeft,
1554  static_cast<GdkModifierType>(GDK_MOD1_MASK |
1555  GDK_MODIFIER_RESERVED_25_MASK));
1556  EXPECT_EQ(call_records->len, 6u);
1557  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(call_records, 5));
1558  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeDown);
1559  EXPECT_EQ(record->event->physical, kPhysicalShiftLeft);
1560  EXPECT_EQ(record->event->logical, kLogicalGroupNext);
1561  EXPECT_EQ(record->event->synthesized, false);
1562 
1563  send_key_event(kRelease, GDK_KEY_ISO_Level3_Shift, kKeyCodeAltRight,
1564  static_cast<GdkModifierType>(GDK_MOD1_MASK |
1565  GDK_MODIFIER_RESERVED_13_MASK |
1566  GDK_MODIFIER_RESERVED_25_MASK));
1567  EXPECT_EQ(call_records->len, 7u);
1568  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(call_records, 6));
1569  EXPECT_EQ(record->event->physical, 0u);
1570  EXPECT_EQ(record->event->logical, 0u);
1571 
1572  send_key_event(kRelease, GDK_KEY_Shift_L, kKeyCodeShiftLeft,
1573  static_cast<GdkModifierType>(GDK_MODIFIER_RESERVED_13_MASK |
1574  GDK_MODIFIER_RESERVED_25_MASK));
1575  EXPECT_EQ(call_records->len, 9u);
1576  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(call_records, 7));
1577  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeUp);
1578  EXPECT_EQ(record->event->physical, kPhysicalAltLeft);
1579  EXPECT_EQ(record->event->logical, kLogicalAltLeft);
1580  EXPECT_EQ(record->event->synthesized, true);
1581 
1582  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(call_records, 8));
1583  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeUp);
1584  EXPECT_EQ(record->event->physical, kPhysicalShiftLeft);
1585  EXPECT_EQ(record->event->logical, kLogicalGroupNext);
1586  EXPECT_EQ(record->event->synthesized, false);
1587 }

References fl_key_embedder_responder_handle_event(), fl_key_embedder_responder_new(), fl_key_event_new(), g_expected_handled, record_calls(), send_key_event(), state, user_data, and verify_response_handled().

◆ TEST() [3/17]

TEST ( FlKeyEmbedderResponderTest  ,
IgnoreAbruptUpEvent   
)

Definition at line 920 of file fl_key_embedder_responder_test.cc.

920  {
921  g_autoptr(GPtrArray) call_records =
922  g_ptr_array_new_with_free_func(g_object_unref);
923  g_autoptr(FlKeyEmbedderResponder) responder =
925  int user_data = 123; // Arbitrary user data
926 
927  // Release KeyA before it was even pressed.
928  g_expected_handled = true; // The empty event is always handled.
929  g_autoptr(FlKeyEvent) event =
930  fl_key_event_new(103, kRelease, kKeyCodeKeyA, GDK_KEY_q,
931  static_cast<GdkModifierType>(0), 0);
932  fl_key_embedder_responder_handle_event(responder, event, 0,
934 
935  EXPECT_EQ(call_records->len, 1u);
936 
937  FlKeyEmbedderCallRecord* record =
938  FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(call_records, 0));
939  EXPECT_EQ(record->event->physical, 0ull);
940  EXPECT_EQ(record->event->logical, 0ull);
941  EXPECT_STREQ(record->event->character, nullptr);
942  EXPECT_EQ(record->event->synthesized, false);
943  EXPECT_EQ(record->callback, nullptr);
944 }

References fl_key_embedder_responder_handle_event(), fl_key_embedder_responder_new(), fl_key_event_new(), g_expected_handled, record_calls(), user_data, and verify_response_handled().

◆ TEST() [4/17]

TEST ( FlKeyEmbedderResponderTest  ,
PressShiftDuringLetterKeyTap   
)

Definition at line 250 of file fl_key_embedder_responder_test.cc.

250  {
251  g_autoptr(GPtrArray) call_records =
252  g_ptr_array_new_with_free_func(g_object_unref);
253  g_autoptr(FlKeyEmbedderResponder) responder =
255  int user_data = 123; // Arbitrary user data
256 
257  // Press shift right
258  g_autoptr(FlKeyEvent) event1 =
259  fl_key_event_new(101, kPress, kKeyCodeShiftRight, GDK_KEY_Shift_R,
260  static_cast<GdkModifierType>(0), 0);
261  fl_key_embedder_responder_handle_event(responder, event1, 0,
263 
264  EXPECT_EQ(call_records->len, 1u);
265  FlKeyEmbedderCallRecord* record =
266  FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(call_records, 0));
267  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeDown);
268  EXPECT_EQ(record->event->physical, kPhysicalShiftRight);
269  EXPECT_EQ(record->event->logical, kLogicalShiftRight);
270  EXPECT_STREQ(record->event->character, nullptr);
271  EXPECT_EQ(record->event->synthesized, false);
272 
274  clear_records(call_records);
275 
276  // Press key A
277  g_autoptr(FlKeyEvent) event2 =
278  fl_key_event_new(102, kPress, kKeyCodeKeyA, GDK_KEY_A, GDK_SHIFT_MASK, 0);
279  fl_key_embedder_responder_handle_event(responder, event2, 0,
281 
282  EXPECT_EQ(call_records->len, 1u);
283  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(call_records, 0));
284  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeDown);
285  EXPECT_EQ(record->event->physical, kPhysicalKeyA);
286  EXPECT_EQ(record->event->logical, kLogicalKeyA);
287  EXPECT_STREQ(record->event->character, "A");
288  EXPECT_EQ(record->event->synthesized, false);
289 
291  clear_records(call_records);
292 
293  // Release shift right
294  g_autoptr(FlKeyEvent) event3 = fl_key_event_new(
295  103, kRelease, kKeyCodeShiftRight, GDK_KEY_Shift_R, GDK_SHIFT_MASK, 0);
296  fl_key_embedder_responder_handle_event(responder, event3, 0,
298 
299  EXPECT_EQ(call_records->len, 1u);
300  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(call_records, 0));
301  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeUp);
302  EXPECT_EQ(record->event->physical, kPhysicalShiftRight);
303  EXPECT_EQ(record->event->logical, kLogicalShiftRight);
304  EXPECT_STREQ(record->event->character, nullptr);
305  EXPECT_EQ(record->event->synthesized, false);
306 
308  clear_records(call_records);
309 
310  // Release key A
311  g_autoptr(FlKeyEvent) event4 =
312  fl_key_event_new(104, kRelease, kKeyCodeKeyA, GDK_KEY_A,
313  static_cast<GdkModifierType>(0), 0);
314  fl_key_embedder_responder_handle_event(responder, event4, 0,
316 
317  EXPECT_EQ(call_records->len, 1u);
318  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(call_records, 0));
319  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeUp);
320  EXPECT_EQ(record->event->physical, kPhysicalKeyA);
321  EXPECT_EQ(record->event->logical, kLogicalKeyA);
322  EXPECT_STREQ(record->event->character, nullptr);
323  EXPECT_EQ(record->event->synthesized, false);
324 
326 }

References clear_records(), fl_key_embedder_responder_handle_event(), fl_key_embedder_responder_new(), fl_key_event_new(), invoke_record_callback_and_verify(), record_calls(), TRUE, user_data, and verify_response_handled().

◆ TEST() [5/17]

TEST ( FlKeyEmbedderResponderTest  ,
ReleaseShiftKeyBetweenDigitKeyEvents   
)

Definition at line 486 of file fl_key_embedder_responder_test.cc.

486  {
487  g_autoptr(GPtrArray) call_records =
488  g_ptr_array_new_with_free_func(g_object_unref);
489  g_autoptr(FlKeyEmbedderResponder) responder =
491  int user_data = 123; // Arbitrary user data
492 
493  GdkModifierType state = static_cast<GdkModifierType>(0);
494 
495  // Press shift left
496  g_autoptr(FlKeyEvent) event1 = fl_key_event_new(
497  101, kPress, kKeyCodeShiftLeft, GDK_KEY_Shift_L, state, 0);
498  fl_key_embedder_responder_handle_event(responder, event1, 0,
500 
501  EXPECT_EQ(call_records->len, 1u);
502  FlKeyEmbedderCallRecord* record =
503  FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(call_records, 0));
504  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeDown);
505  EXPECT_EQ(record->event->physical, kPhysicalShiftLeft);
506  EXPECT_EQ(record->event->logical, kLogicalShiftLeft);
507  EXPECT_STREQ(record->event->character, nullptr);
508  EXPECT_EQ(record->event->synthesized, false);
509 
511  clear_records(call_records);
512 
513  state = GDK_SHIFT_MASK;
514 
515  // Press digit 1, which is '!' on a US keyboard
516  g_autoptr(FlKeyEvent) event2 =
517  fl_key_event_new(102, kPress, kKeyCodeDigit1, GDK_KEY_exclam, state, 0);
518  fl_key_embedder_responder_handle_event(responder, event2, 0,
520 
521  EXPECT_EQ(call_records->len, 1u);
522  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(call_records, 0));
523  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeDown);
524  EXPECT_EQ(record->event->physical, kPhysicalDigit1);
525  EXPECT_EQ(record->event->logical, kLogicalExclamation);
526  EXPECT_STREQ(record->event->character, "!");
527  EXPECT_EQ(record->event->synthesized, false);
528 
530  clear_records(call_records);
531 
532  // Release shift
533  g_autoptr(FlKeyEvent) event3 = fl_key_event_new(
534  103, kRelease, kKeyCodeShiftLeft, GDK_KEY_Shift_L, state, 0);
535  fl_key_embedder_responder_handle_event(responder, event3, 0,
537 
538  EXPECT_EQ(call_records->len, 1u);
539  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(call_records, 0));
540  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeUp);
541  EXPECT_EQ(record->event->physical, kPhysicalShiftLeft);
542  EXPECT_EQ(record->event->logical, kLogicalShiftLeft);
543  EXPECT_STREQ(record->event->character, nullptr);
544  EXPECT_EQ(record->event->synthesized, false);
545 
547  clear_records(call_records);
548 
549  state = static_cast<GdkModifierType>(0);
550 
551  // Release digit 1, which is "1" because shift has been released.
552  g_autoptr(FlKeyEvent) event4 =
553  fl_key_event_new(104, kRelease, kKeyCodeDigit1, GDK_KEY_1, state, 0);
554  fl_key_embedder_responder_handle_event(responder, event4, 0,
556 
557  EXPECT_EQ(call_records->len, 1u);
558  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(call_records, 0));
559  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeUp);
560  EXPECT_EQ(record->event->physical, kPhysicalDigit1);
561  EXPECT_EQ(record->event->logical, kLogicalExclamation); // Important
562  EXPECT_STREQ(record->event->character, nullptr);
563  EXPECT_EQ(record->event->synthesized, false);
564 
566 }

References clear_records(), fl_key_embedder_responder_handle_event(), fl_key_embedder_responder_new(), fl_key_event_new(), invoke_record_callback_and_verify(), record_calls(), state, TRUE, user_data, and verify_response_handled().

◆ TEST() [6/17]

TEST ( FlKeyEmbedderResponderTest  ,
SendKeyEvent   
)

Definition at line 129 of file fl_key_embedder_responder_test.cc.

129  {
130  g_autoptr(GPtrArray) call_records =
131  g_ptr_array_new_with_free_func(g_object_unref);
132  g_autoptr(FlKeyEmbedderResponder) responder =
134  int user_data = 123; // Arbitrary user data
135 
136  // On a QWERTY keyboard, press key Q (physically key A), and release.
137  // Key down
138  g_autoptr(FlKeyEvent) event1 =
139  fl_key_event_new(12345, kPress, kKeyCodeKeyA, GDK_KEY_a,
140  static_cast<GdkModifierType>(0), 0);
141  fl_key_embedder_responder_handle_event(responder, event1, 0,
143 
144  EXPECT_EQ(call_records->len, 1u);
145  FlKeyEmbedderCallRecord* record =
146  FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(call_records, 0));
147  EXPECT_EQ(record->event->struct_size, sizeof(FlutterKeyEvent));
148  EXPECT_EQ(record->event->timestamp, 12345000);
149  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeDown);
150  EXPECT_EQ(record->event->physical, kPhysicalKeyA);
151  EXPECT_EQ(record->event->logical, kLogicalKeyA);
152  EXPECT_STREQ(record->event->character, "a");
153  EXPECT_EQ(record->event->synthesized, false);
154 
156  clear_records(call_records);
157 
158  // Key up
159  g_autoptr(FlKeyEvent) event2 =
160  fl_key_event_new(12346, kRelease, kKeyCodeKeyA, GDK_KEY_a,
161  static_cast<GdkModifierType>(0), 0);
162  fl_key_embedder_responder_handle_event(responder, event2, 0,
164 
165  EXPECT_EQ(call_records->len, 1u);
166  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(call_records, 0));
167  EXPECT_EQ(record->event->struct_size, sizeof(FlutterKeyEvent));
168  EXPECT_EQ(record->event->timestamp, 12346000);
169  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeUp);
170  EXPECT_EQ(record->event->physical, kPhysicalKeyA);
171  EXPECT_EQ(record->event->logical, kLogicalKeyA);
172  EXPECT_STREQ(record->event->character, nullptr);
173  EXPECT_EQ(record->event->synthesized, false);
174 
176  clear_records(call_records);
177 
178  // On an AZERTY keyboard, press key Q (physically key A), and release.
179  // Key down
180  g_autoptr(FlKeyEvent) event3 =
181  fl_key_event_new(12347, kPress, kKeyCodeKeyA, GDK_KEY_q,
182  static_cast<GdkModifierType>(0), 0);
183  fl_key_embedder_responder_handle_event(responder, event3, 0,
185 
186  EXPECT_EQ(call_records->len, 1u);
187  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(call_records, 0));
188  EXPECT_EQ(record->event->struct_size, sizeof(FlutterKeyEvent));
189  EXPECT_EQ(record->event->timestamp, 12347000);
190  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeDown);
191  EXPECT_EQ(record->event->physical, kPhysicalKeyA);
192  EXPECT_EQ(record->event->logical, kLogicalKeyQ);
193  EXPECT_STREQ(record->event->character, "q");
194  EXPECT_EQ(record->event->synthesized, false);
195 
197  clear_records(call_records);
198 
199  // Key up
200  g_autoptr(FlKeyEvent) event4 =
201  fl_key_event_new(12348, kRelease, kKeyCodeKeyA, GDK_KEY_q,
202  static_cast<GdkModifierType>(0), 0);
203  fl_key_embedder_responder_handle_event(responder, event4, 0,
205 
206  EXPECT_EQ(call_records->len, 1u);
207  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(call_records, 0));
208  EXPECT_EQ(record->event->struct_size, sizeof(FlutterKeyEvent));
209  EXPECT_EQ(record->event->timestamp, 12348000);
210  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeUp);
211  EXPECT_EQ(record->event->physical, kPhysicalKeyA);
212  EXPECT_EQ(record->event->logical, kLogicalKeyQ);
213  EXPECT_STREQ(record->event->character, nullptr);
214  EXPECT_EQ(record->event->synthesized, false);
215 
217 }

References clear_records(), fl_key_embedder_responder_handle_event(), fl_key_embedder_responder_new(), fl_key_event_new(), invoke_record_callback_and_verify(), record_calls(), TRUE, user_data, and verify_response_handled().

◆ TEST() [7/17]

TEST ( FlKeyEmbedderResponderTest  ,
SynthesizationOccursOnIgnoredEvents   
)

Definition at line 1444 of file fl_key_embedder_responder_test.cc.

1444  {
1445  g_autoptr(GPtrArray) call_records =
1446  g_ptr_array_new_with_free_func(g_object_unref);
1447  g_autoptr(FlKeyEmbedderResponder) responder =
1449  int user_data = 123; // Arbitrary user data
1450 
1451  // The NumLock is desynchronized by being enabled, and Control is pressed.
1452  GdkModifierType state =
1453  static_cast<GdkModifierType>(GDK_MOD2_MASK | GDK_CONTROL_MASK);
1454 
1455  // Send a KeyA up event, which will be ignored.
1456  g_expected_handled = true; // The ignored event is always handled.
1457  g_autoptr(FlKeyEvent) event =
1458  fl_key_event_new(101, kRelease, kKeyCodeKeyA, GDK_KEY_a, state, 0);
1459  fl_key_embedder_responder_handle_event(responder, event, 0,
1461 
1462  EXPECT_EQ(call_records->len, 2u);
1463  FlKeyEmbedderCallRecord* record =
1464  FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(call_records, 0));
1465  EXPECT_EQ(record->event->timestamp, 101000);
1466  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeDown);
1467  EXPECT_EQ(record->event->physical, kPhysicalNumLock);
1468  EXPECT_EQ(record->event->logical, kLogicalNumLock);
1469  EXPECT_STREQ(record->event->character, nullptr);
1470  EXPECT_EQ(record->event->synthesized, true);
1471 
1472  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(call_records, 1));
1473  EXPECT_EQ(record->event->timestamp, 101000);
1474  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeDown);
1475  EXPECT_EQ(record->event->physical, kPhysicalControlLeft);
1476  EXPECT_EQ(record->event->logical, kLogicalControlLeft);
1477  EXPECT_STREQ(record->event->character, nullptr);
1478  EXPECT_EQ(record->event->synthesized, true);
1479 }

References fl_key_embedder_responder_handle_event(), fl_key_embedder_responder_new(), fl_key_event_new(), g_expected_handled, record_calls(), state, user_data, and verify_response_handled().

◆ TEST() [8/17]

TEST ( FlKeyEmbedderResponderTest  ,
SynthesizeForDesyncLockModeOnNonSelfEvents   
)

Definition at line 1251 of file fl_key_embedder_responder_test.cc.

1251  {
1252  g_autoptr(GPtrArray) call_records =
1253  g_ptr_array_new_with_free_func(g_object_unref);
1254  g_autoptr(FlKeyEmbedderResponder) responder =
1256  int user_data = 123; // Arbitrary user data
1257 
1258  // The NumLock is desynchronized by being enabled.
1259  GdkModifierType state = GDK_MOD2_MASK;
1260 
1261  // Send a normal event
1262  g_autoptr(FlKeyEvent) event1 =
1263  fl_key_event_new(101, kPress, kKeyCodeKeyA, GDK_KEY_a, state, 0);
1264  fl_key_embedder_responder_handle_event(responder, event1, 0,
1266 
1267  EXPECT_EQ(call_records->len, 2u);
1268  FlKeyEmbedderCallRecord* record =
1269  FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(call_records, 0));
1270  EXPECT_EQ(record->event->timestamp, 101000);
1271  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeDown);
1272  EXPECT_EQ(record->event->physical, kPhysicalNumLock);
1273  EXPECT_EQ(record->event->logical, kLogicalNumLock);
1274  EXPECT_STREQ(record->event->character, nullptr);
1275  EXPECT_EQ(record->event->synthesized, true);
1276 
1277  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(call_records, 1));
1278  EXPECT_EQ(record->event->timestamp, 101000);
1279  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeDown);
1280  EXPECT_EQ(record->event->physical, kPhysicalKeyA);
1281  EXPECT_EQ(record->event->logical, kLogicalKeyA);
1282  EXPECT_STREQ(record->event->character, "a");
1283  EXPECT_EQ(record->event->synthesized, false);
1284 
1286  clear_records(call_records);
1287 
1288  // The NumLock is desynchronized by being disabled.
1289  state = static_cast<GdkModifierType>(0);
1290 
1291  // Release key A
1292  g_autoptr(FlKeyEvent) event2 =
1293  fl_key_event_new(102, kRelease, kKeyCodeKeyA, GDK_KEY_A, state, 0);
1294  fl_key_embedder_responder_handle_event(responder, event2, 0,
1296 
1297  EXPECT_EQ(call_records->len, 4u);
1298  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(call_records, 0));
1299  EXPECT_EQ(record->event->timestamp, 102000);
1300  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeUp);
1301  EXPECT_EQ(record->event->physical, kPhysicalNumLock);
1302  EXPECT_EQ(record->event->logical, kLogicalNumLock);
1303  EXPECT_STREQ(record->event->character, nullptr);
1304  EXPECT_EQ(record->event->synthesized, true);
1305 
1306  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(call_records, 1));
1307  EXPECT_EQ(record->event->timestamp, 102000);
1308  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeDown);
1309  EXPECT_EQ(record->event->physical, kPhysicalNumLock);
1310  EXPECT_EQ(record->event->logical, kLogicalNumLock);
1311  EXPECT_STREQ(record->event->character, nullptr);
1312  EXPECT_EQ(record->event->synthesized, true);
1313 
1314  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(call_records, 2));
1315  EXPECT_EQ(record->event->timestamp, 102000);
1316  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeUp);
1317  EXPECT_EQ(record->event->physical, kPhysicalNumLock);
1318  EXPECT_EQ(record->event->logical, kLogicalNumLock);
1319  EXPECT_STREQ(record->event->character, nullptr);
1320  EXPECT_EQ(record->event->synthesized, true);
1321 
1322  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(call_records, 3));
1323  EXPECT_EQ(record->event->timestamp, 102000);
1324  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeUp);
1325  EXPECT_EQ(record->event->physical, kPhysicalKeyA);
1326  EXPECT_EQ(record->event->logical, kLogicalKeyA);
1327  EXPECT_STREQ(record->event->character, nullptr);
1328  EXPECT_EQ(record->event->synthesized, false);
1329 
1331  clear_records(call_records);
1332 
1333  // Release NumLock. Since the previous event should have synthesized NumLock
1334  // to be released, this should result in only an empty event.
1335  g_expected_handled = true;
1336  g_autoptr(FlKeyEvent) event3 = fl_key_event_new(
1337  103, kRelease, kKeyCodeNumLock, GDK_KEY_Num_Lock, state, 0);
1338  fl_key_embedder_responder_handle_event(responder, event3, 0,
1340 
1341  EXPECT_EQ(call_records->len, 1u);
1342  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(call_records, 0));
1343  EXPECT_EQ(record->event->physical, 0ull);
1344  EXPECT_EQ(record->event->logical, 0ull);
1345  EXPECT_STREQ(record->event->character, nullptr);
1346  EXPECT_EQ(record->event->synthesized, false);
1347  EXPECT_EQ(record->callback, nullptr);
1348 }

References clear_records(), fl_key_embedder_responder_handle_event(), fl_key_embedder_responder_new(), fl_key_event_new(), g_expected_handled, invoke_record_callback_and_verify(), record_calls(), state, TRUE, user_data, and verify_response_handled().

◆ TEST() [9/17]

TEST ( FlKeyEmbedderResponderTest  ,
SynthesizeForDesyncLockModeOnSelfEvents   
)

Definition at line 1352 of file fl_key_embedder_responder_test.cc.

1352  {
1353  g_autoptr(GPtrArray) call_records =
1354  g_ptr_array_new_with_free_func(g_object_unref);
1355  g_autoptr(FlKeyEmbedderResponder) responder =
1357  int user_data = 123; // Arbitrary user data
1358 
1359  // The NumLock is desynchronized by being enabled.
1360  GdkModifierType state = GDK_MOD2_MASK;
1361 
1362  // NumLock down
1363  g_autoptr(FlKeyEvent) event1 = fl_key_event_new(101, kPress, kKeyCodeNumLock,
1364  GDK_KEY_Num_Lock, state, 0);
1365  fl_key_embedder_responder_handle_event(responder, event1, 0,
1367 
1368  EXPECT_EQ(call_records->len, 3u);
1369  FlKeyEmbedderCallRecord* record =
1370  FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(call_records, 0));
1371  EXPECT_EQ(record->event->timestamp, 101000);
1372  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeDown);
1373  EXPECT_EQ(record->event->physical, kPhysicalNumLock);
1374  EXPECT_EQ(record->event->logical, kLogicalNumLock);
1375  EXPECT_STREQ(record->event->character, nullptr);
1376  EXPECT_EQ(record->event->synthesized, true);
1377 
1378  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(call_records, 1));
1379  EXPECT_EQ(record->event->timestamp, 101000);
1380  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeUp);
1381  EXPECT_EQ(record->event->physical, kPhysicalNumLock);
1382  EXPECT_EQ(record->event->logical, kLogicalNumLock);
1383  EXPECT_STREQ(record->event->character, nullptr);
1384  EXPECT_EQ(record->event->synthesized, true);
1385 
1386  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(call_records, 2));
1387  EXPECT_EQ(record->event->timestamp, 101000);
1388  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeDown);
1389  EXPECT_EQ(record->event->physical, kPhysicalNumLock);
1390  EXPECT_EQ(record->event->logical, kLogicalNumLock);
1391  EXPECT_STREQ(record->event->character, nullptr);
1392  EXPECT_EQ(record->event->synthesized, false);
1393 
1395  clear_records(call_records);
1396 
1397  // The NumLock is desynchronized by being enabled in a press event.
1398  state = GDK_MOD2_MASK;
1399 
1400  // NumLock up
1401  g_autoptr(FlKeyEvent) event2 = fl_key_event_new(102, kPress, kKeyCodeNumLock,
1402  GDK_KEY_Num_Lock, state, 0);
1403  fl_key_embedder_responder_handle_event(responder, event2, 0,
1405 
1406  EXPECT_EQ(call_records->len, 4u);
1407  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(call_records, 0));
1408  EXPECT_EQ(record->event->timestamp, 102000);
1409  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeUp);
1410  EXPECT_EQ(record->event->physical, kPhysicalNumLock);
1411  EXPECT_EQ(record->event->logical, kLogicalNumLock);
1412  EXPECT_STREQ(record->event->character, nullptr);
1413  EXPECT_EQ(record->event->synthesized, true);
1414 
1415  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(call_records, 1));
1416  EXPECT_EQ(record->event->timestamp, 102000);
1417  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeDown);
1418  EXPECT_EQ(record->event->physical, kPhysicalNumLock);
1419  EXPECT_EQ(record->event->logical, kLogicalNumLock);
1420  EXPECT_STREQ(record->event->character, nullptr);
1421  EXPECT_EQ(record->event->synthesized, true);
1422 
1423  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(call_records, 2));
1424  EXPECT_EQ(record->event->timestamp, 102000);
1425  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeUp);
1426  EXPECT_EQ(record->event->physical, kPhysicalNumLock);
1427  EXPECT_EQ(record->event->logical, kLogicalNumLock);
1428  EXPECT_STREQ(record->event->character, nullptr);
1429  EXPECT_EQ(record->event->synthesized, true);
1430 
1431  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(call_records, 3));
1432  EXPECT_EQ(record->event->timestamp, 102000);
1433  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeDown);
1434  EXPECT_EQ(record->event->physical, kPhysicalNumLock);
1435  EXPECT_EQ(record->event->logical, kLogicalNumLock);
1436  EXPECT_STREQ(record->event->character, nullptr);
1437  EXPECT_EQ(record->event->synthesized, false);
1438 
1440 }

References clear_records(), fl_key_embedder_responder_handle_event(), fl_key_embedder_responder_new(), fl_key_event_new(), invoke_record_callback_and_verify(), record_calls(), state, TRUE, user_data, and verify_response_handled().

◆ TEST() [10/17]

TEST ( FlKeyEmbedderResponderTest  ,
SynthesizeForDesyncPressingStateOnNonSelfEvents   
)

Definition at line 1067 of file fl_key_embedder_responder_test.cc.

1068  {
1069  g_autoptr(GPtrArray) call_records =
1070  g_ptr_array_new_with_free_func(g_object_unref);
1071  g_autoptr(FlKeyEmbedderResponder) responder =
1073  int user_data = 123; // Arbitrary user data
1074 
1075  // A key down of control left is missed.
1076  GdkModifierType state = GDK_CONTROL_MASK;
1077 
1078  // Send a normal event (KeyA down)
1079  g_autoptr(FlKeyEvent) event1 =
1080  fl_key_event_new(101, kPress, kKeyCodeKeyA, GDK_KEY_a, state, 0);
1081  fl_key_embedder_responder_handle_event(responder, event1, 0,
1083 
1084  EXPECT_EQ(call_records->len, 2u);
1085  FlKeyEmbedderCallRecord* record =
1086  FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(call_records, 0));
1087  EXPECT_EQ(record->event->timestamp, 101000);
1088  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeDown);
1089  EXPECT_EQ(record->event->physical, kPhysicalControlLeft);
1090  EXPECT_EQ(record->event->logical, kLogicalControlLeft);
1091  EXPECT_STREQ(record->event->character, nullptr);
1092  EXPECT_EQ(record->event->synthesized, true);
1093 
1094  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(call_records, 1));
1095  EXPECT_EQ(record->event->timestamp, 101000);
1096  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeDown);
1097  EXPECT_EQ(record->event->physical, kPhysicalKeyA);
1098  EXPECT_EQ(record->event->logical, kLogicalKeyA);
1099  EXPECT_STREQ(record->event->character, "a");
1100  EXPECT_EQ(record->event->synthesized, false);
1101 
1103  clear_records(call_records);
1104 
1105  // A key up of control left is missed.
1106  state = static_cast<GdkModifierType>(0);
1107 
1108  // Send a normal event (KeyA up)
1109  g_autoptr(FlKeyEvent) event2 =
1110  fl_key_event_new(102, kRelease, kKeyCodeKeyA, GDK_KEY_A, state, 0);
1111  fl_key_embedder_responder_handle_event(responder, event2, 0,
1113 
1114  EXPECT_EQ(call_records->len, 2u);
1115  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(call_records, 0));
1116  EXPECT_EQ(record->event->timestamp, 102000);
1117  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeUp);
1118  EXPECT_EQ(record->event->physical, kPhysicalControlLeft);
1119  EXPECT_EQ(record->event->logical, kLogicalControlLeft);
1120  EXPECT_STREQ(record->event->character, nullptr);
1121  EXPECT_EQ(record->event->synthesized, true);
1122 
1123  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(call_records, 1));
1124  EXPECT_EQ(record->event->timestamp, 102000);
1125  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeUp);
1126  EXPECT_EQ(record->event->physical, kPhysicalKeyA);
1127  EXPECT_EQ(record->event->logical, kLogicalKeyA);
1128  EXPECT_STREQ(record->event->character, nullptr);
1129  EXPECT_EQ(record->event->synthesized, false);
1130 
1132  clear_records(call_records);
1133 
1134  // Test non-default key mapping.
1135 
1136  // Press a key with physical CapsLock and logical ControlLeft.
1137  state = static_cast<GdkModifierType>(0);
1138 
1139  g_autoptr(FlKeyEvent) event3 = fl_key_event_new(101, kPress, kKeyCodeCapsLock,
1140  GDK_KEY_Control_L, state, 0);
1141  fl_key_embedder_responder_handle_event(responder, event3, 0,
1143 
1144  EXPECT_EQ(call_records->len, 1u);
1145  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(call_records, 0));
1146  EXPECT_EQ(record->event->timestamp, 101000);
1147  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeDown);
1148  EXPECT_EQ(record->event->physical, kPhysicalCapsLock);
1149  EXPECT_EQ(record->event->logical, kLogicalControlLeft);
1150  EXPECT_STREQ(record->event->character, nullptr);
1151  EXPECT_EQ(record->event->synthesized, false);
1152 
1154  clear_records(call_records);
1155 
1156  // The key up of the control left press is missed.
1157  state = static_cast<GdkModifierType>(0);
1158 
1159  // Send a normal event (KeyA down).
1160  g_autoptr(FlKeyEvent) event4 =
1161  fl_key_event_new(102, kPress, kKeyCodeKeyA, GDK_KEY_A, state, 0);
1162  fl_key_embedder_responder_handle_event(responder, event4, 0,
1164 
1165  // The synthesized event should have physical CapsLock and logical
1166  // ControlLeft.
1167  EXPECT_EQ(call_records->len, 2u);
1168  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(call_records, 0));
1169  EXPECT_EQ(record->event->timestamp, 102000);
1170  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeUp);
1171  EXPECT_EQ(record->event->physical, kPhysicalCapsLock);
1172  EXPECT_EQ(record->event->logical, kLogicalControlLeft);
1173  EXPECT_STREQ(record->event->character, nullptr);
1174  EXPECT_EQ(record->event->synthesized, true);
1175 
1176  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(call_records, 1));
1177  EXPECT_EQ(record->event->timestamp, 102000);
1178  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeDown);
1179  EXPECT_EQ(record->event->physical, kPhysicalKeyA);
1180  EXPECT_EQ(record->event->logical, kLogicalKeyA);
1181  EXPECT_STREQ(record->event->character, "A");
1182  EXPECT_EQ(record->event->synthesized, false);
1183 
1185 }

References clear_records(), fl_key_embedder_responder_handle_event(), fl_key_embedder_responder_new(), fl_key_event_new(), invoke_record_callback_and_verify(), record_calls(), state, TRUE, user_data, and verify_response_handled().

◆ TEST() [11/17]

TEST ( FlKeyEmbedderResponderTest  ,
SynthesizeForDesyncPressingStateOnRemappedEvents   
)

Definition at line 1189 of file fl_key_embedder_responder_test.cc.

1190  {
1191  g_autoptr(GPtrArray) call_records =
1192  g_ptr_array_new_with_free_func(g_object_unref);
1193  g_autoptr(FlKeyEmbedderResponder) responder =
1195  int user_data = 123; // Arbitrary user data
1196 
1197  // Press a key with physical CapsLock and logical ControlLeft.
1198  GdkModifierType state = static_cast<GdkModifierType>(0);
1199 
1200  g_autoptr(FlKeyEvent) event1 = fl_key_event_new(101, kPress, kKeyCodeCapsLock,
1201  GDK_KEY_Control_L, state, 0);
1202  fl_key_embedder_responder_handle_event(responder, event1, 0,
1204 
1205  EXPECT_EQ(call_records->len, 1u);
1206  FlKeyEmbedderCallRecord* record =
1207  FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(call_records, 0));
1208  EXPECT_EQ(record->event->timestamp, 101000);
1209  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeDown);
1210  EXPECT_EQ(record->event->physical, kPhysicalCapsLock);
1211  EXPECT_EQ(record->event->logical, kLogicalControlLeft);
1212  EXPECT_STREQ(record->event->character, nullptr);
1213  EXPECT_EQ(record->event->synthesized, false);
1214 
1216  clear_records(call_records);
1217 
1218  // The key up of the control left press is missed.
1219  state = static_cast<GdkModifierType>(0);
1220 
1221  // Send a normal event (KeyA down).
1222  g_autoptr(FlKeyEvent) event2 =
1223  fl_key_event_new(102, kPress, kKeyCodeKeyA, GDK_KEY_A, state, 0);
1224  fl_key_embedder_responder_handle_event(responder, event2, 0,
1226 
1227  // The synthesized event should have physical CapsLock and logical
1228  // ControlLeft.
1229  EXPECT_EQ(call_records->len, 2u);
1230  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(call_records, 0));
1231  EXPECT_EQ(record->event->timestamp, 102000);
1232  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeUp);
1233  EXPECT_EQ(record->event->physical, kPhysicalCapsLock);
1234  EXPECT_EQ(record->event->logical, kLogicalControlLeft);
1235  EXPECT_STREQ(record->event->character, nullptr);
1236  EXPECT_EQ(record->event->synthesized, true);
1237 
1238  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(call_records, 1));
1239  EXPECT_EQ(record->event->timestamp, 102000);
1240  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeDown);
1241  EXPECT_EQ(record->event->physical, kPhysicalKeyA);
1242  EXPECT_EQ(record->event->logical, kLogicalKeyA);
1243  EXPECT_STREQ(record->event->character, "A");
1244  EXPECT_EQ(record->event->synthesized, false);
1245 
1247 }

References clear_records(), fl_key_embedder_responder_handle_event(), fl_key_embedder_responder_new(), fl_key_event_new(), invoke_record_callback_and_verify(), record_calls(), state, TRUE, user_data, and verify_response_handled().

◆ TEST() [12/17]

TEST ( FlKeyEmbedderResponderTest  ,
SynthesizeForDesyncPressingStateOnSelfEvents   
)

Definition at line 948 of file fl_key_embedder_responder_test.cc.

948  {
949  g_autoptr(GPtrArray) call_records =
950  g_ptr_array_new_with_free_func(g_object_unref);
951  g_autoptr(FlKeyEmbedderResponder) responder =
953  int user_data = 123; // Arbitrary user data
954 
955  // Test 1: synthesize key down.
956 
957  // A key down of control left is missed.
958  GdkModifierType state = GDK_CONTROL_MASK;
959 
960  // Send a ControlLeft up
961  g_autoptr(FlKeyEvent) event1 = fl_key_event_new(
962  101, kRelease, kKeyCodeControlLeft, GDK_KEY_Control_L, state, 0);
963  fl_key_embedder_responder_handle_event(responder, event1, 0,
965 
966  EXPECT_EQ(call_records->len, 2u);
967  FlKeyEmbedderCallRecord* record =
968  FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(call_records, 0));
969  EXPECT_EQ(record->event->timestamp, 101000);
970  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeDown);
971  EXPECT_EQ(record->event->physical, kPhysicalControlLeft);
972  EXPECT_EQ(record->event->logical, kLogicalControlLeft);
973  EXPECT_STREQ(record->event->character, nullptr);
974  EXPECT_EQ(record->event->synthesized, true);
975 
976  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(call_records, 1));
977  EXPECT_EQ(record->event->timestamp, 101000);
978  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeUp);
979  EXPECT_EQ(record->event->physical, kPhysicalControlLeft);
980  EXPECT_EQ(record->event->logical, kLogicalControlLeft);
981  EXPECT_STREQ(record->event->character, nullptr);
982  EXPECT_EQ(record->event->synthesized, false);
983 
985  clear_records(call_records);
986 
987  // Test 2: synthesize key up.
988 
989  // Send a ControlLeft down.
990  state = static_cast<GdkModifierType>(0);
991  g_autoptr(FlKeyEvent) event2 = fl_key_event_new(
992  102, kPress, kKeyCodeControlLeft, GDK_KEY_Control_L, state, 0);
993  fl_key_embedder_responder_handle_event(responder, event2, 0,
995  EXPECT_EQ(call_records->len, 1u);
996  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(call_records, 0));
998  clear_records(call_records);
999 
1000  // A key up of control left is missed.
1001  state = static_cast<GdkModifierType>(0);
1002 
1003  // Send another ControlLeft down
1004  g_autoptr(FlKeyEvent) event3 = fl_key_event_new(
1005  103, kPress, kKeyCodeControlLeft, GDK_KEY_Control_L, state, 0);
1006  fl_key_embedder_responder_handle_event(responder, event3, 0,
1008 
1009  EXPECT_EQ(call_records->len, 2u);
1010  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(call_records, 0));
1011  EXPECT_EQ(record->event->timestamp, 103000);
1012  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeUp);
1013  EXPECT_EQ(record->event->physical, kPhysicalControlLeft);
1014  EXPECT_EQ(record->event->logical, kLogicalControlLeft);
1015  EXPECT_STREQ(record->event->character, nullptr);
1016  EXPECT_EQ(record->event->synthesized, true);
1017 
1018  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(call_records, 1));
1019  EXPECT_EQ(record->event->timestamp, 103000);
1020  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeDown);
1021  EXPECT_EQ(record->event->physical, kPhysicalControlLeft);
1022  EXPECT_EQ(record->event->logical, kLogicalControlLeft);
1023  EXPECT_STREQ(record->event->character, nullptr);
1024  EXPECT_EQ(record->event->synthesized, false);
1025 
1027  clear_records(call_records);
1028 
1029  // Send a ControlLeft up to clear up state.
1030  state = GDK_CONTROL_MASK;
1031  g_autoptr(FlKeyEvent) event4 = fl_key_event_new(
1032  104, kRelease, kKeyCodeControlLeft, GDK_KEY_Control_L, state, 0);
1033  fl_key_embedder_responder_handle_event(responder, event4, 0,
1035  EXPECT_EQ(call_records->len, 1u);
1036  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(call_records, 0));
1038  clear_records(call_records);
1039 
1040  // Test 3: synthesize by right modifier.
1041 
1042  // A key down of control right is missed.
1043  state = GDK_CONTROL_MASK;
1044 
1045  // Send a ControlRight up.
1046  g_autoptr(FlKeyEvent) event5 = fl_key_event_new(
1047  105, kRelease, kKeyCodeControlRight, GDK_KEY_Control_R, state, 0);
1048  fl_key_embedder_responder_handle_event(responder, event5, 0,
1050 
1051  // A ControlLeft down is synthesized, with an empty event.
1052  // Reason: The ControlLeft down is synthesized to synchronize the state
1053  // showing Control as pressed. The ControlRight event is ignored because
1054  // the event is considered a duplicate up event.
1055  EXPECT_EQ(call_records->len, 1u);
1056  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(call_records, 0));
1057  EXPECT_EQ(record->event->timestamp, 105000);
1058  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeDown);
1059  EXPECT_EQ(record->event->physical, kPhysicalControlLeft);
1060  EXPECT_EQ(record->event->logical, kLogicalControlLeft);
1061  EXPECT_STREQ(record->event->character, nullptr);
1062  EXPECT_EQ(record->event->synthesized, true);
1063 }

References clear_records(), fl_key_embedder_responder_handle_event(), fl_key_embedder_responder_new(), fl_key_event_new(), invoke_record_callback_and_verify(), record_calls(), state, TRUE, user_data, and verify_response_handled().

◆ TEST() [13/17]

TEST ( FlKeyEmbedderResponderTest  ,
TapLetterKeysBetweenCapsLockEvents   
)

Definition at line 572 of file fl_key_embedder_responder_test.cc.

572  {
573  g_autoptr(GPtrArray) call_records =
574  g_ptr_array_new_with_free_func(g_object_unref);
575  g_autoptr(FlKeyEmbedderResponder) responder =
577  int user_data = 123; // Arbitrary user data
578 
579  // Press CapsLock (stage 0 -> 1)
580  g_autoptr(FlKeyEvent) event1 =
581  fl_key_event_new(101, kPress, kKeyCodeCapsLock, GDK_KEY_Caps_Lock,
582  static_cast<GdkModifierType>(0), 0);
583  fl_key_embedder_responder_handle_event(responder, event1, 0,
585 
586  EXPECT_EQ(call_records->len, 1u);
587  FlKeyEmbedderCallRecord* record =
588  FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(call_records, 0));
589  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeDown);
590  EXPECT_EQ(record->event->physical, kPhysicalCapsLock);
591  EXPECT_EQ(record->event->logical, kLogicalCapsLock);
592  EXPECT_STREQ(record->event->character, nullptr);
593  EXPECT_EQ(record->event->synthesized, false);
594 
596  clear_records(call_records);
597 
598  // Press key A (stage 1)
599  g_autoptr(FlKeyEvent) event2 =
600  fl_key_event_new(102, kPress, kKeyCodeKeyA, GDK_KEY_A, GDK_LOCK_MASK, 0);
601  fl_key_embedder_responder_handle_event(responder, event2, 0,
603 
604  EXPECT_EQ(call_records->len, 1u);
605  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(call_records, 0));
606  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeDown);
607  EXPECT_EQ(record->event->physical, kPhysicalKeyA);
608  EXPECT_EQ(record->event->logical, kLogicalKeyA);
609  EXPECT_STREQ(record->event->character, "A");
610  EXPECT_EQ(record->event->synthesized, false);
611 
613  clear_records(call_records);
614 
615  // Release CapsLock (stage 1 -> 2)
616  g_autoptr(FlKeyEvent) event3 = fl_key_event_new(
617  103, kRelease, kKeyCodeCapsLock, GDK_KEY_Caps_Lock, GDK_LOCK_MASK, 0);
618  fl_key_embedder_responder_handle_event(responder, event3, 0,
620 
621  EXPECT_EQ(call_records->len, 1u);
622  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(call_records, 0));
623  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeUp);
624  EXPECT_EQ(record->event->physical, kPhysicalCapsLock);
625  EXPECT_EQ(record->event->logical, kLogicalCapsLock);
626  EXPECT_STREQ(record->event->character, nullptr);
627  EXPECT_EQ(record->event->synthesized, false);
628 
630  clear_records(call_records);
631 
632  // Release key A (stage 2)
633  g_autoptr(FlKeyEvent) event4 = fl_key_event_new(104, kRelease, kKeyCodeKeyA,
634  GDK_KEY_A, GDK_LOCK_MASK, 0);
635  fl_key_embedder_responder_handle_event(responder, event4, 0,
637 
638  EXPECT_EQ(call_records->len, 1u);
639  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(call_records, 0));
640  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeUp);
641  EXPECT_EQ(record->event->physical, kPhysicalKeyA);
642  EXPECT_EQ(record->event->logical, kLogicalKeyA);
643  EXPECT_STREQ(record->event->character, nullptr);
644  EXPECT_EQ(record->event->synthesized, false);
645 
647  clear_records(call_records);
648 
649  // Press CapsLock (stage 2 -> 3)
650  g_autoptr(FlKeyEvent) event5 = fl_key_event_new(
651  105, kPress, kKeyCodeCapsLock, GDK_KEY_Caps_Lock, GDK_LOCK_MASK, 0);
652  fl_key_embedder_responder_handle_event(responder, event5, 0,
654 
655  EXPECT_EQ(call_records->len, 1u);
656  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(call_records, 0));
657  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeDown);
658  EXPECT_EQ(record->event->physical, kPhysicalCapsLock);
659  EXPECT_EQ(record->event->logical, kLogicalCapsLock);
660  EXPECT_STREQ(record->event->character, nullptr);
661  EXPECT_EQ(record->event->synthesized, false);
662 
664  clear_records(call_records);
665 
666  // Press key A (stage 3)
667  g_autoptr(FlKeyEvent) event6 =
668  fl_key_event_new(106, kPress, kKeyCodeKeyA, GDK_KEY_A, GDK_LOCK_MASK, 0);
669  fl_key_embedder_responder_handle_event(responder, event6, 0,
671 
672  EXPECT_EQ(call_records->len, 1u);
673  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(call_records, 0));
674  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeDown);
675  EXPECT_EQ(record->event->physical, kPhysicalKeyA);
676  EXPECT_EQ(record->event->logical, kLogicalKeyA);
677  EXPECT_STREQ(record->event->character, "A");
678  EXPECT_EQ(record->event->synthesized, false);
679 
681  clear_records(call_records);
682 
683  // Release CapsLock (stage 3 -> 0)
684  g_autoptr(FlKeyEvent) event7 = fl_key_event_new(
685  107, kRelease, kKeyCodeCapsLock, GDK_KEY_Caps_Lock, GDK_LOCK_MASK, 0);
686  fl_key_embedder_responder_handle_event(responder, event7, 0,
688 
689  EXPECT_EQ(call_records->len, 1u);
690  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(call_records, 0));
691  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeUp);
692  EXPECT_EQ(record->event->physical, kPhysicalCapsLock);
693  EXPECT_EQ(record->event->logical, kLogicalCapsLock);
694  EXPECT_STREQ(record->event->character, nullptr);
695  EXPECT_EQ(record->event->synthesized, false);
696 
698  clear_records(call_records);
699 
700  // Release key A (stage 0)
701  g_autoptr(FlKeyEvent) event8 =
702  fl_key_event_new(108, kRelease, kKeyCodeKeyA, GDK_KEY_a,
703  static_cast<GdkModifierType>(0), 0);
704  fl_key_embedder_responder_handle_event(responder, event8, 0,
706 
707  EXPECT_EQ(call_records->len, 1u);
708  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(call_records, 0));
709  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeUp);
710  EXPECT_EQ(record->event->physical, kPhysicalKeyA);
711  EXPECT_EQ(record->event->logical, kLogicalKeyA);
712  EXPECT_STREQ(record->event->character, nullptr);
713  EXPECT_EQ(record->event->synthesized, false);
714 
716 }

References clear_records(), fl_key_embedder_responder_handle_event(), fl_key_embedder_responder_new(), fl_key_event_new(), invoke_record_callback_and_verify(), record_calls(), TRUE, user_data, and verify_response_handled().

◆ TEST() [14/17]

TEST ( FlKeyEmbedderResponderTest  ,
TapLetterKeysBetweenCapsLockEventsReversed   
)

Definition at line 722 of file fl_key_embedder_responder_test.cc.

722  {
723  g_autoptr(GPtrArray) call_records =
724  g_ptr_array_new_with_free_func(g_object_unref);
725  g_autoptr(FlKeyEmbedderResponder) responder =
727  int user_data = 123; // Arbitrary user data
728 
729  // Press key A (stage 0)
730  g_autoptr(FlKeyEvent) event1 = fl_key_event_new(
731  101, kPress, kKeyCodeKeyA, GDK_KEY_a, static_cast<GdkModifierType>(0), 0);
732  fl_key_embedder_responder_handle_event(responder, event1, 0,
734 
735  EXPECT_EQ(call_records->len, 1u);
736  FlKeyEmbedderCallRecord* record =
737  FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(call_records, 0));
738  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeDown);
739  EXPECT_EQ(record->event->physical, kPhysicalKeyA);
740  EXPECT_EQ(record->event->logical, kLogicalKeyA);
741  EXPECT_STREQ(record->event->character, "a");
742  EXPECT_EQ(record->event->synthesized, false);
743 
745  clear_records(call_records);
746 
747  // Press CapsLock (stage 0 -> 1)
748  g_autoptr(FlKeyEvent) event2 = fl_key_event_new(
749  102, kPress, kKeyCodeCapsLock, GDK_KEY_Caps_Lock, GDK_LOCK_MASK, 0);
750  fl_key_embedder_responder_handle_event(responder, event2, 0,
752 
753  EXPECT_EQ(call_records->len, 1u);
754  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(call_records, 0));
755  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeDown);
756  EXPECT_EQ(record->event->physical, kPhysicalCapsLock);
757  EXPECT_EQ(record->event->logical, kLogicalCapsLock);
758  EXPECT_STREQ(record->event->character, nullptr);
759  EXPECT_EQ(record->event->synthesized, false);
760 
762  clear_records(call_records);
763 
764  // Release CapsLock (stage 1 -> 2)
765  g_autoptr(FlKeyEvent) event3 = fl_key_event_new(
766  103, kRelease, kKeyCodeCapsLock, GDK_KEY_Caps_Lock, GDK_LOCK_MASK, 0);
767  fl_key_embedder_responder_handle_event(responder, event3, 0,
769 
770  EXPECT_EQ(call_records->len, 1u);
771  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(call_records, 0));
772  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeUp);
773  EXPECT_EQ(record->event->physical, kPhysicalCapsLock);
774  EXPECT_EQ(record->event->logical, kLogicalCapsLock);
775  EXPECT_STREQ(record->event->character, nullptr);
776  EXPECT_EQ(record->event->synthesized, false);
777 
779  clear_records(call_records);
780 
781  // Release key A (stage 2)
782  g_autoptr(FlKeyEvent) event4 = fl_key_event_new(104, kRelease, kKeyCodeKeyA,
783  GDK_KEY_A, GDK_LOCK_MASK, 0);
784  fl_key_embedder_responder_handle_event(responder, event4, 0,
786 
787  EXPECT_EQ(call_records->len, 1u);
788  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(call_records, 0));
789  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeUp);
790  EXPECT_EQ(record->event->physical, kPhysicalKeyA);
791  EXPECT_EQ(record->event->logical, kLogicalKeyA);
792  EXPECT_STREQ(record->event->character, nullptr);
793  EXPECT_EQ(record->event->synthesized, false);
794 
796  clear_records(call_records);
797 
798  // Press key A (stage 2)
799  g_autoptr(FlKeyEvent) event5 =
800  fl_key_event_new(105, kPress, kKeyCodeKeyA, GDK_KEY_A, GDK_LOCK_MASK, 0);
801  fl_key_embedder_responder_handle_event(responder, event5, 0,
803 
804  EXPECT_EQ(call_records->len, 1u);
805  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(call_records, 0));
806  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeDown);
807  EXPECT_EQ(record->event->physical, kPhysicalKeyA);
808  EXPECT_EQ(record->event->logical, kLogicalKeyA);
809  EXPECT_STREQ(record->event->character, "A");
810  EXPECT_EQ(record->event->synthesized, false);
811 
813  clear_records(call_records);
814 
815  // Press CapsLock (stage 2 -> 3)
816  g_autoptr(FlKeyEvent) event6 =
817  fl_key_event_new(106, kPress, kKeyCodeCapsLock, GDK_KEY_Caps_Lock,
818  static_cast<GdkModifierType>(0), 0);
819  fl_key_embedder_responder_handle_event(responder, event6, 0,
821 
822  EXPECT_EQ(call_records->len, 1u);
823  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(call_records, 0));
824  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeDown);
825  EXPECT_EQ(record->event->physical, kPhysicalCapsLock);
826  EXPECT_EQ(record->event->logical, kLogicalCapsLock);
827  EXPECT_STREQ(record->event->character, nullptr);
828  EXPECT_EQ(record->event->synthesized, false);
829 
831  clear_records(call_records);
832 
833  // Release CapsLock (stage 3 -> 0)
834  g_autoptr(FlKeyEvent) event7 = fl_key_event_new(
835  107, kRelease, kKeyCodeCapsLock, GDK_KEY_Caps_Lock, GDK_LOCK_MASK, 0);
836  fl_key_embedder_responder_handle_event(responder, event7, 0,
838 
839  EXPECT_EQ(call_records->len, 1u);
840  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(call_records, 0));
841  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeUp);
842  EXPECT_EQ(record->event->physical, kPhysicalCapsLock);
843  EXPECT_EQ(record->event->logical, kLogicalCapsLock);
844  EXPECT_STREQ(record->event->character, nullptr);
845  EXPECT_EQ(record->event->synthesized, false);
846 
848  clear_records(call_records);
849 
850  // Release key A (stage 0)
851  g_autoptr(FlKeyEvent) event8 =
852  fl_key_event_new(108, kRelease, kKeyCodeKeyA, GDK_KEY_a,
853  static_cast<GdkModifierType>(0), 0);
854  fl_key_embedder_responder_handle_event(responder, event8, 0,
856 
857  EXPECT_EQ(call_records->len, 1u);
858  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(call_records, 0));
859  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeUp);
860  EXPECT_EQ(record->event->physical, kPhysicalKeyA);
861  EXPECT_EQ(record->event->logical, kLogicalKeyA);
862  EXPECT_STREQ(record->event->character, nullptr);
863  EXPECT_EQ(record->event->synthesized, false);
864 
866 }

References clear_records(), fl_key_embedder_responder_handle_event(), fl_key_embedder_responder_new(), fl_key_event_new(), invoke_record_callback_and_verify(), record_calls(), TRUE, user_data, and verify_response_handled().

◆ TEST() [15/17]

TEST ( FlKeyEmbedderResponderTest  ,
TapNumPadKeysBetweenNumLockEvents   
)

Definition at line 336 of file fl_key_embedder_responder_test.cc.

336  {
337  g_autoptr(GPtrArray) call_records =
338  g_ptr_array_new_with_free_func(g_object_unref);
339  g_autoptr(FlKeyEmbedderResponder) responder =
341  int user_data = 123; // Arbitrary user data
342 
343  // Press Numpad 1 (stage 0)
344  g_autoptr(FlKeyEvent) event1 =
345  fl_key_event_new(101, kPress, kKeyCodeNumpad1, GDK_KEY_KP_End,
346  static_cast<GdkModifierType>(0), 0);
347  fl_key_embedder_responder_handle_event(responder, event1, 0,
349 
350  EXPECT_EQ(call_records->len, 1u);
351  FlKeyEmbedderCallRecord* record =
352  FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(call_records, 0));
353  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeDown);
354  EXPECT_EQ(record->event->physical, kPhysicalNumpad1);
355  EXPECT_EQ(record->event->logical, kLogicalNumpad1);
356  EXPECT_STREQ(record->event->character, nullptr); // TODO(chrome-bot):
357  EXPECT_EQ(record->event->synthesized, false);
358 
360  clear_records(call_records);
361 
362  // Press NumLock (stage 0 -> 1)
363  g_autoptr(FlKeyEvent) event2 =
364  fl_key_event_new(102, kPress, kKeyCodeNumLock, GDK_KEY_Num_Lock,
365  static_cast<GdkModifierType>(0), 0);
366  fl_key_embedder_responder_handle_event(responder, event2, 0,
368 
369  EXPECT_EQ(call_records->len, 1u);
370  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(call_records, 0));
371  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeDown);
372  EXPECT_EQ(record->event->physical, kPhysicalNumLock);
373  EXPECT_EQ(record->event->logical, kLogicalNumLock);
374  EXPECT_STREQ(record->event->character, nullptr);
375  EXPECT_EQ(record->event->synthesized, false);
376 
378  clear_records(call_records);
379 
380  // Release numpad 1 (stage 1)
381  g_autoptr(FlKeyEvent) event3 = fl_key_event_new(
382  104, kRelease, kKeyCodeNumpad1, GDK_KEY_KP_1, GDK_MOD2_MASK, 0);
383  fl_key_embedder_responder_handle_event(responder, event3, 0,
385 
386  EXPECT_EQ(call_records->len, 1u);
387  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(call_records, 0));
388  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeUp);
389  EXPECT_EQ(record->event->physical, kPhysicalNumpad1);
390  EXPECT_EQ(record->event->logical, kLogicalNumpad1);
391  EXPECT_STREQ(record->event->character, nullptr);
392  EXPECT_EQ(record->event->synthesized, false);
393 
395  clear_records(call_records);
396 
397  // Release NumLock (stage 1 -> 2)
398  g_autoptr(FlKeyEvent) event4 = fl_key_event_new(
399  103, kRelease, kKeyCodeNumLock, GDK_KEY_Num_Lock, GDK_MOD2_MASK, 0);
400  fl_key_embedder_responder_handle_event(responder, event4, 0,
402 
403  EXPECT_EQ(call_records->len, 1u);
404  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(call_records, 0));
405  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeUp);
406  EXPECT_EQ(record->event->physical, kPhysicalNumLock);
407  EXPECT_EQ(record->event->logical, kLogicalNumLock);
408  EXPECT_STREQ(record->event->character, nullptr);
409  EXPECT_EQ(record->event->synthesized, false);
410 
412  clear_records(call_records);
413 
414  // Press Numpad 1 (stage 2)
415  g_autoptr(FlKeyEvent) event5 = fl_key_event_new(
416  101, kPress, kKeyCodeNumpad1, GDK_KEY_KP_End, GDK_MOD2_MASK, 0);
417  fl_key_embedder_responder_handle_event(responder, event5, 0,
419 
420  EXPECT_EQ(call_records->len, 1u);
421  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(call_records, 0));
422  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeDown);
423  EXPECT_EQ(record->event->physical, kPhysicalNumpad1);
424  EXPECT_EQ(record->event->logical, kLogicalNumpad1);
425  EXPECT_STREQ(record->event->character, nullptr); // TODO(chrome-bot):
426  EXPECT_EQ(record->event->synthesized, false);
427 
429  clear_records(call_records);
430 
431  // Press NumLock (stage 2 -> 3)
432  g_autoptr(FlKeyEvent) event6 = fl_key_event_new(
433  102, kPress, kKeyCodeNumLock, GDK_KEY_Num_Lock, GDK_MOD2_MASK, 0);
434  fl_key_embedder_responder_handle_event(responder, event6, 0,
436 
437  EXPECT_EQ(call_records->len, 1u);
438  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(call_records, 0));
439  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeDown);
440  EXPECT_EQ(record->event->physical, kPhysicalNumLock);
441  EXPECT_EQ(record->event->logical, kLogicalNumLock);
442  EXPECT_STREQ(record->event->character, nullptr);
443  EXPECT_EQ(record->event->synthesized, false);
444 
446  clear_records(call_records);
447 
448  // Release numpad 1 (stage 3)
449  g_autoptr(FlKeyEvent) event7 = fl_key_event_new(
450  104, kRelease, kKeyCodeNumpad1, GDK_KEY_KP_1, GDK_MOD2_MASK, 0);
451  fl_key_embedder_responder_handle_event(responder, event7, 0,
453 
454  EXPECT_EQ(call_records->len, 1u);
455  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(call_records, 0));
456  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeUp);
457  EXPECT_EQ(record->event->physical, kPhysicalNumpad1);
458  EXPECT_EQ(record->event->logical, kLogicalNumpad1);
459  EXPECT_STREQ(record->event->character, nullptr);
460  EXPECT_EQ(record->event->synthesized, false);
461 
463  clear_records(call_records);
464 
465  // Release NumLock (stage 3 -> 0)
466  g_autoptr(FlKeyEvent) event8 = fl_key_event_new(
467  103, kRelease, kKeyCodeNumLock, GDK_KEY_Num_Lock, GDK_MOD2_MASK, 0);
468  fl_key_embedder_responder_handle_event(responder, event8, 0,
470 
471  EXPECT_EQ(call_records->len, 1u);
472  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(call_records, 0));
473  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeUp);
474  EXPECT_EQ(record->event->physical, kPhysicalNumLock);
475  EXPECT_EQ(record->event->logical, kLogicalNumLock);
476  EXPECT_STREQ(record->event->character, nullptr);
477  EXPECT_EQ(record->event->synthesized, false);
478 
480 }

References clear_records(), fl_key_embedder_responder_handle_event(), fl_key_embedder_responder_new(), fl_key_event_new(), invoke_record_callback_and_verify(), record_calls(), TRUE, user_data, and verify_response_handled().

◆ TEST() [16/17]

TEST ( FlKeyEmbedderResponderTest  ,
TurnDuplicateDownEventsToRepeats   
)

Definition at line 868 of file fl_key_embedder_responder_test.cc.

868  {
869  g_autoptr(GPtrArray) call_records =
870  g_ptr_array_new_with_free_func(g_object_unref);
871  g_autoptr(FlKeyEmbedderResponder) responder =
873  int user_data = 123; // Arbitrary user data
874 
875  // Press KeyA
876  g_autoptr(FlKeyEvent) event1 = fl_key_event_new(
877  101, kPress, kKeyCodeKeyA, GDK_KEY_a, static_cast<GdkModifierType>(0), 0);
878  fl_key_embedder_responder_handle_event(responder, event1, 0,
880 
881  EXPECT_EQ(call_records->len, 1u);
882 
883  FlKeyEmbedderCallRecord* record =
884  FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(call_records, 0));
886  clear_records(call_records);
887 
888  // Another KeyA down events, which usually means a repeated event.
889  g_expected_handled = false;
890  g_autoptr(FlKeyEvent) event2 = fl_key_event_new(
891  102, kPress, kKeyCodeKeyA, GDK_KEY_a, static_cast<GdkModifierType>(0), 0);
892  fl_key_embedder_responder_handle_event(responder, event2, 0,
894 
895  EXPECT_EQ(call_records->len, 1u);
896 
897  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(call_records, 0));
898  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeRepeat);
899  EXPECT_EQ(record->event->physical, kPhysicalKeyA);
900  EXPECT_EQ(record->event->logical, kLogicalKeyA);
901  EXPECT_STREQ(record->event->character, "a");
902  EXPECT_EQ(record->event->synthesized, false);
903  EXPECT_NE(record->callback, nullptr);
904 
906  clear_records(call_records);
907 
908  // Release KeyA
909  g_autoptr(FlKeyEvent) event3 =
910  fl_key_event_new(103, kRelease, kKeyCodeKeyA, GDK_KEY_q,
911  static_cast<GdkModifierType>(0), 0);
912  fl_key_embedder_responder_handle_event(responder, event3, 0,
914 
915  EXPECT_EQ(call_records->len, 1u);
916  record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(call_records, 0));
918 }

References clear_records(), fl_key_embedder_responder_handle_event(), fl_key_embedder_responder_new(), fl_key_event_new(), g_expected_handled, invoke_record_callback_and_verify(), record_calls(), TRUE, user_data, and verify_response_handled().

◆ TEST() [17/17]

TEST ( FlKeyEmbedderResponderTest  ,
UsesSpecifiedLogicalKey   
)

Definition at line 220 of file fl_key_embedder_responder_test.cc.

220  {
221  g_autoptr(GPtrArray) call_records =
222  g_ptr_array_new_with_free_func(g_object_unref);
223  g_autoptr(FlKeyEmbedderResponder) responder =
225  int user_data = 123; // Arbitrary user data
226 
227  // On an AZERTY keyboard, press physical key 1, and release.
228  // Key down
229  g_autoptr(FlKeyEvent) event =
230  fl_key_event_new(12345, kPress, kKeyCodeDigit1, GDK_KEY_ampersand,
231  static_cast<GdkModifierType>(0), 0);
232  fl_key_embedder_responder_handle_event(responder, event, kLogicalDigit1,
234 
235  EXPECT_EQ(call_records->len, 1u);
236  FlKeyEmbedderCallRecord* record =
237  FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(call_records, 0));
238  EXPECT_EQ(record->event->struct_size, sizeof(FlutterKeyEvent));
239  EXPECT_EQ(record->event->timestamp, 12345000);
240  EXPECT_EQ(record->event->type, kFlutterKeyEventTypeDown);
241  EXPECT_EQ(record->event->physical, kPhysicalDigit1);
242  EXPECT_EQ(record->event->logical, kLogicalDigit1);
243  EXPECT_STREQ(record->event->character, "&");
244  EXPECT_EQ(record->event->synthesized, false);
245 
247 }

References fl_key_embedder_responder_handle_event(), fl_key_embedder_responder_new(), fl_key_event_new(), invoke_record_callback_and_verify(), record_calls(), TRUE, user_data, and verify_response_handled().

◆ verify_response_handled()

static void verify_response_handled ( bool  handled,
gpointer  user_data 
)
static

Definition at line 103 of file fl_key_embedder_responder_test.cc.

103  {
104  EXPECT_EQ(handled, g_expected_handled);
105 }

References g_expected_handled.

Referenced by TEST().

Variable Documentation

◆ g_expected_handled

gboolean g_expected_handled
static

◆ g_expected_user_data

gpointer g_expected_user_data
static
fl_key_embedder_responder_handle_event
void fl_key_embedder_responder_handle_event(FlKeyEmbedderResponder *self, FlKeyEvent *event, uint64_t specified_logical_key, FlKeyEmbedderResponderAsyncCallback callback, gpointer user_data)
Definition: fl_key_embedder_responder.cc:835
state
AtkStateType state
Definition: fl_accessible_node.cc:10
user_data
G_BEGIN_DECLS G_MODULE_EXPORT FlValue gpointer user_data
Definition: fl_event_channel.h:90
record_calls
static void record_calls(const FlutterKeyEvent *event, FlutterKeyEventCallback callback, void *callback_user_data, void *send_key_event_user_data)
Definition: fl_key_embedder_responder_test.cc:116
fl_key_embedder_responder_new
FlKeyEmbedderResponder * fl_key_embedder_responder_new(EmbedderSendKeyEvent send_key_event, void *send_key_event_user_data)
Definition: fl_key_embedder_responder.cc:237
TRUE
return TRUE
Definition: fl_pixel_buffer_texture_test.cc:53
fl_key_embedder_call_record_dispose
static void fl_key_embedder_call_record_dispose(GObject *object)
Definition: fl_key_embedder_responder_test.cc:59
clear_records
static void clear_records(GPtrArray *array)
Definition: fl_key_embedder_responder_test.cc:34
fl_key_embedder_call_record_new
static FlKeyEmbedderCallRecord * fl_key_embedder_call_record_new(const FlutterKeyEvent *event, FlutterKeyEventCallback callback, gpointer user_data)
Definition: fl_key_embedder_responder_test.cc:76
send_key_event
static void send_key_event(FlTextInputHandler *handler, gint keyval, gint state=0)
Definition: fl_text_input_handler_test.cc:144
g_expected_handled
static gboolean g_expected_handled
Definition: fl_key_embedder_responder_test.cc:100
invoke_record_callback_and_verify
static void invoke_record_callback_and_verify(FlKeyEmbedderCallRecord *record, bool expected_handled, void *expected_user_data)
Definition: fl_key_embedder_responder_test.cc:107
g_expected_user_data
static gpointer g_expected_user_data
Definition: fl_key_embedder_responder_test.cc:101
verify_response_handled
static void verify_response_handled(bool handled, gpointer user_data)
Definition: fl_key_embedder_responder_test.cc:103
fl_key_event_new
FlKeyEvent * fl_key_event_new(guint32 time, gboolean is_press, guint16 keycode, guint keyval, GdkModifierType state, guint8 group)
Definition: fl_key_event.cc:34