Flutter Engine
The Flutter Engine
Classes | Functions | Variables
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 g_ptr_array_clear (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 FlKeyEventfl_key_event_new_by_mock (guint32 time_in_milliseconds, bool is_press, guint keyval, guint16 keycode, GdkModifierType state, gboolean is_modifier)
 
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)
 
static void clear_g_call_records ()
 
 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_g_call_records()

static void clear_g_call_records ( )
static

Definition at line 162 of file fl_key_embedder_responder_test.cc.

162 {
163 g_ptr_array_free(g_call_records, TRUE);
164 g_call_records = nullptr;
165}

◆ fl_key_embedder_call_record_class_init()

static void fl_key_embedder_call_record_class_init ( FlKeyEmbedderCallRecordClass *  klass)
static

Definition at line 74 of file fl_key_embedder_responder_test.cc.

75 {
76 G_OBJECT_CLASS(klass)->dispose = fl_key_embedder_call_record_dispose;
77}
static void fl_key_embedder_call_record_dispose(GObject *object)

◆ fl_key_embedder_call_record_dispose()

static void fl_key_embedder_call_record_dispose ( GObject *  object)
static

Definition at line 62 of file fl_key_embedder_responder_test.cc.

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

◆ 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 79 of file fl_key_embedder_responder_test.cc.

82 {
83 g_return_val_if_fail(event != nullptr, nullptr);
84
85 FlKeyEmbedderCallRecord* self = FL_KEY_EMBEDDER_CALL_RECORD(
86 g_object_new(fl_key_embedder_call_record_get_type(), nullptr));
87
88 FlutterKeyEvent* clone_event = g_new(FlutterKeyEvent, 1);
89 *clone_event = *event;
90 if (event->character != nullptr) {
91 size_t character_length = strlen(event->character);
92 char* clone_character = g_new(char, character_length + 1);
93 strncpy(clone_character, event->character, character_length + 1);
94 clone_event->character = clone_character;
95 }
96 self->event = clone_event;
97 self->callback = callback;
98 self->user_data = user_data;
99
100 return self;
101}
FlKeyEvent uint64_t FlKeyResponderAsyncCallback callback
FlKeyEvent * event
const char * character
Definition: embedder.h:1137
void * user_data

◆ fl_key_event_new_by_mock()

static FlKeyEvent * fl_key_event_new_by_mock ( guint32  time_in_milliseconds,
bool  is_press,
guint  keyval,
guint16  keycode,
GdkModifierType  state,
gboolean  is_modifier 
)
static

Definition at line 115 of file fl_key_embedder_responder_test.cc.

120 {
121 _g_key_event.is_press = is_press;
122 _g_key_event.time = time_in_milliseconds;
123 _g_key_event.state = state;
124 _g_key_event.keyval = keyval;
125 _g_key_event.keycode = keycode;
126 _g_key_event.origin = nullptr;
127 return &_g_key_event;
128}
AtkStateType state

◆ 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 55 of file fl_key_embedder_responder_test.cc.

59 {}

◆ g_ptr_array_clear()

static void g_ptr_array_clear ( GPtrArray *  array)
static

Definition at line 37 of file fl_key_embedder_responder_test.cc.

37 {
38 g_ptr_array_remove_range(array, 0, array->len);
39}

◆ 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 137 of file fl_key_embedder_responder_test.cc.

139 {
140 g_return_if_fail(record->callback != nullptr);
142 g_expected_user_data = expected_user_data;
143 record->callback(expected_handled, record->user_data);
144}
static gboolean expected_handled
static gpointer g_expected_user_data
static gboolean g_expected_handled

◆ 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 150 of file fl_key_embedder_responder_test.cc.

153 {
154 GPtrArray* records_array =
155 reinterpret_cast<GPtrArray*>(send_key_event_user_data);
156 if (records_array != nullptr) {
157 g_ptr_array_add(records_array, fl_key_embedder_call_record_new(
158 event, callback, callback_user_data));
159 }
160}
static FlKeyEmbedderCallRecord * fl_key_embedder_call_record_new(const FlutterKeyEvent *event, FlutterKeyEventCallback callback, gpointer user_data)

◆ TEST() [1/17]

TEST ( FlKeyEmbedderResponderTest  ,
HandlesShiftAltLeftIsMetaLeft   
)

Definition at line 1757 of file fl_key_embedder_responder_test.cc.

1757 {
1758 EXPECT_EQ(g_call_records, nullptr);
1759 g_call_records = g_ptr_array_new_with_free_func(g_object_unref);
1760 FlKeyResponder* responder = FL_KEY_RESPONDER(
1762
1763 g_expected_handled = true;
1764 guint32 now_time = 1;
1765 // A convenient shorthand to simulate events.
1766 auto send_key_event = [responder, &now_time](bool is_press, guint keyval,
1767 guint16 keycode,
1768 GdkModifierType state) {
1769 now_time += 1;
1770 int user_data = 123; // Arbitrary user data
1772 responder,
1773 fl_key_event_new_by_mock(now_time, is_press, keyval, keycode, state,
1774 kIsModifier),
1776 };
1777
1778 FlKeyEmbedderCallRecord* record;
1779
1780 // ShiftLeft + AltLeft
1781 send_key_event(kPress, GDK_KEY_Shift_L, kKeyCodeShiftLeft,
1782 GDK_MODIFIER_RESERVED_25_MASK);
1783 EXPECT_EQ(g_call_records->len, 1u);
1784 record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 0));
1785 EXPECT_EQ(record->event->type, kFlutterKeyEventTypeDown);
1786 EXPECT_EQ(record->event->physical, kPhysicalShiftLeft);
1787 EXPECT_EQ(record->event->logical, kLogicalShiftLeft);
1788 EXPECT_EQ(record->event->synthesized, false);
1789
1790 send_key_event(kPress, GDK_KEY_Meta_L, kKeyCodeAltLeft,
1791 static_cast<GdkModifierType>(GDK_SHIFT_MASK |
1792 GDK_MODIFIER_RESERVED_25_MASK));
1793 EXPECT_EQ(g_call_records->len, 2u);
1794 record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 1));
1795 EXPECT_EQ(record->event->type, kFlutterKeyEventTypeDown);
1796 EXPECT_EQ(record->event->physical, kPhysicalMetaLeft);
1797 EXPECT_EQ(record->event->logical, kLogicalMetaLeft);
1798 EXPECT_EQ(record->event->synthesized, false);
1799
1800 send_key_event(kRelease, GDK_KEY_Meta_L, kKeyCodeAltLeft,
1801 static_cast<GdkModifierType>(GDK_MODIFIER_RESERVED_13_MASK |
1802 GDK_MODIFIER_RESERVED_25_MASK));
1803 send_key_event(kRelease, GDK_KEY_Shift_L, kKeyCodeShiftLeft,
1804 GDK_MODIFIER_RESERVED_25_MASK);
1805 g_ptr_array_clear(g_call_records);
1806
1807 // ShiftRight + AltLeft
1808 send_key_event(kPress, GDK_KEY_Shift_R, kKeyCodeShiftRight,
1809 GDK_MODIFIER_RESERVED_25_MASK);
1810 EXPECT_EQ(g_call_records->len, 1u);
1811 record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 0));
1812 EXPECT_EQ(record->event->type, kFlutterKeyEventTypeDown);
1813 EXPECT_EQ(record->event->physical, kPhysicalShiftRight);
1814 EXPECT_EQ(record->event->logical, kLogicalShiftRight);
1815 EXPECT_EQ(record->event->synthesized, false);
1816
1817 send_key_event(kPress, GDK_KEY_Meta_L, kKeyCodeAltLeft,
1818 static_cast<GdkModifierType>(GDK_SHIFT_MASK |
1819 GDK_MODIFIER_RESERVED_25_MASK));
1820 EXPECT_EQ(g_call_records->len, 2u);
1821 record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 1));
1822 EXPECT_EQ(record->event->type, kFlutterKeyEventTypeDown);
1823 EXPECT_EQ(record->event->physical, kPhysicalMetaLeft);
1824 EXPECT_EQ(record->event->logical, kLogicalMetaLeft);
1825 EXPECT_EQ(record->event->synthesized, false);
1826
1828 g_object_unref(responder);
1829}
@ kFlutterKeyEventTypeDown
Definition: embedder.h:1076
FlKeyEmbedderResponder * fl_key_embedder_responder_new(EmbedderSendKeyEvent send_key_event, void *send_key_event_user_data)
static void record_calls(const FlutterKeyEvent *event, FlutterKeyEventCallback callback, void *callback_user_data, void *send_key_event_user_data)
static void verify_response_handled(bool handled, gpointer user_data)
static void clear_g_call_records()
static FlKeyEvent * fl_key_event_new_by_mock(guint32 time_in_milliseconds, bool is_press, guint keyval, guint16 keycode, GdkModifierType state, gboolean is_modifier)
static void g_ptr_array_clear(GPtrArray *array)
void fl_key_responder_handle_event(FlKeyResponder *self, FlKeyEvent *event, FlKeyResponderAsyncCallback callback, gpointer user_data, uint64_t specified_logical_key)
static void send_key_event(FlTextInputPlugin *plugin, gint keyval, gint state=0)
constexpr uint64_t kLogicalShiftRight
Definition: key_codes.g.h:684
constexpr uint64_t kPhysicalShiftLeft
Definition: key_codes.g.h:225
constexpr uint64_t kLogicalMetaLeft
Definition: key_codes.g.h:687
constexpr uint64_t kPhysicalMetaLeft
Definition: key_codes.g.h:227
constexpr uint64_t kLogicalShiftLeft
Definition: key_codes.g.h:683
constexpr uint64_t kPhysicalShiftRight
Definition: key_codes.g.h:229
constexpr int kKeyCodeShiftLeft

◆ TEST() [2/17]

TEST ( FlKeyEmbedderResponderTest  ,
HandlesShiftAltVersusGroupNext   
)

Definition at line 1648 of file fl_key_embedder_responder_test.cc.

1648 {
1649 EXPECT_EQ(g_call_records, nullptr);
1650 g_call_records = g_ptr_array_new_with_free_func(g_object_unref);
1651 FlKeyResponder* responder = FL_KEY_RESPONDER(
1653
1654 g_expected_handled = true;
1655 guint32 now_time = 1;
1656 // A convenient shorthand to simulate events.
1657 auto send_key_event = [responder, &now_time](bool is_press, guint keyval,
1658 guint16 keycode,
1659 GdkModifierType state) {
1660 now_time += 1;
1661 int user_data = 123; // Arbitrary user data
1663 responder,
1664 fl_key_event_new_by_mock(now_time, is_press, keyval, keycode, state,
1665 kIsModifier),
1667 };
1668
1669 FlKeyEmbedderCallRecord* record;
1670
1671 send_key_event(kPress, GDK_KEY_Shift_L, kKeyCodeShiftLeft,
1672 GDK_MODIFIER_RESERVED_25_MASK);
1673 EXPECT_EQ(g_call_records->len, 1u);
1674 record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 0));
1675 EXPECT_EQ(record->event->type, kFlutterKeyEventTypeDown);
1676 EXPECT_EQ(record->event->physical, kPhysicalShiftLeft);
1677 EXPECT_EQ(record->event->logical, kLogicalShiftLeft);
1678 EXPECT_EQ(record->event->synthesized, false);
1679
1680 send_key_event(kPress, GDK_KEY_Meta_R, kKeyCodeAltRight,
1681 static_cast<GdkModifierType>(GDK_SHIFT_MASK |
1682 GDK_MODIFIER_RESERVED_25_MASK));
1683 EXPECT_EQ(g_call_records->len, 2u);
1684 record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 1));
1685 EXPECT_EQ(record->event->type, kFlutterKeyEventTypeDown);
1686 EXPECT_EQ(record->event->physical, kPhysicalAltRight);
1687 EXPECT_EQ(record->event->logical, kLogicalMetaRight);
1688 EXPECT_EQ(record->event->synthesized, false);
1689
1690 send_key_event(kRelease, GDK_KEY_ISO_Next_Group, kKeyCodeShiftLeft,
1691 static_cast<GdkModifierType>(GDK_SHIFT_MASK | GDK_MOD1_MASK |
1692 GDK_MODIFIER_RESERVED_25_MASK));
1693 EXPECT_EQ(g_call_records->len, 5u);
1694 record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 2));
1695 EXPECT_EQ(record->event->type, kFlutterKeyEventTypeDown);
1696 EXPECT_EQ(record->event->physical, kPhysicalAltLeft);
1697 EXPECT_EQ(record->event->logical, kLogicalAltLeft);
1698 EXPECT_EQ(record->event->synthesized, true);
1699
1700 record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 3));
1701 EXPECT_EQ(record->event->type, kFlutterKeyEventTypeUp);
1702 EXPECT_EQ(record->event->physical, kPhysicalAltRight);
1703 EXPECT_EQ(record->event->logical, kLogicalMetaRight);
1704 EXPECT_EQ(record->event->synthesized, true);
1705
1706 record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 4));
1707 EXPECT_EQ(record->event->type, kFlutterKeyEventTypeUp);
1708 EXPECT_EQ(record->event->physical, kPhysicalShiftLeft);
1709 EXPECT_EQ(record->event->logical, kLogicalShiftLeft);
1710 EXPECT_EQ(record->event->synthesized, false);
1711
1712 send_key_event(kPress, GDK_KEY_ISO_Next_Group, kKeyCodeShiftLeft,
1713 static_cast<GdkModifierType>(GDK_MOD1_MASK |
1714 GDK_MODIFIER_RESERVED_25_MASK));
1715 EXPECT_EQ(g_call_records->len, 6u);
1716 record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 5));
1717 EXPECT_EQ(record->event->type, kFlutterKeyEventTypeDown);
1718 EXPECT_EQ(record->event->physical, kPhysicalShiftLeft);
1719 EXPECT_EQ(record->event->logical, kLogicalGroupNext);
1720 EXPECT_EQ(record->event->synthesized, false);
1721
1722 send_key_event(kRelease, GDK_KEY_ISO_Level3_Shift, kKeyCodeAltRight,
1723 static_cast<GdkModifierType>(GDK_MOD1_MASK |
1724 GDK_MODIFIER_RESERVED_13_MASK |
1725 GDK_MODIFIER_RESERVED_25_MASK));
1726 EXPECT_EQ(g_call_records->len, 7u);
1727 record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 6));
1728 EXPECT_EQ(record->event->physical, 0u);
1729 EXPECT_EQ(record->event->logical, 0u);
1730
1731 send_key_event(kRelease, GDK_KEY_Shift_L, kKeyCodeShiftLeft,
1732 static_cast<GdkModifierType>(GDK_MODIFIER_RESERVED_13_MASK |
1733 GDK_MODIFIER_RESERVED_25_MASK));
1734 EXPECT_EQ(g_call_records->len, 9u);
1735 record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 7));
1736 EXPECT_EQ(record->event->type, kFlutterKeyEventTypeUp);
1737 EXPECT_EQ(record->event->physical, kPhysicalAltLeft);
1738 EXPECT_EQ(record->event->logical, kLogicalAltLeft);
1739 EXPECT_EQ(record->event->synthesized, true);
1740
1741 record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 8));
1742 EXPECT_EQ(record->event->type, kFlutterKeyEventTypeUp);
1743 EXPECT_EQ(record->event->physical, kPhysicalShiftLeft);
1744 EXPECT_EQ(record->event->logical, kLogicalGroupNext);
1745 EXPECT_EQ(record->event->synthesized, false);
1746
1748 g_object_unref(responder);
1749}
@ kFlutterKeyEventTypeUp
Definition: embedder.h:1075
constexpr uint64_t kPhysicalAltRight
Definition: key_codes.g.h:230
constexpr uint64_t kLogicalMetaRight
Definition: key_codes.g.h:688
constexpr uint64_t kLogicalGroupNext
Definition: key_codes.g.h:438
constexpr uint64_t kPhysicalAltLeft
Definition: key_codes.g.h:226
constexpr uint64_t kLogicalAltLeft
Definition: key_codes.g.h:685

◆ TEST() [3/17]

TEST ( FlKeyEmbedderResponderTest  ,
IgnoreAbruptUpEvent   
)

Definition at line 1025 of file fl_key_embedder_responder_test.cc.

1025 {
1026 FlKeyEmbedderCallRecord* record;
1027
1028 EXPECT_EQ(g_call_records, nullptr);
1029 g_call_records = g_ptr_array_new_with_free_func(g_object_unref);
1030 FlKeyResponder* responder = FL_KEY_RESPONDER(
1032 int user_data = 123; // Arbitrary user data
1033
1034 // Release KeyA before it was even pressed.
1035 g_expected_handled = true; // The empty event is always handled.
1037 responder,
1038 fl_key_event_new_by_mock(103, kRelease, GDK_KEY_q, kKeyCodeKeyA,
1039 static_cast<GdkModifierType>(0), kIsNotModifier),
1041
1042 EXPECT_EQ(g_call_records->len, 1u);
1043
1044 record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 0));
1045 EXPECT_EQ(record->event->physical, 0ull);
1046 EXPECT_EQ(record->event->logical, 0ull);
1047 EXPECT_STREQ(record->event->character, nullptr);
1048 EXPECT_EQ(record->event->synthesized, false);
1049 EXPECT_EQ(record->callback, nullptr);
1050
1052 g_object_unref(responder);
1053}

◆ TEST() [4/17]

TEST ( FlKeyEmbedderResponderTest  ,
PressShiftDuringLetterKeyTap   
)

Definition at line 299 of file fl_key_embedder_responder_test.cc.

299 {
300 EXPECT_EQ(g_call_records, nullptr);
301 g_call_records = g_ptr_array_new_with_free_func(g_object_unref);
302 FlKeyResponder* responder = FL_KEY_RESPONDER(
304 int user_data = 123; // Arbitrary user data
305
306 FlKeyEmbedderCallRecord* record;
307
308 // Press shift right
310 responder,
311 fl_key_event_new_by_mock(101, kPress, GDK_KEY_Shift_R, kKeyCodeShiftRight,
312 static_cast<GdkModifierType>(0), kIsModifier),
314
315 EXPECT_EQ(g_call_records->len, 1u);
316 record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 0));
317 EXPECT_EQ(record->event->type, kFlutterKeyEventTypeDown);
318 EXPECT_EQ(record->event->physical, kPhysicalShiftRight);
319 EXPECT_EQ(record->event->logical, kLogicalShiftRight);
320 EXPECT_STREQ(record->event->character, nullptr);
321 EXPECT_EQ(record->event->synthesized, false);
322
324 g_ptr_array_clear(g_call_records);
325
326 // Press key A
328 responder,
329 fl_key_event_new_by_mock(102, kPress, GDK_KEY_A, kKeyCodeKeyA,
330 GDK_SHIFT_MASK, kIsNotModifier),
332
333 EXPECT_EQ(g_call_records->len, 1u);
334 record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 0));
335 EXPECT_EQ(record->event->type, kFlutterKeyEventTypeDown);
336 EXPECT_EQ(record->event->physical, kPhysicalKeyA);
337 EXPECT_EQ(record->event->logical, kLogicalKeyA);
338 EXPECT_STREQ(record->event->character, "A");
339 EXPECT_EQ(record->event->synthesized, false);
340
342 g_ptr_array_clear(g_call_records);
343
344 // Release shift right
346 responder,
347 fl_key_event_new_by_mock(103, kRelease, GDK_KEY_Shift_R,
348 kKeyCodeShiftRight, GDK_SHIFT_MASK, kIsModifier),
350
351 EXPECT_EQ(g_call_records->len, 1u);
352 record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 0));
353 EXPECT_EQ(record->event->type, kFlutterKeyEventTypeUp);
354 EXPECT_EQ(record->event->physical, kPhysicalShiftRight);
355 EXPECT_EQ(record->event->logical, kLogicalShiftRight);
356 EXPECT_STREQ(record->event->character, nullptr);
357 EXPECT_EQ(record->event->synthesized, false);
358
360 g_ptr_array_clear(g_call_records);
361
362 // Release key A
364 responder,
365 fl_key_event_new_by_mock(104, kRelease, GDK_KEY_A, kKeyCodeKeyA,
366 static_cast<GdkModifierType>(0), kIsNotModifier),
368
369 EXPECT_EQ(g_call_records->len, 1u);
370 record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 0));
371 EXPECT_EQ(record->event->type, kFlutterKeyEventTypeUp);
372 EXPECT_EQ(record->event->physical, kPhysicalKeyA);
373 EXPECT_EQ(record->event->logical, kLogicalKeyA);
374 EXPECT_STREQ(record->event->character, nullptr);
375 EXPECT_EQ(record->event->synthesized, false);
376
378 g_ptr_array_clear(g_call_records);
379
381 g_object_unref(responder);
382}
static void invoke_record_callback_and_verify(FlKeyEmbedderCallRecord *record, bool expected_handled, void *expected_user_data)
constexpr uint64_t kPhysicalKeyA
Definition: key_codes.g.h:77
constexpr uint64_t kLogicalKeyA
Definition: key_codes.g.h:339

◆ TEST() [5/17]

TEST ( FlKeyEmbedderResponderTest  ,
ReleaseShiftKeyBetweenDigitKeyEvents   
)

Definition at line 553 of file fl_key_embedder_responder_test.cc.

553 {
554 EXPECT_EQ(g_call_records, nullptr);
555 g_call_records = g_ptr_array_new_with_free_func(g_object_unref);
556 FlKeyResponder* responder = FL_KEY_RESPONDER(
558 int user_data = 123; // Arbitrary user data
559
560 FlKeyEmbedderCallRecord* record;
561
562 GdkModifierType state = static_cast<GdkModifierType>(0);
563
564 // Press shift left
566 responder,
567 fl_key_event_new_by_mock(101, kPress, GDK_KEY_Shift_L, kKeyCodeShiftLeft,
568 state, kIsModifier),
570
571 EXPECT_EQ(g_call_records->len, 1u);
572 record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 0));
573 EXPECT_EQ(record->event->type, kFlutterKeyEventTypeDown);
574 EXPECT_EQ(record->event->physical, kPhysicalShiftLeft);
575 EXPECT_EQ(record->event->logical, kLogicalShiftLeft);
576 EXPECT_STREQ(record->event->character, nullptr);
577 EXPECT_EQ(record->event->synthesized, false);
578
580 g_ptr_array_clear(g_call_records);
581
582 state = GDK_SHIFT_MASK;
583
584 // Press digit 1, which is '!' on a US keyboard
586 responder,
587 fl_key_event_new_by_mock(102, kPress, GDK_KEY_exclam, kKeyCodeDigit1,
588 state, kIsNotModifier),
590
591 EXPECT_EQ(g_call_records->len, 1u);
592 record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 0));
593 EXPECT_EQ(record->event->type, kFlutterKeyEventTypeDown);
594 EXPECT_EQ(record->event->physical, kPhysicalDigit1);
595 EXPECT_EQ(record->event->logical, kLogicalExclamation);
596 EXPECT_STREQ(record->event->character, "!");
597 EXPECT_EQ(record->event->synthesized, false);
598
600 g_ptr_array_clear(g_call_records);
601
602 // Release shift
604 responder,
605 fl_key_event_new_by_mock(103, kRelease, GDK_KEY_Shift_L,
606 kKeyCodeShiftLeft, state, kIsModifier),
608
609 EXPECT_EQ(g_call_records->len, 1u);
610 record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 0));
611 EXPECT_EQ(record->event->type, kFlutterKeyEventTypeUp);
612 EXPECT_EQ(record->event->physical, kPhysicalShiftLeft);
613 EXPECT_EQ(record->event->logical, kLogicalShiftLeft);
614 EXPECT_STREQ(record->event->character, nullptr);
615 EXPECT_EQ(record->event->synthesized, false);
616
618 g_ptr_array_clear(g_call_records);
619
620 state = static_cast<GdkModifierType>(0);
621
622 // Release digit 1, which is "1" because shift has been released.
624 responder,
625 fl_key_event_new_by_mock(104, kRelease, GDK_KEY_1, kKeyCodeDigit1, state,
626 kIsNotModifier),
628
629 EXPECT_EQ(g_call_records->len, 1u);
630 record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 0));
631 EXPECT_EQ(record->event->type, kFlutterKeyEventTypeUp);
632 EXPECT_EQ(record->event->physical, kPhysicalDigit1);
633 EXPECT_EQ(record->event->logical, kLogicalExclamation); // Important
634 EXPECT_STREQ(record->event->character, nullptr);
635 EXPECT_EQ(record->event->synthesized, false);
636
638 g_ptr_array_clear(g_call_records);
639
641 g_object_unref(responder);
642}
constexpr uint64_t kPhysicalDigit1
Definition: key_codes.g.h:103
constexpr uint64_t kLogicalExclamation
Definition: key_codes.g.h:301

◆ TEST() [6/17]

TEST ( FlKeyEmbedderResponderTest  ,
SendKeyEvent   
)

Definition at line 168 of file fl_key_embedder_responder_test.cc.

168 {
169 EXPECT_EQ(g_call_records, nullptr);
170 g_call_records = g_ptr_array_new_with_free_func(g_object_unref);
171 FlKeyResponder* responder = FL_KEY_RESPONDER(
173 int user_data = 123; // Arbitrary user data
174
175 FlKeyEmbedderCallRecord* record;
176
177 // On a QWERTY keyboard, press key Q (physically key A), and release.
178 // Key down
180 responder,
181 fl_key_event_new_by_mock(12345, kPress, GDK_KEY_a, kKeyCodeKeyA,
182 static_cast<GdkModifierType>(0), kIsNotModifier),
184
185 EXPECT_EQ(g_call_records->len, 1u);
186 record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 0));
187 EXPECT_EQ(record->event->struct_size, sizeof(FlutterKeyEvent));
188 EXPECT_EQ(record->event->timestamp, 12345000);
189 EXPECT_EQ(record->event->type, kFlutterKeyEventTypeDown);
190 EXPECT_EQ(record->event->physical, kPhysicalKeyA);
191 EXPECT_EQ(record->event->logical, kLogicalKeyA);
192 EXPECT_STREQ(record->event->character, "a");
193 EXPECT_EQ(record->event->synthesized, false);
194
196 g_ptr_array_clear(g_call_records);
197
198 // Key up
200 responder,
201 fl_key_event_new_by_mock(12346, kRelease, GDK_KEY_a, kKeyCodeKeyA,
202 static_cast<GdkModifierType>(0), kIsNotModifier),
204
205 EXPECT_EQ(g_call_records->len, 1u);
206 record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 0));
207 EXPECT_EQ(record->event->struct_size, sizeof(FlutterKeyEvent));
208 EXPECT_EQ(record->event->timestamp, 12346000);
209 EXPECT_EQ(record->event->type, kFlutterKeyEventTypeUp);
210 EXPECT_EQ(record->event->physical, kPhysicalKeyA);
211 EXPECT_EQ(record->event->logical, kLogicalKeyA);
212 EXPECT_STREQ(record->event->character, nullptr);
213 EXPECT_EQ(record->event->synthesized, false);
214
216 g_ptr_array_clear(g_call_records);
217
218 // On an AZERTY keyboard, press key Q (physically key A), and release.
219 // Key down
221 responder,
222 fl_key_event_new_by_mock(12347, kPress, GDK_KEY_q, kKeyCodeKeyA,
223 static_cast<GdkModifierType>(0), kIsNotModifier),
225
226 EXPECT_EQ(g_call_records->len, 1u);
227 record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 0));
228 EXPECT_EQ(record->event->struct_size, sizeof(FlutterKeyEvent));
229 EXPECT_EQ(record->event->timestamp, 12347000);
230 EXPECT_EQ(record->event->type, kFlutterKeyEventTypeDown);
231 EXPECT_EQ(record->event->physical, kPhysicalKeyA);
232 EXPECT_EQ(record->event->logical, kLogicalKeyQ);
233 EXPECT_STREQ(record->event->character, "q");
234 EXPECT_EQ(record->event->synthesized, false);
235
237 g_ptr_array_clear(g_call_records);
238
239 // Key up
241 responder,
242 fl_key_event_new_by_mock(12348, kRelease, GDK_KEY_q, kKeyCodeKeyA,
243 static_cast<GdkModifierType>(0), kIsNotModifier),
245
246 EXPECT_EQ(g_call_records->len, 1u);
247 record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 0));
248 EXPECT_EQ(record->event->struct_size, sizeof(FlutterKeyEvent));
249 EXPECT_EQ(record->event->timestamp, 12348000);
250 EXPECT_EQ(record->event->type, kFlutterKeyEventTypeUp);
251 EXPECT_EQ(record->event->physical, kPhysicalKeyA);
252 EXPECT_EQ(record->event->logical, kLogicalKeyQ);
253 EXPECT_STREQ(record->event->character, nullptr);
254 EXPECT_EQ(record->event->synthesized, false);
255
257 g_ptr_array_clear(g_call_records);
258
260 g_object_unref(responder);
261}
return FALSE
constexpr uint64_t kLogicalKeyQ
Definition: key_codes.g.h:355

◆ TEST() [7/17]

TEST ( FlKeyEmbedderResponderTest  ,
SynthesizationOccursOnIgnoredEvents   
)

Definition at line 1594 of file fl_key_embedder_responder_test.cc.

1594 {
1595 EXPECT_EQ(g_call_records, nullptr);
1596 g_call_records = g_ptr_array_new_with_free_func(g_object_unref);
1597 FlKeyResponder* responder = FL_KEY_RESPONDER(
1599 int user_data = 123; // Arbitrary user data
1600
1601 FlKeyEmbedderCallRecord* record;
1602
1603 // The NumLock is desynchronized by being enabled, and Control is pressed.
1604 GdkModifierType state =
1605 static_cast<GdkModifierType>(GDK_MOD2_MASK | GDK_CONTROL_MASK);
1606
1607 // Send a KeyA up event, which will be ignored.
1608 g_expected_handled = true; // The ignored event is always handled.
1610 responder,
1611 fl_key_event_new_by_mock(101, kRelease, GDK_KEY_a, kKeyCodeKeyA, state,
1612 kIsNotModifier),
1614
1615 EXPECT_EQ(g_call_records->len, 2u);
1616 record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 0));
1617 EXPECT_EQ(record->event->timestamp, 101000);
1618 EXPECT_EQ(record->event->type, kFlutterKeyEventTypeDown);
1619 EXPECT_EQ(record->event->physical, kPhysicalNumLock);
1620 EXPECT_EQ(record->event->logical, kLogicalNumLock);
1621 EXPECT_STREQ(record->event->character, nullptr);
1622 EXPECT_EQ(record->event->synthesized, true);
1623
1624 record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 1));
1625 EXPECT_EQ(record->event->timestamp, 101000);
1626 EXPECT_EQ(record->event->type, kFlutterKeyEventTypeDown);
1627 EXPECT_EQ(record->event->physical, kPhysicalControlLeft);
1628 EXPECT_EQ(record->event->logical, kLogicalControlLeft);
1629 EXPECT_STREQ(record->event->character, nullptr);
1630 EXPECT_EQ(record->event->synthesized, true);
1631
1632 g_ptr_array_clear(g_call_records);
1633
1635 g_object_unref(responder);
1636}
constexpr uint64_t kPhysicalNumLock
Definition: key_codes.g.h:155
constexpr uint64_t kPhysicalControlLeft
Definition: key_codes.g.h:224
constexpr uint64_t kLogicalControlLeft
Definition: key_codes.g.h:681
constexpr uint64_t kLogicalNumLock
Definition: key_codes.g.h:381

◆ TEST() [8/17]

TEST ( FlKeyEmbedderResponderTest  ,
SynthesizeForDesyncLockModeOnNonSelfEvents   
)

Definition at line 1387 of file fl_key_embedder_responder_test.cc.

1387 {
1388 EXPECT_EQ(g_call_records, nullptr);
1389 g_call_records = g_ptr_array_new_with_free_func(g_object_unref);
1390 FlKeyResponder* responder = FL_KEY_RESPONDER(
1392 int user_data = 123; // Arbitrary user data
1393
1394 FlKeyEmbedderCallRecord* record;
1395
1396 // The NumLock is desynchronized by being enabled.
1397 GdkModifierType state = GDK_MOD2_MASK;
1398
1399 // Send a normal event
1401 responder,
1402 fl_key_event_new_by_mock(101, kPress, GDK_KEY_a, kKeyCodeKeyA, state,
1403 kIsNotModifier),
1405
1406 EXPECT_EQ(g_call_records->len, 2u);
1407 record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 0));
1408 EXPECT_EQ(record->event->timestamp, 101000);
1409 EXPECT_EQ(record->event->type, kFlutterKeyEventTypeDown);
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(g_call_records, 1));
1416 EXPECT_EQ(record->event->timestamp, 101000);
1417 EXPECT_EQ(record->event->type, kFlutterKeyEventTypeDown);
1418 EXPECT_EQ(record->event->physical, kPhysicalKeyA);
1419 EXPECT_EQ(record->event->logical, kLogicalKeyA);
1420 EXPECT_STREQ(record->event->character, "a");
1421 EXPECT_EQ(record->event->synthesized, false);
1422
1424 g_ptr_array_clear(g_call_records);
1425
1426 // The NumLock is desynchronized by being disabled.
1427 state = static_cast<GdkModifierType>(0);
1428
1429 // Release key A
1431 responder,
1432 fl_key_event_new_by_mock(102, kRelease, GDK_KEY_A, kKeyCodeKeyA, state,
1433 kIsNotModifier),
1435
1436 EXPECT_EQ(g_call_records->len, 4u);
1437 record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 0));
1438 EXPECT_EQ(record->event->timestamp, 102000);
1439 EXPECT_EQ(record->event->type, kFlutterKeyEventTypeUp);
1440 EXPECT_EQ(record->event->physical, kPhysicalNumLock);
1441 EXPECT_EQ(record->event->logical, kLogicalNumLock);
1442 EXPECT_STREQ(record->event->character, nullptr);
1443 EXPECT_EQ(record->event->synthesized, true);
1444
1445 record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 1));
1446 EXPECT_EQ(record->event->timestamp, 102000);
1447 EXPECT_EQ(record->event->type, kFlutterKeyEventTypeDown);
1448 EXPECT_EQ(record->event->physical, kPhysicalNumLock);
1449 EXPECT_EQ(record->event->logical, kLogicalNumLock);
1450 EXPECT_STREQ(record->event->character, nullptr);
1451 EXPECT_EQ(record->event->synthesized, true);
1452
1453 record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 2));
1454 EXPECT_EQ(record->event->timestamp, 102000);
1455 EXPECT_EQ(record->event->type, kFlutterKeyEventTypeUp);
1456 EXPECT_EQ(record->event->physical, kPhysicalNumLock);
1457 EXPECT_EQ(record->event->logical, kLogicalNumLock);
1458 EXPECT_STREQ(record->event->character, nullptr);
1459 EXPECT_EQ(record->event->synthesized, true);
1460
1461 record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 3));
1462 EXPECT_EQ(record->event->timestamp, 102000);
1463 EXPECT_EQ(record->event->type, kFlutterKeyEventTypeUp);
1464 EXPECT_EQ(record->event->physical, kPhysicalKeyA);
1465 EXPECT_EQ(record->event->logical, kLogicalKeyA);
1466 EXPECT_STREQ(record->event->character, nullptr);
1467 EXPECT_EQ(record->event->synthesized, false);
1468
1470 g_ptr_array_clear(g_call_records);
1471
1472 // Release NumLock. Since the previous event should have synthesized NumLock
1473 // to be released, this should result in only an empty event.
1474 g_expected_handled = true;
1476 responder,
1477 fl_key_event_new_by_mock(103, kRelease, GDK_KEY_Num_Lock, kKeyCodeNumLock,
1478 state, kIsModifier),
1480
1481 EXPECT_EQ(g_call_records->len, 1u);
1482 record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 0));
1483 EXPECT_EQ(record->event->physical, 0ull);
1484 EXPECT_EQ(record->event->logical, 0ull);
1485 EXPECT_STREQ(record->event->character, nullptr);
1486 EXPECT_EQ(record->event->synthesized, false);
1487 EXPECT_EQ(record->callback, nullptr);
1488
1490 g_object_unref(responder);
1491}

◆ TEST() [9/17]

TEST ( FlKeyEmbedderResponderTest  ,
SynthesizeForDesyncLockModeOnSelfEvents   
)

Definition at line 1495 of file fl_key_embedder_responder_test.cc.

1495 {
1496 EXPECT_EQ(g_call_records, nullptr);
1497 g_call_records = g_ptr_array_new_with_free_func(g_object_unref);
1498 FlKeyResponder* responder = FL_KEY_RESPONDER(
1500 int user_data = 123; // Arbitrary user data
1501
1502 FlKeyEmbedderCallRecord* record;
1503
1504 // The NumLock is desynchronized by being enabled.
1505 GdkModifierType state = GDK_MOD2_MASK;
1506
1507 // NumLock down
1509 responder,
1510 fl_key_event_new_by_mock(101, kPress, GDK_KEY_Num_Lock, kKeyCodeNumLock,
1511 state, kIsModifier),
1513
1514 EXPECT_EQ(g_call_records->len, 3u);
1515 record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 0));
1516 EXPECT_EQ(record->event->timestamp, 101000);
1517 EXPECT_EQ(record->event->type, kFlutterKeyEventTypeDown);
1518 EXPECT_EQ(record->event->physical, kPhysicalNumLock);
1519 EXPECT_EQ(record->event->logical, kLogicalNumLock);
1520 EXPECT_STREQ(record->event->character, nullptr);
1521 EXPECT_EQ(record->event->synthesized, true);
1522
1523 record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 1));
1524 EXPECT_EQ(record->event->timestamp, 101000);
1525 EXPECT_EQ(record->event->type, kFlutterKeyEventTypeUp);
1526 EXPECT_EQ(record->event->physical, kPhysicalNumLock);
1527 EXPECT_EQ(record->event->logical, kLogicalNumLock);
1528 EXPECT_STREQ(record->event->character, nullptr);
1529 EXPECT_EQ(record->event->synthesized, true);
1530
1531 record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 2));
1532 EXPECT_EQ(record->event->timestamp, 101000);
1533 EXPECT_EQ(record->event->type, kFlutterKeyEventTypeDown);
1534 EXPECT_EQ(record->event->physical, kPhysicalNumLock);
1535 EXPECT_EQ(record->event->logical, kLogicalNumLock);
1536 EXPECT_STREQ(record->event->character, nullptr);
1537 EXPECT_EQ(record->event->synthesized, false);
1538
1540 g_ptr_array_clear(g_call_records);
1541
1542 // The NumLock is desynchronized by being enabled in a press event.
1543 state = GDK_MOD2_MASK;
1544
1545 // NumLock up
1547 responder,
1548 fl_key_event_new_by_mock(102, kPress, GDK_KEY_Num_Lock, kKeyCodeNumLock,
1549 state, kIsModifier),
1551
1552 EXPECT_EQ(g_call_records->len, 4u);
1553 record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 0));
1554 EXPECT_EQ(record->event->timestamp, 102000);
1555 EXPECT_EQ(record->event->type, kFlutterKeyEventTypeUp);
1556 EXPECT_EQ(record->event->physical, kPhysicalNumLock);
1557 EXPECT_EQ(record->event->logical, kLogicalNumLock);
1558 EXPECT_STREQ(record->event->character, nullptr);
1559 EXPECT_EQ(record->event->synthesized, true);
1560
1561 record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 1));
1562 EXPECT_EQ(record->event->timestamp, 102000);
1563 EXPECT_EQ(record->event->type, kFlutterKeyEventTypeDown);
1564 EXPECT_EQ(record->event->physical, kPhysicalNumLock);
1565 EXPECT_EQ(record->event->logical, kLogicalNumLock);
1566 EXPECT_STREQ(record->event->character, nullptr);
1567 EXPECT_EQ(record->event->synthesized, true);
1568
1569 record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 2));
1570 EXPECT_EQ(record->event->timestamp, 102000);
1571 EXPECT_EQ(record->event->type, kFlutterKeyEventTypeUp);
1572 EXPECT_EQ(record->event->physical, kPhysicalNumLock);
1573 EXPECT_EQ(record->event->logical, kLogicalNumLock);
1574 EXPECT_STREQ(record->event->character, nullptr);
1575 EXPECT_EQ(record->event->synthesized, true);
1576
1577 record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 3));
1578 EXPECT_EQ(record->event->timestamp, 102000);
1579 EXPECT_EQ(record->event->type, kFlutterKeyEventTypeDown);
1580 EXPECT_EQ(record->event->physical, kPhysicalNumLock);
1581 EXPECT_EQ(record->event->logical, kLogicalNumLock);
1582 EXPECT_STREQ(record->event->character, nullptr);
1583 EXPECT_EQ(record->event->synthesized, false);
1584
1586 g_ptr_array_clear(g_call_records);
1587
1589 g_object_unref(responder);
1590}

◆ TEST() [10/17]

TEST ( FlKeyEmbedderResponderTest  ,
SynthesizeForDesyncPressingStateOnNonSelfEvents   
)

Definition at line 1187 of file fl_key_embedder_responder_test.cc.

1188 {
1189 EXPECT_EQ(g_call_records, nullptr);
1190 g_call_records = g_ptr_array_new_with_free_func(g_object_unref);
1191 FlKeyResponder* responder = FL_KEY_RESPONDER(
1193 int user_data = 123; // Arbitrary user data
1194
1195 FlKeyEmbedderCallRecord* record;
1196
1197 // A key down of control left is missed.
1198 GdkModifierType state = GDK_CONTROL_MASK;
1199
1200 // Send a normal event (KeyA down)
1202 responder,
1203 fl_key_event_new_by_mock(101, kPress, GDK_KEY_a, kKeyCodeKeyA, state,
1204 kIsNotModifier),
1206
1207 EXPECT_EQ(g_call_records->len, 2u);
1208 record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 0));
1209 EXPECT_EQ(record->event->timestamp, 101000);
1210 EXPECT_EQ(record->event->type, kFlutterKeyEventTypeDown);
1211 EXPECT_EQ(record->event->physical, kPhysicalControlLeft);
1212 EXPECT_EQ(record->event->logical, kLogicalControlLeft);
1213 EXPECT_STREQ(record->event->character, nullptr);
1214 EXPECT_EQ(record->event->synthesized, true);
1215
1216 record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 1));
1217 EXPECT_EQ(record->event->timestamp, 101000);
1218 EXPECT_EQ(record->event->type, kFlutterKeyEventTypeDown);
1219 EXPECT_EQ(record->event->physical, kPhysicalKeyA);
1220 EXPECT_EQ(record->event->logical, kLogicalKeyA);
1221 EXPECT_STREQ(record->event->character, "a");
1222 EXPECT_EQ(record->event->synthesized, false);
1223
1225 g_ptr_array_clear(g_call_records);
1226
1227 // A key up of control left is missed.
1228 state = static_cast<GdkModifierType>(0);
1229
1230 // Send a normal event (KeyA up)
1232 responder,
1233 fl_key_event_new_by_mock(102, kRelease, GDK_KEY_A, kKeyCodeKeyA, state,
1234 kIsNotModifier),
1236
1237 EXPECT_EQ(g_call_records->len, 2u);
1238 record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 0));
1239 EXPECT_EQ(record->event->timestamp, 102000);
1240 EXPECT_EQ(record->event->type, kFlutterKeyEventTypeUp);
1241 EXPECT_EQ(record->event->physical, kPhysicalControlLeft);
1242 EXPECT_EQ(record->event->logical, kLogicalControlLeft);
1243 EXPECT_STREQ(record->event->character, nullptr);
1244 EXPECT_EQ(record->event->synthesized, true);
1245
1246 record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 1));
1247 EXPECT_EQ(record->event->timestamp, 102000);
1248 EXPECT_EQ(record->event->type, kFlutterKeyEventTypeUp);
1249 EXPECT_EQ(record->event->physical, kPhysicalKeyA);
1250 EXPECT_EQ(record->event->logical, kLogicalKeyA);
1251 EXPECT_STREQ(record->event->character, nullptr);
1252 EXPECT_EQ(record->event->synthesized, false);
1253
1255 g_ptr_array_clear(g_call_records);
1256
1257 // Test non-default key mapping.
1258
1259 // Press a key with physical CapsLock and logical ControlLeft.
1260 state = static_cast<GdkModifierType>(0);
1261
1263 responder,
1264 fl_key_event_new_by_mock(101, kPress, GDK_KEY_Control_L, kKeyCodeCapsLock,
1265 state, kIsModifier),
1267
1268 EXPECT_EQ(g_call_records->len, 1u);
1269 record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 0));
1270 EXPECT_EQ(record->event->timestamp, 101000);
1271 EXPECT_EQ(record->event->type, kFlutterKeyEventTypeDown);
1272 EXPECT_EQ(record->event->physical, kPhysicalCapsLock);
1273 EXPECT_EQ(record->event->logical, kLogicalControlLeft);
1274 EXPECT_STREQ(record->event->character, nullptr);
1275 EXPECT_EQ(record->event->synthesized, false);
1276
1278 g_ptr_array_clear(g_call_records);
1279
1280 // The key up of the control left press is missed.
1281 state = static_cast<GdkModifierType>(0);
1282
1283 // Send a normal event (KeyA down).
1285 responder,
1286 fl_key_event_new_by_mock(102, kPress, GDK_KEY_A, kKeyCodeKeyA, state,
1287 kIsNotModifier),
1289
1290 // The synthesized event should have physical CapsLock and logical
1291 // ControlLeft.
1292 EXPECT_EQ(g_call_records->len, 2u);
1293 record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 0));
1294 EXPECT_EQ(record->event->timestamp, 102000);
1295 EXPECT_EQ(record->event->type, kFlutterKeyEventTypeUp);
1296 EXPECT_EQ(record->event->physical, kPhysicalCapsLock);
1297 EXPECT_EQ(record->event->logical, kLogicalControlLeft);
1298 EXPECT_STREQ(record->event->character, nullptr);
1299 EXPECT_EQ(record->event->synthesized, true);
1300
1301 record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 1));
1302 EXPECT_EQ(record->event->timestamp, 102000);
1303 EXPECT_EQ(record->event->type, kFlutterKeyEventTypeDown);
1304 EXPECT_EQ(record->event->physical, kPhysicalKeyA);
1305 EXPECT_EQ(record->event->logical, kLogicalKeyA);
1306 EXPECT_STREQ(record->event->character, "A");
1307 EXPECT_EQ(record->event->synthesized, false);
1308
1310 g_ptr_array_clear(g_call_records);
1311
1313 g_object_unref(responder);
1314}
constexpr uint64_t kPhysicalCapsLock
Definition: key_codes.g.h:129

◆ TEST() [11/17]

TEST ( FlKeyEmbedderResponderTest  ,
SynthesizeForDesyncPressingStateOnRemappedEvents   
)

Definition at line 1318 of file fl_key_embedder_responder_test.cc.

1319 {
1320 EXPECT_EQ(g_call_records, nullptr);
1321 g_call_records = g_ptr_array_new_with_free_func(g_object_unref);
1322 FlKeyResponder* responder = FL_KEY_RESPONDER(
1324 int user_data = 123; // Arbitrary user data
1325
1326 FlKeyEmbedderCallRecord* record;
1327
1328 // Press a key with physical CapsLock and logical ControlLeft.
1329 GdkModifierType state = static_cast<GdkModifierType>(0);
1330
1332 responder,
1333 fl_key_event_new_by_mock(101, kPress, GDK_KEY_Control_L, kKeyCodeCapsLock,
1334 state, kIsModifier),
1336
1337 EXPECT_EQ(g_call_records->len, 1u);
1338 record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 0));
1339 EXPECT_EQ(record->event->timestamp, 101000);
1340 EXPECT_EQ(record->event->type, kFlutterKeyEventTypeDown);
1341 EXPECT_EQ(record->event->physical, kPhysicalCapsLock);
1342 EXPECT_EQ(record->event->logical, kLogicalControlLeft);
1343 EXPECT_STREQ(record->event->character, nullptr);
1344 EXPECT_EQ(record->event->synthesized, false);
1345
1347 g_ptr_array_clear(g_call_records);
1348
1349 // The key up of the control left press is missed.
1350 state = static_cast<GdkModifierType>(0);
1351
1352 // Send a normal event (KeyA down).
1354 responder,
1355 fl_key_event_new_by_mock(102, kPress, GDK_KEY_A, kKeyCodeKeyA, state,
1356 kIsNotModifier),
1358
1359 // The synthesized event should have physical CapsLock and logical
1360 // ControlLeft.
1361 EXPECT_EQ(g_call_records->len, 2u);
1362 record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 0));
1363 EXPECT_EQ(record->event->timestamp, 102000);
1364 EXPECT_EQ(record->event->type, kFlutterKeyEventTypeUp);
1365 EXPECT_EQ(record->event->physical, kPhysicalCapsLock);
1366 EXPECT_EQ(record->event->logical, kLogicalControlLeft);
1367 EXPECT_STREQ(record->event->character, nullptr);
1368 EXPECT_EQ(record->event->synthesized, true);
1369
1370 record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 1));
1371 EXPECT_EQ(record->event->timestamp, 102000);
1372 EXPECT_EQ(record->event->type, kFlutterKeyEventTypeDown);
1373 EXPECT_EQ(record->event->physical, kPhysicalKeyA);
1374 EXPECT_EQ(record->event->logical, kLogicalKeyA);
1375 EXPECT_STREQ(record->event->character, "A");
1376 EXPECT_EQ(record->event->synthesized, false);
1377
1379 g_ptr_array_clear(g_call_records);
1380
1382 g_object_unref(responder);
1383}

◆ TEST() [12/17]

TEST ( FlKeyEmbedderResponderTest  ,
SynthesizeForDesyncPressingStateOnSelfEvents   
)

Definition at line 1057 of file fl_key_embedder_responder_test.cc.

1057 {
1058 EXPECT_EQ(g_call_records, nullptr);
1059 g_call_records = g_ptr_array_new_with_free_func(g_object_unref);
1060 FlKeyResponder* responder = FL_KEY_RESPONDER(
1062 int user_data = 123; // Arbitrary user data
1063
1064 FlKeyEmbedderCallRecord* record;
1065
1066 // Test 1: synthesize key down.
1067
1068 // A key down of control left is missed.
1069 GdkModifierType state = GDK_CONTROL_MASK;
1070
1071 // Send a ControlLeft up
1073 responder,
1074 fl_key_event_new_by_mock(101, kRelease, GDK_KEY_Control_L,
1075 kKeyCodeControlLeft, state, kIsModifier),
1077
1078 EXPECT_EQ(g_call_records->len, 2u);
1079 record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 0));
1080 EXPECT_EQ(record->event->timestamp, 101000);
1081 EXPECT_EQ(record->event->type, kFlutterKeyEventTypeDown);
1082 EXPECT_EQ(record->event->physical, kPhysicalControlLeft);
1083 EXPECT_EQ(record->event->logical, kLogicalControlLeft);
1084 EXPECT_STREQ(record->event->character, nullptr);
1085 EXPECT_EQ(record->event->synthesized, true);
1086
1087 record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 1));
1088 EXPECT_EQ(record->event->timestamp, 101000);
1089 EXPECT_EQ(record->event->type, kFlutterKeyEventTypeUp);
1090 EXPECT_EQ(record->event->physical, kPhysicalControlLeft);
1091 EXPECT_EQ(record->event->logical, kLogicalControlLeft);
1092 EXPECT_STREQ(record->event->character, nullptr);
1093 EXPECT_EQ(record->event->synthesized, false);
1094
1096 g_ptr_array_clear(g_call_records);
1097
1098 // Test 2: synthesize key up.
1099
1100 // Send a ControlLeft down.
1101 state = static_cast<GdkModifierType>(0);
1103 responder,
1104 fl_key_event_new_by_mock(102, kPress, GDK_KEY_Control_L,
1105 kKeyCodeControlLeft, state, kIsModifier),
1107 EXPECT_EQ(g_call_records->len, 1u);
1108 record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 0));
1110 g_ptr_array_clear(g_call_records);
1111
1112 // A key up of control left is missed.
1113 state = static_cast<GdkModifierType>(0);
1114
1115 // Send another ControlLeft down
1117 responder,
1118 fl_key_event_new_by_mock(103, kPress, GDK_KEY_Control_L,
1119 kKeyCodeControlLeft, state, kIsModifier),
1121
1122 EXPECT_EQ(g_call_records->len, 2u);
1123 record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 0));
1124 EXPECT_EQ(record->event->timestamp, 103000);
1125 EXPECT_EQ(record->event->type, kFlutterKeyEventTypeUp);
1126 EXPECT_EQ(record->event->physical, kPhysicalControlLeft);
1127 EXPECT_EQ(record->event->logical, kLogicalControlLeft);
1128 EXPECT_STREQ(record->event->character, nullptr);
1129 EXPECT_EQ(record->event->synthesized, true);
1130
1131 record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 1));
1132 EXPECT_EQ(record->event->timestamp, 103000);
1133 EXPECT_EQ(record->event->type, kFlutterKeyEventTypeDown);
1134 EXPECT_EQ(record->event->physical, kPhysicalControlLeft);
1135 EXPECT_EQ(record->event->logical, kLogicalControlLeft);
1136 EXPECT_STREQ(record->event->character, nullptr);
1137 EXPECT_EQ(record->event->synthesized, false);
1138
1140 g_ptr_array_clear(g_call_records);
1141
1142 // Send a ControlLeft up to clear up state.
1143 state = GDK_CONTROL_MASK;
1145 responder,
1146 fl_key_event_new_by_mock(104, kRelease, GDK_KEY_Control_L,
1147 kKeyCodeControlLeft, state, kIsModifier),
1149 EXPECT_EQ(g_call_records->len, 1u);
1150 record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 0));
1152 g_ptr_array_clear(g_call_records);
1153
1154 // Test 3: synthesize by right modifier.
1155
1156 // A key down of control right is missed.
1157 state = GDK_CONTROL_MASK;
1158
1159 // Send a ControlRight up.
1161 responder,
1162 fl_key_event_new_by_mock(105, kRelease, GDK_KEY_Control_R,
1163 kKeyCodeControlRight, state, kIsModifier),
1165
1166 // A ControlLeft down is synthesized, with an empty event.
1167 // Reason: The ControlLeft down is synthesized to synchronize the state
1168 // showing Control as pressed. The ControlRight event is ignored because
1169 // the event is considered a duplicate up event.
1170 EXPECT_EQ(g_call_records->len, 1u);
1171 record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 0));
1172 EXPECT_EQ(record->event->timestamp, 105000);
1173 EXPECT_EQ(record->event->type, kFlutterKeyEventTypeDown);
1174 EXPECT_EQ(record->event->physical, kPhysicalControlLeft);
1175 EXPECT_EQ(record->event->logical, kLogicalControlLeft);
1176 EXPECT_STREQ(record->event->character, nullptr);
1177 EXPECT_EQ(record->event->synthesized, true);
1178
1179 g_ptr_array_clear(g_call_records);
1180
1182 g_object_unref(responder);
1183}
constexpr int kKeyCodeControlLeft

◆ TEST() [13/17]

TEST ( FlKeyEmbedderResponderTest  ,
TapLetterKeysBetweenCapsLockEvents   
)

Definition at line 648 of file fl_key_embedder_responder_test.cc.

648 {
649 EXPECT_EQ(g_call_records, nullptr);
650 g_call_records = g_ptr_array_new_with_free_func(g_object_unref);
651 FlKeyResponder* responder = FL_KEY_RESPONDER(
653 int user_data = 123; // Arbitrary user data
654
655 FlKeyEmbedderCallRecord* record;
656
657 // Press CapsLock (stage 0 -> 1)
659 responder,
660 fl_key_event_new_by_mock(101, kPress, GDK_KEY_Caps_Lock, kKeyCodeCapsLock,
661 static_cast<GdkModifierType>(0), kIsModifier),
663
664 EXPECT_EQ(g_call_records->len, 1u);
665 record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 0));
666 EXPECT_EQ(record->event->type, kFlutterKeyEventTypeDown);
667 EXPECT_EQ(record->event->physical, kPhysicalCapsLock);
668 EXPECT_EQ(record->event->logical, kLogicalCapsLock);
669 EXPECT_STREQ(record->event->character, nullptr);
670 EXPECT_EQ(record->event->synthesized, false);
671
673 g_ptr_array_clear(g_call_records);
674
675 // Press key A (stage 1)
677 responder,
678 fl_key_event_new_by_mock(102, kPress, GDK_KEY_A, kKeyCodeKeyA,
679 GDK_LOCK_MASK, kIsNotModifier),
681
682 EXPECT_EQ(g_call_records->len, 1u);
683 record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 0));
684 EXPECT_EQ(record->event->type, kFlutterKeyEventTypeDown);
685 EXPECT_EQ(record->event->physical, kPhysicalKeyA);
686 EXPECT_EQ(record->event->logical, kLogicalKeyA);
687 EXPECT_STREQ(record->event->character, "A");
688 EXPECT_EQ(record->event->synthesized, false);
689
691 g_ptr_array_clear(g_call_records);
692
693 // Release CapsLock (stage 1 -> 2)
695 responder,
696 fl_key_event_new_by_mock(103, kRelease, GDK_KEY_Caps_Lock,
697 kKeyCodeCapsLock, GDK_LOCK_MASK, kIsModifier),
699
700 EXPECT_EQ(g_call_records->len, 1u);
701 record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 0));
702 EXPECT_EQ(record->event->type, kFlutterKeyEventTypeUp);
703 EXPECT_EQ(record->event->physical, kPhysicalCapsLock);
704 EXPECT_EQ(record->event->logical, kLogicalCapsLock);
705 EXPECT_STREQ(record->event->character, nullptr);
706 EXPECT_EQ(record->event->synthesized, false);
707
709 g_ptr_array_clear(g_call_records);
710
711 // Release key A (stage 2)
713 responder,
714 fl_key_event_new_by_mock(104, kRelease, GDK_KEY_A, kKeyCodeKeyA,
715 GDK_LOCK_MASK, kIsNotModifier),
717
718 EXPECT_EQ(g_call_records->len, 1u);
719 record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 0));
720 EXPECT_EQ(record->event->type, kFlutterKeyEventTypeUp);
721 EXPECT_EQ(record->event->physical, kPhysicalKeyA);
722 EXPECT_EQ(record->event->logical, kLogicalKeyA);
723 EXPECT_STREQ(record->event->character, nullptr);
724 EXPECT_EQ(record->event->synthesized, false);
725
727 g_ptr_array_clear(g_call_records);
728
729 // Press CapsLock (stage 2 -> 3)
731 responder,
732 fl_key_event_new_by_mock(105, kPress, GDK_KEY_Caps_Lock, kKeyCodeCapsLock,
733 GDK_LOCK_MASK, kIsModifier),
735
736 EXPECT_EQ(g_call_records->len, 1u);
737 record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 0));
738 EXPECT_EQ(record->event->type, kFlutterKeyEventTypeDown);
739 EXPECT_EQ(record->event->physical, kPhysicalCapsLock);
740 EXPECT_EQ(record->event->logical, kLogicalCapsLock);
741 EXPECT_STREQ(record->event->character, nullptr);
742 EXPECT_EQ(record->event->synthesized, false);
743
745 g_ptr_array_clear(g_call_records);
746
747 // Press key A (stage 3)
749 responder,
750 fl_key_event_new_by_mock(106, kPress, GDK_KEY_A, kKeyCodeKeyA,
751 GDK_LOCK_MASK, kIsNotModifier),
753
754 EXPECT_EQ(g_call_records->len, 1u);
755 record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 0));
756 EXPECT_EQ(record->event->type, kFlutterKeyEventTypeDown);
757 EXPECT_EQ(record->event->physical, kPhysicalKeyA);
758 EXPECT_EQ(record->event->logical, kLogicalKeyA);
759 EXPECT_STREQ(record->event->character, "A");
760 EXPECT_EQ(record->event->synthesized, false);
761
763 g_ptr_array_clear(g_call_records);
764
765 // Release CapsLock (stage 3 -> 0)
767 responder,
768 fl_key_event_new_by_mock(107, kRelease, GDK_KEY_Caps_Lock,
769 kKeyCodeCapsLock, GDK_LOCK_MASK, kIsModifier),
771
772 EXPECT_EQ(g_call_records->len, 1u);
773 record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 0));
774 EXPECT_EQ(record->event->type, kFlutterKeyEventTypeUp);
775 EXPECT_EQ(record->event->physical, kPhysicalCapsLock);
776 EXPECT_EQ(record->event->logical, kLogicalCapsLock);
777 EXPECT_STREQ(record->event->character, nullptr);
778 EXPECT_EQ(record->event->synthesized, false);
779
781 g_ptr_array_clear(g_call_records);
782
783 // Release key A (stage 0)
785 responder,
786 fl_key_event_new_by_mock(108, kRelease, GDK_KEY_a, kKeyCodeKeyA,
787 static_cast<GdkModifierType>(0), kIsNotModifier),
789
790 EXPECT_EQ(g_call_records->len, 1u);
791 record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 0));
792 EXPECT_EQ(record->event->type, kFlutterKeyEventTypeUp);
793 EXPECT_EQ(record->event->physical, kPhysicalKeyA);
794 EXPECT_EQ(record->event->logical, kLogicalKeyA);
795 EXPECT_STREQ(record->event->character, nullptr);
796 EXPECT_EQ(record->event->synthesized, false);
797
799 g_ptr_array_clear(g_call_records);
800
802 g_object_unref(responder);
803}
constexpr uint64_t kLogicalCapsLock
Definition: key_codes.g.h:377

◆ TEST() [14/17]

TEST ( FlKeyEmbedderResponderTest  ,
TapLetterKeysBetweenCapsLockEventsReversed   
)

Definition at line 809 of file fl_key_embedder_responder_test.cc.

809 {
810 EXPECT_EQ(g_call_records, nullptr);
811 g_call_records = g_ptr_array_new_with_free_func(g_object_unref);
812 FlKeyResponder* responder = FL_KEY_RESPONDER(
814 int user_data = 123; // Arbitrary user data
815
816 FlKeyEmbedderCallRecord* record;
817
818 // Press key A (stage 0)
820 responder,
821 fl_key_event_new_by_mock(101, kPress, GDK_KEY_a, kKeyCodeKeyA,
822 static_cast<GdkModifierType>(0), kIsNotModifier),
824
825 EXPECT_EQ(g_call_records->len, 1u);
826 record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 0));
827 EXPECT_EQ(record->event->type, kFlutterKeyEventTypeDown);
828 EXPECT_EQ(record->event->physical, kPhysicalKeyA);
829 EXPECT_EQ(record->event->logical, kLogicalKeyA);
830 EXPECT_STREQ(record->event->character, "a");
831 EXPECT_EQ(record->event->synthesized, false);
832
834 g_ptr_array_clear(g_call_records);
835
836 // Press CapsLock (stage 0 -> 1)
838 responder,
839 fl_key_event_new_by_mock(102, kPress, GDK_KEY_Caps_Lock, kKeyCodeCapsLock,
840 GDK_LOCK_MASK, kIsModifier),
842
843 EXPECT_EQ(g_call_records->len, 1u);
844 record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 0));
845 EXPECT_EQ(record->event->type, kFlutterKeyEventTypeDown);
846 EXPECT_EQ(record->event->physical, kPhysicalCapsLock);
847 EXPECT_EQ(record->event->logical, kLogicalCapsLock);
848 EXPECT_STREQ(record->event->character, nullptr);
849 EXPECT_EQ(record->event->synthesized, false);
850
852 g_ptr_array_clear(g_call_records);
853
854 // Release CapsLock (stage 1 -> 2)
856 responder,
857 fl_key_event_new_by_mock(103, kRelease, GDK_KEY_Caps_Lock,
858 kKeyCodeCapsLock, GDK_LOCK_MASK, kIsModifier),
860
861 EXPECT_EQ(g_call_records->len, 1u);
862 record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 0));
863 EXPECT_EQ(record->event->type, kFlutterKeyEventTypeUp);
864 EXPECT_EQ(record->event->physical, kPhysicalCapsLock);
865 EXPECT_EQ(record->event->logical, kLogicalCapsLock);
866 EXPECT_STREQ(record->event->character, nullptr);
867 EXPECT_EQ(record->event->synthesized, false);
868
870 g_ptr_array_clear(g_call_records);
871
872 // Release key A (stage 2)
874 responder,
875 fl_key_event_new_by_mock(104, kRelease, GDK_KEY_A, kKeyCodeKeyA,
876 GDK_LOCK_MASK, kIsNotModifier),
878
879 EXPECT_EQ(g_call_records->len, 1u);
880 record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 0));
881 EXPECT_EQ(record->event->type, kFlutterKeyEventTypeUp);
882 EXPECT_EQ(record->event->physical, kPhysicalKeyA);
883 EXPECT_EQ(record->event->logical, kLogicalKeyA);
884 EXPECT_STREQ(record->event->character, nullptr);
885 EXPECT_EQ(record->event->synthesized, false);
886
888 g_ptr_array_clear(g_call_records);
889
890 // Press key A (stage 2)
892 responder,
893 fl_key_event_new_by_mock(105, kPress, GDK_KEY_A, kKeyCodeKeyA,
894 GDK_LOCK_MASK, kIsNotModifier),
896
897 EXPECT_EQ(g_call_records->len, 1u);
898 record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 0));
899 EXPECT_EQ(record->event->type, kFlutterKeyEventTypeDown);
900 EXPECT_EQ(record->event->physical, kPhysicalKeyA);
901 EXPECT_EQ(record->event->logical, kLogicalKeyA);
902 EXPECT_STREQ(record->event->character, "A");
903 EXPECT_EQ(record->event->synthesized, false);
904
906 g_ptr_array_clear(g_call_records);
907
908 // Press CapsLock (stage 2 -> 3)
910 responder,
911 fl_key_event_new_by_mock(106, kPress, GDK_KEY_Caps_Lock, kKeyCodeCapsLock,
912 static_cast<GdkModifierType>(0), kIsModifier),
914
915 EXPECT_EQ(g_call_records->len, 1u);
916 record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 0));
917 EXPECT_EQ(record->event->type, kFlutterKeyEventTypeDown);
918 EXPECT_EQ(record->event->physical, kPhysicalCapsLock);
919 EXPECT_EQ(record->event->logical, kLogicalCapsLock);
920 EXPECT_STREQ(record->event->character, nullptr);
921 EXPECT_EQ(record->event->synthesized, false);
922
924 g_ptr_array_clear(g_call_records);
925
926 // Release CapsLock (stage 3 -> 0)
928 responder,
929 fl_key_event_new_by_mock(107, kRelease, GDK_KEY_Caps_Lock,
930 kKeyCodeCapsLock, GDK_LOCK_MASK, kIsModifier),
932
933 EXPECT_EQ(g_call_records->len, 1u);
934 record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 0));
935 EXPECT_EQ(record->event->type, kFlutterKeyEventTypeUp);
936 EXPECT_EQ(record->event->physical, kPhysicalCapsLock);
937 EXPECT_EQ(record->event->logical, kLogicalCapsLock);
938 EXPECT_STREQ(record->event->character, nullptr);
939 EXPECT_EQ(record->event->synthesized, false);
940
942 g_ptr_array_clear(g_call_records);
943
944 // Release key A (stage 0)
946 responder,
947 fl_key_event_new_by_mock(108, kRelease, GDK_KEY_a, kKeyCodeKeyA,
948 static_cast<GdkModifierType>(0), kIsNotModifier),
950
951 EXPECT_EQ(g_call_records->len, 1u);
952 record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 0));
953 EXPECT_EQ(record->event->type, kFlutterKeyEventTypeUp);
954 EXPECT_EQ(record->event->physical, kPhysicalKeyA);
955 EXPECT_EQ(record->event->logical, kLogicalKeyA);
956 EXPECT_STREQ(record->event->character, nullptr);
957 EXPECT_EQ(record->event->synthesized, false);
958
960 g_ptr_array_clear(g_call_records);
961
963 g_object_unref(responder);
964}

◆ TEST() [15/17]

TEST ( FlKeyEmbedderResponderTest  ,
TapNumPadKeysBetweenNumLockEvents   
)

Definition at line 392 of file fl_key_embedder_responder_test.cc.

392 {
393 EXPECT_EQ(g_call_records, nullptr);
394 g_call_records = g_ptr_array_new_with_free_func(g_object_unref);
395 FlKeyResponder* responder = FL_KEY_RESPONDER(
397 int user_data = 123; // Arbitrary user data
398
399 FlKeyEmbedderCallRecord* record;
400
401 // Press Numpad 1 (stage 0)
403 responder,
404 fl_key_event_new_by_mock(101, kPress, GDK_KEY_KP_End, kKeyCodeNumpad1,
405 static_cast<GdkModifierType>(0), kIsNotModifier),
407
408 EXPECT_EQ(g_call_records->len, 1u);
409 record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 0));
410 EXPECT_EQ(record->event->type, kFlutterKeyEventTypeDown);
411 EXPECT_EQ(record->event->physical, kPhysicalNumpad1);
412 EXPECT_EQ(record->event->logical, kLogicalNumpad1);
413 EXPECT_STREQ(record->event->character, nullptr); // TODO(chrome-bot):
414 EXPECT_EQ(record->event->synthesized, false);
415
417 g_ptr_array_clear(g_call_records);
418
419 // Press NumLock (stage 0 -> 1)
421 responder,
422 fl_key_event_new_by_mock(102, kPress, GDK_KEY_Num_Lock, kKeyCodeNumLock,
423 static_cast<GdkModifierType>(0), kIsNotModifier),
425
426 EXPECT_EQ(g_call_records->len, 1u);
427 record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 0));
428 EXPECT_EQ(record->event->type, kFlutterKeyEventTypeDown);
429 EXPECT_EQ(record->event->physical, kPhysicalNumLock);
430 EXPECT_EQ(record->event->logical, kLogicalNumLock);
431 EXPECT_STREQ(record->event->character, nullptr);
432 EXPECT_EQ(record->event->synthesized, false);
433
435 g_ptr_array_clear(g_call_records);
436
437 // Release numpad 1 (stage 1)
439 responder,
440 fl_key_event_new_by_mock(104, kRelease, GDK_KEY_KP_1, kKeyCodeNumpad1,
441 GDK_MOD2_MASK, kIsNotModifier),
443
444 EXPECT_EQ(g_call_records->len, 1u);
445 record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 0));
446 EXPECT_EQ(record->event->type, kFlutterKeyEventTypeUp);
447 EXPECT_EQ(record->event->physical, kPhysicalNumpad1);
448 EXPECT_EQ(record->event->logical, kLogicalNumpad1);
449 EXPECT_STREQ(record->event->character, nullptr);
450 EXPECT_EQ(record->event->synthesized, false);
451
453 g_ptr_array_clear(g_call_records);
454
455 // Release NumLock (stage 1 -> 2)
457 responder,
458 fl_key_event_new_by_mock(103, kRelease, GDK_KEY_Num_Lock, kKeyCodeNumLock,
459 GDK_MOD2_MASK, kIsModifier),
461
462 EXPECT_EQ(g_call_records->len, 1u);
463 record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 0));
464 EXPECT_EQ(record->event->type, kFlutterKeyEventTypeUp);
465 EXPECT_EQ(record->event->physical, kPhysicalNumLock);
466 EXPECT_EQ(record->event->logical, kLogicalNumLock);
467 EXPECT_STREQ(record->event->character, nullptr);
468 EXPECT_EQ(record->event->synthesized, false);
469
471 g_ptr_array_clear(g_call_records);
472
473 // Press Numpad 1 (stage 2)
475 responder,
476 fl_key_event_new_by_mock(101, kPress, GDK_KEY_KP_End, kKeyCodeNumpad1,
477 GDK_MOD2_MASK, kIsNotModifier),
479
480 EXPECT_EQ(g_call_records->len, 1u);
481 record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 0));
482 EXPECT_EQ(record->event->type, kFlutterKeyEventTypeDown);
483 EXPECT_EQ(record->event->physical, kPhysicalNumpad1);
484 EXPECT_EQ(record->event->logical, kLogicalNumpad1);
485 EXPECT_STREQ(record->event->character, nullptr); // TODO(chrome-bot):
486 EXPECT_EQ(record->event->synthesized, false);
487
489 g_ptr_array_clear(g_call_records);
490
491 // Press NumLock (stage 2 -> 3)
493 responder,
494 fl_key_event_new_by_mock(102, kPress, GDK_KEY_Num_Lock, kKeyCodeNumLock,
495 GDK_MOD2_MASK, kIsNotModifier),
497
498 EXPECT_EQ(g_call_records->len, 1u);
499 record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 0));
500 EXPECT_EQ(record->event->type, kFlutterKeyEventTypeDown);
501 EXPECT_EQ(record->event->physical, kPhysicalNumLock);
502 EXPECT_EQ(record->event->logical, kLogicalNumLock);
503 EXPECT_STREQ(record->event->character, nullptr);
504 EXPECT_EQ(record->event->synthesized, false);
505
507 g_ptr_array_clear(g_call_records);
508
509 // Release numpad 1 (stage 3)
511 responder,
512 fl_key_event_new_by_mock(104, kRelease, GDK_KEY_KP_1, kKeyCodeNumpad1,
513 GDK_MOD2_MASK, kIsNotModifier),
515
516 EXPECT_EQ(g_call_records->len, 1u);
517 record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 0));
518 EXPECT_EQ(record->event->type, kFlutterKeyEventTypeUp);
519 EXPECT_EQ(record->event->physical, kPhysicalNumpad1);
520 EXPECT_EQ(record->event->logical, kLogicalNumpad1);
521 EXPECT_STREQ(record->event->character, nullptr);
522 EXPECT_EQ(record->event->synthesized, false);
523
525 g_ptr_array_clear(g_call_records);
526
527 // Release NumLock (stage 3 -> 0)
529 responder,
530 fl_key_event_new_by_mock(103, kRelease, GDK_KEY_Num_Lock, kKeyCodeNumLock,
531 GDK_MOD2_MASK, kIsModifier),
533
534 EXPECT_EQ(g_call_records->len, 1u);
535 record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 0));
536 EXPECT_EQ(record->event->type, kFlutterKeyEventTypeUp);
537 EXPECT_EQ(record->event->physical, kPhysicalNumLock);
538 EXPECT_EQ(record->event->logical, kLogicalNumLock);
539 EXPECT_STREQ(record->event->character, nullptr);
540 EXPECT_EQ(record->event->synthesized, false);
541
543 g_ptr_array_clear(g_call_records);
544
546 g_object_unref(responder);
547}
constexpr uint64_t kLogicalNumpad1
Definition: key_codes.g.h:703
constexpr uint64_t kPhysicalNumpad1
Definition: key_codes.g.h:161

◆ TEST() [16/17]

TEST ( FlKeyEmbedderResponderTest  ,
TurnDuplicateDownEventsToRepeats   
)

Definition at line 966 of file fl_key_embedder_responder_test.cc.

966 {
967 EXPECT_EQ(g_call_records, nullptr);
968 g_call_records = g_ptr_array_new_with_free_func(g_object_unref);
969 FlKeyResponder* responder = FL_KEY_RESPONDER(
971 int user_data = 123; // Arbitrary user data
972
973 FlKeyEmbedderCallRecord* record;
974
975 // Press KeyA
977 responder,
978 fl_key_event_new_by_mock(101, kPress, GDK_KEY_a, kKeyCodeKeyA,
979 static_cast<GdkModifierType>(0), kIsNotModifier),
981
982 EXPECT_EQ(g_call_records->len, 1u);
983
984 record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 0));
986 g_ptr_array_clear(g_call_records);
987
988 // Another KeyA down events, which usually means a repeated event.
989 g_expected_handled = false;
991 responder,
992 fl_key_event_new_by_mock(102, kPress, GDK_KEY_a, kKeyCodeKeyA,
993 static_cast<GdkModifierType>(0), kIsNotModifier),
995
996 EXPECT_EQ(g_call_records->len, 1u);
997
998 record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 0));
999 EXPECT_EQ(record->event->type, kFlutterKeyEventTypeRepeat);
1000 EXPECT_EQ(record->event->physical, kPhysicalKeyA);
1001 EXPECT_EQ(record->event->logical, kLogicalKeyA);
1002 EXPECT_STREQ(record->event->character, "a");
1003 EXPECT_EQ(record->event->synthesized, false);
1004 EXPECT_NE(record->callback, nullptr);
1005
1007 g_ptr_array_clear(g_call_records);
1008
1009 // Release KeyA
1011 responder,
1012 fl_key_event_new_by_mock(103, kRelease, GDK_KEY_q, kKeyCodeKeyA,
1013 static_cast<GdkModifierType>(0), kIsNotModifier),
1015
1016 EXPECT_EQ(g_call_records->len, 1u);
1017 record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 0));
1019 g_ptr_array_clear(g_call_records);
1020
1022 g_object_unref(responder);
1023}
@ kFlutterKeyEventTypeRepeat
Definition: embedder.h:1077

◆ TEST() [17/17]

TEST ( FlKeyEmbedderResponderTest  ,
UsesSpecifiedLogicalKey   
)

Definition at line 264 of file fl_key_embedder_responder_test.cc.

264 {
265 EXPECT_EQ(g_call_records, nullptr);
266 g_call_records = g_ptr_array_new_with_free_func(g_object_unref);
267 FlKeyResponder* responder = FL_KEY_RESPONDER(
269 int user_data = 123; // Arbitrary user data
270
271 FlKeyEmbedderCallRecord* record;
272
273 // On an AZERTY keyboard, press physical key 1, and release.
274 // Key down
276 responder,
277 fl_key_event_new_by_mock(12345, kPress, GDK_KEY_ampersand, kKeyCodeDigit1,
278 static_cast<GdkModifierType>(0), kIsNotModifier),
280
281 EXPECT_EQ(g_call_records->len, 1u);
282 record = FL_KEY_EMBEDDER_CALL_RECORD(g_ptr_array_index(g_call_records, 0));
283 EXPECT_EQ(record->event->struct_size, sizeof(FlutterKeyEvent));
284 EXPECT_EQ(record->event->timestamp, 12345000);
285 EXPECT_EQ(record->event->type, kFlutterKeyEventTypeDown);
286 EXPECT_EQ(record->event->physical, kPhysicalDigit1);
287 EXPECT_EQ(record->event->logical, kLogicalDigit1);
288 EXPECT_STREQ(record->event->character, "&");
289 EXPECT_EQ(record->event->synthesized, false);
290
292 g_ptr_array_clear(g_call_records);
293
295 g_object_unref(responder);
296}
constexpr uint64_t kLogicalDigit1
Definition: key_codes.g.h:317

◆ verify_response_handled()

static void verify_response_handled ( bool  handled,
gpointer  user_data 
)
static

Definition at line 133 of file fl_key_embedder_responder_test.cc.

133 {
134 EXPECT_EQ(handled, g_expected_handled);
135}

Variable Documentation

◆ g_expected_handled

gboolean g_expected_handled
static

Definition at line 130 of file fl_key_embedder_responder_test.cc.

◆ g_expected_user_data

gpointer g_expected_user_data
static

Definition at line 131 of file fl_key_embedder_responder_test.cc.