diff --git a/src/gui/CMakeLists.txt b/src/gui/CMakeLists.txt index 815dcb1398a..8934b025ed4 100644 --- a/src/gui/CMakeLists.txt +++ b/src/gui/CMakeLists.txt @@ -114,6 +114,7 @@ qt_internal_add_module(Gui kernel/qplatformintegration.cpp kernel/qplatformintegration.h kernel/qplatformintegrationfactory.cpp kernel/qplatformintegrationfactory_p.h kernel/qplatformintegrationplugin.cpp kernel/qplatformintegrationplugin.h + kernel/qplatformkeymapper.cpp kernel/qplatformkeymapper.h kernel/qplatformmenu.cpp kernel/qplatformmenu.h kernel/qplatformmenu_p.h kernel/qplatformnativeinterface.cpp kernel/qplatformnativeinterface.h kernel/qplatformoffscreensurface.cpp kernel/qplatformoffscreensurface.h diff --git a/src/gui/kernel/qguiapplication.cpp b/src/gui/kernel/qguiapplication.cpp index 5d98548ada9..3e9e966cf06 100644 --- a/src/gui/kernel/qguiapplication.cpp +++ b/src/gui/kernel/qguiapplication.cpp @@ -17,6 +17,7 @@ #include #include #include +#include #include #include @@ -1847,7 +1848,7 @@ Qt::KeyboardModifiers QGuiApplication::queryKeyboardModifiers() { CHECK_QAPP_INSTANCE(Qt::KeyboardModifiers{}) QPlatformIntegration *pi = QGuiApplicationPrivate::platformIntegration(); - return pi->queryKeyboardModifiers(); + return pi->keyMapper()->queryKeyboardModifiers(); } /*! diff --git a/src/gui/kernel/qkeymapper.cpp b/src/gui/kernel/qkeymapper.cpp index ff781ec43ba..bd7dbd90e9d 100644 --- a/src/gui/kernel/qkeymapper.cpp +++ b/src/gui/kernel/qkeymapper.cpp @@ -9,6 +9,7 @@ #include #include +#include QT_BEGIN_NAMESPACE @@ -36,14 +37,21 @@ QKeyMapper::~QKeyMapper() QList QKeyMapper::possibleKeys(const QKeyEvent *e) { - QList result = QGuiApplicationPrivate::platformIntegration()->possibleKeys(e); - if (!result.isEmpty()) - return result; + QList result; + + const auto *platformIntegration = QGuiApplicationPrivate::platformIntegration(); + const auto *platformKeyMapper = platformIntegration->keyMapper(); + const auto keyCombinations = platformKeyMapper->possibleKeyCombinations(e); + for (auto keyCombination : keyCombinations) + result << keyCombination.toCombined(); + + if (result.isEmpty()) { + if (e->key() && (e->key() != Qt::Key_unknown)) + result << e->keyCombination().toCombined(); + else if (!e->text().isEmpty()) + result << int(e->text().at(0).unicode() + (int)e->modifiers()); + } - if (e->key() && (e->key() != Qt::Key_unknown)) - result << e->keyCombination().toCombined(); - else if (!e->text().isEmpty()) - result << int(e->text().at(0).unicode() + (int)e->modifiers()); return result; } diff --git a/src/gui/kernel/qplatformintegration.cpp b/src/gui/kernel/qplatformintegration.cpp index b7117b121dd..3b20d2e7e47 100644 --- a/src/gui/kernel/qplatformintegration.cpp +++ b/src/gui/kernel/qplatformintegration.cpp @@ -6,6 +6,7 @@ #include #include #include +#include #include #include #include @@ -342,6 +343,21 @@ QPlatformInputContext *QPlatformIntegration::inputContext() const return nullptr; } +/*! + Accessor for the platform integration's key mapper. + + Default implementation returns a default QPlatformKeyMapper. + + \sa QPlatformKeyMapper +*/ +QPlatformKeyMapper *QPlatformIntegration::keyMapper() const +{ + static QPlatformKeyMapper *keyMapper = nullptr; + if (!keyMapper) + keyMapper = new QPlatformKeyMapper; + return keyMapper; +} + #if QT_CONFIG(accessibility) /*! diff --git a/src/gui/kernel/qplatformintegration.h b/src/gui/kernel/qplatformintegration.h index 393845012ac..71bf23a55c9 100644 --- a/src/gui/kernel/qplatformintegration.h +++ b/src/gui/kernel/qplatformintegration.h @@ -33,6 +33,7 @@ class QPlatformOpenGLContext; class QGuiGLFormat; class QAbstractEventDispatcher; class QPlatformInputContext; +class QPlatformKeyMapper; class QPlatformAccessibility; class QPlatformTheme; class QPlatformDialogHelper; @@ -171,8 +172,12 @@ public: virtual QVariant styleHint(StyleHint hint) const; virtual Qt::WindowState defaultWindowState(Qt::WindowFlags) const; +protected: virtual Qt::KeyboardModifiers queryKeyboardModifiers() const; virtual QList possibleKeys(const QKeyEvent *) const; + friend class QPlatformKeyMapper; +public: + virtual QPlatformKeyMapper *keyMapper() const; virtual QStringList themeNames() const; virtual QPlatformTheme *createPlatformTheme(const QString &name) const; diff --git a/src/gui/kernel/qplatformkeymapper.cpp b/src/gui/kernel/qplatformkeymapper.cpp new file mode 100644 index 00000000000..f54e4ff3794 --- /dev/null +++ b/src/gui/kernel/qplatformkeymapper.cpp @@ -0,0 +1,38 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + +#include "qplatformkeymapper.h" + +#include +#include + +QT_BEGIN_NAMESPACE + +Q_LOGGING_CATEGORY(lcQpaKeyMapper, "qt.qpa.keymapper") + +QPlatformKeyMapper::~QPlatformKeyMapper() +{ +} + +/* + Should return a list of possible key combinations for the given key event. + + For example, given a US English keyboard layout, the key event Shift+5 + can represent both a "Shift+5" key combination, as well as just "%". +*/ +QList QPlatformKeyMapper::possibleKeyCombinations(const QKeyEvent *event) const +{ + auto *platformIntegration = QGuiApplicationPrivate::platformIntegration(); + QList possibleKeys = platformIntegration->possibleKeys(event); + QList combinations; + for (int key : possibleKeys) + combinations << QKeyCombination::fromCombined(key); + return combinations; +} + +Qt::KeyboardModifiers QPlatformKeyMapper::queryKeyboardModifiers() const +{ + return QGuiApplicationPrivate::platformIntegration()->queryKeyboardModifiers(); +} + +QT_END_NAMESPACE diff --git a/src/gui/kernel/qplatformkeymapper.h b/src/gui/kernel/qplatformkeymapper.h new file mode 100644 index 00000000000..fb5b0cdb8bd --- /dev/null +++ b/src/gui/kernel/qplatformkeymapper.h @@ -0,0 +1,36 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + +#ifndef QPLATFORMKEYMAPPER_P +#define QPLATFORMKEYMAPPER_P + +// +// W A R N I N G +// ------------- +// +// This file is part of the QPA API and is not meant to be used +// in applications. Usage of this API may make your code +// source and binary incompatible with future versions of Qt. +// + +#include +#include + +QT_BEGIN_NAMESPACE + +Q_DECLARE_EXPORTED_LOGGING_CATEGORY(lcQpaKeyMapper, Q_GUI_EXPORT) + +class QKeyEvent; + +class Q_GUI_EXPORT QPlatformKeyMapper +{ +public: + virtual ~QPlatformKeyMapper(); + + virtual QList possibleKeyCombinations(const QKeyEvent *event) const; + virtual Qt::KeyboardModifiers queryKeyboardModifiers() const; +}; + +QT_END_NAMESPACE + +#endif // QPLATFORMKEYMAPPER_P diff --git a/src/gui/platform/darwin/qapplekeymapper.mm b/src/gui/platform/darwin/qapplekeymapper.mm index f7dbc1990d0..12381041864 100644 --- a/src/gui/platform/darwin/qapplekeymapper.mm +++ b/src/gui/platform/darwin/qapplekeymapper.mm @@ -18,7 +18,6 @@ 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) diff --git a/src/gui/platform/darwin/qapplekeymapper_p.h b/src/gui/platform/darwin/qapplekeymapper_p.h index 34557c8ede8..0f096e95378 100644 --- a/src/gui/platform/darwin/qapplekeymapper_p.h +++ b/src/gui/platform/darwin/qapplekeymapper_p.h @@ -19,6 +19,8 @@ #include #endif +#include + #include #include #include