diff options
author | Morten Johan Sørvig <morten.sorvig@qt.io> | 2021-03-18 15:14:45 +0100 |
---|---|---|
committer | Morten Johan Sørvig <morten.sorvig@qt.io> | 2021-09-08 19:01:54 +0200 |
commit | 04fd894400325fc26af739ff289c3f457acdb41d (patch) | |
tree | 2ec09a6d4c795a0aca7cca75ab2b40fc6ebd49c8 | |
parent | 95d5710d7b608cd4e22b20d570d54dbadc8105cb (diff) | |
download | qtbase-04fd894400325fc26af739ff289c3f457acdb41d.tar.gz |
High-dpi configuration change testing
Export configuration() and setConfiguration() from the offscreen
platform plugin using QPlatformNativeInterface. tst_qighdpi can
then resolve and make use of them since it always uses the offscreen
platform plugin.
Add screenDpiChange() auto test.
Change-Id: I459b4df5d94ec4991234a346e3a94618cb3485e9
Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
4 files changed, 153 insertions, 1 deletions
diff --git a/src/plugins/platforms/offscreen/qoffscreencommon.cpp b/src/plugins/platforms/offscreen/qoffscreencommon.cpp index 29e2cc417d..f485b4eed8 100644 --- a/src/plugins/platforms/offscreen/qoffscreencommon.cpp +++ b/src/plugins/platforms/offscreen/qoffscreencommon.cpp @@ -236,6 +236,38 @@ void QOffscreenBackingStore::clearHash() QHash<WId, QOffscreenBackingStore *> QOffscreenBackingStore::m_backingStoreForWinIdHash; +QOffscreenPlatformNativeInterface::QOffscreenPlatformNativeInterface(QOffscreenIntegration *integration) + : m_integration(integration) +{ + +} + QOffscreenPlatformNativeInterface::~QOffscreenPlatformNativeInterface() = default; +/* + Set platform configuration, e.g. screen configuration +*/ +void QOffscreenPlatformNativeInterface::setConfiguration(const QJsonObject &configuration, QOffscreenPlatformNativeInterface *iface) +{ + iface->m_integration->setConfiguration(configuration); +} + +/* + Get the current platform configuration +*/ +QJsonObject QOffscreenPlatformNativeInterface::configuration(QOffscreenPlatformNativeInterface *iface) +{ + return iface->m_integration->configuration(); +} + +void *QOffscreenPlatformNativeInterface::nativeResourceForIntegration(const QByteArray &resource) +{ + if (resource == "setConfiguration") + return reinterpret_cast<void*>(&QOffscreenPlatformNativeInterface::setConfiguration); + else if (resource == "configuration") + return reinterpret_cast<void*>(&QOffscreenPlatformNativeInterface::configuration); + else + return nullptr; +} + QT_END_NAMESPACE diff --git a/src/plugins/platforms/offscreen/qoffscreencommon.h b/src/plugins/platforms/offscreen/qoffscreencommon.h index 7f92c5b4d9..d0edfcc48b 100644 --- a/src/plugins/platforms/offscreen/qoffscreencommon.h +++ b/src/plugins/platforms/offscreen/qoffscreencommon.h @@ -51,6 +51,7 @@ #include <qscopedpointer.h> #include <qimage.h> +#include <qjsonobject.h> #include <qhash.h> QT_BEGIN_NAMESPACE @@ -120,7 +121,15 @@ private: class QOffscreenPlatformNativeInterface : public QPlatformNativeInterface { public: + QOffscreenPlatformNativeInterface(QOffscreenIntegration *integration); ~QOffscreenPlatformNativeInterface(); + + static void setConfiguration(const QJsonObject &configuration, QOffscreenPlatformNativeInterface *iface); + static QJsonObject configuration(QOffscreenPlatformNativeInterface *iface); + + void *nativeResourceForIntegration(const QByteArray &resource) override; +private: + QOffscreenIntegration *m_integration; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/offscreen/qoffscreenintegration.cpp b/src/plugins/platforms/offscreen/qoffscreenintegration.cpp index a8504316d8..2613a42755 100644 --- a/src/plugins/platforms/offscreen/qoffscreenintegration.cpp +++ b/src/plugins/platforms/offscreen/qoffscreenintegration.cpp @@ -388,7 +388,7 @@ QAbstractEventDispatcher *QOffscreenIntegration::createEventDispatcher() const QPlatformNativeInterface *QOffscreenIntegration::nativeInterface() const { if (!m_nativeInterface) - m_nativeInterface.reset(new QOffscreenPlatformNativeInterface); + m_nativeInterface.reset(new QOffscreenPlatformNativeInterface(const_cast<QOffscreenIntegration*>(this))); return m_nativeInterface.get(); } diff --git a/tests/auto/gui/kernel/qhighdpi/tst_qhighdpi.cpp b/tests/auto/gui/kernel/qhighdpi/tst_qhighdpi.cpp index f0b1cab41a..b732954230 100644 --- a/tests/auto/gui/kernel/qhighdpi/tst_qhighdpi.cpp +++ b/tests/auto/gui/kernel/qhighdpi/tst_qhighdpi.cpp @@ -28,11 +28,13 @@ #include <private/qhighdpiscaling_p.h> #include <qpa/qplatformscreen.h> +#include <qpa/qplatformnativeinterface.h> #include <QTest> #include <QJsonArray> #include <QJsonObject> #include <QJsonDocument> +#include <QStringView> Q_LOGGING_CATEGORY(lcTests, "qt.gui.tests") @@ -45,6 +47,10 @@ private: // helpers QGuiApplication *createStandardOffscreenApp(const QList<qreal> &dpiValues); QGuiApplication *createStandardOffscreenApp(const QJsonArray &screens); static void standardScreenDpiTestData(); + + static void setOffscreenConfiguration(const QJsonObject &configuration); + static QJsonObject offscreenConfiguration(); + private slots: void cleanup(); void qhighdpiscaling_data(); @@ -53,6 +59,7 @@ private slots: void noscreens(); void screenDpiAndDpr_data(); void screenDpiAndDpr(); + void screenDpiChange(); void environment_QT_SCALE_FACTOR(); void environment_QT_SCREEN_SCALE_FACTORS_data(); void environment_QT_SCREEN_SCALE_FACTORS(); @@ -178,6 +185,83 @@ void tst_QHighDpi::standardScreenDpiTestData() QTest::newRow("240-252-360") << QList<qreal> { 400./160 * 96, 420./160 * 96, 600./160 * 96 }; } +void tst_QHighDpi::setOffscreenConfiguration(const QJsonObject &configuration) +{ + Q_ASSERT(qApp->platformName() == QLatin1String("offscreen")); + QPlatformNativeInterface *platformNativeInterface = qApp->platformNativeInterface(); + auto setConfiguration = reinterpret_cast<void (*)(QJsonObject, QPlatformNativeInterface *)>( + platformNativeInterface->nativeResourceForIntegration("setConfiguration")); + setConfiguration(configuration, platformNativeInterface); +} + +QJsonObject tst_QHighDpi::offscreenConfiguration() +{ + Q_ASSERT(qApp->platformName() == QLatin1String("offscreen")); + QPlatformNativeInterface *platformNativeInterface = qApp->platformNativeInterface(); + auto getConfiguration = reinterpret_cast<QJsonObject (*)(QPlatformNativeInterface *)>( + platformNativeInterface->nativeResourceForIntegration("configuration")); + return getConfiguration(platformNativeInterface); +} + +// JsonValueRef implements support for mutating nested JSON structures, e.g. +// +// JsonValueRef::get(&config)["screens"][0]["logicalDpi"] = 192 +// +class JsonValueRef { +public: + static JsonValueRef get(QJsonValue *value) { + return JsonValueRef(value); + } + + JsonValueRef(QJsonValue *value) + : m_value(value) { } + + JsonValueRef(QJsonValue *value, JsonValueRef *parent, QString key) + : m_value(value), m_parent(parent), m_key(key) { } + + JsonValueRef(QJsonValue *value, JsonValueRef *parent, int index) + : m_value(value), m_parent(parent), m_index(index) { } + + ~JsonValueRef() { + if (m_parent) { + if (!m_key.isNull()) { + QJsonObject parentObject = m_parent->m_value->toObject(); + parentObject[m_key] = *m_value; + *m_parent->m_value = parentObject; + } else if (m_index > -1) { + QJsonArray parentArray = m_parent->m_value->toArray(); + parentArray[m_index] = *m_value; + *m_parent->m_value = parentArray; + } + delete m_value; // owned if we have a parent, see operator[] + } + } + + JsonValueRef operator[](const char *str) { + QString key = QString::fromUtf8(str); + return JsonValueRef(new QJsonValue((*m_value)[key]), this, key); + } + + JsonValueRef operator[](int index) { + return JsonValueRef(new QJsonValue((*m_value)[index]), this, index); + } + + void operator=(int value) { + *m_value = QJsonValue(value); + } + + void operator=(const char *str) { + *m_value = QJsonValue(QString(str)); + } + +private: + Q_DISABLE_COPY(JsonValueRef); + QJsonValue *m_value = nullptr; + JsonValueRef *m_parent = nullptr; + QString m_key; + int m_index = -1; +}; + void tst_QHighDpi::cleanup() { // Some test functions set environment variables. Unset them here, @@ -233,6 +317,33 @@ void tst_QHighDpi::screenDpiAndDpr() } } +void tst_QHighDpi::screenDpiChange() +{ + QList<qreal> dpiValues = { 96, 96, 96}; + std::unique_ptr<QGuiApplication> app(createStandardOffscreenApp(dpiValues)); + + QCOMPARE(app->devicePixelRatio(), 1); + + // Set new DPI + int newDpi = 192; + QJsonValue config = offscreenConfiguration(); + JsonValueRef::get(&config)["screens"][0]["logicalDpi"] = newDpi; + JsonValueRef::get(&config)["screens"][1]["logicalDpi"] = newDpi; + JsonValueRef::get(&config)["screens"][2]["logicalDpi"] = newDpi; + setOffscreenConfiguration(config.toObject()); + + // TODO check events + + // Verify that the new DPI is in use + for (QScreen *screen : app->screens()) { + QCOMPARE(screen->devicePixelRatio(), newDpi / standardBaseDpi); + QCOMPARE(screen->logicalDotsPerInch(), newDpi / screen->devicePixelRatio()); + QWindow window(screen); + QCOMPARE(window.devicePixelRatio(), screen->devicePixelRatio()); + } + QCOMPARE(app->devicePixelRatio(), newDpi / standardBaseDpi); +} + void tst_QHighDpi::environment_QT_SCALE_FACTOR() { qreal factor = 3.1415; |