Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Mac] Fix keyDown event #13280

Merged
merged 8 commits into from
Oct 18, 2023
66 changes: 54 additions & 12 deletions native/Avalonia.Native/src/OSX/AvnView.mm
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ @implementation AvnView
bool _isLeftPressed, _isMiddlePressed, _isRightPressed, _isXButton1Pressed, _isXButton2Pressed;
AvnInputModifiers _modifierState;
NSEvent* _lastMouseDownEvent;
bool _lastKeyConsumeByInputContext;
AvnPixelSize _lastPixelSize;
NSObject<IRenderTarget>* _currentRenderTarget;
AvnPlatformResizeReason _resizeReason;
Expand All @@ -24,6 +23,7 @@ @implementation AvnView
NSMutableAttributedString* _text;
NSRange _selectedRange;
NSRange _markedRange;
NSEvent* _lastKeyDownEvent;
}

- (void)onClosed
Expand Down Expand Up @@ -461,13 +461,7 @@ - (void) keyboardEvent: (NSEvent *) event withType: (AvnRawKeyEventType)type
auto timestamp = static_cast<uint64_t>([event timestamp] * 1000);
auto modifiers = [self getModifiers:[event modifierFlags]];

if(!_lastKeyConsumeByInputContext || key <= 32){
auto handled = _parent->BaseEvents->RawKeyEvent(type, timestamp, modifiers, key, physicalKey, keySymbolUtf8);

if(type == KeyDown && !handled && keySymbolUtf8 != NULL){
_parent->BaseEvents->RawTextInputEvent(timestamp, keySymbolUtf8);
}
}
_parent->BaseEvents->RawKeyEvent(type, timestamp, modifiers, key, physicalKey, keySymbolUtf8);
}

- (void)flagsChanged:(NSEvent *)event
Expand All @@ -484,7 +478,6 @@ - (void)flagsChanged:(NSEvent *)event
bool isShiftPressed = (newModifierState & Shift) == Shift;
bool isCommandPressed = (newModifierState & Windows) == Windows;


if (isAltPressed && !isAltCurrentlyPressed)
{
[self keyboardEvent:event withType:KeyDown];
Expand Down Expand Up @@ -527,15 +520,61 @@ - (void)flagsChanged:(NSEvent *)event
[super flagsChanged:event];
}

- (bool) handleKeyDown: (NSTimeInterval) timestamp withKey:(AvnKey)key withPhysicalKey:(AvnPhysicalKey)physicalKey withModifiers:(AvnInputModifiers)modifiers withKeySymbol:(NSString*)keySymbol {
return _parent->BaseEvents->RawKeyEvent(KeyDown, timestamp, modifiers, key, physicalKey, [keySymbol UTF8String]);
}

- (void)keyDown:(NSEvent *)event
{
_lastKeyConsumeByInputContext = false;
if([self ignoreUserInput: false] || _parent == nullptr)
{
return;
}

_lastKeyDownEvent = event;

auto timestamp = static_cast<uint64_t>([event timestamp] * 1000);

auto scanCode = [event keyCode];
auto key = VirtualKeyFromScanCode(scanCode, [event modifierFlags]);
auto physicalKey = PhysicalKeyFromScanCode(scanCode);
auto keySymbol = KeySymbolFromScanCode(scanCode, [event modifierFlags]);

auto modifiers = [self getModifiers:[event modifierFlags]];

//InputMethod is active
if(_parent->InputMethod->IsActive()){
_lastKeyConsumeByInputContext = [[self inputContext] handleEvent:event] == YES;
auto hasInputModifier = modifiers != AvnInputModifiersNone;

//Handle keyDown first if an input modifier is present
if(hasInputModifier){
if([self handleKeyDown:timestamp withKey:key withPhysicalKey:physicalKey withModifiers:modifiers withKeySymbol:keySymbol]){
//User code has handled the event
return;
}
}

if([[self inputContext] handleEvent:event] == NO){
//KeyDown has not been consumed by the input context

//Only raise a keyDown if we don't have a modifier
if(!hasInputModifier){
[self handleKeyDown:timestamp withKey:key withPhysicalKey:physicalKey withModifiers:modifiers withKeySymbol:keySymbol];
}
}

}
//InputMethod not active
else{
auto keyDownHandled = [self handleKeyDown:timestamp withKey:key withPhysicalKey:physicalKey withModifiers:modifiers withKeySymbol:keySymbol];

//Raise text input event for unhandled key down if there is some key symbol and no input modifier is present
if(!keyDownHandled && modifiers == AvnInputModifiersNone && keySymbol != NULL){
_parent->BaseEvents->RawTextInputEvent(timestamp, [keySymbol UTF8String]);
}
}

[self keyboardEvent:event withType:KeyDown];
_lastKeyDownEvent = nullptr;
}

- (void)keyUp:(NSEvent *)event
Expand All @@ -545,6 +584,9 @@ - (void)keyUp:(NSEvent *)event
}

- (void) doCommandBySelector:(SEL)selector{
if(_lastKeyDownEvent != nullptr){
[self keyboardEvent:_lastKeyDownEvent withType:KeyDown];
}
}

- (AvnInputModifiers)getModifiers:(NSEventModifierFlags)mod
Expand Down