summaryrefslogtreecommitdiffstats
path: root/src/plugins/platforms/cocoa/qcocoakeymapper.mm
diff options
context:
space:
mode:
authorAndy Shaw <andy.shaw@qt.io>2020-12-04 15:04:49 +0100
committerAndy Shaw <andy.shaw@qt.io>2021-01-20 12:29:38 +0100
commit15576c961047231a49afda9b9ee0159ba132c0ae (patch)
treed2ff922cd5a3f910471d69380ea12ce99155a212 /src/plugins/platforms/cocoa/qcocoakeymapper.mm
parenta5bb7b3ca510c301baf84e1dd46d5aeeb4986eb2 (diff)
iOS: Handle keyboard events when using an external keyboard
This enables the two possible approaches for handling external keyboard events. While support still exists for before 13.4 then both approaches are needed. This ensures that all external keyboard events are handled as key events and passed on accordingly. Additionally, this accounts for possible shortcuts too, therefore a new function is added to QShortcutMap to aid that. As a result, code has now moved from QCocoaKeyMapper to be part of the gui/platforms/darwin part to make it easier to reuse this code elsewhere. Fixes: QTBUG-85727 Change-Id: I349af43468b03fd8dcb16adba02669974affe154 Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
Diffstat (limited to 'src/plugins/platforms/cocoa/qcocoakeymapper.mm')
-rw-r--r--src/plugins/platforms/cocoa/qcocoakeymapper.mm547
1 files changed, 0 insertions, 547 deletions
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