diff options
Diffstat (limited to 'src/plugins/platforms/cocoa')
-rw-r--r-- | src/plugins/platforms/cocoa/CMakeLists.txt | 1 | ||||
-rw-r--r-- | src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm | 2 | ||||
-rw-r--r-- | src/plugins/platforms/cocoa/qcocoaintegration.h | 4 | ||||
-rw-r--r-- | src/plugins/platforms/cocoa/qcocoaintegration.mm | 4 | ||||
-rw-r--r-- | src/plugins/platforms/cocoa/qcocoakeymapper.h | 93 | ||||
-rw-r--r-- | src/plugins/platforms/cocoa/qcocoakeymapper.mm | 547 | ||||
-rw-r--r-- | src/plugins/platforms/cocoa/qcocoamenuitem.mm | 6 | ||||
-rw-r--r-- | src/plugins/platforms/cocoa/qcocoansmenu.mm | 6 | ||||
-rw-r--r-- | src/plugins/platforms/cocoa/qnsview_dragging.mm | 6 | ||||
-rw-r--r-- | src/plugins/platforms/cocoa/qnsview_keys.mm | 8 | ||||
-rw-r--r-- | src/plugins/platforms/cocoa/qnsview_mouse.mm | 4 | ||||
-rw-r--r-- | src/plugins/platforms/cocoa/qnsview_tablet.mm | 2 |
12 files changed, 21 insertions, 662 deletions
diff --git a/src/plugins/platforms/cocoa/CMakeLists.txt b/src/plugins/platforms/cocoa/CMakeLists.txt index d9832c2c6c..8dbf534c9b 100644 --- a/src/plugins/platforms/cocoa/CMakeLists.txt +++ b/src/plugins/platforms/cocoa/CMakeLists.txt @@ -26,7 +26,6 @@ qt_internal_add_plugin(QCocoaIntegrationPlugin qcocoainputcontext.h qcocoainputcontext.mm qcocoaintegration.h qcocoaintegration.mm qcocoaintrospection.h qcocoaintrospection.mm - qcocoakeymapper.h qcocoakeymapper.mm qcocoamenu.h qcocoamenu.mm qcocoamenubar.h qcocoamenubar.mm qcocoamenuitem.h qcocoamenuitem.mm diff --git a/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm b/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm index e6e46cda81..40d8f639fc 100644 --- a/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm +++ b/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm @@ -371,7 +371,7 @@ QT_USE_NAMESPACE return; QScopedScopeLevelCounter scopeLevelCounter(QGuiApplicationPrivate::instance()->threadData.loadRelaxed()); - QGuiApplicationPrivate::modifier_buttons = QCocoaKeyMapper::fromCocoaModifiers([NSEvent modifierFlags]); + QGuiApplicationPrivate::modifier_buttons = QAppleKeyMapper::fromCocoaModifiers([NSEvent modifierFlags]); static QMetaMethod activatedSignal = QMetaMethod::fromSignal(&QCocoaMenuItem::activated); activatedSignal.invoke(platformItem, Qt::QueuedConnection); diff --git a/src/plugins/platforms/cocoa/qcocoaintegration.h b/src/plugins/platforms/cocoa/qcocoaintegration.h index 4f1969dd98..caf47e38d3 100644 --- a/src/plugins/platforms/cocoa/qcocoaintegration.h +++ b/src/plugins/platforms/cocoa/qcocoaintegration.h @@ -48,7 +48,6 @@ #include "qcocoaclipboard.h" #include "qcocoadrag.h" #include "qcocoaservices.h" -#include "qcocoakeymapper.h" #if QT_CONFIG(vulkan) #include "qcocoavulkaninstance.h" #endif @@ -57,6 +56,7 @@ #include <qpa/qplatformintegration.h> #include <QtGui/private/qcoretextfontdatabase_p.h> #include <QtGui/private/qopenglcontext_p.h> +#include <QtGui/private/qapplekeymapper_p.h> Q_FORWARD_DECLARE_OBJC_CLASS(NSToolbar); @@ -156,7 +156,7 @@ private: QScopedPointer<QCocoaDrag> mCocoaDrag; QScopedPointer<QCocoaNativeInterface> mNativeInterface; QScopedPointer<QCocoaServices> mServices; - QScopedPointer<QCocoaKeyMapper> mKeyboardMapper; + QScopedPointer<QAppleKeyMapper> mKeyboardMapper; #if QT_CONFIG(vulkan) mutable QCocoaVulkanInstance *mCocoaVulkanInstance = nullptr; diff --git a/src/plugins/platforms/cocoa/qcocoaintegration.mm b/src/plugins/platforms/cocoa/qcocoaintegration.mm index 872d9bb7f1..1ab30df7e8 100644 --- a/src/plugins/platforms/cocoa/qcocoaintegration.mm +++ b/src/plugins/platforms/cocoa/qcocoaintegration.mm @@ -136,7 +136,7 @@ QCocoaIntegration::QCocoaIntegration(const QStringList ¶mList) , mCocoaDrag(new QCocoaDrag) , mNativeInterface(new QCocoaNativeInterface) , mServices(new QCocoaServices) - , mKeyboardMapper(new QCocoaKeyMapper) + , mKeyboardMapper(new QAppleKeyMapper) { logVersionInformation(); @@ -420,7 +420,7 @@ QVariant QCocoaIntegration::styleHint(StyleHint hint) const Qt::KeyboardModifiers QCocoaIntegration::queryKeyboardModifiers() const { - return QCocoaKeyMapper::queryKeyboardModifiers(); + return QAppleKeyMapper::queryKeyboardModifiers(); } QList<int> QCocoaIntegration::possibleKeys(const QKeyEvent *event) const diff --git a/src/plugins/platforms/cocoa/qcocoakeymapper.h b/src/plugins/platforms/cocoa/qcocoakeymapper.h deleted file mode 100644 index dbf164c18e..0000000000 --- a/src/plugins/platforms/cocoa/qcocoakeymapper.h +++ /dev/null @@ -1,93 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QCOCOAKEYMAPPER_H -#define QCOCOAKEYMAPPER_H - -#include <Carbon/Carbon.h> - -#include <QtCore/QList> -#include <QtGui/QKeyEvent> - -#include <QtCore/private/qcore_mac_p.h> - -QT_BEGIN_NAMESPACE - -class QCocoaKeyMapper -{ -public: - static Qt::KeyboardModifiers queryKeyboardModifiers(); - QList<int> possibleKeys(const QKeyEvent *event) const; - - static Qt::KeyboardModifiers fromCocoaModifiers(NSEventModifierFlags cocoaModifiers); - static NSEventModifierFlags toCocoaModifiers(Qt::KeyboardModifiers); - - static QChar toCocoaKey(Qt::Key key); - static Qt::Key fromCocoaKey(QChar keyCode); - -private: - static constexpr int kNumModifierCombinations = 16; - struct KeyMap : std::array<char32_t, kNumModifierCombinations> - { - // Initialize first element to a sentinel that allows us - // to distinguish an uninitialized map from an initialized. - // Using 0 would not allow us to map U+0000 (NUL), however - // unlikely that is. - KeyMap() : std::array<char32_t, 16>{Qt::Key_unknown} {} - }; - - bool updateKeyboard(); - - using VirtualKeyCode = unsigned short; - const KeyMap &keyMapForKey(VirtualKeyCode virtualKey, QChar unicodeKey) const; - - QCFType<TISInputSourceRef> m_currentInputSource = nullptr; - - enum { NullMode, UnicodeMode, OtherMode } m_keyboardMode = NullMode; - const UCKeyboardLayout *m_keyboardLayoutFormat = nullptr; - KeyboardLayoutKind m_keyboardKind = kKLKCHRuchrKind; - mutable UInt32 m_deadKeyState = 0; // Maintains dead key state beween calls to UCKeyTranslate - - mutable QHash<VirtualKeyCode, KeyMap> m_keyMap; -}; - -QT_END_NAMESPACE - -#endif - diff --git a/src/plugins/platforms/cocoa/qcocoakeymapper.mm b/src/plugins/platforms/cocoa/qcocoakeymapper.mm deleted file mode 100644 index caa68ae694..0000000000 --- a/src/plugins/platforms/cocoa/qcocoakeymapper.mm +++ /dev/null @@ -1,547 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2020 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the plugins of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include <AppKit/AppKit.h> - -#include "qcocoakeymapper.h" - -#include <QtCore/qloggingcategory.h> -#include <QtGui/QGuiApplication> - -QT_BEGIN_NAMESPACE - -Q_LOGGING_CATEGORY(lcQpaKeyMapper, "qt.qpa.keymapper"); -Q_LOGGING_CATEGORY(lcQpaKeyMapperKeys, "qt.qpa.keymapper.keys"); - -static Qt::KeyboardModifiers swapModifiersIfNeeded(const Qt::KeyboardModifiers modifiers) -{ - if (QCoreApplication::testAttribute(Qt::AA_MacDontSwapCtrlAndMeta)) - return modifiers; - - Qt::KeyboardModifiers swappedModifiers = modifiers; - swappedModifiers &= ~(Qt::MetaModifier | Qt::ControlModifier); - - if (modifiers & Qt::ControlModifier) - swappedModifiers |= Qt::MetaModifier; - if (modifiers & Qt::MetaModifier) - swappedModifiers |= Qt::ControlModifier; - - return swappedModifiers; -} - -static constexpr std::tuple<NSEventModifierFlags, Qt::KeyboardModifier> cocoaModifierMap[] = { - { NSEventModifierFlagShift, Qt::ShiftModifier }, - { NSEventModifierFlagControl, Qt::ControlModifier }, - { NSEventModifierFlagCommand, Qt::MetaModifier }, - { NSEventModifierFlagOption, Qt::AltModifier }, - { NSEventModifierFlagNumericPad, Qt::KeypadModifier } -}; - -Qt::KeyboardModifiers QCocoaKeyMapper::fromCocoaModifiers(NSEventModifierFlags cocoaModifiers) -{ - Qt::KeyboardModifiers qtModifiers = Qt::NoModifier; - for (const auto &[cocoaModifier, qtModifier] : cocoaModifierMap) { - if (cocoaModifiers & cocoaModifier) - qtModifiers |= qtModifier; - } - - return swapModifiersIfNeeded(qtModifiers); -} - -NSEventModifierFlags QCocoaKeyMapper::toCocoaModifiers(Qt::KeyboardModifiers qtModifiers) -{ - qtModifiers = swapModifiersIfNeeded(qtModifiers); - - NSEventModifierFlags cocoaModifiers = 0; - for (const auto &[cocoaModifier, qtModifier] : cocoaModifierMap) { - if (qtModifiers & qtModifier) - cocoaModifiers |= cocoaModifier; - } - - return cocoaModifiers; -} - -using CarbonModifiers = UInt32; // As opposed to EventModifiers which is UInt16 - -static CarbonModifiers toCarbonModifiers(Qt::KeyboardModifiers qtModifiers) -{ - qtModifiers = swapModifiersIfNeeded(qtModifiers); - - static constexpr std::tuple<int, Qt::KeyboardModifier> carbonModifierMap[] = { - { shiftKey, Qt::ShiftModifier }, - { controlKey, Qt::ControlModifier }, - { cmdKey, Qt::MetaModifier }, - { optionKey, Qt::AltModifier }, - { kEventKeyModifierNumLockMask, Qt::KeypadModifier } - }; - - CarbonModifiers carbonModifiers = 0; - for (const auto &[carbonModifier, qtModifier] : carbonModifierMap) { - if (qtModifiers & qtModifier) - carbonModifiers |= carbonModifier; - } - - return carbonModifiers; -} - -// Keyboard keys (non-modifiers) -static QHash<char16_t, Qt::Key> standardKeys = { - { kHomeCharCode, Qt::Key_Home }, - { kEnterCharCode, Qt::Key_Enter }, - { kEndCharCode, Qt::Key_End }, - { kBackspaceCharCode, Qt::Key_Backspace }, - { kTabCharCode, Qt::Key_Tab }, - { kPageUpCharCode, Qt::Key_PageUp }, - { kPageDownCharCode, Qt::Key_PageDown }, - { kReturnCharCode, Qt::Key_Return }, - { kEscapeCharCode, Qt::Key_Escape }, - { kLeftArrowCharCode, Qt::Key_Left }, - { kRightArrowCharCode, Qt::Key_Right }, - { kUpArrowCharCode, Qt::Key_Up }, - { kDownArrowCharCode, Qt::Key_Down }, - { kHelpCharCode, Qt::Key_Help }, - { kDeleteCharCode, Qt::Key_Delete }, - // ASCII maps, for debugging - { ':', Qt::Key_Colon }, - { ';', Qt::Key_Semicolon }, - { '<', Qt::Key_Less }, - { '=', Qt::Key_Equal }, - { '>', Qt::Key_Greater }, - { '?', Qt::Key_Question }, - { '@', Qt::Key_At }, - { ' ', Qt::Key_Space }, - { '!', Qt::Key_Exclam }, - { '"', Qt::Key_QuoteDbl }, - { '#', Qt::Key_NumberSign }, - { '$', Qt::Key_Dollar }, - { '%', Qt::Key_Percent }, - { '&', Qt::Key_Ampersand }, - { '\'', Qt::Key_Apostrophe }, - { '(', Qt::Key_ParenLeft }, - { ')', Qt::Key_ParenRight }, - { '*', Qt::Key_Asterisk }, - { '+', Qt::Key_Plus }, - { ',', Qt::Key_Comma }, - { '-', Qt::Key_Minus }, - { '.', Qt::Key_Period }, - { '/', Qt::Key_Slash }, - { '[', Qt::Key_BracketLeft }, - { ']', Qt::Key_BracketRight }, - { '\\', Qt::Key_Backslash }, - { '_', Qt::Key_Underscore }, - { '`', Qt::Key_QuoteLeft }, - { '{', Qt::Key_BraceLeft }, - { '}', Qt::Key_BraceRight }, - { '|', Qt::Key_Bar }, - { '~', Qt::Key_AsciiTilde }, - { '^', Qt::Key_AsciiCircum } -}; - -static QHash<char16_t, Qt::Key> virtualKeys = { - { kVK_F1, Qt::Key_F1 }, - { kVK_F2, Qt::Key_F2 }, - { kVK_F3, Qt::Key_F3 }, - { kVK_F4, Qt::Key_F4 }, - { kVK_F5, Qt::Key_F5 }, - { kVK_F6, Qt::Key_F6 }, - { kVK_F7, Qt::Key_F7 }, - { kVK_F8, Qt::Key_F8 }, - { kVK_F9, Qt::Key_F9 }, - { kVK_F10, Qt::Key_F10 }, - { kVK_F11, Qt::Key_F11 }, - { kVK_F12, Qt::Key_F12 }, - { kVK_F13, Qt::Key_F13 }, - { kVK_F14, Qt::Key_F14 }, - { kVK_F15, Qt::Key_F15 }, - { kVK_F16, Qt::Key_F16 }, - { kVK_Return, Qt::Key_Return }, - { kVK_Tab, Qt::Key_Tab }, - { kVK_Escape, Qt::Key_Escape }, - { kVK_Help, Qt::Key_Help }, - { kVK_UpArrow, Qt::Key_Up }, - { kVK_DownArrow, Qt::Key_Down }, - { kVK_LeftArrow, Qt::Key_Left }, - { kVK_RightArrow, Qt::Key_Right }, - { kVK_PageUp, Qt::Key_PageUp }, - { kVK_PageDown, Qt::Key_PageDown } -}; - -static QHash<char16_t, Qt::Key> functionKeys = { - { NSUpArrowFunctionKey, Qt::Key_Up }, - { NSDownArrowFunctionKey, Qt::Key_Down }, - { NSLeftArrowFunctionKey, Qt::Key_Left }, - { NSRightArrowFunctionKey, Qt::Key_Right }, - // F1-35 function keys handled manually below - { NSInsertFunctionKey, Qt::Key_Insert }, - { NSDeleteFunctionKey, Qt::Key_Delete }, - { NSHomeFunctionKey, Qt::Key_Home }, - { NSEndFunctionKey, Qt::Key_End }, - { NSPageUpFunctionKey, Qt::Key_PageUp }, - { NSPageDownFunctionKey, Qt::Key_PageDown }, - { NSPrintScreenFunctionKey, Qt::Key_Print }, - { NSScrollLockFunctionKey, Qt::Key_ScrollLock }, - { NSPauseFunctionKey, Qt::Key_Pause }, - { NSSysReqFunctionKey, Qt::Key_SysReq }, - { NSMenuFunctionKey, Qt::Key_Menu }, - { NSPrintFunctionKey, Qt::Key_Printer }, - { NSClearDisplayFunctionKey, Qt::Key_Clear }, - { NSInsertCharFunctionKey, Qt::Key_Insert }, - { NSDeleteCharFunctionKey, Qt::Key_Delete }, - { NSSelectFunctionKey, Qt::Key_Select }, - { NSExecuteFunctionKey, Qt::Key_Execute }, - { NSUndoFunctionKey, Qt::Key_Undo }, - { NSRedoFunctionKey, Qt::Key_Redo }, - { NSFindFunctionKey, Qt::Key_Find }, - { NSHelpFunctionKey, Qt::Key_Help }, - { NSModeSwitchFunctionKey, Qt::Key_Mode_switch } -}; - -static int toKeyCode(const QChar &key, int virtualKey, int modifiers) -{ - qCDebug(lcQpaKeyMapperKeys, "Mapping key: %d (0x%04x) / vk %d (0x%04x)", - key.unicode(), key.unicode(), virtualKey, virtualKey); - - if (key == QChar(kClearCharCode) && virtualKey == 0x47) - return Qt::Key_Clear; - - if (key.isDigit()) { - qCDebug(lcQpaKeyMapperKeys, "Got digit key: %d", key.digitValue()); - return key.digitValue() + Qt::Key_0; - } - - if (key.isLetter()) { - qCDebug(lcQpaKeyMapperKeys, "Got letter key: %d", (key.toUpper().unicode() - 'A')); - return (key.toUpper().unicode() - 'A') + Qt::Key_A; - } - if (key.isSymbol()) { - qCDebug(lcQpaKeyMapperKeys, "Got symbol key: %d", (key.unicode())); - return key.unicode(); - } - - if (auto qtKey = standardKeys.value(key.unicode())) { - // To work like Qt for X11 we issue Backtab when Shift + Tab are pressed - if (qtKey == Qt::Key_Tab && (modifiers & Qt::ShiftModifier)) { - qCDebug(lcQpaKeyMapperKeys, "Got key: Qt::Key_Backtab"); - return Qt::Key_Backtab; - } - - qCDebug(lcQpaKeyMapperKeys) << "Got" << qtKey; - return qtKey; - } - - // Last ditch try to match the scan code - if (auto qtKey = virtualKeys.value(virtualKey)) { - qCDebug(lcQpaKeyMapperKeys) << "Got scancode" << qtKey; - return qtKey; - } - - // Check if they belong to key codes in private unicode range - if (key >= QChar(NSUpArrowFunctionKey) && key <= QChar(NSModeSwitchFunctionKey)) { - if (auto qtKey = functionKeys.value(key.unicode())) { - qCDebug(lcQpaKeyMapperKeys) << "Got" << qtKey; - return qtKey; - } else if (key >= QChar(NSF1FunctionKey) && key <= QChar(NSF35FunctionKey)) { - auto functionKey = Qt::Key_F1 + (key.unicode() - NSF1FunctionKey) ; - qCDebug(lcQpaKeyMapperKeys) << "Got" << functionKey; - return functionKey; - } - } - - qCDebug(lcQpaKeyMapperKeys, "Unknown case.. %d[%d] %d", key.unicode(), key.toLatin1(), virtualKey); - return Qt::Key_unknown; -} - -// --------- Cocoa key mapping moved from Qt Core --------- - -static const int NSEscapeCharacter = 27; // not defined by Cocoa headers - -static const QHash<char16_t, Qt::Key> cocoaKeys = { - { NSEnterCharacter, Qt::Key_Enter }, - { NSBackspaceCharacter, Qt::Key_Backspace }, - { NSTabCharacter, Qt::Key_Tab }, - { NSNewlineCharacter, Qt::Key_Return }, - { NSCarriageReturnCharacter, Qt::Key_Return }, - { NSBackTabCharacter, Qt::Key_Backtab }, - { NSEscapeCharacter, Qt::Key_Escape }, - { NSDeleteCharacter, Qt::Key_Backspace }, - { NSUpArrowFunctionKey, Qt::Key_Up }, - { NSDownArrowFunctionKey, Qt::Key_Down }, - { NSLeftArrowFunctionKey, Qt::Key_Left }, - { NSRightArrowFunctionKey, Qt::Key_Right }, - { NSF1FunctionKey, Qt::Key_F1 }, - { NSF2FunctionKey, Qt::Key_F2 }, - { NSF3FunctionKey, Qt::Key_F3 }, - { NSF4FunctionKey, Qt::Key_F4 }, - { NSF5FunctionKey, Qt::Key_F5 }, - { NSF6FunctionKey, Qt::Key_F6 }, - { NSF7FunctionKey, Qt::Key_F7 }, - { NSF8FunctionKey, Qt::Key_F8 }, - { NSF9FunctionKey, Qt::Key_F9 }, - { NSF10FunctionKey, Qt::Key_F10 }, - { NSF11FunctionKey, Qt::Key_F11 }, - { NSF12FunctionKey, Qt::Key_F12 }, - { NSF13FunctionKey, Qt::Key_F13 }, - { NSF14FunctionKey, Qt::Key_F14 }, - { NSF15FunctionKey, Qt::Key_F15 }, - { NSF16FunctionKey, Qt::Key_F16 }, - { NSF17FunctionKey, Qt::Key_F17 }, - { NSF18FunctionKey, Qt::Key_F18 }, - { NSF19FunctionKey, Qt::Key_F19 }, - { NSF20FunctionKey, Qt::Key_F20 }, - { NSF21FunctionKey, Qt::Key_F21 }, - { NSF22FunctionKey, Qt::Key_F22 }, - { NSF23FunctionKey, Qt::Key_F23 }, - { NSF24FunctionKey, Qt::Key_F24 }, - { NSF25FunctionKey, Qt::Key_F25 }, - { NSF26FunctionKey, Qt::Key_F26 }, - { NSF27FunctionKey, Qt::Key_F27 }, - { NSF28FunctionKey, Qt::Key_F28 }, - { NSF29FunctionKey, Qt::Key_F29 }, - { NSF30FunctionKey, Qt::Key_F30 }, - { NSF31FunctionKey, Qt::Key_F31 }, - { NSF32FunctionKey, Qt::Key_F32 }, - { NSF33FunctionKey, Qt::Key_F33 }, - { NSF34FunctionKey, Qt::Key_F34 }, - { NSF35FunctionKey, Qt::Key_F35 }, - { NSInsertFunctionKey, Qt::Key_Insert }, - { NSDeleteFunctionKey, Qt::Key_Delete }, - { NSHomeFunctionKey, Qt::Key_Home }, - { NSEndFunctionKey, Qt::Key_End }, - { NSPageUpFunctionKey, Qt::Key_PageUp }, - { NSPageDownFunctionKey, Qt::Key_PageDown }, - { NSPrintScreenFunctionKey, Qt::Key_Print }, - { NSScrollLockFunctionKey, Qt::Key_ScrollLock }, - { NSPauseFunctionKey, Qt::Key_Pause }, - { NSSysReqFunctionKey, Qt::Key_SysReq }, - { NSMenuFunctionKey, Qt::Key_Menu }, - { NSHelpFunctionKey, Qt::Key_Help }, -}; - -QChar QCocoaKeyMapper::toCocoaKey(Qt::Key key) -{ - // Prioritize overloaded keys - if (key == Qt::Key_Return) - return QChar(NSNewlineCharacter); - if (key == Qt::Key_Backspace) - return QChar(NSBackspaceCharacter); - - static QHash<Qt::Key, char16_t> reverseCocoaKeys; - if (reverseCocoaKeys.isEmpty()) { - reverseCocoaKeys.reserve(cocoaKeys.size()); - for (auto it = cocoaKeys.begin(); it != cocoaKeys.end(); ++it) - reverseCocoaKeys.insert(it.value(), it.key()); - } - - return reverseCocoaKeys.value(key); -} - -Qt::Key QCocoaKeyMapper::fromCocoaKey(QChar keyCode) -{ - if (auto key = cocoaKeys.value(keyCode.unicode())) - return key; - - return Qt::Key(keyCode.toUpper().unicode()); -} - -// ------------------------------------------------ - -Qt::KeyboardModifiers QCocoaKeyMapper::queryKeyboardModifiers() -{ - return fromCocoaModifiers(NSEvent.modifierFlags); -} - -bool QCocoaKeyMapper::updateKeyboard() -{ - QCFType<TISInputSourceRef> source = TISCopyInputMethodKeyboardLayoutOverride(); - if (!source) - source = TISCopyCurrentKeyboardInputSource(); - - if (m_keyboardMode != NullMode && source == m_currentInputSource) - return false; - - Q_ASSERT(source); - m_currentInputSource = source; - m_keyboardKind = LMGetKbdType(); - m_deadKeyState = 0; - - m_keyMap.clear(); - - if (auto data = CFDataRef(TISGetInputSourceProperty(source, kTISPropertyUnicodeKeyLayoutData))) { - const UCKeyboardLayout *uchrData = reinterpret_cast<const UCKeyboardLayout *>(CFDataGetBytePtr(data)); - Q_ASSERT(uchrData); - m_keyboardLayoutFormat = uchrData; - m_keyboardMode = UnicodeMode; - } else { - m_keyboardLayoutFormat = nullptr; - m_keyboardMode = NullMode; - } - - qCDebug(lcQpaKeyMapper) << "Updated keyboard to" - << QString::fromCFString(CFStringRef(TISGetInputSourceProperty( - m_currentInputSource, kTISPropertyLocalizedName))); - - return true; -} - -static constexpr Qt::KeyboardModifiers modifierCombinations[] = { - Qt::NoModifier, // 0 - Qt::ShiftModifier, // 1 - Qt::ControlModifier, // 2 - Qt::ControlModifier | Qt::ShiftModifier, // 3 - Qt::AltModifier, // 4 - Qt::AltModifier | Qt::ShiftModifier, // 5 - Qt::AltModifier | Qt::ControlModifier, // 6 - Qt::AltModifier | Qt::ShiftModifier | Qt::ControlModifier, // 7 - Qt::MetaModifier, // 8 - Qt::MetaModifier | Qt::ShiftModifier, // 9 - Qt::MetaModifier | Qt::ControlModifier, // 10 - Qt::MetaModifier | Qt::ControlModifier | Qt::ShiftModifier, // 11 - Qt::MetaModifier | Qt::AltModifier, // 12 - Qt::MetaModifier | Qt::AltModifier | Qt::ShiftModifier, // 13 - Qt::MetaModifier | Qt::AltModifier | Qt::ControlModifier, // 14 - Qt::MetaModifier | Qt::AltModifier | Qt::ShiftModifier | Qt::ControlModifier, // 15 -}; - -/* - Returns a key map for the given \virtualKey based on all - possible modifier combinations. -*/ -const QCocoaKeyMapper::KeyMap &QCocoaKeyMapper::keyMapForKey(VirtualKeyCode virtualKey, QChar unicodeKey) const -{ - static_assert(sizeof(modifierCombinations) / sizeof(Qt::KeyboardModifiers) == kNumModifierCombinations); - - const_cast<QCocoaKeyMapper *>(this)->updateKeyboard(); - - auto &keyMap = m_keyMap[virtualKey]; - if (keyMap[Qt::NoModifier] != Qt::Key_unknown) - return keyMap; // Already filled - - qCDebug(lcQpaKeyMapper, "Updating key map for virtual key = 0x%02x!", (uint)virtualKey); - - // Key mapping via [NSEvent charactersByApplyingModifiers:] only works for key down - // events, but we might (wrongly) get into this code path for other key events such - // as NSEventTypeFlagsChanged. - const bool canMapCocoaEvent = NSApp.currentEvent.type == NSEventTypeKeyDown; - - if (!canMapCocoaEvent) - qCWarning(lcQpaKeyMapper) << "Could not map key to character for event" << NSApp.currentEvent; - - for (int i = 0; i < kNumModifierCombinations; ++i) { - Q_ASSERT(!i || keyMap[i] == 0); - - auto qtModifiers = modifierCombinations[i]; - auto carbonModifiers = toCarbonModifiers(qtModifiers); - const UInt32 modifierKeyState = (carbonModifiers >> 8) & 0xFF; - - static const UniCharCount maxStringLength = 10; - static UniChar unicodeString[maxStringLength]; - UniCharCount actualStringLength = 0; - OSStatus err = UCKeyTranslate(m_keyboardLayoutFormat, virtualKey, - kUCKeyActionDown, modifierKeyState, m_keyboardKind, OptionBits(0), - &m_deadKeyState, maxStringLength, &actualStringLength, unicodeString); - - // Use translated unicode key if valid - if (err == noErr && actualStringLength) - unicodeKey = QChar(unicodeString[0]); - - if (@available(macOS 10.15, *)) { - if (canMapCocoaEvent) { - // Until we've verified that the Cocoa API works as expected - // we first run the event through the Carbon APIs and then - // compare the results to Cocoa. - auto cocoaModifiers = toCocoaModifiers(qtModifiers); - auto *charactersWithModifiers = [NSApp.currentEvent charactersByApplyingModifiers:cocoaModifiers]; - Q_ASSERT(charactersWithModifiers && charactersWithModifiers.length > 0); - auto cocoaUnicodeKey = QChar([charactersWithModifiers characterAtIndex:0]); - if (cocoaUnicodeKey != unicodeKey) { - qCWarning(lcQpaKeyMapper) << "Mismatch between Cocoa" << cocoaUnicodeKey - << "and Carbon" << unicodeKey << "for virtual key" << virtualKey - << "with" << qtModifiers; - } - } - } - - int qtkey = toKeyCode(unicodeKey, virtualKey, qtModifiers); - if (qtkey == Qt::Key_unknown) - qtkey = unicodeKey.unicode(); - - keyMap[i] = qtkey; - - qCDebug(lcQpaKeyMapper, " [%d] (%d,0x%02x,'%c')", i, qtkey, qtkey, qtkey); - } - - return keyMap; -} - -QList<int> QCocoaKeyMapper::possibleKeys(const QKeyEvent *event) const -{ - QList<int> ret; - - const auto nativeVirtualKey = event->nativeVirtualKey(); - if (!nativeVirtualKey) - return ret; - - auto keyMap = keyMapForKey(nativeVirtualKey, QChar(event->key())); - - auto unmodifiedKey = keyMap[Qt::NoModifier]; - Q_ASSERT(unmodifiedKey != Qt::Key_unknown); - - auto eventModifiers = event->modifiers(); - - // The base key, with the complete set of modifiers, - // is always valid, and the first priority. - ret << int(unmodifiedKey) + int(eventModifiers); - - // FIXME: We only compute the first 8 combinations. Why? - for (int i = 1; i < 8; ++i) { - auto keyAfterApplyingModifiers = keyMap[i]; - if (keyAfterApplyingModifiers == unmodifiedKey) - continue; - - // Include key if event modifiers includes, or matches - // perfectly, the current candidate modifiers. - auto candidateModifiers = modifierCombinations[i]; - if ((eventModifiers & candidateModifiers) == candidateModifiers) - ret << int(keyAfterApplyingModifiers) + int(eventModifiers & ~candidateModifiers); - } - - return ret; -} - -QT_END_NAMESPACE diff --git a/src/plugins/platforms/cocoa/qcocoamenuitem.mm b/src/plugins/platforms/cocoa/qcocoamenuitem.mm index 4806b244c3..f11d7bd996 100644 --- a/src/plugins/platforms/cocoa/qcocoamenuitem.mm +++ b/src/plugins/platforms/cocoa/qcocoamenuitem.mm @@ -50,9 +50,9 @@ #include "qcocoahelpers.h" #include "qcocoaapplication.h" // for custom application category #include "qcocoamenuloader.h" -#include "qcocoakeymapper.h" #include <QtGui/private/qcoregraphics_p.h> #include <QtCore/qregularexpression.h> +#include <QtGui/private/qapplekeymapper_p.h> #include <QtCore/QDebug> @@ -356,7 +356,7 @@ NSMenuItem *QCocoaMenuItem::sync() auto key = accel[0].key(); auto modifiers = accel[0].keyboardModifiers(); - QChar cocoaKey = QCocoaKeyMapper::toCocoaKey(key); + QChar cocoaKey = QAppleKeyMapper::toCocoaKey(key); if (cocoaKey.isNull()) cocoaKey = QChar(key).toLower().unicode(); // Similar to qt_mac_removePrivateUnicode change the delete key, @@ -365,7 +365,7 @@ NSMenuItem *QCocoaMenuItem::sync() cocoaKey = QChar(NSDeleteCharacter); m_native.keyEquivalent = QStringView(&cocoaKey, 1).toNSString(); - m_native.keyEquivalentModifierMask = QCocoaKeyMapper::toCocoaModifiers(modifiers); + m_native.keyEquivalentModifierMask = QAppleKeyMapper::toCocoaModifiers(modifiers); } else #endif { diff --git a/src/plugins/platforms/cocoa/qcocoansmenu.mm b/src/plugins/platforms/cocoa/qcocoansmenu.mm index b94d31251e..6760ae59ff 100644 --- a/src/plugins/platforms/cocoa/qcocoansmenu.mm +++ b/src/plugins/platforms/cocoa/qcocoansmenu.mm @@ -46,10 +46,10 @@ #include "qcocoawindow.h" #include "qnsview.h" #include "qcocoahelpers.h" -#include "qcocoakeymapper.h" #include <QtCore/qcoreapplication.h> #include <QtCore/qcoreevent.h> +#include <QtGui/private/qapplekeymapper_p.h> static NSString *qt_mac_removePrivateUnicode(NSString *string) { @@ -254,7 +254,7 @@ static NSString *qt_mac_removePrivateUnicode(NSString *string) QChar ch; int keyCode; ulong nativeModifiers = event.modifierFlags; - Qt::KeyboardModifiers modifiers = QCocoaKeyMapper::fromCocoaModifiers(nativeModifiers); + Qt::KeyboardModifiers modifiers = QAppleKeyMapper::fromCocoaModifiers(nativeModifiers); NSString *charactersIgnoringModifiers = event.charactersIgnoringModifiers; NSString *characters = event.characters; @@ -264,7 +264,7 @@ static NSString *qt_mac_removePrivateUnicode(NSString *string) } else { ch = QChar([charactersIgnoringModifiers characterAtIndex:0]); } - keyCode = QCocoaKeyMapper::fromCocoaKey(ch); + keyCode = QAppleKeyMapper::fromCocoaKey(ch); } else { // might be a dead key ch = QChar::ReplacementCharacter; diff --git a/src/plugins/platforms/cocoa/qnsview_dragging.mm b/src/plugins/platforms/cocoa/qnsview_dragging.mm index d4ab5f4a24..945217e928 100644 --- a/src/plugins/platforms/cocoa/qnsview_dragging.mm +++ b/src/plugins/platforms/cocoa/qnsview_dragging.mm @@ -197,7 +197,7 @@ static QPoint mapWindowCoordinates(QWindow *source, QWindow *target, QPoint poin if (!target) return NSDragOperationNone; - const auto modifiers = QCocoaKeyMapper::fromCocoaModifiers(NSApp.currentEvent.modifierFlags); + const auto modifiers = QAppleKeyMapper::fromCocoaModifiers(NSApp.currentEvent.modifierFlags); const auto buttons = currentlyPressedMouseButtons(); const auto point = mapWindowCoordinates(m_platformWindow->window(), target, windowPoint); @@ -261,7 +261,7 @@ static QPoint mapWindowCoordinates(QWindow *source, QWindow *target, QPoint poin QPlatformDropQtResponse response(false, Qt::IgnoreAction); QCocoaDrag* nativeDrag = QCocoaIntegration::instance()->drag(); - const auto modifiers = QCocoaKeyMapper::fromCocoaModifiers(NSApp.currentEvent.modifierFlags); + const auto modifiers = QAppleKeyMapper::fromCocoaModifiers(NSApp.currentEvent.modifierFlags); const auto buttons = currentlyPressedMouseButtons(); const auto point = mapWindowCoordinates(m_platformWindow->window(), target, windowPoint); @@ -302,7 +302,7 @@ static QPoint mapWindowCoordinates(QWindow *source, QWindow *target, QPoint poin // this case won't send the matching release event, so we have to // synthesize it here. m_buttons = currentlyPressedMouseButtons(); - const auto modifiers = QCocoaKeyMapper::fromCocoaModifiers(NSApp.currentEvent.modifierFlags); + const auto modifiers = QAppleKeyMapper::fromCocoaModifiers(NSApp.currentEvent.modifierFlags); NSPoint windowPoint = [self.window convertRectFromScreen:NSMakeRect(screenPoint.x, screenPoint.y, 1, 1)].origin; NSPoint nsViewPoint = [self convertPoint: windowPoint fromView: nil]; diff --git a/src/plugins/platforms/cocoa/qnsview_keys.mm b/src/plugins/platforms/cocoa/qnsview_keys.mm index 09d78485f4..23b8254d63 100644 --- a/src/plugins/platforms/cocoa/qnsview_keys.mm +++ b/src/plugins/platforms/cocoa/qnsview_keys.mm @@ -45,7 +45,7 @@ { ulong timestamp = [nsevent timestamp] * 1000; ulong nativeModifiers = [nsevent modifierFlags]; - Qt::KeyboardModifiers modifiers = QCocoaKeyMapper::fromCocoaModifiers(nativeModifiers); + Qt::KeyboardModifiers modifiers = QAppleKeyMapper::fromCocoaModifiers(nativeModifiers); NSString *charactersIgnoringModifiers = [nsevent charactersIgnoringModifiers]; NSString *characters = [nsevent characters]; if (m_inputSource != characters) { @@ -74,7 +74,7 @@ ch = QChar([charactersIgnoringModifiers characterAtIndex:0]); else if ([characters length] != 0) ch = QChar([characters characterAtIndex:0]); - keyCode = QCocoaKeyMapper::fromCocoaKey(ch); + keyCode = QAppleKeyMapper::fromCocoaKey(ch); } // we will send a key event unless the input method sets m_sendKeyEvent to false @@ -194,7 +194,7 @@ { ulong timestamp = [nsevent timestamp] * 1000; ulong nativeModifiers = [nsevent modifierFlags]; - Qt::KeyboardModifiers modifiers = QCocoaKeyMapper::fromCocoaModifiers(nativeModifiers); + Qt::KeyboardModifiers modifiers = QAppleKeyMapper::fromCocoaModifiers(nativeModifiers); // Scan codes are hardware dependent codes for each key. There is no way to get these // from Carbon or Cocoa, so leave it 0, as documented in QKeyEvent::nativeScanCode(). @@ -238,7 +238,7 @@ (lastKnownModifiers & mac_mask) ? QEvent::KeyRelease : QEvent::KeyPress, qtCode, - modifiers ^ QCocoaKeyMapper::fromCocoaModifiers(mac_mask), + modifiers ^ QAppleKeyMapper::fromCocoaModifiers(mac_mask), nativeScanCode, nativeVirtualKey, nativeModifiers ^ mac_mask); } diff --git a/src/plugins/platforms/cocoa/qnsview_mouse.mm b/src/plugins/platforms/cocoa/qnsview_mouse.mm index 336f1085b9..d00cfb7886 100644 --- a/src/plugins/platforms/cocoa/qnsview_mouse.mm +++ b/src/plugins/platforms/cocoa/qnsview_mouse.mm @@ -279,7 +279,7 @@ QCocoaDrag* nativeDrag = QCocoaIntegration::instance()->drag(); nativeDrag->setLastMouseEvent(theEvent, self); - const auto modifiers = QCocoaKeyMapper::fromCocoaModifiers(theEvent.modifierFlags); + const auto modifiers = QAppleKeyMapper::fromCocoaModifiers(theEvent.modifierFlags); auto button = cocoaButton2QtButton(theEvent); if (button == Qt::LeftButton && m_sendUpAsRightButton) button = Qt::RightButton; @@ -678,7 +678,7 @@ // after scrolling in Qt Creator: not taking the phase into account causes // the end of the event stream to be interpreted as font size changes. if (theEvent.momentumPhase == NSEventPhaseNone) - m_currentWheelModifiers = QCocoaKeyMapper::fromCocoaModifiers(theEvent.modifierFlags); + m_currentWheelModifiers = QAppleKeyMapper::fromCocoaModifiers(theEvent.modifierFlags); // "isInverted": natural OS X scrolling, inverted from the Qt/other platform/Jens perspective. bool isInverted = [theEvent isDirectionInvertedFromDevice]; diff --git a/src/plugins/platforms/cocoa/qnsview_tablet.mm b/src/plugins/platforms/cocoa/qnsview_tablet.mm index 804c502775..2b269d038a 100644 --- a/src/plugins/platforms/cocoa/qnsview_tablet.mm +++ b/src/plugins/platforms/cocoa/qnsview_tablet.mm @@ -109,7 +109,7 @@ Q_GLOBAL_STATIC(QCocoaTabletDeviceDataHash, tabletDeviceDataHash) if (rotation > 180.0) rotation -= 360.0; - Qt::KeyboardModifiers keyboardModifiers = QCocoaKeyMapper::fromCocoaModifiers(theEvent.modifierFlags); + Qt::KeyboardModifiers keyboardModifiers = QAppleKeyMapper::fromCocoaModifiers(theEvent.modifierFlags); Qt::MouseButtons buttons = ignoreButtonMapping ? static_cast<Qt::MouseButtons>(static_cast<uint>([theEvent buttonMask])) : m_buttons; qCDebug(lcQpaTablet, "event on tablet %d with tool %d type %d unique ID %lld pos %6.1f, %6.1f root pos %6.1f, %6.1f buttons 0x%x pressure %4.2lf tilt %d, %d rotation %6.2lf", |