Commit 0c8f738c authored by Sharaf Zaman's avatar Sharaf Zaman

Merge branch 'master' of https://anongit.kde.org/krita into sh-zam/T10784-android-port

parents bfe13322 dd3746f6
From e553433c3dfa2664140a2ccf4b479821fc382e83 Mon Sep 17 00:00:00 2001
From: Andy Shaw <andy.shaw@qt.io>
Date: Fri, 21 Dec 2018 15:53:57 +0100
Subject: [PATCH 30/36] Windows QPA: Make the expected screen be in sync with
the geometry changes
When the window moves to a new screen then we should ensure the screen
is updated at that point with the new size so it can account for any
scaling changes.
This reverts f1ec81b543fe1d5090acff298e24faf10a7bac63.
Change-Id: I2be3aab677c4677841a07beaaf373f498483b320
Fixes: QTBUG-72504
Reviewed-by: Friedemann Kleint <Friedemann.Kleint@qt.io>
---
src/plugins/platforms/windows/qwindowswindow.cpp | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/src/plugins/platforms/windows/qwindowswindow.cpp b/src/plugins/platforms/windows/qwindowswindow.cpp
index 910d8dd209..865874846e 100644
--- a/src/plugins/platforms/windows/qwindowswindow.cpp
+++ b/src/plugins/platforms/windows/qwindowswindow.cpp
@@ -1756,15 +1756,12 @@ void QWindowsWindow::checkForScreenChanged()
QPlatformScreen *currentScreen = screen();
const auto &screenManager = QWindowsContext::instance()->screenManager();
- // QTBUG-62971: When dragging a window by its border, detect by mouse position
- // to prevent it from oscillating between screens when it resizes
- const QWindowsScreen *newScreen = testFlag(ResizeMoveActive)
- ? screenManager.screenAtDp(QWindowsCursor::mousePosition())
- : screenManager.screenForHwnd(m_data.hwnd);
+ const QWindowsScreen *newScreen = screenManager.screenForHwnd(m_data.hwnd);
if (newScreen != nullptr && newScreen != currentScreen) {
qCDebug(lcQpaWindows).noquote().nospace() << __FUNCTION__
<< ' ' << window() << " \"" << currentScreen->name()
<< "\"->\"" << newScreen->name() << '"';
+ setFlag(SynchronousGeometryChangeEvent);
QWindowSystemInterface::handleWindowScreenChanged(window(), newScreen->screen());
}
}
@@ -1783,11 +1780,14 @@ void QWindowsWindow::handleGeometryChange()
fireExpose(QRect(QPoint(0, 0), m_data.geometry.size()), true);
}
+ const bool wasSync = testFlag(SynchronousGeometryChangeEvent);
checkForScreenChanged();
if (testFlag(SynchronousGeometryChangeEvent))
QWindowSystemInterface::flushWindowSystemEvents(QEventLoop::ExcludeUserInputEvents);
+ if (!wasSync)
+ clearFlag(SynchronousGeometryChangeEvent);
qCDebug(lcQpaEvents) << __FUNCTION__ << this << window() << m_data.geometry;
}
--
2.18.0.windows.1
From 676320297d7e5654cbe66fe4bd86125824e05840 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Morten=20Johan=20S=C3=B8rvig?= <morten.sorvig@qt.io>
Date: Mon, 25 Apr 2016 09:27:48 +0200
Subject: [PATCH 31/36] Compute logical DPI on a per-screen basis
The logical DPI reported to applications is the platform screen
logical DPI divided by the platform screen scale factor.
Use the screen in question when calculating the DPI instead of
the values from the main screen.
QHighDpiScaling::logicalDpi now takes a QScreen pointer.
Done-with: Friedemann Kleint <Friedemann.Kleint@qt.io>
Task-number: QTBUG-53022
Change-Id: I0f62b5878c37e3488e9a8cc48aef183ff822d0c4
---
src/gui/kernel/qhighdpiscaling.cpp | 20 +++++++++-----------
src/gui/kernel/qhighdpiscaling_p.h | 2 +-
src/gui/kernel/qscreen.cpp | 6 +++---
3 files changed, 13 insertions(+), 15 deletions(-)
diff --git a/src/gui/kernel/qhighdpiscaling.cpp b/src/gui/kernel/qhighdpiscaling.cpp
index 22e46e0851..541d4f12af 100644
--- a/src/gui/kernel/qhighdpiscaling.cpp
+++ b/src/gui/kernel/qhighdpiscaling.cpp
@@ -224,7 +224,6 @@ bool QHighDpiScaling::m_usePixelDensity = false; // use scale factor from platfo
bool QHighDpiScaling::m_pixelDensityScalingActive = false; // pixel density scale factor > 1
bool QHighDpiScaling::m_globalScalingActive = false; // global scale factor is active
bool QHighDpiScaling::m_screenFactorSet = false; // QHighDpiScaling::setScreenFactor has been used
-QDpi QHighDpiScaling::m_logicalDpi = QDpi(-1,-1); // The scaled logical DPI of the primary screen
/*
Initializes the QHighDpiScaling global variables. Called before the
@@ -312,14 +311,6 @@ void QHighDpiScaling::updateHighDpiScaling()
}
}
m_active = m_globalScalingActive || m_screenFactorSet || m_pixelDensityScalingActive;
-
- QScreen *primaryScreen = QGuiApplication::primaryScreen();
- if (!primaryScreen)
- return;
- QPlatformScreen *platformScreen = primaryScreen->handle();
- qreal sf = screenSubfactor(platformScreen);
- QDpi primaryDpi = platformScreen->logicalDpi();
- m_logicalDpi = QDpi(primaryDpi.first / sf, primaryDpi.second / sf);
}
/*
@@ -405,9 +396,16 @@ qreal QHighDpiScaling::screenSubfactor(const QPlatformScreen *screen)
return factor;
}
-QDpi QHighDpiScaling::logicalDpi()
+QDpi QHighDpiScaling::logicalDpi(const QScreen *screen)
{
- return m_logicalDpi;
+ // (Note: m_active test is performed at call site.)
+ if (!screen)
+ return QDpi(96, 96);
+
+ qreal platformScreenfactor = screenSubfactor(screen->handle());
+ QDpi platformScreenDpi = screen->handle()->logicalDpi();
+ return QDpi(platformScreenDpi.first / platformScreenfactor,
+ platformScreenDpi.second / platformScreenfactor);
}
qreal QHighDpiScaling::factor(const QScreen *screen)
diff --git a/src/gui/kernel/qhighdpiscaling_p.h b/src/gui/kernel/qhighdpiscaling_p.h
index 83fc9452c5..ecd9ed6515 100644
--- a/src/gui/kernel/qhighdpiscaling_p.h
+++ b/src/gui/kernel/qhighdpiscaling_p.h
@@ -85,7 +85,7 @@ public:
static QPoint origin(const QPlatformScreen *platformScreen);
static QPoint mapPositionFromNative(const QPoint &pos, const QPlatformScreen *platformScreen);
static QPoint mapPositionToNative(const QPoint &pos, const QPlatformScreen *platformScreen);
- static QDpi logicalDpi();
+ static QDpi logicalDpi(const QScreen *screen);
private:
static qreal screenSubfactor(const QPlatformScreen *screen);
diff --git a/src/gui/kernel/qscreen.cpp b/src/gui/kernel/qscreen.cpp
index f208eb02be..82ee62e6b4 100644
--- a/src/gui/kernel/qscreen.cpp
+++ b/src/gui/kernel/qscreen.cpp
@@ -279,7 +279,7 @@ qreal QScreen::logicalDotsPerInchX() const
{
Q_D(const QScreen);
if (QHighDpiScaling::isActive())
- return QHighDpiScaling::logicalDpi().first;
+ return QHighDpiScaling::logicalDpi(this).first;
return d->logicalDpi.first;
}
@@ -295,7 +295,7 @@ qreal QScreen::logicalDotsPerInchY() const
{
Q_D(const QScreen);
if (QHighDpiScaling::isActive())
- return QHighDpiScaling::logicalDpi().second;
+ return QHighDpiScaling::logicalDpi(this).second;
return d->logicalDpi.second;
}
@@ -314,7 +314,7 @@ qreal QScreen::logicalDotsPerInchY() const
qreal QScreen::logicalDotsPerInch() const
{
Q_D(const QScreen);
- QDpi dpi = QHighDpiScaling::isActive() ? QHighDpiScaling::logicalDpi() : d->logicalDpi;
+ QDpi dpi = QHighDpiScaling::isActive() ? QHighDpiScaling::logicalDpi(this) : d->logicalDpi;
return (dpi.first + dpi.second) * qreal(0.5);
}
--
2.18.0.windows.1
From 3ef20bcb114c316efb74a0a704e918731847620c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Morten=20Johan=20S=C3=B8rvig?= <morten.sorvig@qt.io>
Date: Mon, 25 Apr 2016 11:31:34 +0200
Subject: [PATCH 32/36] Update Dpi and scale factor computation
Remove pixelScale() in favor of logicalBaseDpi(). Compute scale factor
based on logical DPI and logical base DPI, or optionally based on the
physical DPI.
Add policies for running the scale factor and adjusting the logical
DPI reported to the application. The policies are set via environment
variables:
QT_SCALE_FACTOR_ROUNDING_POLICY=Round|Ceil|Floor|RoundPreferFloor|PassThrough
QT_DPI_ADJUSTMENT_POLICY=AdjustDpi|DontAdjustDpi|AdjustUpOnly
QT_USE_PHYSICAL_DPI=0|1
Done-with: Friedemann Kleint <Friedemann.Kleint@qt.io>
Task-number: QTBUG-53022
Change-Id: I4846f223186df665eb0a9c827eaef0a96d1f458f
---
src/gui/kernel/qhighdpiscaling.cpp | 234 ++++++++++++++++--
src/gui/kernel/qhighdpiscaling_p.h | 29 +++
src/gui/kernel/qplatformscreen.cpp | 14 ++
src/gui/kernel/qplatformscreen.h | 1 +
.../android/qandroidplatformscreen.cpp | 8 +-
.../android/qandroidplatformscreen.h | 2 +-
src/plugins/platforms/cocoa/qcocoascreen.h | 1 +
.../platforms/windows/qwindowsscreen.cpp | 9 -
.../platforms/windows/qwindowsscreen.h | 2 +-
src/plugins/platforms/xcb/qxcbscreen.cpp | 11 -
src/plugins/platforms/xcb/qxcbscreen.h | 3 +-
tests/manual/highdpi/highdpi.pro | 1 +
12 files changed, 264 insertions(+), 51 deletions(-)
diff --git a/src/gui/kernel/qhighdpiscaling.cpp b/src/gui/kernel/qhighdpiscaling.cpp
index 541d4f12af..ae531569ce 100644
--- a/src/gui/kernel/qhighdpiscaling.cpp
+++ b/src/gui/kernel/qhighdpiscaling.cpp
@@ -44,6 +44,9 @@
#include "private/qscreen_p.h"
#include <QtCore/qdebug.h>
+#include <QtCore/qmetaobject.h>
+
+#include <algorithm>
QT_BEGIN_NAMESPACE
@@ -54,6 +57,18 @@ static const char legacyDevicePixelEnvVar[] = "QT_DEVICE_PIXEL_RATIO";
static const char scaleFactorEnvVar[] = "QT_SCALE_FACTOR";
static const char autoScreenEnvVar[] = "QT_AUTO_SCREEN_SCALE_FACTOR";
static const char screenFactorsEnvVar[] = "QT_SCREEN_SCALE_FACTORS";
+static const char scaleFactorRoundingPolicyEnvVar[] = "QT_SCALE_FACTOR_ROUNDING_POLICY";
+static const char dpiAdjustmentPolicyEnvVar[] = "QT_DPI_ADJUSTMENT_POLICY";
+static const char usePhysicalDpiEnvVar[] = "QT_USE_PHYSICAL_DPI";
+
+// 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)
+{
+ bool ok = false;
+ int value = qEnvironmentVariableIntValue(name, &ok);
+ return ok ? value > 0 : defaultValue;
+}
static inline qreal initialGlobalScaleFactor()
{
@@ -247,6 +262,191 @@ static inline bool usePixelDensity()
qgetenv(legacyDevicePixelEnvVar).compare("auto", Qt::CaseInsensitive) == 0);
}
+qreal QHighDpiScaling::rawScaleFactor(const QPlatformScreen *screen)
+{
+ // Determine if physical DPI should be used
+ static bool usePhysicalDpi = qEnvironmentVariableAsBool(usePhysicalDpiEnvVar, false);
+
+ // Calculate scale factor beased on platform screen DPI values
+ qreal factor;
+ QDpi platformBaseDpi = screen->logicalBaseDpi();
+ if (usePhysicalDpi) {
+ qreal platformPhysicalDpi = screen->screen()->physicalDotsPerInch();
+ factor = qreal(platformPhysicalDpi) / qreal(platformBaseDpi.first);
+ } else {
+ QDpi platformLogicalDpi = screen->logicalDpi();
+ factor = qreal(platformLogicalDpi.first) / qreal(platformBaseDpi.first);
+ }
+
+ return factor;
+}
+
+template <class EnumType>
+struct EnumLookup
+{
+ const char *name;
+ EnumType value;
+};
+
+template <class EnumType>
+static bool operator==(const EnumLookup<EnumType> &e1, const EnumLookup<EnumType> &e2)
+{
+ return qstricmp(e1.name, e2.name) == 0;
+}
+
+template <class EnumType>
+static QByteArray joinEnumValues(const EnumLookup<EnumType> *i1, const EnumLookup<EnumType> *i2)
+{
+ QByteArray result;
+ for (; i1 < i2; ++i1) {
+ if (!result.isEmpty())
+ result += QByteArrayLiteral(", ");
+ result += i1->name;
+ }
+ return result;
+}
+
+using ScaleFactorRoundingPolicyLookup = EnumLookup<QHighDpiScaling::HighDpiScaleFactorRoundingPolicy>;
+
+static const ScaleFactorRoundingPolicyLookup scaleFactorRoundingPolicyLookup[] =
+{
+ {"Round", QHighDpiScaling::HighDpiScaleFactorRoundingPolicy::Round},
+ {"Ceil", QHighDpiScaling::HighDpiScaleFactorRoundingPolicy::Ceil},
+ {"Floor", QHighDpiScaling::HighDpiScaleFactorRoundingPolicy::Floor},
+ {"RoundPreferFloor", QHighDpiScaling::HighDpiScaleFactorRoundingPolicy::RoundPreferFloor},
+ {"PassThrough", QHighDpiScaling::HighDpiScaleFactorRoundingPolicy::PassThrough}
+};
+
+static QHighDpiScaling::HighDpiScaleFactorRoundingPolicy
+ lookupScaleFactorRoundingPolicy(const QByteArray &v)
+{
+ auto end = std::end(scaleFactorRoundingPolicyLookup);
+ auto it = std::find(std::begin(scaleFactorRoundingPolicyLookup), end,
+ ScaleFactorRoundingPolicyLookup{v.constData(), QHighDpiScaling::HighDpiScaleFactorRoundingPolicy::NotSet});
+ return it != end ? it->value : QHighDpiScaling::HighDpiScaleFactorRoundingPolicy::NotSet;
+}
+
+using DpiAdjustmentPolicyLookup = EnumLookup<QHighDpiScaling::DpiAdjustmentPolicy>;
+
+static const DpiAdjustmentPolicyLookup dpiAdjustmentPolicyLookup[] =
+{
+ {"AdjustDpi", QHighDpiScaling::DpiAdjustmentPolicy::Enabled},
+ {"DontAdjustDpi", QHighDpiScaling::DpiAdjustmentPolicy::Disabled},
+ {"AdjustUpOnly", QHighDpiScaling::DpiAdjustmentPolicy::UpOnly}
+};
+
+static QHighDpiScaling::DpiAdjustmentPolicy
+ lookupDpiAdjustmentPolicy(const QByteArray &v)
+{
+ auto end = std::end(dpiAdjustmentPolicyLookup);
+ auto it = std::find(std::begin(dpiAdjustmentPolicyLookup), end,
+ DpiAdjustmentPolicyLookup{v.constData(), QHighDpiScaling::DpiAdjustmentPolicy::NotSet});
+ return it != end ? it->value : QHighDpiScaling::DpiAdjustmentPolicy::NotSet;
+}
+
+qreal QHighDpiScaling::roundScaleFactor(qreal rawFactor)
+{
+ // Apply scale factor rounding policy. Using mathematically correct rounding
+ // may not give the most desirable visual results, especially for
+ // critical fractions like .5. In general, rounding down results in visual
+ // 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 = HighDpiScaleFactorRoundingPolicy::NotSet;
+
+ // Determine rounding policy
+ if (scaleFactorRoundingPolicy == HighDpiScaleFactorRoundingPolicy::NotSet) {
+ // Check environment
+ if (qEnvironmentVariableIsSet(scaleFactorRoundingPolicyEnvVar)) {
+ QByteArray policyText = qgetenv(scaleFactorRoundingPolicyEnvVar);
+ auto policyEnumValue = lookupScaleFactorRoundingPolicy(policyText);
+ if (policyEnumValue != HighDpiScaleFactorRoundingPolicy::NotSet) {
+ 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());
+ }
+ } else {
+ // Set default policy if no environment variable is set.
+ scaleFactorRoundingPolicy = HighDpiScaleFactorRoundingPolicy::RoundPreferFloor;
+ }
+ }
+
+ // Apply rounding policy.
+ qreal roundedFactor = rawFactor;
+ switch (scaleFactorRoundingPolicy) {
+ case HighDpiScaleFactorRoundingPolicy::Round:
+ roundedFactor = qRound(rawFactor);
+ break;
+ case HighDpiScaleFactorRoundingPolicy::Ceil:
+ roundedFactor = qCeil(rawFactor);
+ break;
+ case HighDpiScaleFactorRoundingPolicy::Floor:
+ roundedFactor = qFloor(rawFactor);
+ break;
+ case HighDpiScaleFactorRoundingPolicy::RoundPreferFloor:
+ // Round up for .75 and higher. This favors "small UI" over "large UI".
+ roundedFactor = rawFactor - qFloor(rawFactor) < 0.75
+ ? qFloor(rawFactor) : qCeil(rawFactor);
+ break;
+ case HighDpiScaleFactorRoundingPolicy::PassThrough:
+ case HighDpiScaleFactorRoundingPolicy::NotSet:
+ break;
+ }
+
+ // Don't round down to to zero; clamp the minimum (rounded) factor to 1.
+ // This is not a common case but can happen if a display reports a very
+ // low DPI.
+ if (scaleFactorRoundingPolicy != HighDpiScaleFactorRoundingPolicy::PassThrough)
+ roundedFactor = qMax(roundedFactor, qreal(1));
+
+ return roundedFactor;
+}
+
+QDpi QHighDpiScaling::effectiveLogicalDpi(const QPlatformScreen *screen, qreal rawFactor, qreal roundedFactor)
+{
+ // Apply DPI adjustment policy, if needed. If enabled this will change
+ // the reported logical DPI to account for the difference between the
+ // rounded scale factor and the actual scale factor. The effect
+ // is that text size will be correct for the screen dpi, but may be (slightly)
+ // out of sync 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::NotSet;
+
+ // Determine adjustment policy.
+ if (dpiAdjustmentPolicy == DpiAdjustmentPolicy::NotSet) {
+ if (qEnvironmentVariableIsSet(dpiAdjustmentPolicyEnvVar)) {
+ QByteArray policyText = qgetenv(dpiAdjustmentPolicyEnvVar);
+ auto policyEnumValue = lookupDpiAdjustmentPolicy(policyText);
+ if (policyEnumValue != DpiAdjustmentPolicy::NotSet) {
+ 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::NotSet)
+ 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)
+ return baseDpi;
+ if (dpiAdjustmentPolicy == DpiAdjustmentPolicy::UpOnly && dpiAdjustmentFactor < 1)
+ return baseDpi;
+
+ return QDpi(baseDpi.first * dpiAdjustmentFactor, baseDpi.second * dpiAdjustmentFactor);
+}
+
void QHighDpiScaling::initHighDpiScaling()
{
// Determine if there is a global scale factor set.
@@ -257,8 +457,6 @@ void QHighDpiScaling::initHighDpiScaling()
m_pixelDensityScalingActive = false; //set in updateHighDpiScaling below
- // we update m_active in updateHighDpiScaling, but while we create the
- // screens, we have to assume that m_usePixelDensity implies scaling
m_active = m_globalScalingActive || m_usePixelDensity;
}
@@ -310,7 +508,7 @@ void QHighDpiScaling::updateHighDpiScaling()
++i;
}
}
- m_active = m_globalScalingActive || m_screenFactorSet || m_pixelDensityScalingActive;
+ m_active = m_globalScalingActive || m_usePixelDensity;
}
/*
@@ -371,22 +569,8 @@ qreal QHighDpiScaling::screenSubfactor(const QPlatformScreen *screen)
{
qreal factor = qreal(1.0);
if (screen) {
- if (m_usePixelDensity) {
- qreal pixelDensity = screen->pixelDensity();
-
- // Pixel density reported by the screen is sometimes not precise enough,
- // so recalculate it: divide px (physical pixels) by dp (device-independent pixels)
- // for both width and height, and then use the average if it is different from
- // the one initially reported by the screen
- QRect screenGeometry = screen->geometry();
- qreal wFactor = qreal(screenGeometry.width()) / qRound(screenGeometry.width() / pixelDensity);
- qreal hFactor = qreal(screenGeometry.height()) / qRound(screenGeometry.height() / pixelDensity);
- qreal averageDensity = (wFactor + hFactor) / 2;
- if (!qFuzzyCompare(pixelDensity, averageDensity))
- pixelDensity = averageDensity;
-
- factor *= pixelDensity;
- }
+ if (m_usePixelDensity)
+ factor *= roundScaleFactor(rawScaleFactor(screen));
if (m_screenFactorSet) {
QVariant screenFactor = screen->screen()->property(scaleFactorProperty);
if (screenFactor.isValid())
@@ -399,13 +583,15 @@ qreal QHighDpiScaling::screenSubfactor(const QPlatformScreen *screen)
QDpi QHighDpiScaling::logicalDpi(const QScreen *screen)
{
// (Note: m_active test is performed at call site.)
- if (!screen)
+ if (!screen || !screen->handle())
return QDpi(96, 96);
- qreal platformScreenfactor = screenSubfactor(screen->handle());
- QDpi platformScreenDpi = screen->handle()->logicalDpi();
- return QDpi(platformScreenDpi.first / platformScreenfactor,
- platformScreenDpi.second / platformScreenfactor);
+ if (!m_usePixelDensity)
+ return screen->handle()->logicalDpi();
+
+ const qreal scaleFactor = rawScaleFactor(screen->handle());
+ const qreal roundedScaleFactor = roundScaleFactor(scaleFactor);
+ return effectiveLogicalDpi(screen->handle(), scaleFactor, roundedScaleFactor);
}
qreal QHighDpiScaling::factor(const QScreen *screen)
diff --git a/src/gui/kernel/qhighdpiscaling_p.h b/src/gui/kernel/qhighdpiscaling_p.h
index ecd9ed6515..55bddfeb88 100644
--- a/src/gui/kernel/qhighdpiscaling_p.h
+++ b/src/gui/kernel/qhighdpiscaling_p.h
@@ -71,7 +71,33 @@ typedef QPair<qreal, qreal> QDpi;
#ifndef QT_NO_HIGHDPISCALING
class Q_GUI_EXPORT QHighDpiScaling {
+ Q_GADGET
public:
+ enum class HighDpiScaleFactorRoundingPolicy {
+ NotSet,
+ Round,
+ Ceil,
+ Floor,
+ RoundPreferFloor,
+ PassThrough
+ };
+ Q_ENUM(HighDpiScaleFactorRoundingPolicy)
+
+ enum class DpiAdjustmentPolicy {
+ NotSet,
+ Enabled,
+ Disabled,
+ UpOnly
+ };
+ Q_ENUM(DpiAdjustmentPolicy)
+
+ QHighDpiScaling() = delete;
+ ~QHighDpiScaling() = delete;
+ QHighDpiScaling(const QHighDpiScaling &) = delete;
+ QHighDpiScaling &operator=(const QHighDpiScaling &) = delete;
+ QHighDpiScaling(QHighDpiScaling &&) = delete;
+ QHighDpiScaling &operator=(QHighDpiScaling &&) = delete;
+
static void initHighDpiScaling();
static void updateHighDpiScaling();
static void setGlobalFactor(qreal factor);
@@ -88,6 +114,9 @@ public:
static QDpi logicalDpi(const QScreen *screen);
private:
+ static qreal rawScaleFactor(const QPlatformScreen *screen);
+ static qreal roundScaleFactor(qreal rawFactor);
+ static QDpi effectiveLogicalDpi(const QPlatformScreen *screen, qreal rawFactor, qreal roundedFactor);
static qreal screenSubfactor(const QPlatformScreen *screen);
static qreal m_factor;
diff --git a/src/gui/kernel/qplatformscreen.cpp b/src/gui/kernel/qplatformscreen.cpp
index b7b312e89e..07a2231228 100644
--- a/src/gui/kernel/qplatformscreen.cpp
+++ b/src/gui/kernel/qplatformscreen.cpp
@@ -194,6 +194,20 @@ QDpi QPlatformScreen::logicalDpi() const
25.4 * s.height() / ps.height());
}
+/*!
+ Reimplement to return the base logical DPI for the platform. This
+ DPI value should correspond to a standard-DPI (1x) display. The
+ default implementation returns 96.
+
+ QtGui will use this value (together with logicalDpi) to compute
+ the scale factor when high-DPI scaling is enabled:
+ factor = logicalDPI / baseDPI
+*/
+QDpi QPlatformScreen::logicalBaseDpi() const
+{
+ return QDpi(96, 96);
+}
+
/*!
Reimplement this function in subclass to return the device pixel ratio
for the screen. This is the ratio between physical pixels and the
diff --git a/src/gui/kernel/qplatformscreen.h b/src/gui/kernel/qplatformscreen.h
index e9d64c8a29..63b5d5a4a7 100644
--- a/src/gui/kernel/qplatformscreen.h
+++ b/src/gui/kernel/qplatformscreen.h
@@ -113,6 +113,7 @@ public:
virtual QSizeF physicalSize() const;
virtual QDpi logicalDpi() const;
+ virtual QDpi logicalBaseDpi() const;
virtual qreal devicePixelRatio() const;
virtual qreal pixelDensity() const;
diff --git a/src/plugins/platforms/android/qandroidplatformscreen.cpp b/src/plugins/platforms/android/qandroidplatformscreen.cpp
index 7dc8bb8080..80757c2135 100644
--- a/src/plugins/platforms/android/qandroidplatformscreen.cpp
+++ b/src/plugins/platforms/android/qandroidplatformscreen.cpp
@@ -401,15 +401,17 @@ void QAndroidPlatformScreen::doRedraw()
m_dirtyRect = QRect();
}
+static const int androidLogicalDpi = 72;
+
QDpi QAndroidPlatformScreen::logicalDpi() const
{
- qreal lDpi = QtAndroid::scaledDensity() * 72;
+ qreal lDpi = QtAndroid::scaledDensity() * androidLogicalDpi;
return QDpi(lDpi, lDpi);
}
-qreal QAndroidPlatformScreen::pixelDensity() const
+QDpi QAndroidPlatformScreen::logicalBaseDpi() const
{
- return QtAndroid::pixelDensity();
+ return QDpi(androidLogicalDpi, androidLogicalDpi);
}
Qt::ScreenOrientation QAndroidPlatformScreen::orientation() const
diff --git a/src/plugins/platforms/android/qandroidplatformscreen.h b/src/plugins/platforms/android/qandroidplatformscreen.h
index f15aeae3fd..5dc158e351 100644
--- a/src/plugins/platforms/android/qandroidplatformscreen.h
+++ b/src/plugins/platforms/android/qandroidplatformscreen.h
@@ -103,7 +103,7 @@ protected:
private:
QDpi logicalDpi() const override;
- qreal pixelDensity() const override;
+ QDpi logicalBaseDpi() const override;
Qt::ScreenOrientation orientation() const override;
Qt::ScreenOrientation nativeOrientation() const override;
void surfaceChanged(JNIEnv *env, jobject surface, int w, int h) override;
diff --git a/src/plugins/platforms/cocoa/qcocoascreen.h b/src/plugins/platforms/cocoa/qcocoascreen.h
index 9ded98df32..a73b97c771 100644
--- a/src/plugins/platforms/cocoa/qcocoascreen.h
+++ b/src/plugins/platforms/cocoa/qcocoascreen.h
@@ -64,6 +64,7 @@ public:
qreal devicePixelRatio() const override;
QSizeF physicalSize() const override { return m_physicalSize; }
QDpi logicalDpi() const override { return m_logicalDpi; }
+ QDpi logicalBaseDpi() const override { return m_logicalDpi; }
qreal refreshRate() const override { return m_refreshRate; }
QString name() const override { return m_name; }
QPlatformCursor *cursor() const override { return m_cursor; }
diff --git a/src/plugins/platforms/windows/qwindowsscreen.cpp b/src/plugins/platforms/windows/qwindowsscreen.cpp
index 8a5f0e6577..ebde684038 100644
--- a/src/plugins/platforms/windows/qwindowsscreen.cpp
+++ b/src/plugins/platforms/windows/qwindowsscreen.cpp
@@ -254,15 +254,6 @@ QWindow *QWindowsScreen::windowAt(const QPoint &screenPoint, unsigned flags)
return result;
}
-qreal QWindowsScreen::pixelDensity() const
-{
- // QTBUG-49195: Use logical DPI instead of physical DPI to calculate
- // the pixel density since it is reflects the Windows UI scaling.
- // High DPI auto scaling should be disabled when the user chooses
- // small fonts on a High DPI monitor, resulting in lower logical DPI.
- return qMax(1, qRound(logicalDpi().first / 96));
-}
-
/*!
\brief Determine siblings in a virtual desktop system.
diff --git a/src/plugins/platforms/windows/qwindowsscreen.h b/src/plugins/platforms/windows/qwindowsscreen.h
index 33c9effa2a..a7b1c64e29 100644
--- a/src/plugins/platforms/windows/qwindowsscreen.h
+++ b/src/plugins/platforms/windows/qwindowsscreen.h
@@ -87,7 +87,7 @@ public:
QImage::Format format() const override { return m_data.format; }
QSizeF physicalSize() const override { return m_data.physicalSizeMM; }
QDpi logicalDpi() const override { return m_data.dpi; }
- qreal pixelDensity() const override;
+ QDpi logicalBaseDpi() const override { return QDpi(96, 96); };
qreal devicePixelRatio() const override { return 1.0; }
qreal refreshRate() const override { return m_data.refreshRateHz; }
QString name() const override { return m_data.name; }
diff --git a/src/plugins/platforms/xcb/qxcbscreen.cpp b/src/plugins/platforms/xcb/qxcbscreen.cpp
index 57dbdc9bec..9af0794d29 100644
--- a/src/plugins/platforms/xcb/qxcbscreen.cpp
+++ b/src/plugins/platforms/xcb/qxcbscreen.cpp
@@ -671,11 +671,6 @@ QDpi QXcbScreen::logicalDpi() const
return m_virtualDesktop->dpi();
}
-qreal QXcbScreen::pixelDensity() const
-{
- return m_pixelDensity;
-}
-
QPlatformCursor *QXcbScreen::cursor() const