5#import <Foundation/Foundation.h>
6#import <OCMock/OCMock.h>
7#import <XCTest/XCTest.h>
8#include <_types/_uint64_t.h>
10#import "flutter/shell/platform/darwin/common/framework/Headers/FlutterMacros.h"
11#import "flutter/shell/platform/darwin/ios/framework/Source/FlutterEmbedderKeyResponder.h"
12#import "flutter/shell/platform/darwin/ios/framework/Source/FlutterFakeKeyEvents.h"
13#import "flutter/shell/platform/darwin/ios/framework/Source/KeyCodeMap_Internal.h"
14#include "flutter/shell/platform/embedder/embedder.h"
15#include "flutter/shell/platform/embedder/test_utils/key_codes.g.h"
22#define XCTAssertStrEqual(value, expected) \
23 XCTAssertTrue(strcmp(value, expected) == 0, \
24 @"String \"%s\" not equal to the expected value of \"%s\"", value, expected)
36 userData:(nullable
void*)userData {
39 if (
event->character !=
nullptr) {
40 size_t len = strlen(
event->character);
51 return _callback != nil;
54- (void)respond:(
BOOL)handled {
57 @"Improper call to `respond` that does not have a callback.");
58 _callback(handled, _userData);
62 if (_data->character !=
nullptr) {
63 delete[] _data->character;
71constexpr UIKeyboardHIDUsage kKeyCodeUndefined = (UIKeyboardHIDUsage)0x03;
73constexpr UIKeyboardHIDUsage kKeyCodeKeyA = (UIKeyboardHIDUsage)0x04;
75constexpr UIKeyboardHIDUsage kKeyCodePeriod = (UIKeyboardHIDUsage)0x37;
77constexpr UIKeyboardHIDUsage kKeyCodeKeyW = (UIKeyboardHIDUsage)0x1a;
81constexpr UIKeyboardHIDUsage kKeyCodeShiftRight = (UIKeyboardHIDUsage)0xe5;
83constexpr UIKeyboardHIDUsage kKeyCodeNumpad1 = (UIKeyboardHIDUsage)0x59;
85constexpr UIKeyboardHIDUsage kKeyCodeCapsLock = (UIKeyboardHIDUsage)0x39;
87constexpr UIKeyboardHIDUsage kKeyCodeF1 = (UIKeyboardHIDUsage)0x3a;
89constexpr UIKeyboardHIDUsage kKeyCodeCommandLeft = (UIKeyboardHIDUsage)0xe3;
91constexpr UIKeyboardHIDUsage kKeyCodeAltRight = (UIKeyboardHIDUsage)0xe6;
93constexpr UIKeyboardHIDUsage kKeyCodeEject = (UIKeyboardHIDUsage)0xb8;
95constexpr uint64_t kPhysicalKeyUndefined = 0x00070003;
97constexpr uint64_t kLogicalKeyUndefined = 0x1300000003;
99constexpr uint64_t kModifierFlagNone = 0x0;
101typedef
void (^ResponseCallback)(
bool handled);
111 if (@available(iOS 13.4, *)) {
113 XCTSkip(
@"Required API not present for test.");
124 __block NSMutableArray<TestKeyEvent*>* events = [[NSMutableArray<TestKeyEvent*> alloc] init];
129 initWithSendEvent:^(const FlutterKeyEvent& event, _Nullable FlutterKeyEventCallback callback,
130 void* _Nullable user_data) {
131 [events addObject:[[
TestKeyEvent alloc] initWithEvent:&event
133 userData:user_data]];
136 last_handled =
FALSE;
137 [responder
handlePress:keyDownEvent(kKeyCodeKeyA, kModifierFlagNone, 123.0f, "a", "a")
139 last_handled = handled;
142 XCTAssertEqual([events
count], 1u);
143 event = [events lastObject].data;
144 XCTAssertNotEqual(
event,
nullptr);
147 XCTAssertEqual(
event->timestamp, 123000000.0f);
151 XCTAssertEqual(
event->synthesized,
false);
153 XCTAssertEqual(last_handled,
FALSE);
155 [[events lastObject] respond:TRUE];
156 XCTAssertEqual(last_handled,
TRUE);
158 [events removeAllObjects];
161 [responder
handlePress:keyUpEvent(kKeyCodeKeyA, kModifierFlagNone, 123.0f)
163 last_handled = handled;
166 XCTAssertEqual([events
count], 1u);
167 event = [events lastObject].data;
168 XCTAssertNotEqual(
event,
nullptr);
171 XCTAssertEqual(
event->timestamp, 123000000.0f);
174 XCTAssertEqual(
event->character,
nullptr);
175 XCTAssertEqual(
event->synthesized,
false);
177 XCTAssertEqual(last_handled,
TRUE);
179 [[events lastObject] respond:FALSE];
180 XCTAssertEqual(last_handled,
FALSE);
182 [events removeAllObjects];
186 __block NSMutableArray<TestKeyEvent*>* events = [[NSMutableArray<TestKeyEvent*> alloc] init];
191 initWithSendEvent:^(const FlutterKeyEvent& event, _Nullable FlutterKeyEventCallback callback,
192 void* _Nullable user_data) {
193 [events addObject:[[
TestKeyEvent alloc] initWithEvent:&event
195 userData:user_data]];
198 last_handled =
FALSE;
201 [responder
handlePress:keyDownEvent(kKeyCodeEject, kModifierFlagNone, 123.0f)
203 last_handled = handled;
206 XCTAssertEqual([events
count], 1u);
207 event = [events lastObject].data;
208 XCTAssertNotEqual(
event,
nullptr);
213 XCTAssertEqual(
event->character,
nullptr);
214 XCTAssertEqual(
event->synthesized,
false);
216 XCTAssertEqual(last_handled,
FALSE);
217 XCTAssert([[events lastObject] hasCallback]);
218 [[events lastObject] respond:TRUE];
219 XCTAssertEqual(last_handled,
TRUE);
221 [events removeAllObjects];
224 [responder
handlePress:keyUpEvent(kKeyCodeEject, kModifierFlagNone, 123.0f)
226 last_handled = handled;
229 XCTAssertEqual([events
count], 1u);
230 event = [events lastObject].data;
231 XCTAssertNotEqual(
event,
nullptr);
236 XCTAssertEqual(
event->character,
nullptr);
237 XCTAssertEqual(
event->synthesized,
false);
239 XCTAssertEqual(last_handled,
TRUE);
240 XCTAssert([[events lastObject] hasCallback]);
241 [[events lastObject] respond:FALSE];
242 XCTAssertEqual(last_handled,
FALSE);
244 [events removeAllObjects];
248 __block NSMutableArray<TestKeyEvent*>* events = [[NSMutableArray<TestKeyEvent*> alloc] init];
252 initWithSendEvent:^(const FlutterKeyEvent& event, _Nullable FlutterKeyEventCallback callback,
253 void* _Nullable user_data) {
254 [events addObject:[[
TestKeyEvent alloc] initWithEvent:&event
256 userData:user_data]];
261 [responder
handlePress:keyDownEvent(kKeyCodeAltRight, kModifierFlagAltAny, 123.0f)
265 XCTAssertEqual([events
count], 1u);
266 event = [events lastObject].data;
267 XCTAssertNotEqual(
event,
nullptr);
272 XCTAssertEqual(
event->character,
nullptr);
273 XCTAssertEqual(
event->synthesized,
false);
275 [events removeAllObjects];
278 [responder
handlePress:keyDownEvent(kKeyCodeKeyW, kModifierFlagAltAny, 123.0f, "∑", "w")
282 XCTAssertEqual([events
count], 1u);
283 event = [events lastObject].data;
284 XCTAssertNotEqual(
event,
nullptr);
290 XCTAssertEqual(
event->synthesized,
false);
292 [events removeAllObjects];
296 [responder
handlePress:keyUpEvent(kKeyCodeAltRight, kModifierFlagAltAny, 123.0f)
300 XCTAssertEqual([events
count], 1u);
301 event = [events lastObject].data;
302 XCTAssertNotEqual(
event,
nullptr);
307 XCTAssertEqual(
event->character,
nullptr);
308 XCTAssertEqual(
event->synthesized,
false);
310 [events removeAllObjects];
317 [responder
handlePress:keyUpEvent(kKeyCodeKeyW, kModifierFlagAltAny, 123.0f)
321 XCTAssertEqual([events
count], 1u);
322 event = [events lastObject].data;
323 XCTAssertNotEqual(
event,
nullptr);
328 XCTAssertEqual(
event->character,
nullptr);
329 XCTAssertEqual(
event->synthesized,
false);
331 [events removeAllObjects];
335 [responder
handlePress:keyDownEvent(kKeyCodeKeyA, kModifierFlagNone, 123.0f, "å", "a")
339 XCTAssertEqual([events
count], 1u);
340 event = [events lastObject].data;
341 XCTAssertNotEqual(
event,
nullptr);
347 XCTAssertEqual(
event->synthesized,
false);
351 __block NSMutableArray<TestKeyEvent*>* events = [[NSMutableArray<TestKeyEvent*> alloc] init];
356 initWithSendEvent:^(const FlutterKeyEvent& event, _Nullable FlutterKeyEventCallback callback,
357 void* _Nullable user_data) {
358 [events addObject:[[
TestKeyEvent alloc] initWithEvent:&event
360 userData:user_data]];
363 last_handled =
FALSE;
364 [responder
handlePress:keyDownEvent(kKeyCodeKeyA, kModifierFlagNone, 123.0f, "a", "a")
366 last_handled = handled;
369 XCTAssertEqual([events
count], 1u);
370 event = [events lastObject].data;
371 XCTAssertNotEqual(
event,
nullptr);
377 XCTAssertEqual(
event->synthesized,
false);
378 XCTAssertEqual(last_handled,
FALSE);
379 [[events lastObject] respond:TRUE];
380 XCTAssertEqual(last_handled,
TRUE);
382 [events removeAllObjects];
384 last_handled =
FALSE;
385 [responder
handlePress:keyDownEvent(kKeyCodeKeyA, kModifierFlagNone, 123.0f, "a", "a")
387 last_handled = handled;
390 XCTAssertEqual([events
count], 1u);
391 event = [events lastObject].data;
392 XCTAssertNotEqual(
event,
nullptr);
393 XCTAssertEqual(
event->physical, 0ull);
394 XCTAssertEqual(
event->logical, 0ull);
395 XCTAssertEqual(
event->synthesized,
false);
396 XCTAssertFalse([[events lastObject] hasCallback]);
397 XCTAssertEqual(last_handled,
TRUE);
399 [events removeAllObjects];
401 last_handled =
FALSE;
402 [responder
handlePress:keyUpEvent(kKeyCodeKeyA, kModifierFlagNone, 123.0f)
404 last_handled = handled;
407 XCTAssertEqual([events
count], 1u);
408 event = [events lastObject].data;
409 XCTAssertNotEqual(
event,
nullptr);
414 XCTAssertEqual(
event->character,
nullptr);
415 XCTAssertEqual(
event->synthesized,
false);
416 XCTAssertEqual(last_handled,
FALSE);
417 [[events lastObject] respond:TRUE];
418 XCTAssertEqual(last_handled,
TRUE);
420 [events removeAllObjects];
424 __block NSMutableArray<TestKeyEvent*>* events = [[NSMutableArray<TestKeyEvent*> alloc] init];
429 initWithSendEvent:^(const FlutterKeyEvent& event, _Nullable FlutterKeyEventCallback callback,
430 void* _Nullable user_data) {
431 [events addObject:[[
TestKeyEvent alloc] initWithEvent:&event
433 userData:user_data]];
436 last_handled =
FALSE;
437 [responder
handlePress:keyUpEvent(kKeyCodeKeyA, kModifierFlagNone, 123.0f)
439 last_handled = handled;
442 XCTAssertEqual([events
count], 1u);
443 event = [events lastObject].data;
444 XCTAssertNotEqual(
event,
nullptr);
445 XCTAssertEqual(
event->physical, 0ull);
446 XCTAssertEqual(
event->logical, 0ull);
447 XCTAssertEqual(
event->synthesized,
false);
448 XCTAssertFalse([[events lastObject] hasCallback]);
449 XCTAssertEqual(last_handled,
TRUE);
451 [events removeAllObjects];
459 __block NSMutableArray<TestKeyEvent*>* events = [[NSMutableArray<TestKeyEvent*> alloc] init];
463 initWithSendEvent:^(const FlutterKeyEvent& event, _Nullable FlutterKeyEventCallback callback,
464 void* _Nullable user_data) {
465 [events addObject:[[
TestKeyEvent alloc] initWithEvent:&event
467 userData:user_data]];
470 [responder
handlePress:keyDownEvent(kKeyCodeShiftRight, kModifierFlagShiftAny, 123.0f)
474 XCTAssertEqual([events
count], 1u);
476 event = [events lastObject].data;
477 XCTAssertNotEqual(
event,
nullptr);
480 XCTAssertEqual(
event->timestamp, 123000000.0f);
483 XCTAssertEqual(
event->character,
nullptr);
484 XCTAssertEqual(
event->synthesized,
false);
485 [[events lastObject] respond:TRUE];
487 [events removeAllObjects];
489 [responder
handlePress:keyDownEvent(kKeyCodeKeyA, kModifierFlagShiftAny, 123.0f, "A", "A")
493 XCTAssertEqual([events
count], 1u);
494 event = [events lastObject].data;
495 XCTAssertNotEqual(
event,
nullptr);
501 XCTAssertEqual(
event->synthesized,
false);
502 [[events lastObject] respond:TRUE];
504 [events removeAllObjects];
506 [responder
handlePress:keyUpEvent(kKeyCodeShiftRight, kModifierFlagNone, 123.0f)
510 XCTAssertEqual([events
count], 1u);
511 event = [events lastObject].data;
512 XCTAssertNotEqual(
event,
nullptr);
517 XCTAssertEqual(
event->character,
nullptr);
518 XCTAssertEqual(
event->synthesized,
false);
519 [[events lastObject] respond:TRUE];
521 [events removeAllObjects];
523 [responder
handlePress:keyUpEvent(kKeyCodeKeyA, kModifierFlagNone, 123.0f)
527 XCTAssertEqual([events
count], 1u);
528 event = [events lastObject].data;
529 XCTAssertNotEqual(
event,
nullptr);
534 XCTAssertEqual(
event->character,
nullptr);
535 XCTAssertEqual(
event->synthesized,
false);
536 [[events lastObject] respond:TRUE];
538 [events removeAllObjects];
547 __block NSMutableArray<TestKeyEvent*>* events = [[NSMutableArray<TestKeyEvent*> alloc] init];
550 id keyEventCallback = ^(
BOOL handled) {
551 last_handled = handled;
555 initWithSendEvent:^(const FlutterKeyEvent& event, _Nullable FlutterKeyEventCallback callback,
556 void* _Nullable user_data) {
557 [events addObject:[[
TestKeyEvent alloc] initWithEvent:&event
559 userData:user_data]];
567 [responder
handlePress:keyDownEvent(kKeyCodeNumpad1, kModifierFlagNumPadKey, 123.0, "1", "1")
570 XCTAssertEqual([events
count], 1u);
571 event = [events lastObject].data;
572 XCTAssertNotEqual(
event,
nullptr);
578 XCTAssertEqual(
event->synthesized,
false);
579 [[events lastObject] respond:TRUE];
581 [events removeAllObjects];
585 [responder
handlePress:keyDownEvent(kKeyCodeUndefined, kModifierFlagNone, 123.0)
588 XCTAssertEqual([events
count], 1u);
589 event = [events lastObject].data;
590 XCTAssertNotEqual(
event,
nullptr);
593 XCTAssertEqual(
event->physical, kPhysicalKeyUndefined);
594 XCTAssertEqual(
event->logical, kLogicalKeyUndefined);
595 XCTAssertEqual(
event->character,
nullptr);
596 XCTAssertEqual(
event->synthesized,
false);
597 [[events lastObject] respond:TRUE];
599 [events removeAllObjects];
603 [responder
handlePress:keyDownEvent(kKeyCodeF1, kModifierFlagNone, 123.0f, "\\^P", "\\^P")
606 XCTAssertEqual([events
count], 1u);
607 event = [events lastObject].data;
608 XCTAssertNotEqual(
event,
nullptr);
613 XCTAssertEqual(
event->character,
nullptr);
614 XCTAssertEqual(
event->synthesized,
false);
615 [[events lastObject] respond:TRUE];
617 [events removeAllObjects];
621 [responder
handlePress:keyDownEvent(kKeyCodeKeyA, kModifierFlagNone, 123.0f, "a", "a")
624 XCTAssertEqual([events
count], 1u);
625 event = [events lastObject].data;
626 XCTAssertNotEqual(
event,
nullptr);
632 XCTAssertEqual(
event->synthesized,
false);
633 [[events lastObject] respond:TRUE];
635 [events removeAllObjects];
639 [responder
handlePress:keyDownEvent(kKeyCodeShiftLeft, kModifierFlagShiftAny, 123.0f)
642 XCTAssertEqual([events
count], 1u);
643 event = [events lastObject].data;
644 XCTAssertNotEqual(
event,
nullptr);
649 XCTAssertEqual(
event->character,
nullptr);
650 XCTAssertEqual(
event->synthesized,
false);
652 [events removeAllObjects];
656 [responder
handlePress:keyUpEvent(kKeyCodeNumpad1, kModifierFlagNumPadKey, 123.0f)
659 XCTAssertEqual([events
count], 2u);
663 event = [events firstObject].data;
664 XCTAssertNotEqual(
event,
nullptr);
669 XCTAssertEqual(
event->character,
nullptr);
670 XCTAssertEqual(
event->synthesized,
true);
672 event = [events lastObject].data;
673 XCTAssertNotEqual(
event,
nullptr);
678 XCTAssertEqual(
event->character,
nullptr);
679 XCTAssertEqual(
event->synthesized,
false);
680 [[events lastObject] respond:TRUE];
682 [events removeAllObjects];
686 [responder
handlePress:keyUpEvent(kKeyCodeF1, kModifierFlagNone, 123.0f)
689 XCTAssertEqual([events
count], 1u);
690 event = [events lastObject].data;
691 XCTAssertNotEqual(
event,
nullptr);
696 XCTAssertEqual(
event->character,
nullptr);
697 XCTAssertEqual(
event->synthesized,
false);
698 [[events lastObject] respond:TRUE];
700 [events removeAllObjects];
704 [responder
handlePress:keyUpEvent(kKeyCodeUndefined, kModifierFlagNone, 123.0)
707 XCTAssertEqual([events
count], 1u);
708 event = [events lastObject].data;
709 XCTAssertNotEqual(
event,
nullptr);
712 XCTAssertEqual(
event->physical, kPhysicalKeyUndefined);
713 XCTAssertEqual(
event->logical, kLogicalKeyUndefined);
714 XCTAssertEqual(
event->synthesized,
false);
715 [[events lastObject] respond:TRUE];
717 [events removeAllObjects];
721 [responder
handlePress:keyUpEvent(kKeyCodeKeyA, kModifierFlagNone, 123.0f)
724 XCTAssertEqual([events
count], 1u);
725 event = [events lastObject].data;
726 XCTAssertNotEqual(
event,
nullptr);
731 XCTAssertEqual(
event->character,
nullptr);
732 XCTAssertEqual(
event->synthesized,
false);
733 [[events lastObject] respond:TRUE];
735 [events removeAllObjects];
739 [responder
handlePress:keyUpEvent(kKeyCodeShiftLeft, kModifierFlagShiftAny, 123.0f)
742 XCTAssertEqual([events
count], 1u);
743 event = [events lastObject].data;
744 XCTAssertNotEqual(
event,
nullptr);
745 XCTAssertEqual(
event->physical, 0ull);
746 XCTAssertEqual(
event->logical, 0ull);
747 XCTAssertEqual(
event->synthesized,
false);
748 XCTAssertFalse([[events lastObject] hasCallback]);
749 XCTAssertEqual(last_handled,
TRUE);
751 [events removeAllObjects];
755 __block NSMutableArray<TestKeyEvent*>* events = [[NSMutableArray<TestKeyEvent*> alloc] init];
759 initWithSendEvent:^(const FlutterKeyEvent& event, _Nullable FlutterKeyEventCallback callback,
760 void* _Nullable user_data) {
761 [events addObject:[[
TestKeyEvent alloc] initWithEvent:&event
763 userData:user_data]];
766 [responder
handlePress:keyDownEvent(kKeyCodeShiftLeft, kModifierFlagShiftAny, 123.0f)
770 XCTAssertEqual([events
count], 1u);
771 event = [events lastObject].data;
772 XCTAssertNotEqual(
event,
nullptr);
777 XCTAssertEqual(
event->character,
nullptr);
778 XCTAssertEqual(
event->synthesized,
false);
779 [[events lastObject] respond:TRUE];
781 [events removeAllObjects];
783 [responder
handlePress:keyDownEvent(kKeyCodeShiftRight, kModifierFlagShiftAny, 123.0f)
787 XCTAssertEqual([events
count], 1u);
788 event = [events lastObject].data;
789 XCTAssertNotEqual(
event,
nullptr);
794 XCTAssertEqual(
event->character,
nullptr);
795 XCTAssertEqual(
event->synthesized,
false);
796 [[events lastObject] respond:TRUE];
798 [events removeAllObjects];
800 [responder
handlePress:keyUpEvent(kKeyCodeShiftLeft, kModifierFlagShiftAny, 123.0f)
804 XCTAssertEqual([events
count], 1u);
805 event = [events lastObject].data;
806 XCTAssertNotEqual(
event,
nullptr);
811 XCTAssertEqual(
event->character,
nullptr);
812 XCTAssertEqual(
event->synthesized,
false);
813 [[events lastObject] respond:TRUE];
815 [events removeAllObjects];
817 [responder
handlePress:keyUpEvent(kKeyCodeShiftRight, kModifierFlagShiftAny, 123.0f)
821 XCTAssertEqual([events
count], 1u);
822 event = [events lastObject].data;
823 XCTAssertNotEqual(
event,
nullptr);
828 XCTAssertEqual(
event->character,
nullptr);
829 XCTAssertEqual(
event->synthesized,
false);
830 [[events lastObject] respond:TRUE];
832 [events removeAllObjects];
837 __block NSMutableArray<TestKeyEvent*>* events = [[NSMutableArray<TestKeyEvent*> alloc] init];
839 id keyEventCallback = ^(
BOOL handled) {
840 last_handled = handled;
845 initWithSendEvent:^(const FlutterKeyEvent& event, _Nullable FlutterKeyEventCallback callback,
846 void* _Nullable user_data) {
847 [events addObject:[[
TestKeyEvent alloc] initWithEvent:&event
849 userData:user_data]];
852 last_handled =
FALSE;
853 [responder
handlePress:keyDownEvent(kKeyCodeKeyA, kModifierFlagCapsLock, 123.0f, "A", "A")
856 XCTAssertEqual([events
count], 3u);
858 event = events[0].data;
859 XCTAssertNotEqual(
event,
nullptr);
864 XCTAssertEqual(
event->character,
nullptr);
865 XCTAssertEqual(
event->synthesized,
true);
866 XCTAssertFalse([events[0] hasCallback]);
868 event = events[1].data;
869 XCTAssertNotEqual(
event,
nullptr);
874 XCTAssertEqual(
event->character,
nullptr);
875 XCTAssertEqual(
event->synthesized,
true);
876 XCTAssertFalse([events[1] hasCallback]);
878 event = events[2].data;
879 XCTAssertNotEqual(
event,
nullptr);
885 XCTAssertEqual(
event->synthesized,
false);
886 XCTAssert([events[2] hasCallback]);
888 XCTAssertEqual(last_handled,
FALSE);
889 [[events lastObject] respond:TRUE];
890 XCTAssertEqual(last_handled,
TRUE);
892 [events removeAllObjects];
895 [responder
handlePress:keyUpEvent(kKeyCodeKeyA, kModifierFlagCapsLock, 123.0f)
897 XCTAssertEqual([events
count], 1u);
898 event = [events lastObject].data;
899 XCTAssertNotEqual(
event,
nullptr);
904 XCTAssertEqual(
event->synthesized,
false);
906 [events removeAllObjects];
910 last_handled =
FALSE;
911 [responder
handlePress:keyDownEvent(kKeyCodeCapsLock, kModifierFlagCapsLock, 123.0f)
914 XCTAssertEqual([events
count], 1u);
915 event = [events firstObject].data;
916 XCTAssertNotEqual(
event,
nullptr);
921 XCTAssertEqual(
event->character,
nullptr);
922 XCTAssertEqual(
event->synthesized,
false);
923 XCTAssert([[events firstObject] hasCallback]);
925 [events removeAllObjects];
931 last_handled =
FALSE;
932 [responder
handlePress:keyUpEvent(kKeyCodeCapsLock, kModifierFlagCapsLock, 123.0f)
935 XCTAssertEqual([events
count], 1u);
936 event = [events firstObject].data;
937 XCTAssertNotEqual(
event,
nullptr);
942 XCTAssertEqual(
event->character,
nullptr);
943 XCTAssertEqual(
event->synthesized,
false);
944 XCTAssert([[events firstObject] hasCallback]);
946 [events removeAllObjects];
948 last_handled =
FALSE;
949 [responder
handlePress:keyDownEvent(kKeyCodeKeyA, kModifierFlagNone, 123.0f, "a", "a")
954 XCTAssertEqual([events
count], 1u);
955 event = [events lastObject].data;
956 XCTAssertNotEqual(
event,
nullptr);
962 XCTAssertEqual(
event->synthesized,
false);
963 XCTAssert([[events firstObject] hasCallback]);
968 __block NSMutableArray<TestKeyEvent*>* events = [[NSMutableArray<TestKeyEvent*> alloc] init];
970 id keyEventCallback = ^(
BOOL handled) {
971 last_handled = handled;
976 initWithSendEvent:^(const FlutterKeyEvent& event, _Nullable FlutterKeyEventCallback callback,
977 void* _Nullable user_data) {
978 [events addObject:[[
TestKeyEvent alloc] initWithEvent:&event
980 userData:user_data]];
983 last_handled =
FALSE;
984 [responder
handlePress:keyDownEvent(kKeyCodeKeyA, kModifierFlagCapsLock, 123.0f, "A", "a")
987 XCTAssertEqual([events
count], 3u);
989 event = events[0].data;
994 XCTAssertEqual(
event->character,
nullptr);
995 XCTAssertEqual(
event->synthesized,
true);
996 XCTAssertFalse([events[0] hasCallback]);
998 event = events[1].data;
1003 XCTAssertEqual(
event->character,
nullptr);
1004 XCTAssertEqual(
event->synthesized,
true);
1005 XCTAssertFalse([events[1] hasCallback]);
1007 event = events[2].data;
1013 XCTAssertEqual(
event->synthesized,
false);
1014 XCTAssert([events[2] hasCallback]);
1016 XCTAssertEqual(last_handled,
FALSE);
1017 [[events lastObject] respond:TRUE];
1018 XCTAssertEqual(last_handled,
TRUE);
1020 [events removeAllObjects];
1025 __block NSMutableArray<TestKeyEvent*>* events = [[NSMutableArray<TestKeyEvent*> alloc] init];
1026 id keyEventCallback = ^(
BOOL handled) {
1031 initWithSendEvent:^(const FlutterKeyEvent& event, _Nullable FlutterKeyEventCallback callback,
1032 void* _Nullable user_data) {
1033 [events addObject:[[
TestKeyEvent alloc] initWithEvent:&event callback:nil userData:nil]];
1034 callback(true, user_data);
1038 [responder
handlePress:keyDownEvent(kKeyCodeCommandLeft, kModifierFlagMetaAny, 123.0f, "", "")
1040 XCTAssertEqual([events
count], 1u);
1041 event = events[0].data;
1046 XCTAssertEqual(
event->character,
nullptr);
1047 XCTAssertEqual(
event->synthesized,
false);
1048 [events removeAllObjects];
1051 [responder
handlePress:keyDownEvent(kKeyCodePeriod, kModifierFlagMetaAny, 123.0f,
1052 "UIKeyInputEscape", "UIKeyInputEscape")
1054 XCTAssertEqual([events
count], 1u);
1055 event = events[0].data;
1060 XCTAssertEqual(
event->character,
nullptr);
1061 XCTAssertEqual(
event->synthesized,
false);
1062 [events removeAllObjects];
1065 [responder
handlePress:keyUpEvent(kKeyCodePeriod, kModifierFlagMetaAny, 123.0f,
1066 "UIKeyInputEscape", "UIKeyInputEscape")
1068 XCTAssertEqual([events
count], 1u);
1069 event = events[0].data;
1074 XCTAssertEqual(
event->character,
nullptr);
1075 XCTAssertEqual(
event->synthesized,
false);
1076 [events removeAllObjects];
1079 [responder
handlePress:keyUpEvent(kKeyCodeCommandLeft, kModifierFlagMetaAny, 123.0f, "", "")
1081 XCTAssertEqual([events
count], 1u);
1082 event = events[0].data;
1087 XCTAssertEqual(
event->character,
nullptr);
1088 XCTAssertEqual(
event->synthesized,
false);
1089 [events removeAllObjects];
@ kFlutterKeyEventDeviceTypeKeyboard
void(* FlutterKeyEventCallback)(bool, void *)
@ kFlutterKeyEventTypeDown
void handlePress:callback:(nonnull FlutterUIPressProxy *press, [callback] ios(13.4) API_AVAILABLE)
FlutterKeyEventCallback callback
#define XCTAssertStrEqual(value, expected)
SK_API sk_sp< SkSurface > ios(9.0)
constexpr uint64_t kPhysicalAltRight
constexpr uint64_t kPhysicalKeyW
constexpr uint64_t kLogicalF1
constexpr uint64_t kLogicalShiftRight
constexpr uint64_t kLogicalNumpad1
constexpr uint64_t kPhysicalShiftLeft
constexpr uint64_t kLogicalEscape
constexpr uint64_t kPhysicalKeyA
constexpr uint64_t kLogicalMetaLeft
constexpr uint64_t kPhysicalCapsLock
constexpr uint64_t kLogicalKeyW
constexpr uint64_t kLogicalKeyA
constexpr uint64_t kLogicalAltRight
constexpr uint64_t kPhysicalF1
constexpr uint64_t kPhysicalNumpad1
constexpr uint64_t kLogicalCapsLock
constexpr uint64_t kPhysicalMetaLeft
constexpr uint64_t kPhysicalPeriod
constexpr uint64_t kLogicalShiftLeft
constexpr uint64_t kPhysicalShiftRight
constexpr int kKeyCodeShiftLeft
API_AVAILABLE(ios(14.0), macos(11.0)) static NSString *MTLCommandEncoderErrorStateToString(MTLCommandEncoderErrorState state)