From c74cfae7a3a8f446415a483846c74092189af31d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tor=20Arne=20Vestb=C3=B8?= Date: Wed, 20 Sep 2023 23:35:13 +0200 Subject: [PATCH] Long live QPlatformKeyMapper! The QKeyMapper class never got a platform integration companion. As we might be adding more functionality here in the future, let's fix that now, instead of adding more hooks directly to the platform integration class. The QKeyMapper will soon update its possibleKeys signature to return QKeyCombination, but for now transform the result. Change-Id: I88ef498180b2a8a7937a74627b7eb6b5156e872a Reviewed-by: Liang Qi --- src/gui/CMakeLists.txt | 1 + src/gui/kernel/qguiapplication.cpp | 3 +- src/gui/kernel/qkeymapper.cpp | 22 ++++++++---- src/gui/kernel/qplatformintegration.cpp | 16 +++++++++ src/gui/kernel/qplatformintegration.h | 5 +++ src/gui/kernel/qplatformkeymapper.cpp | 38 +++++++++++++++++++++ src/gui/kernel/qplatformkeymapper.h | 36 +++++++++++++++++++ src/gui/platform/darwin/qapplekeymapper.mm | 1 - src/gui/platform/darwin/qapplekeymapper_p.h | 2 ++ 9 files changed, 115 insertions(+), 9 deletions(-) create mode 100644 src/gui/kernel/qplatformkeymapper.cpp create mode 100644 src/gui/kernel/qplatformkeymapper.h 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