diff --git a/native/Avalonia.Native/src/OSX/KeyTransform.h b/native/Avalonia.Native/src/OSX/KeyTransform.h index 515811d0f6..2f434570c9 100644 --- a/native/Avalonia.Native/src/OSX/KeyTransform.h +++ b/native/Avalonia.Native/src/OSX/KeyTransform.h @@ -7,4 +7,8 @@ extern std::map s_KeyMap; extern std::map s_AvnKeyMap; +extern std::map s_QwertyKeyMap; + +extern std::map s_UnicodeKeyMap; + #endif diff --git a/native/Avalonia.Native/src/OSX/KeyTransform.mm b/native/Avalonia.Native/src/OSX/KeyTransform.mm index 559251b26d..6b7d95b619 100644 --- a/native/Avalonia.Native/src/OSX/KeyTransform.mm +++ b/native/Avalonia.Native/src/OSX/KeyTransform.mm @@ -120,6 +120,138 @@ const int kVK_UpArrow = 0x7E; //const int kVK_JIS_Eisu = 0x66; const int kVK_JIS_Kana = 0x68; +// converts from AvaloniaKeys to UnicodeSpecial keys. +std::map s_UnicodeKeyMap = +{ + { Up, NSUpArrowFunctionKey }, + { Down, NSDownArrowFunctionKey }, + { Left, NSLeftArrowFunctionKey }, + { Right, NSRightArrowFunctionKey }, + { F1, NSF1FunctionKey }, + { F2, NSF2FunctionKey }, + { F3, NSF3FunctionKey }, + { F4, NSF4FunctionKey }, + { F5, NSF5FunctionKey }, + { F6, NSF6FunctionKey }, + { F7, NSF7FunctionKey }, + { F8, NSF8FunctionKey }, + { F9, NSF9FunctionKey }, + { F10, NSF10FunctionKey }, + { F11, NSF11FunctionKey }, + { F12, NSF12FunctionKey }, + { F13, NSF13FunctionKey }, + { F14, NSF14FunctionKey }, + { F15, NSF15FunctionKey }, + { F16, NSF16FunctionKey }, + { F17, NSF17FunctionKey }, + { F18, NSF18FunctionKey }, + { F19, NSF19FunctionKey }, + { F20, NSF20FunctionKey }, + { F21, NSF21FunctionKey }, + { F22, NSF22FunctionKey }, + { F23, NSF23FunctionKey }, + { F24, NSF24FunctionKey }, + { Insert, NSInsertFunctionKey }, + { Delete, NSDeleteFunctionKey }, + { Home, NSHomeFunctionKey }, + //{ Begin, NSBeginFunctionKey }, + { End, NSEndFunctionKey }, + { PageUp, NSPageUpFunctionKey }, + { PageDown, NSPageDownFunctionKey }, + { PrintScreen, NSPrintScreenFunctionKey }, + { Scroll, NSScrollLockFunctionKey }, + //{ SysReq, NSSysReqFunctionKey }, + //{ Break, NSBreakFunctionKey }, + //{ Reset, NSResetFunctionKey }, + //{ Stop, NSStopFunctionKey }, + //{ Menu, NSMenuFunctionKey }, + //{ UserFunction, NSUserFunctionKey }, + //{ SystemFunction, NSSystemFunctionKey }, + { Print, NSPrintFunctionKey }, + //{ ClearLine, NSClearLineFunctionKey }, + //{ ClearDisplay, NSClearDisplayFunctionKey }, +}; + +// Converts from Ansi virtual keys to Qwerty Keyboard map. +std::map s_QwertyKeyMap = +{ + { 0, "a" }, + { 1, "s" }, + { 2, "d" }, + { 3, "f" }, + { 4, "h" }, + { 5, "g" }, + { 6, "z" }, + { 7, "x" }, + { 8, "c" }, + { 9, "v" }, + { 10, "ยง" }, + { 11, "b" }, + { 12, "q" }, + { 13, "w" }, + { 14, "e" }, + { 15, "r" }, + { 16, "y" }, + { 17, "t" }, + { 18, "1" }, + { 19, "2" }, + { 20, "3" }, + { 21, "4" }, + { 22, "6" }, + { 23, "5" }, + { 24, "=" }, + { 25, "9" }, + { 26, "7" }, + { 27, "-" }, + { 28, "8" }, + { 29, "0" }, + { 30, "]" }, + { 31, "o" }, + { 32, "u" }, + { 33, "[" }, + { 34, "i" }, + { 35, "p" }, + { 37, "l" }, + { 38, "j" }, + { 39, "'" }, + { 40, "k" }, + { 41, ";" }, + { 42, "\\" }, + { 43, "," }, + { 44, "/" }, + { 45, "n" }, + { 46, "m" }, + { 47, "." }, + { 49, " " }, + { 50, "`" }, + { 51, "" }, + { 52, "" }, + { 53, "" }, + { 65, "." }, + { 66, "" }, + { 67, "*" }, + { 69, "+" }, + { 70, "" }, + { 71, "" }, + { 72, "" }, + { 75, "/" }, + { 76, "" }, + { 77, "" }, + { 78, "-" }, + { 81, "=" }, + { 82, "0" }, + { 83, "1" }, + { 84, "2" }, + { 85, "3" }, + { 86, "4" }, + { 87, "5" }, + { 88, "6" }, + { 89, "7" }, + { 91, "8" }, + { 92, "9" } +}; + +// converts from ansi virtualkeys to AvnKeys. std::map s_KeyMap = { {kVK_ANSI_A, A}, @@ -253,5 +385,6 @@ static std::map BuildAvnKeyMap () return result; } +// Converts AvnKeys to Ansi VirtualKeys std::map s_AvnKeyMap = BuildAvnKeyMap(); diff --git a/native/Avalonia.Native/src/OSX/menu.mm b/native/Avalonia.Native/src/OSX/menu.mm index 5621cb3f9f..198b01714f 100644 --- a/native/Avalonia.Native/src/OSX/menu.mm +++ b/native/Avalonia.Native/src/OSX/menu.mm @@ -125,80 +125,58 @@ HRESULT AvnAppMenuItem::SetTitle (char* utf8String) } } -NSString* keyCodeToString(CGKeyCode keyCode) -{ - TISInputSourceRef currentKeyboard = TISCopyCurrentKeyboardInputSource(); - CFDataRef uchr = - (CFDataRef)TISGetInputSourceProperty(currentKeyboard, - kTISPropertyUnicodeKeyLayoutData); - const UCKeyboardLayout *keyboardLayout = - (const UCKeyboardLayout*)CFDataGetBytePtr(uchr); - - if(keyboardLayout) - { - UInt32 deadKeyState = 0; - UniCharCount maxStringLength = 255; - UniCharCount actualStringLength = 0; - UniChar unicodeString[maxStringLength]; - - OSStatus status = UCKeyTranslate(keyboardLayout, - keyCode, kUCKeyActionDown, 0, - LMGetKbdType(), 0, - &deadKeyState, - maxStringLength, - &actualStringLength, unicodeString); - - if (actualStringLength == 0 && deadKeyState) - { - status = UCKeyTranslate(keyboardLayout, - kVK_Space, kUCKeyActionDown, 0, - LMGetKbdType(), 0, - &deadKeyState, - maxStringLength, - &actualStringLength, unicodeString); - } - if(actualStringLength > 0 && status == noErr) - return [[NSString stringWithCharacters:unicodeString - length:(NSUInteger)actualStringLength] lowercaseString]; - } - - return nil; -} - HRESULT AvnAppMenuItem::SetGesture (AvnKey key, AvnInputModifiers modifiers) { @autoreleasepool { - NSEventModifierFlags flags = 0; - - if (modifiers & Control) - flags |= NSEventModifierFlagControl; - if (modifiers & Shift) - flags |= NSEventModifierFlagShift; - if (modifiers & Alt) - flags |= NSEventModifierFlagOption; - if (modifiers & Windows) - flags |= NSEventModifierFlagCommand; - - auto it = s_AvnKeyMap.find(key); - - if(it != s_AvnKeyMap.end()) + if(key != AvnKeyNone) { - auto keyString = keyCodeToString(it->second); + NSEventModifierFlags flags = 0; + + if (modifiers & Control) + flags |= NSEventModifierFlagControl; + if (modifiers & Shift) + flags |= NSEventModifierFlagShift; + if (modifiers & Alt) + flags |= NSEventModifierFlagOption; + if (modifiers & Windows) + flags |= NSEventModifierFlagCommand; - if(keyString != nullptr) + auto it = s_UnicodeKeyMap.find(key); + + if(it != s_UnicodeKeyMap.end()) { + auto keyString= [NSString stringWithFormat:@"%C", (unsigned short)it->second]; + [_native setKeyEquivalent: keyString]; [_native setKeyEquivalentModifierMask:flags]; + + return S_OK; } else { - [_native setKeyEquivalent: @""]; - [_native setKeyEquivalentModifierMask: 0]; + auto it = s_AvnKeyMap.find(key); // check if a virtual key is mapped. + + if(it != s_AvnKeyMap.end()) + { + auto it1 = s_QwertyKeyMap.find(it->second); // convert virtual key to qwerty string. + + if(it1 != s_QwertyKeyMap.end()) + { + [_native setKeyEquivalent: [NSString stringWithUTF8String: it1->second]]; + [_native setKeyEquivalentModifierMask:flags]; + + return S_OK; + } + } } } + // Nothing matched... clear. + [_native setKeyEquivalent: @""]; + [_native setKeyEquivalentModifierMask: 0]; + return S_OK; } }