1111#import < objc/runtime.h>
1212#import < objc/message.h>
1313
14- #if TARGET_OS_SIMULATOR
14+ #if TARGET_OS_SIMULATOR || TARGET_OS_MACCATALYST
1515
1616@interface UIEvent (UIPhysicalKeyboardEvent)
1717
@@ -23,21 +23,109 @@ @interface UIEvent (UIPhysicalKeyboardEvent)
2323
2424@end
2525
26+ #if TARGET_OS_MACCATALYST
27+
28+ @interface FLEXKeyInput : UIKeyCommand
29+
30+ @end
31+
32+ @interface UIKeyCommand (FLEX)
33+
34+ @property (nonatomic , assign , readonly ) BOOL isCreatedByFLEX;
35+
36+ #else
37+
2638@interface FLEXKeyInput : NSObject <NSCopying >
2739
40+ #endif
41+
2842@property (nonatomic , copy , readonly ) NSString *key;
2943@property (nonatomic , assign , readonly ) UIKeyModifierFlags flags;
3044@property (nonatomic , copy , readonly ) NSString *helpDescription;
3145
3246@end
3347
48+ #if TARGET_OS_MACCATALYST
49+
50+ @implementation FLEXKeyInput
51+
52+ @end
53+
54+ @implementation UIKeyCommand (FLEX)
55+
56+ - (NSString *)key {
57+
58+ return objc_getAssociatedObject (self, @selector (key ));
59+ }
60+
61+ - (void )setKey : (NSString *)key {
62+
63+ objc_setAssociatedObject (self, @selector (key ), key, OBJC_ASSOCIATION_COPY_NONATOMIC );
64+ }
65+
66+ - (UIKeyModifierFlags)flags {
67+
68+ UIKeyModifierFlags (^block)() = objc_getAssociatedObject (self, @selector (flags ));
69+
70+ return (block ? block () : kNilOptions );
71+ }
72+
73+ - (void )setFlags : (UIKeyModifierFlags)flags {
74+
75+ UIKeyModifierFlags (^block)() = ^{
76+ return flags;
77+ };
78+
79+ objc_setAssociatedObject (self, @selector (flags ), block, OBJC_ASSOCIATION_COPY );
80+ }
81+
82+ - (NSString *)helpDescription {
83+
84+ return objc_getAssociatedObject (self, @selector (helpDescription ));
85+ }
86+
87+ - (void )setHelpDescription : (NSString *)helpDescription {
88+
89+ objc_setAssociatedObject (self, @selector (helpDescription ), helpDescription, OBJC_ASSOCIATION_COPY_NONATOMIC );
90+ }
91+
92+ - (BOOL )isCreatedByFLEX {
93+
94+ BOOL (^block)() = objc_getAssociatedObject (self, @selector (isCreatedByFLEX ));
95+
96+ return (block ? block () : NO );
97+ }
98+
99+ - (void )setIsCreatedByFLEX : (BOOL )isCreatedByFLEX {
100+
101+ BOOL (^block)() = ^{
102+ return isCreatedByFLEX;
103+ };
104+
105+ objc_setAssociatedObject (self, @selector (isCreatedByFLEX ), block, OBJC_ASSOCIATION_COPY );
106+ }
107+
108+ #else
109+
34110@implementation FLEXKeyInput
35111
112+ #endif
113+
36114- (BOOL )isEqual : (id )object
37115{
38116 BOOL isEqual = NO ;
117+ #if TARGET_OS_MACCATALYST
118+ if ([object isKindOfClass: [UIKeyCommand class ]]) {
119+ UIKeyCommand *keyCommand = (UIKeyCommand *)object;
120+ if (!keyCommand.isCreatedByFLEX ) {
121+ // Not FLEX's business anymore.
122+
123+ return [super isEqual: object];
124+ }
125+ #else
39126 if ([object isKindOfClass: [FLEXKeyInput class ]]) {
40127 FLEXKeyInput *keyCommand = (FLEXKeyInput *)object;
128+ #endif
41129 BOOL equalKeys = self.key == keyCommand.key || [self .key isEqual: keyCommand.key];
42130 BOOL equalFlags = self.flags == keyCommand.flags ;
43131 isEqual = equalKeys && equalFlags;
@@ -98,6 +186,23 @@ + (instancetype)keyInputForKey:(NSString *)key flags:(UIKeyModifierFlags)flags
98186 return [self keyInputForKey: key flags: flags helpDescription: nil ];
99187}
100188
189+ #if TARGET_OS_MACCATALYST
190+
191+ + (instancetype )keyInputForKey:(NSString *)key flags:(UIKeyModifierFlags)flags helpDescription:(NSString *)helpDescription
192+ {
193+ FLEXKeyInput *keyInput = [UIKeyCommand keyCommandWithInput: key modifierFlags: flags action: nil ];
194+ if (keyInput) {
195+ [keyInput setKey: key];
196+ [keyInput setFlags: flags];
197+ [keyInput setHelpDescription: helpDescription];
198+
199+ [keyInput setIsCreatedByFLEX: YES ];
200+ }
201+ return keyInput;
202+ }
203+
204+ #else
205+
101206+ (instancetype )keyInputForKey:(NSString *)key flags:(UIKeyModifierFlags)flags helpDescription:(NSString *)helpDescription
102207{
103208 FLEXKeyInput *keyInput = [[self alloc ] init ];
@@ -109,12 +214,22 @@ + (instancetype)keyInputForKey:(NSString *)key flags:(UIKeyModifierFlags)flags h
109214 return keyInput;
110215}
111216
217+ #endif
218+
112219@end
113220
114221@interface FLEXKeyboardShortcutManager ()
115222
223+ #if TARGET_OS_MACCATALYST
224+
225+ @property (nonatomic , strong ) NSMutableDictionary <UIKeyCommand *, dispatch_block_t> *actionsForKeyInputs;
226+
227+ #else
228+
116229@property (nonatomic , strong ) NSMutableDictionary <FLEXKeyInput *, dispatch_block_t> *actionsForKeyInputs;
117230
231+ #endif
232+
118233@property (nonatomic , assign , getter =isPressingShift) BOOL pressingShift;
119234@property (nonatomic , assign , getter =isPressingCommand) BOOL pressingCommand;
120235@property (nonatomic , assign , getter =isPressingControl) BOOL pressingControl;
@@ -305,6 +420,15 @@ - (NSString *)keyboardShortcutsDescription
305420 return [description copy ];
306421}
307422
423+ #if TARGET_OS_MACCATALYST
424+
425+ - (NSArray <UIKeyCommand *> *)getKeyCommands {
426+
427+ return self.actionsForKeyInputs .allKeys ;
428+ }
429+
430+ #endif
431+
308432@end
309433
310434#endif
0 commit comments