summaryrefslogtreecommitdiffstats
path: root/src/plugins
diff options
context:
space:
mode:
authorTor Arne Vestbø <tor.arne.vestbo@qt.io>2020-07-02 15:23:54 +0200
committerTor Arne Vestbø <tor.arne.vestbo@qt.io>2020-07-02 15:35:18 +0200
commitfcd3d4fb71c86eb5a97a785b8ebeaf1fe81b65de (patch)
tree5eb890fcbe198f20a3d9b5c39fa166f3cebbe7a2 /src/plugins
parent0a52eba3c0ba1c3ddaa263f83db8b64c3058824c (diff)
macOS: Move key mapping from QtCore to platform plugin
There's a bunch of similar and overlapping logic in QCocoaKeyMapper already. Moving it to the same place allows us to easier find ways to reduce the overlap. None of the exported functions were used outside of the plugin. Change-Id: I6953690cdfda5ee8265b33ccbf919184c3a1700f Reviewed-by: Timur Pocheptsov <timur.pocheptsov@qt.io>
Diffstat (limited to 'src/plugins')
-rw-r--r--src/plugins/platforms/cocoa/qcocoakeymapper.h2
-rw-r--r--src/plugins/platforms/cocoa/qcocoakeymapper.mm142
-rw-r--r--src/plugins/platforms/cocoa/qcocoamenuitem.mm3
-rw-r--r--src/plugins/platforms/cocoa/qcocoansmenu.mm2
-rw-r--r--src/plugins/platforms/cocoa/qnsview_keys.mm7
5 files changed, 148 insertions, 8 deletions
diff --git a/src/plugins/platforms/cocoa/qcocoakeymapper.h b/src/plugins/platforms/cocoa/qcocoakeymapper.h
index f195cda7be..d93fe16b20 100644
--- a/src/plugins/platforms/cocoa/qcocoakeymapper.h
+++ b/src/plugins/platforms/cocoa/qcocoakeymapper.h
@@ -83,6 +83,8 @@ public:
QList<int> possibleKeys(const QKeyEvent *event) const;
static Qt::KeyboardModifiers fromCocoaModifiers(NSEventModifierFlags cocoaModifiers);
+ static QChar toCocoaKey(Qt::Key key);
+ static Qt::Key fromCocoaKey(QChar keyCode);
private:
bool updateKeyboard();
diff --git a/src/plugins/platforms/cocoa/qcocoakeymapper.mm b/src/plugins/platforms/cocoa/qcocoakeymapper.mm
index 40d13e2d6a..fdb4fb01e7 100644
--- a/src/plugins/platforms/cocoa/qcocoakeymapper.mm
+++ b/src/plugins/platforms/cocoa/qcocoakeymapper.mm
@@ -295,6 +295,148 @@ static int toKeyCode(const QChar &key, int virtualKey, int modifiers)
return Qt::Key_unknown;
}
+// --------- Cocoa key mapping moved from Qt Core ---------
+
+// Use this method to keep all the information in the TextSegment. As long as it is ordered
+// we are in OK shape, and we can influence that ourselves.
+struct KeyPair
+{
+ QChar cocoaKey;
+ Qt::Key qtKey;
+};
+
+bool operator==(const KeyPair &entry, QChar qchar)
+{
+ return entry.cocoaKey == qchar;
+}
+
+bool operator<(const KeyPair &entry, QChar qchar)
+{
+ return entry.cocoaKey < qchar;
+}
+
+bool operator<(QChar qchar, const KeyPair &entry)
+{
+ return qchar < entry.cocoaKey;
+}
+
+bool operator<(const Qt::Key &key, const KeyPair &entry)
+{
+ return key < entry.qtKey;
+}
+
+bool operator<(const KeyPair &entry, const Qt::Key &key)
+{
+ return entry.qtKey < key;
+}
+
+struct qtKey2CocoaKeySortLessThan
+{
+ typedef bool result_type;
+ Q_DECL_CONSTEXPR result_type operator()(const KeyPair &entry1, const KeyPair &entry2) const noexcept
+ {
+ return entry1.qtKey < entry2.qtKey;
+ }
+};
+
+static const int NSEscapeCharacter = 27; // not defined by Cocoa headers
+static const int NumEntries = 59;
+static const KeyPair entries[NumEntries] = {
+ { 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 },
+ // Cocoa sends us delete when pressing backspace!
+ // (NB when we reverse this list in qtKey2CocoaKey, there
+ // will be two indices of Qt::Key_Backspace. But is seems to work
+ // ok for menu shortcuts (which uses that function):
+ { 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 },
+};
+static const KeyPair * const end = entries + NumEntries;
+
+QChar QCocoaKeyMapper::toCocoaKey(Qt::Key key)
+{
+ // The first time this function is called, create a reverse
+ // lookup table sorted on Qt Key rather than Cocoa key:
+ static QVector<KeyPair> rev_entries(NumEntries);
+ static bool mustInit = true;
+ if (mustInit){
+ mustInit = false;
+ for (int i=0; i<NumEntries; ++i)
+ rev_entries[i] = entries[i];
+ std::sort(rev_entries.begin(), rev_entries.end(), qtKey2CocoaKeySortLessThan());
+ }
+ const QVector<KeyPair>::iterator i
+ = std::lower_bound(rev_entries.begin(), rev_entries.end(), key);
+ if ((i == rev_entries.end()) || (key < *i))
+ return QChar();
+ return i->cocoaKey;
+}
+
+Qt::Key QCocoaKeyMapper::fromCocoaKey(QChar keyCode)
+{
+ const KeyPair *i = std::lower_bound(entries, end, keyCode);
+ if ((i == end) || (keyCode < *i))
+ return Qt::Key(keyCode.toUpper().unicode());
+ return i->qtKey;
+}
+
+// ------------------------------------------------
+
QCocoaKeyMapper::QCocoaKeyMapper()
{
memset(m_keyLayout, 0, sizeof(m_keyLayout));
diff --git a/src/plugins/platforms/cocoa/qcocoamenuitem.mm b/src/plugins/platforms/cocoa/qcocoamenuitem.mm
index c51edb3dec..e5dc1c54e6 100644
--- a/src/plugins/platforms/cocoa/qcocoamenuitem.mm
+++ b/src/plugins/platforms/cocoa/qcocoamenuitem.mm
@@ -50,6 +50,7 @@
#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>
@@ -99,7 +100,7 @@ static quint32 constructModifierMask(quint32 accel_key)
NSString *keySequenceToKeyEqivalent(const QKeySequence &accel)
{
quint32 accel_key = (accel[0] & ~(Qt::MODIFIER_MASK | Qt::UNICODE_ACCEL));
- QChar cocoa_key = qt_mac_qtKey2CocoaKey(Qt::Key(accel_key));
+ QChar cocoa_key = QCocoaKeyMapper::toCocoaKey(Qt::Key(accel_key));
if (cocoa_key.isNull())
cocoa_key = QChar(accel_key).toLower().unicode();
// Similar to qt_mac_removePrivateUnicode change the delete key so the symbol is correctly seen in native menubar
diff --git a/src/plugins/platforms/cocoa/qcocoansmenu.mm b/src/plugins/platforms/cocoa/qcocoansmenu.mm
index d271a566d9..b94d31251e 100644
--- a/src/plugins/platforms/cocoa/qcocoansmenu.mm
+++ b/src/plugins/platforms/cocoa/qcocoansmenu.mm
@@ -264,7 +264,7 @@ static NSString *qt_mac_removePrivateUnicode(NSString *string)
} else {
ch = QChar([charactersIgnoringModifiers characterAtIndex:0]);
}
- keyCode = qt_mac_cocoaKey2QtKey(ch);
+ keyCode = QCocoaKeyMapper::fromCocoaKey(ch);
} else {
// might be a dead key
ch = QChar::ReplacementCharacter;
diff --git a/src/plugins/platforms/cocoa/qnsview_keys.mm b/src/plugins/platforms/cocoa/qnsview_keys.mm
index 73b2b89176..0122c01972 100644
--- a/src/plugins/platforms/cocoa/qnsview_keys.mm
+++ b/src/plugins/platforms/cocoa/qnsview_keys.mm
@@ -41,11 +41,6 @@
@implementation QNSView (Keys)
-- (int)convertKeyCode:(QChar)keyChar
-{
- return qt_mac_cocoaKey2QtKey(keyChar);
-}
-
- (bool)handleKeyEvent:(NSEvent *)nsevent eventType:(int)eventType
{
ulong timestamp = [nsevent timestamp] * 1000;
@@ -78,7 +73,7 @@
ch = QChar([charactersIgnoringModifiers characterAtIndex:0]);
else if ([characters length] != 0)
ch = QChar([characters characterAtIndex:0]);
- keyCode = [self convertKeyCode:ch];
+ keyCode = QCocoaKeyMapper::fromCocoaKey(ch);
}
// we will send a key event unless the input method sets m_sendKeyEvent to false