From 4d1f13f3549a73f5ca4e64dac9137e83138080fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20Johan=20S=C3=B8rvig?= Date: Tue, 9 Mar 2021 12:13:41 +0100 Subject: [PATCH 1/4] Read high-dpi env. variables in initHighDpiScaling() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Move all environment access to initHighDpiScaling(), which makes it so that all environment access happens at one point in time during QGuiApplication construction. Replace the “qt.scaling” logging category with “qt.highdpi”, and log each recognized env. variable. Further logging of DPI and computed scale factors will be introduced later on. This also enables auto-testing of the environment variable settings, since the auto-test can now control when the environment is read by (re-)creating the application object. Change-Id: I4e62a9c0050438357a58ace5b50fb7c5950c87ce Reviewed-by: Tor Arne Vestbø --- src/gui/kernel/qhighdpiscaling.cpp | 211 ++++++++++++++++------------- src/gui/kernel/qhighdpiscaling_p.h | 5 +- 2 files changed, 118 insertions(+), 98 deletions(-) diff --git a/src/gui/kernel/qhighdpiscaling.cpp b/src/gui/kernel/qhighdpiscaling.cpp index 5bc3f11b3d..4fa8b9378f 100644 --- a/src/gui/kernel/qhighdpiscaling.cpp +++ b/src/gui/kernel/qhighdpiscaling.cpp @@ -49,10 +49,11 @@ #include #include +#include QT_BEGIN_NAMESPACE -Q_LOGGING_CATEGORY(lcScaling, "qt.scaling"); +Q_LOGGING_CATEGORY(lcHighDpi, "qt.highdpi"); #ifndef QT_NO_HIGHDPISCALING @@ -68,30 +69,38 @@ static const char usePhysicalDpiEnvVar[] = "QT_USE_PHYSICAL_DPI"; // disconnect/connect cycles where the screen object may be deleted. typedef QHash QScreenScaleFactorHash; Q_GLOBAL_STATIC(QScreenScaleFactorHash, qNamedScreenScaleFactors); - -// Reads and interprets the given environment variable as a bool, -// returns the default value if not set. -static bool qEnvironmentVariableAsBool(const char *name, bool defaultValue) +static std::optional qEnvironmentVariableOptionalString(const char *name) { - bool ok = false; - int value = qEnvironmentVariableIntValue(name, &ok); - return ok ? value > 0 : defaultValue; + if (!qEnvironmentVariableIsSet(name)) + return std::nullopt; + + return std::optional(qEnvironmentVariable(name)); } -static inline qreal initialGlobalScaleFactor() +static std::optional qEnvironmentVariableOptionalByteArray(const char *name) { + if (!qEnvironmentVariableIsSet(name)) + return std::nullopt; - qreal result = 1; - if (qEnvironmentVariableIsSet(scaleFactorEnvVar)) { - bool ok; - const qreal f = qEnvironmentVariable(scaleFactorEnvVar).toDouble(&ok); - if (ok && f > 0) { - qCDebug(lcScaling) << "Apply " << scaleFactorEnvVar << f; - result = f; - } - } + return std::optional(qgetenv(name)); +} - return result; +static std::optional qEnvironmentVariableOptionalInt(const char *name) +{ + bool ok = false; + const int value = qEnvironmentVariableIntValue(name, &ok); + auto opt = ok ? std::optional(value) : std::nullopt; + return opt; +} + +static std::optional qEnvironmentVariableOptionalReal(const char *name) +{ + if (!qEnvironmentVariableIsSet(name)) + return std::nullopt; + + bool ok = false; + const qreal value = qEnvironmentVariable(name).toDouble(&ok); + return ok ? std::optional(value) : std::nullopt; } /*! @@ -275,35 +284,16 @@ bool QHighDpiScaling::m_usePlatformPluginDpi = false; // use scale factor based bool QHighDpiScaling::m_platformPluginDpiScalingActive = false; // platform plugin DPI gives a scale factor > 1 bool QHighDpiScaling::m_globalScalingActive = false; // global scale factor is active bool QHighDpiScaling::m_screenFactorSet = false; // QHighDpiScaling::setScreenFactor has been used - -/* - Initializes the QHighDpiScaling global variables. Called before the - platform plugin is created. -*/ - -static inline bool usePlatformPluginDpi() -{ - // Determine if we should set a scale factor based on the logical DPI - // reported by the platform plugin. - - bool enableEnvValueOk; - const int enableEnvValue = qEnvironmentVariableIntValue(enableHighDpiScalingEnvVar, &enableEnvValueOk); - if (enableEnvValueOk && enableEnvValue < 1) - return false; - - // Enable by default - return true; -} +bool QHighDpiScaling::m_usePhysicalDpi = false; +QHighDpiScaling::DpiAdjustmentPolicy QHighDpiScaling::m_dpiAdjustmentPolicy = QHighDpiScaling::DpiAdjustmentPolicy::Unset; +QString QHighDpiScaling::m_screenFactorsSpec; qreal QHighDpiScaling::rawScaleFactor(const QPlatformScreen *screen) { - // Determine if physical DPI should be used - static const bool usePhysicalDpi = qEnvironmentVariableAsBool(usePhysicalDpiEnvVar, false); - // Calculate scale factor beased on platform screen DPI values qreal factor; QDpi platformBaseDpi = screen->logicalBaseDpi(); - if (usePhysicalDpi) { + if (QHighDpiScaling::m_usePhysicalDpi) { QSize sz = screen->geometry().size(); QSizeF psz = screen->physicalSize(); qreal platformPhysicalDpi = ((sz.height() / psz.height()) + (sz.width() / psz.width())) * qreal(25.4 * 0.5); @@ -387,32 +377,9 @@ qreal QHighDpiScaling::roundScaleFactor(qreal rawFactor) // sizes that are smaller than the ideal size, and opposite for rounding up. // Rounding down is then preferable since "small UI" is a more acceptable // high-DPI experience than "large UI". - static auto scaleFactorRoundingPolicy = Qt::HighDpiScaleFactorRoundingPolicy::Unset; - // Determine rounding policy - if (scaleFactorRoundingPolicy == Qt::HighDpiScaleFactorRoundingPolicy::Unset) { - // Check environment - if (qEnvironmentVariableIsSet(scaleFactorRoundingPolicyEnvVar)) { - QByteArray policyText = qgetenv(scaleFactorRoundingPolicyEnvVar); - auto policyEnumValue = lookupScaleFactorRoundingPolicy(policyText); - if (policyEnumValue != Qt::HighDpiScaleFactorRoundingPolicy::Unset) { - scaleFactorRoundingPolicy = policyEnumValue; - } else { - auto values = joinEnumValues(std::begin(scaleFactorRoundingPolicyLookup), - std::end(scaleFactorRoundingPolicyLookup)); - qWarning("Unknown scale factor rounding policy: %s. Supported values are: %s.", - policyText.constData(), values.constData()); - } - } - - // Check application object if no environment value was set. - if (scaleFactorRoundingPolicy == Qt::HighDpiScaleFactorRoundingPolicy::Unset) { - scaleFactorRoundingPolicy = QGuiApplication::highDpiScaleFactorRoundingPolicy(); - } else { - // Make application setting reflect environment - QGuiApplication::setHighDpiScaleFactorRoundingPolicy(scaleFactorRoundingPolicy); - } - } + Qt::HighDpiScaleFactorRoundingPolicy scaleFactorRoundingPolicy = + QGuiApplication::highDpiScaleFactorRoundingPolicy(); // Apply rounding policy. qreal roundedFactor = rawFactor; @@ -452,56 +419,107 @@ QDpi QHighDpiScaling::effectiveLogicalDpi(const QPlatformScreen *screen, qreal r // with the rest of the UI. The amount of out-of-synch-ness depends on how // well user code handles a non-standard DPI values, but since the // adjustment is small (typically +/- 48 max) this might be OK. - static auto dpiAdjustmentPolicy = DpiAdjustmentPolicy::Unset; - - // Determine adjustment policy. - if (dpiAdjustmentPolicy == DpiAdjustmentPolicy::Unset) { - if (qEnvironmentVariableIsSet(dpiAdjustmentPolicyEnvVar)) { - QByteArray policyText = qgetenv(dpiAdjustmentPolicyEnvVar); - auto policyEnumValue = lookupDpiAdjustmentPolicy(policyText); - if (policyEnumValue != DpiAdjustmentPolicy::Unset) { - dpiAdjustmentPolicy = policyEnumValue; - } else { - auto values = joinEnumValues(std::begin(dpiAdjustmentPolicyLookup), - std::end(dpiAdjustmentPolicyLookup)); - qWarning("Unknown DPI adjustment policy: %s. Supported values are: %s.", - policyText.constData(), values.constData()); - } - } - if (dpiAdjustmentPolicy == DpiAdjustmentPolicy::Unset) - dpiAdjustmentPolicy = DpiAdjustmentPolicy::UpOnly; - } // Apply adjustment policy. const QDpi baseDpi = screen->logicalBaseDpi(); const qreal dpiAdjustmentFactor = rawFactor / roundedFactor; // Return the base DPI for cases where there is no adjustment - if (dpiAdjustmentPolicy == DpiAdjustmentPolicy::Disabled) + if (QHighDpiScaling::m_dpiAdjustmentPolicy == DpiAdjustmentPolicy::Disabled) return baseDpi; - if (dpiAdjustmentPolicy == DpiAdjustmentPolicy::UpOnly && dpiAdjustmentFactor < 1) + if (QHighDpiScaling::m_dpiAdjustmentPolicy == DpiAdjustmentPolicy::UpOnly && dpiAdjustmentFactor < 1) return baseDpi; return QDpi(baseDpi.first * dpiAdjustmentFactor, baseDpi.second * dpiAdjustmentFactor); } +/* + Determine and apply global/initial configuration which do not depend on + having access to QScreen objects - this function is called before they + have been created. Screen-dependent configuration happens later in + updateHighDpiScaling(). +*/ void QHighDpiScaling::initHighDpiScaling() { - // Determine if there is a global scale factor set. - m_factor = initialGlobalScaleFactor(); + // Read environment variables + static const char* envDebugStr = "environment variable set:"; + std::optional envEnableHighDpiScaling = qEnvironmentVariableOptionalInt(enableHighDpiScalingEnvVar); + if (envEnableHighDpiScaling.has_value()) + qCDebug(lcHighDpi) << envDebugStr << enableHighDpiScalingEnvVar << envEnableHighDpiScaling.value(); + + std::optional envScaleFactor = qEnvironmentVariableOptionalReal(scaleFactorEnvVar); + if (envScaleFactor.has_value()) + qCDebug(lcHighDpi) << envDebugStr << scaleFactorEnvVar << envScaleFactor.value(); + + std::optional envScreenFactors = qEnvironmentVariableOptionalString(screenFactorsEnvVar); + if (envScreenFactors.has_value()) + qCDebug(lcHighDpi) << envDebugStr << screenFactorsEnvVar << envScreenFactors.value(); + + std::optional envUsePhysicalDpi = qEnvironmentVariableOptionalInt(usePhysicalDpiEnvVar); + if (envUsePhysicalDpi.has_value()) + qCDebug(lcHighDpi) << envDebugStr << usePhysicalDpiEnvVar << envUsePhysicalDpi.value(); + + std::optional envScaleFactorRoundingPolicy = qEnvironmentVariableOptionalByteArray(scaleFactorRoundingPolicyEnvVar); + if (envScaleFactorRoundingPolicy.has_value()) + qCDebug(lcHighDpi) << envDebugStr << scaleFactorRoundingPolicyEnvVar << envScaleFactorRoundingPolicy.value(); + + std::optional envDpiAdjustmentPolicy = qEnvironmentVariableOptionalByteArray(dpiAdjustmentPolicyEnvVar); + if (envDpiAdjustmentPolicy.has_value()) + qCDebug(lcHighDpi) << envDebugStr << dpiAdjustmentPolicyEnvVar << envDpiAdjustmentPolicy.value(); + + // High-dpi scaling is enabled by default; check for global disable. + m_usePlatformPluginDpi = envEnableHighDpiScaling.value_or(1) > 0; + m_platformPluginDpiScalingActive = false; // see updateHighDpiScaling() + + // Check for glabal scale factor (different from 1) + m_factor = envScaleFactor.value_or(qreal(1)); m_globalScalingActive = !qFuzzyCompare(m_factor, qreal(1)); - m_usePlatformPluginDpi = usePlatformPluginDpi(); + // Store the envScreenFactors string for later use. The string format + // supports using screen names, which means that screen DPI cannot + // be resolved at this point. + QHighDpiScaling::m_screenFactorsSpec = envScreenFactors.value_or(QString()); - m_platformPluginDpiScalingActive = false; //set in updateHighDpiScaling below + m_usePhysicalDpi = envUsePhysicalDpi.value_or(0) > 0; + // Resolve HighDpiScaleFactorRoundingPolicy to QGuiApplication::highDpiScaleFactorRoundingPolicy + if (envScaleFactorRoundingPolicy.has_value()) { + QByteArray policyText = envScaleFactorRoundingPolicy.value(); + auto policyEnumValue = lookupScaleFactorRoundingPolicy(policyText); + if (policyEnumValue != Qt::HighDpiScaleFactorRoundingPolicy::Unset) { + QGuiApplication::setHighDpiScaleFactorRoundingPolicy(policyEnumValue); + } else { + auto values = joinEnumValues(std::begin(scaleFactorRoundingPolicyLookup), + std::end(scaleFactorRoundingPolicyLookup)); + qWarning("Unknown scale factor rounding policy: %s. Supported values are: %s.", + policyText.constData(), values.constData()); + } + } + + // Resolve DpiAdjustmentPolicy to m_dpiAdjustmentPolicy + if (envDpiAdjustmentPolicy.has_value()) { + QByteArray policyText = envScaleFactorRoundingPolicy.value(); + auto policyEnumValue = lookupDpiAdjustmentPolicy(policyText); + if (policyEnumValue != DpiAdjustmentPolicy::Unset) { + QHighDpiScaling::m_dpiAdjustmentPolicy = policyEnumValue; + } else { + auto values = joinEnumValues(std::begin(dpiAdjustmentPolicyLookup), + std::end(dpiAdjustmentPolicyLookup)); + qWarning("Unknown DPI adjustment policy: %s. Supported values are: %s.", + policyText.constData(), values.constData()); + } + } + + // Set initial active state m_active = m_globalScalingActive || m_usePlatformPluginDpi; } +/* + Update configuration based on available screens and screen properties. + This function may be called whenever the screen configuration changed. +*/ void QHighDpiScaling::updateHighDpiScaling() { - m_usePlatformPluginDpi = usePlatformPluginDpi(); - if (m_usePlatformPluginDpi && !m_platformPluginDpiScalingActive ) { const auto screens = QGuiApplication::screens(); for (QScreen *screen : screens) { @@ -511,10 +529,9 @@ void QHighDpiScaling::updateHighDpiScaling() } } } - if (qEnvironmentVariableIsSet(screenFactorsEnvVar)) { + if (!m_screenFactorsSpec.isNull()) { int i = 0; - const QString spec = qEnvironmentVariable(screenFactorsEnvVar); - const auto specs = QStringView{spec}.split(u';'); + const auto specs = QStringView{m_screenFactorsSpec}.split(u';'); for (const auto &spec : specs) { int equalsPos = spec.lastIndexOf(QLatin1Char('=')); qreal factor = 0; diff --git a/src/gui/kernel/qhighdpiscaling_p.h b/src/gui/kernel/qhighdpiscaling_p.h index 3a3983387c..e3522d41c1 100644 --- a/src/gui/kernel/qhighdpiscaling_p.h +++ b/src/gui/kernel/qhighdpiscaling_p.h @@ -64,7 +64,7 @@ QT_BEGIN_NAMESPACE -Q_DECLARE_LOGGING_CATEGORY(lcScaling); +Q_DECLARE_LOGGING_CATEGORY(lcHighDpi); class QScreen; class QPlatformScreen; @@ -138,6 +138,9 @@ private: static bool m_platformPluginDpiScalingActive; static bool m_globalScalingActive; static bool m_screenFactorSet; + static bool m_usePhysicalDpi; + static QString m_screenFactorsSpec; + static DpiAdjustmentPolicy m_dpiAdjustmentPolicy; }; namespace QHighDpi { From 657284acbc1869f5f93b2cc6e9b7530e2e145435 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20Johan=20S=C3=B8rvig?= Date: Fri, 12 Mar 2021 14:21:36 +0100 Subject: [PATCH 2/4] =?UTF-8?q?Don=E2=80=99t=20store=20screen=20scale=20fa?= =?UTF-8?q?ctors=20in=20GLOBAL=5FSTATIC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use a normal static variable, like the other high-dpi variables. Clear the stored factors in initHighDpiScaling(). This makes auto-testing possible where the application object is recreated for each test case and should start with a clean slate. Change-Id: I1831c856b5d7a2c522e62c7ed0657da771c3144f Reviewed-by: Tor Arne Vestbø --- src/gui/kernel/qhighdpiscaling.cpp | 13 +++++-------- src/gui/kernel/qhighdpiscaling_p.h | 1 + 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/src/gui/kernel/qhighdpiscaling.cpp b/src/gui/kernel/qhighdpiscaling.cpp index 4fa8b9378f..3a70e5acf7 100644 --- a/src/gui/kernel/qhighdpiscaling.cpp +++ b/src/gui/kernel/qhighdpiscaling.cpp @@ -64,11 +64,6 @@ static const char scaleFactorRoundingPolicyEnvVar[] = "QT_SCALE_FACTOR_ROUNDING_ static const char dpiAdjustmentPolicyEnvVar[] = "QT_DPI_ADJUSTMENT_POLICY"; static const char usePhysicalDpiEnvVar[] = "QT_USE_PHYSICAL_DPI"; -// Per-screen scale factors for named screens set with QT_SCREEN_SCALE_FACTORS -// are stored here. Use a global hash to keep the factor across screen -// disconnect/connect cycles where the screen object may be deleted. -typedef QHash QScreenScaleFactorHash; -Q_GLOBAL_STATIC(QScreenScaleFactorHash, qNamedScreenScaleFactors); static std::optional qEnvironmentVariableOptionalString(const char *name) { if (!qEnvironmentVariableIsSet(name)) @@ -287,6 +282,7 @@ bool QHighDpiScaling::m_screenFactorSet = false; // QHighDpiScaling::setScreenFa bool QHighDpiScaling::m_usePhysicalDpi = false; QHighDpiScaling::DpiAdjustmentPolicy QHighDpiScaling::m_dpiAdjustmentPolicy = QHighDpiScaling::DpiAdjustmentPolicy::Unset; QString QHighDpiScaling::m_screenFactorsSpec; +QHash QHighDpiScaling::m_namedScreenScaleFactors; // Per-screen scale factors (screen name -> factor) qreal QHighDpiScaling::rawScaleFactor(const QPlatformScreen *screen) { @@ -479,6 +475,7 @@ void QHighDpiScaling::initHighDpiScaling() // supports using screen names, which means that screen DPI cannot // be resolved at this point. QHighDpiScaling::m_screenFactorsSpec = envScreenFactors.value_or(QString()); + m_namedScreenScaleFactors.clear(); m_usePhysicalDpi = envUsePhysicalDpi.value_or(0) > 0; @@ -600,7 +597,7 @@ void QHighDpiScaling::setScreenFactor(QScreen *screen, qreal factor) if (name.isEmpty()) screen->setProperty(scaleFactorProperty, QVariant(factor)); else - qNamedScreenScaleFactors()->insert(name, factor); + QHighDpiScaling::m_namedScreenScaleFactors.insert(name, factor); // hack to force re-evaluation of screen geometry if (screen->handle()) @@ -647,8 +644,8 @@ qreal QHighDpiScaling::screenSubfactor(const QPlatformScreen *screen) } if (!screenPropertyUsed) { - auto byNameIt = qNamedScreenScaleFactors()->constFind(screen->name()); - if ((screenPropertyUsed = byNameIt != qNamedScreenScaleFactors()->cend())) + auto byNameIt = QHighDpiScaling::m_namedScreenScaleFactors.constFind(screen->name()); + if ((screenPropertyUsed = byNameIt != QHighDpiScaling::m_namedScreenScaleFactors.cend())) factor = *byNameIt; } } diff --git a/src/gui/kernel/qhighdpiscaling_p.h b/src/gui/kernel/qhighdpiscaling_p.h index e3522d41c1..e85a9b4bd6 100644 --- a/src/gui/kernel/qhighdpiscaling_p.h +++ b/src/gui/kernel/qhighdpiscaling_p.h @@ -141,6 +141,7 @@ private: static bool m_usePhysicalDpi; static QString m_screenFactorsSpec; static DpiAdjustmentPolicy m_dpiAdjustmentPolicy; + static QHash m_namedScreenScaleFactors; }; namespace QHighDpi { From f0bf7667a9914d00c3b3510bd46bb94d573d7d1a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20Johan=20S=C3=B8rvig?= Date: Wed, 10 Mar 2021 14:30:31 +0100 Subject: [PATCH 3/4] Auto-test some high-dpi env variables MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add auto-tests for QT_SCALE_FACTOR and QT_SCREEN_SCALE_FACTORS Change-Id: I57bffa266be910f2ba26cb1a870e09ae202fcae0 Reviewed-by: Tor Arne Vestbø --- .../auto/gui/kernel/qhighdpi/tst_qhighdpi.cpp | 49 +++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/tests/auto/gui/kernel/qhighdpi/tst_qhighdpi.cpp b/tests/auto/gui/kernel/qhighdpi/tst_qhighdpi.cpp index 512209ab73..339ff0ed20 100644 --- a/tests/auto/gui/kernel/qhighdpi/tst_qhighdpi.cpp +++ b/tests/auto/gui/kernel/qhighdpi/tst_qhighdpi.cpp @@ -47,12 +47,15 @@ private: // helpers static void standardScreenDpiTestData(); private slots: void initTestCase(); + void cleanup(); void qhighdpiscaling_data(); void qhighdpiscaling(); void minimumDpr(); void noscreens(); void screenDpiAndDpr_data(); void screenDpiAndDpr(); + void environment_QT_SCALE_FACTOR(); + void environment_QT_SCREEN_SCALE_FACTORS(); void screenAt_data(); void screenAt(); void screenGeometry_data(); @@ -178,6 +181,14 @@ void tst_QHighDpi::initTestCase() #endif } +void tst_QHighDpi::cleanup() +{ + // Some test functions set environment variables. Unset them here, + // in order to avoid getting confusing follow-on errors on test failures. + qunsetenv("QT_SCALE_FACTOR"); + qunsetenv("QT_SCREEN_SCALE_FACTORS"); +} + void tst_QHighDpi::qhighdpiscaling_data() { standardScreenDpiTestData(); @@ -224,6 +235,44 @@ void tst_QHighDpi::screenDpiAndDpr() } } +void tst_QHighDpi::environment_QT_SCALE_FACTOR() +{ + qreal factor = 3.1415; + qputenv("QT_SCALE_FACTOR", QByteArray::number(factor)); + + QList dpiValues { 96, 144, 192 }; + std::unique_ptr app(createStandardOffscreenApp(dpiValues)); + int i = 0; + for (QScreen *screen : app->screens()) { + // Verify that QT_SCALE_FACTOR applies as a multiplicative factor. + qreal expextedDpr = (dpiValues[i] / standardBaseDpi) * factor; + ++i; + QCOMPARE(screen->devicePixelRatio(), expextedDpr); + QCOMPARE(screen->logicalDotsPerInch(), 96); + QWindow window(screen); + QCOMPARE(window.devicePixelRatio(), expextedDpr); + } +} + +void tst_QHighDpi::environment_QT_SCREEN_SCALE_FACTORS() +{ + qreal factors[] = {1, 1.5, 2}; + qputenv("QT_SCREEN_SCALE_FACTORS", "1;1.5;2"); + + QList dpiValues { 192, 216, 240 }; + std::unique_ptr app(createStandardOffscreenApp(dpiValues)); + int i = 0; + for (QScreen *screen : app->screens()) { + qreal expextedDpr = factors[i]; + ++i; + // Verify that setting QT_SCREEN_SCALE_FACTORS overrides the from-dpi DPR + QCOMPARE(screen->devicePixelRatio(), expextedDpr); + QCOMPARE(screen->logicalDotsPerInch(), 96); + QWindow window(screen); + QCOMPARE(window.devicePixelRatio(), expextedDpr); + } +} + void tst_QHighDpi::minimumDpr() { QList dpiValues { 40, 60, 95 }; From f9f9004b40ed7a4f4d280ba48bf6422cac6d21a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20Johan=20S=C3=B8rvig?= Date: Fri, 12 Mar 2021 14:49:09 +0100 Subject: [PATCH 4/4] Add auto-test for QT_USE_PHYSICAL_DPI MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Test that setting QT_USE_PHYSICAL_DPI uses physical DPI instead of logical DPI. Change-Id: I7f89cf1af5e013454cc3d8ec3559f2719514fea3 Reviewed-by: Tor Arne Vestbø --- .../auto/gui/kernel/qhighdpi/tst_qhighdpi.cpp | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/tests/auto/gui/kernel/qhighdpi/tst_qhighdpi.cpp b/tests/auto/gui/kernel/qhighdpi/tst_qhighdpi.cpp index 339ff0ed20..31a41eeff6 100644 --- a/tests/auto/gui/kernel/qhighdpi/tst_qhighdpi.cpp +++ b/tests/auto/gui/kernel/qhighdpi/tst_qhighdpi.cpp @@ -56,6 +56,7 @@ private slots: void screenDpiAndDpr(); void environment_QT_SCALE_FACTOR(); void environment_QT_SCREEN_SCALE_FACTORS(); + void environment_QT_USE_PHYSICAL_DPI(); void screenAt_data(); void screenAt(); void screenGeometry_data(); @@ -187,6 +188,7 @@ void tst_QHighDpi::cleanup() // in order to avoid getting confusing follow-on errors on test failures. qunsetenv("QT_SCALE_FACTOR"); qunsetenv("QT_SCREEN_SCALE_FACTORS"); + qunsetenv("QT_USE_PHYSICAL_DPI"); } void tst_QHighDpi::qhighdpiscaling_data() @@ -273,6 +275,31 @@ void tst_QHighDpi::environment_QT_SCREEN_SCALE_FACTORS() } } +void tst_QHighDpi::environment_QT_USE_PHYSICAL_DPI() +{ + qputenv("QT_USE_PHYSICAL_DPI", "1"); + + QList dpiValues { 96, 144, 192 }; + std::unique_ptr app(createStandardOffscreenApp(dpiValues)); + + // Verify that the device pixel ratio is computed as physicalDpi / baseDpi. + // (which in practice uses physicalSize since this is what QPlatformScreen provides) + + // The default QPlatformScreen::physicalSize() implementation (which QOffscreenScreen + // currerently uses) assumes a default DPI of 100 and calculates a fake physical size + // based on that value. Use DPI 100 here as well: if you have changed the default value + // in QPlatformScreen and get a test failure then update the value below. + const qreal platformScreenDefualtDpi = 100; + qreal expextedDpr = (platformScreenDefualtDpi / qreal(standardBaseDpi)); + + for (QScreen *screen : app->screens()) { + QCOMPARE(screen->devicePixelRatio(), expextedDpr); + QCOMPARE(screen->logicalDotsPerInch(), 96); + QWindow window(screen); + QCOMPARE(window.devicePixelRatio(), expextedDpr); + } +} + void tst_QHighDpi::minimumDpr() { QList dpiValues { 40, 60, 95 };