7 #import <objc/message.h>
9 #include "fml/memory/weak_ptr.h"
23 typedef NS_OPTIONS(NSInteger, kKeyboardModifier) {
24 kKeyboardModifierAlphaShift = 0x10000,
25 kKeyboardModifierShift = 0x20000,
26 kKeyboardModifierLeftShift = 0x02,
27 kKeyboardModifierRightShift = 0x04,
28 kKeyboardModifierControl = 0x40000,
29 kKeyboardModifierLeftControl = 0x01,
30 kKeyboardModifierRightControl = 0x2000,
31 kKeyboardModifierOption = 0x80000,
32 kKeyboardModifierLeftOption = 0x20,
33 kKeyboardModifierRightOption = 0x40,
34 kKeyboardModifierCommand = 0x100000,
35 kKeyboardModifierLeftCommand = 0x08,
36 kKeyboardModifierRightCommand = 0x10,
37 kKeyboardModifierNumericPad = 0x200000,
38 kKeyboardModifierMask = kKeyboardModifierAlphaShift |
39 kKeyboardModifierShift |
40 kKeyboardModifierLeftShift |
41 kKeyboardModifierRightShift |
42 kKeyboardModifierControl |
43 kKeyboardModifierLeftControl |
44 kKeyboardModifierRightControl |
45 kKeyboardModifierOption |
46 kKeyboardModifierLeftOption |
47 kKeyboardModifierRightOption |
48 kKeyboardModifierCommand |
49 kKeyboardModifierLeftCommand |
50 kKeyboardModifierRightCommand |
51 kKeyboardModifierNumericPad,
57 static NSString* getEventCharacters(NSString* characters, UIKeyboardHIDUsage keyCode)
59 if (characters == nil) {
62 if ([characters length] == 0) {
65 if (@available(iOS 13.4, *)) {
91 - (void)updatePressedModifiers:(nonnull
FlutterUIPressProxy*)press API_AVAILABLE(ios(13.4));
93 @property(nonatomic) kKeyboardModifier pressedModifiers;
102 _pressedModifiers = 0;
109 if (@available(iOS 13.4, *)) {
115 switch (press.phase) {
116 case UIPressPhaseBegan:
119 case UIPressPhaseCancelled:
124 case UIPressPhaseEnded:
127 case UIPressPhaseChanged:
130 case UIPressPhaseStationary:
139 NSString* characters = getEventCharacters(press.key.characters, press.key.keyCode);
140 NSString* charactersIgnoringModifiers =
141 getEventCharacters(press.key.charactersIgnoringModifiers, press.key.keyCode);
142 NSMutableDictionary* keyMessage = [[@{
145 @"keyCode" : @(press.key.keyCode),
146 @"modifiers" : @([
self adjustModifiers:press]),
147 @"characters" : characters == nil ? @"" : characters,
148 @"charactersIgnoringModifiers" : charactersIgnoringModifiers == nil
150 : charactersIgnoringModifiers,
151 } mutableCopy] autorelease];
152 [
self.channel sendMessage:keyMessage
154 bool handled = reply ? [[reply valueForKey:@"handled"] boolValue] : true;
159 #pragma mark - Private
161 - (void)updatePressedModifiers:(nonnull
FlutterUIPressProxy*)press API_AVAILABLE(ios(13.4)) {
162 if (@available(iOS 13.4, *)) {
168 bool isKeyDown =
false;
169 switch (press.phase) {
170 case UIPressPhaseStationary:
171 case UIPressPhaseChanged:
173 NSAssert(
false,
@"Unexpected key event type received in updatePressedModifiers.");
175 case UIPressPhaseBegan:
178 case UIPressPhaseCancelled:
179 case UIPressPhaseEnded:
184 void (^update)(kKeyboardModifier, bool) = ^(kKeyboardModifier mod,
bool isOn) {
186 _pressedModifiers |= mod;
188 _pressedModifiers &= ~mod;
191 switch (press.key.keyCode) {
192 case UIKeyboardHIDUsageKeyboardCapsLock:
193 update(kKeyboardModifierAlphaShift, isKeyDown);
195 case UIKeyboardHIDUsageKeypadNumLock:
196 update(kKeyboardModifierNumericPad, isKeyDown);
198 case UIKeyboardHIDUsageKeyboardLeftShift:
199 update(kKeyboardModifierLeftShift, isKeyDown);
201 case UIKeyboardHIDUsageKeyboardRightShift:
202 update(kKeyboardModifierRightShift, isKeyDown);
204 case UIKeyboardHIDUsageKeyboardLeftControl:
205 update(kKeyboardModifierLeftControl, isKeyDown);
207 case UIKeyboardHIDUsageKeyboardRightControl:
208 update(kKeyboardModifierRightControl, isKeyDown);
210 case UIKeyboardHIDUsageKeyboardLeftAlt:
211 update(kKeyboardModifierLeftOption, isKeyDown);
213 case UIKeyboardHIDUsageKeyboardRightAlt:
214 update(kKeyboardModifierRightOption, isKeyDown);
216 case UIKeyboardHIDUsageKeyboardLeftGUI:
217 update(kKeyboardModifierLeftCommand, isKeyDown);
219 case UIKeyboardHIDUsageKeyboardRightGUI:
220 update(kKeyboardModifierRightCommand, isKeyDown);
227 update(kKeyboardModifierShift,
228 _pressedModifiers & (kKeyboardModifierRightShift | kKeyboardModifierLeftShift));
229 update(kKeyboardModifierControl,
230 _pressedModifiers & (kKeyboardModifierRightControl | kKeyboardModifierLeftControl));
231 update(kKeyboardModifierOption,
232 _pressedModifiers & (kKeyboardModifierRightOption | kKeyboardModifierLeftOption));
233 update(kKeyboardModifierCommand,
234 _pressedModifiers & (kKeyboardModifierRightCommand | kKeyboardModifierLeftCommand));
240 - (NSInteger)adjustModifiers:(nonnull
FlutterUIPressProxy*)press API_AVAILABLE(ios(13.4)) {
241 if (@available(iOS 13.4, *)) {
244 return press.key.modifierFlags;
247 [
self updatePressedModifiers:press];
249 return _pressedModifiers | (press.key.modifierFlags & ~kKeyboardModifierMask);