6 #include "flutter/fml/platform/darwin/message_loop_darwin.h"
7 #include "flutter/fml/platform/darwin/weak_nsobject.h"
16 @property(nonatomic, retain, readonly)
17 NSMutableArray<id<FlutterKeyPrimaryResponder>>* primaryResponders;
22 @property(nonatomic, retain, readonly)
23 NSMutableArray<id<FlutterKeySecondaryResponder>>* secondaryResponders;
27 API_AVAILABLE(ios(13.4));
32 std::unique_ptr<fml::WeakNSObjectFactory<FlutterKeyboardManager>>
_weakFactory;
35 - (nonnull instancetype)init {
38 _primaryResponders = [[NSMutableArray alloc] init];
39 _secondaryResponders = [[NSMutableArray alloc] init];
40 _weakFactory = std::make_unique<fml::WeakNSObjectFactory<FlutterKeyboardManager>>(
self);
46 [_primaryResponders addObject:responder];
50 [_secondaryResponders addObject:responder];
58 [_primaryResponders removeAllObjects];
59 [_secondaryResponders removeAllObjects];
60 [_primaryResponders release];
61 [_secondaryResponders release];
62 _primaryResponders = nil;
63 _secondaryResponders = nil;
67 - (fml::WeakNSObject<FlutterKeyboardManager>)getWeakNSObject {
72 nextAction:(nonnull
void (^)())next API_AVAILABLE(ios(13.4)) {
73 if (@available(iOS 13.4, *)) {
79 bool __block wasHandled =
false;
82 CFRunLoopStop(CFRunLoopGetCurrent());
84 switch (press.phase) {
85 case UIPressPhaseBegan:
86 case UIPressPhaseEnded: {
90 NSAssert([_primaryResponders count] >= 0,
@"At least one primary responder must be added.");
92 __block
auto weakSelf = [
self getWeakNSObject];
93 __block NSUInteger unreplied = [
self.primaryResponders count];
94 __block BOOL anyHandled =
false;
97 NSAssert(unreplied >= 0,
@"More primary responders replied than expected.");
98 anyHandled = anyHandled || handled;
100 if (!anyHandled && weakSelf) {
101 [weakSelf.get() dispatchToSecondaryResponders:press complete:completeCallback];
103 completeCallback(
true, press);
107 for (id<FlutterKeyPrimaryResponder> responder in _primaryResponders) {
108 [responder handlePress:press callback:replyCallback];
117 CFRunLoopRunInMode(fml::MessageLoopDarwin::kMessageLoopCFRunLoopMode,
kDistantFuture, NO);
120 case UIPressPhaseChanged:
121 case UIPressPhaseCancelled:
122 case UIPressPhaseStationary:
130 #pragma mark - Private
134 API_AVAILABLE(ios(13.4)) {
135 if (@available(iOS 13.4, *)) {
138 callback(
false, press);
142 for (id<FlutterKeySecondaryResponder> responder in _secondaryResponders) {
143 if ([responder handlePress:press]) {
144 callback(
true, press);
148 callback(
false, press);