5#import <objc/message.h>
9#import "flutter/shell/platform/darwin/common/framework/Headers/FlutterCodecs.h"
10#import "flutter/shell/platform/darwin/macos/framework/Source/FlutterViewController_Internal.h"
11#import "flutter/shell/platform/embedder/embedder.h"
38 _previouslyPressedFlags = 0;
45- (void)checkModifierFlag:(NSUInteger)targetMask
46 forEventFlags:(NSEventModifierFlags)eventFlags
47 keyCode:(NSUInteger)keyCode
48 timestamp:(NSTimeInterval)timestamp {
49 NSAssert((targetMask & (targetMask - 1)) == 0,
@"targetMask must only have one bit set");
50 if ((eventFlags & targetMask) != (_previouslyPressedFlags & targetMask)) {
51 uint64_t newFlags = (_previouslyPressedFlags & ~targetMask) | (eventFlags & targetMask);
54 auto updateCombinedFlag = [&](uint64_t side1, uint64_t side2, NSEventModifierFlags
flag) {
55 if (newFlags & (side1 | side2)) {
62 NSEventModifierFlagShift);
64 NSEventModifierFlagControl);
66 NSEventModifierFlagOption);
68 NSEventModifierFlagCommand);
70 NSEvent*
event = [NSEvent keyEventWithType:NSEventTypeFlagsChanged
72 modifierFlags:newFlags
77 charactersIgnoringModifiers:@""
80 [
self handleEvent:event
86- (void)syncModifiersIfNeeded:(NSEventModifierFlags)modifierFlags
87 timestamp:(NSTimeInterval)timestamp {
88 modifierFlags = modifierFlags & ~0x100;
89 if (_previouslyPressedFlags == modifierFlags) {
93 [flutter::modifierFlagToKeyCode
94 enumerateKeysAndObjectsUsingBlock:^(NSNumber* flag, NSNumber* keyCode, BOOL* stop) {
95 [
self checkModifierFlag:[flag unsignedShortValue]
96 forEventFlags:modifierFlags
97 keyCode:[keyCode unsignedShortValue]
102 [
self checkModifierFlag:NSEventModifierFlagCapsLock
103 forEventFlags:modifierFlags
105 timestamp:timestamp];
108 FML_DCHECK(_previouslyPressedFlags == modifierFlags);
113 NSEventModifierFlags modifierFlags =
event.modifierFlags & ~0x100;
115 switch (
event.type) {
116 case NSEventTypeKeyDown:
119 case NSEventTypeKeyUp:
122 case NSEventTypeFlagsChanged:
123 if (modifierFlags < _previouslyPressedFlags) {
125 }
else if (modifierFlags > _previouslyPressedFlags) {
135 NSAssert(
false,
@"Unexpected key event type (got %lu).",
event.type);
139 _previouslyPressedFlags = modifierFlags;
140 NSMutableDictionary* keyMessage = [@{
141 @"keymap" : @"macos",
143 @"keyCode" : @(event.keyCode),
144 @"modifiers" : @(modifierFlags),
148 if (
event.type == NSEventTypeKeyDown ||
event.type == NSEventTypeKeyUp) {
149 keyMessage[@"characters"] =
event.characters;
150 keyMessage[@"charactersIgnoringModifiers"] =
event.charactersIgnoringModifiers;
152 NSNumber* specifiedLogicalKey =
layoutMap[@(event.keyCode)];
153 if (specifiedLogicalKey != nil) {
154 keyMessage[@"specifiedLogicalKey"] = specifiedLogicalKey;
156 [
self.channel sendMessage:keyMessage
159 return callback(true);
163 callback([[reply valueForKey:@"handled"] boolValue]);
167#pragma mark - Private
FlutterMethodChannel * _channel
FlutterSemanticsFlag flag
FlKeyEvent uint64_t FlKeyResponderAsyncCallback callback
#define FML_DCHECK(condition)
FlutterBasicMessageChannel * channel
uint64_t previouslyPressedFlags
void(^ FlutterAsyncKeyCallback)(BOOL handled)
@ kModifierFlagControlLeft
@ kModifierFlagControlRight
@ kModifierFlagShiftRight
NSMutableDictionary< NSNumber *, NSNumber * > * layoutMap