diff --git a/native/Avalonia.Native/src/OSX/AvnView.mm b/native/Avalonia.Native/src/OSX/AvnView.mm index 2f5fe3b27a..ee124b1964 100644 --- a/native/Avalonia.Native/src/OSX/AvnView.mm +++ b/native/Avalonia.Native/src/OSX/AvnView.mm @@ -15,7 +15,6 @@ bool _isLeftPressed, _isMiddlePressed, _isRightPressed, _isXButton1Pressed, _isXButton2Pressed; AvnInputModifiers _modifierState; NSEvent* _lastMouseDownEvent; - bool _lastKeyConsumeByInputContext; AvnPixelSize _lastPixelSize; NSObject* _currentRenderTarget; AvnPlatformResizeReason _resizeReason; @@ -24,6 +23,7 @@ NSMutableAttributedString* _text; NSRange _selectedRange; NSRange _markedRange; + NSEvent* _lastKeyDownEvent; } - (void)onClosed @@ -461,13 +461,7 @@ auto timestamp = static_cast([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(key > 32 && type == KeyDown && !handled){ - _parent->BaseEvents->RawTextInputEvent(timestamp, keySymbolUtf8); - } - } + _parent->BaseEvents->RawKeyEvent(type, timestamp, modifiers, key, physicalKey, keySymbolUtf8); } - (void)flagsChanged:(NSEvent *)event @@ -484,7 +478,6 @@ bool isShiftPressed = (newModifierState & Shift) == Shift; bool isCommandPressed = (newModifierState & Windows) == Windows; - if (isAltPressed && !isAltCurrentlyPressed) { [self keyboardEvent:event withType:KeyDown]; @@ -527,15 +520,61 @@ [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([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 @@ -545,6 +584,9 @@ } - (void) doCommandBySelector:(SEL)selector{ + if(_lastKeyDownEvent != nullptr){ + [self keyboardEvent:_lastKeyDownEvent withType:KeyDown]; + } } - (AvnInputModifiers)getModifiers:(NSEventModifierFlags)mod