7 #include "flutter/fml/platform/darwin/message_loop_darwin.h"
19 @property(nonatomic, copy, readonly)
20 NSMutableArray<id<FlutterKeyPrimaryResponder>>* primaryResponders;
25 @property(nonatomic, copy, readonly)
26 NSMutableArray<id<FlutterKeySecondaryResponder>>* secondaryResponders;
30 API_AVAILABLE(ios(13.4));
36 - (nonnull instancetype)init {
39 _primaryResponders = [[NSMutableArray alloc] init];
40 _secondaryResponders = [[NSMutableArray alloc] init];
46 [_primaryResponders addObject:responder];
50 [_secondaryResponders addObject:responder];
54 nextAction:(nonnull
void (^)())next API_AVAILABLE(ios(13.4)) {
55 if (@available(iOS 13.4, *)) {
61 bool __block wasHandled =
false;
64 CFRunLoopStop(CFRunLoopGetCurrent());
66 switch (press.phase) {
67 case UIPressPhaseBegan:
68 case UIPressPhaseEnded: {
72 NSAssert([_primaryResponders count] >= 0,
@"At least one primary responder must be added.");
74 __block __weak __typeof(
self) weakSelf =
self;
75 __block NSUInteger unreplied = [
self.primaryResponders count];
76 __block BOOL anyHandled =
false;
79 NSAssert(unreplied >= 0,
@"More primary responders replied than expected.");
80 anyHandled = anyHandled || handled;
82 if (!anyHandled && weakSelf) {
83 [weakSelf dispatchToSecondaryResponders:press complete:completeCallback];
85 completeCallback(
true, press);
89 for (id<FlutterKeyPrimaryResponder> responder in _primaryResponders) {
90 [responder handlePress:press callback:replyCallback];
99 CFRunLoopRunInMode(fml::MessageLoopDarwin::kMessageLoopCFRunLoopMode,
kDistantFuture, NO);
102 case UIPressPhaseChanged:
103 case UIPressPhaseCancelled:
104 case UIPressPhaseStationary:
112 #pragma mark - Private
116 API_AVAILABLE(ios(13.4)) {
117 if (@available(iOS 13.4, *)) {
120 callback(
false, press);
124 for (id<FlutterKeySecondaryResponder> responder in _secondaryResponders) {
125 if ([responder handlePress:press]) {
126 callback(
true, press);
130 callback(
false, press);