summaryrefslogtreecommitdiffstats
path: root/src/gui/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'src/gui/kernel')
-rw-r--r--src/gui/kernel/qevent.cpp56
-rw-r--r--src/gui/kernel/qguiapplication.cpp44
-rw-r--r--src/gui/kernel/qguiapplication.h3
-rw-r--r--src/gui/kernel/qguiapplication_p.h1
-rw-r--r--src/gui/kernel/qguivariant.cpp1
-rw-r--r--src/gui/kernel/qhighdpiscaling.cpp337
-rw-r--r--src/gui/kernel/qhighdpiscaling_p.h43
-rw-r--r--src/gui/kernel/qopenglcontext.cpp3
-rw-r--r--src/gui/kernel/qplatformintegration.cpp3
-rw-r--r--src/gui/kernel/qplatformintegration.h3
-rw-r--r--src/gui/kernel/qplatformscreen.cpp22
-rw-r--r--src/gui/kernel/qplatformscreen.h3
-rw-r--r--src/gui/kernel/qscreen.cpp13
-rw-r--r--src/gui/kernel/qsurface.cpp6
-rw-r--r--src/gui/kernel/qsurfaceformat.cpp12
-rw-r--r--src/gui/kernel/qtouchdevice.cpp32
-rw-r--r--src/gui/kernel/qwindowsysteminterface.cpp4
17 files changed, 442 insertions, 144 deletions
diff --git a/src/gui/kernel/qevent.cpp b/src/gui/kernel/qevent.cpp
index 96f61e7ae9..8e5945be41 100644
--- a/src/gui/kernel/qevent.cpp
+++ b/src/gui/kernel/qevent.cpp
@@ -535,13 +535,6 @@ Qt::MouseEventFlags QMouseEvent::flags() const
*/
/*!
- \fn QPointF QMouseEvent::posF() const
- \obsolete
-
- Use localPos() instead.
-*/
-
-/*!
\class QHoverEvent
\ingroup events
\inmodule QtGui
@@ -750,12 +743,14 @@ QHoverEvent::~QHoverEvent()
\l inverted always returns false.
*/
+#if QT_DEPRECATED_SINCE(5, 15)
/*!
\fn Qt::Orientation QWheelEvent::orientation() const
\obsolete
Use angleDelta() instead.
*/
+#endif
#if QT_CONFIG(wheelevent)
#if QT_DEPRECATED_SINCE(5, 15)
@@ -936,6 +931,7 @@ QWheelEvent::~QWheelEvent()
\endlist
*/
+#if QT_DEPRECATED_SINCE(5, 15)
/*!
\fn int QWheelEvent::delta() const
\obsolete
@@ -999,6 +995,7 @@ QWheelEvent::~QWheelEvent()
This function has been deprecated, use globalPosition() instead.
*/
+#endif
/*!
\fn Qt::ScrollPhase QWheelEvent::phase() const
@@ -1102,16 +1099,6 @@ QKeyEvent::~QKeyEvent()
}
/*!
- \fn QKeyEvent *QKeyEvent::createExtendedKeyEvent(Type type, int key, Qt::KeyboardModifiers modifiers, quint32 nativeScanCode, quint32 nativeVirtualKey, quint32 nativeModifiers, const QString& text, bool autorep, ushort count)
- \internal
-*/
-
-/*!
- \fn bool QKeyEvent::hasExtendedInfo() const
- \internal
-*/
-
-/*!
\fn quint32 QKeyEvent::nativeScanCode() const
\since 4.2
@@ -2539,7 +2526,7 @@ Qt::MouseButtons QTabletEvent::buttons() const
globalPos() can differ significantly from the current position
QCursor::pos().
- \sa globalX(), globalY(), hiResGlobalPos()
+ \sa globalX(), globalY()
*/
/*!
@@ -2584,15 +2571,6 @@ Qt::MouseButtons QTabletEvent::buttons() const
*/
/*!
- \fn const QPointF &QTabletEvent::hiResGlobalPos() const
-
- The high precision coordinates delivered from the tablet expressed.
- Sub pixeling information is in the fractional part of the QPointF.
-
- \sa globalPos(), hiResGlobalX(), hiResGlobalY()
-*/
-
-/*!
\fn qreal &QTabletEvent::hiResGlobalX() const
The high precision x position of the tablet device.
@@ -2674,10 +2652,10 @@ Qt::MouseButtons QTabletEvent::buttons() const
\sa Qt::NativeGestureType, QGestureEvent
*/
+#if QT_DEPRECATED_SINCE(5, 10)
/*!
\deprecated The QTouchDevice parameter is now required
*/
-#if QT_DEPRECATED_SINCE(5, 10)
QNativeGestureEvent::QNativeGestureEvent(Qt::NativeGestureType type, const QPointF &localPos, const QPointF &windowPos,
const QPointF &screenPos, qreal realValue, ulong sequenceId, quint64 intValue)
: QInputEvent(QEvent::NativeGesture), mGestureType(type),
@@ -4279,18 +4257,6 @@ QWindowStateChangeEvent::~QWindowStateChangeEvent()
QGraphicsItem::acceptTouchEvents()
*/
-/*! \enum QTouchEvent::DeviceType
- \obsolete
-
- This enum represents the type of device that generated a QTouchEvent.
-
- This enum has been deprecated. Use QTouchDevice::DeviceType instead.
- \omitvalue TouchPad
- \omitvalue TouchScreen
-
- \sa QTouchDevice::DeviceType, QTouchDevice::type(), QTouchEvent::device()
-*/
-
/*!
Constructs a QTouchEvent with the given \a eventType, \a device, and
\a touchPoints. The \a touchPointStates and \a modifiers
@@ -4330,16 +4296,6 @@ QTouchEvent::~QTouchEvent()
This is typically a QWidget or a QQuickItem. May be 0 when no specific target is available.
*/
-/*! \fn QTouchEvent::DeviceType QTouchEvent::deviceType() const
- \obsolete
-
- Returns the touch device Type, which is of type \l {QTouchEvent::DeviceType} {DeviceType}.
-
- This function has been deprecated. Use QTouchDevice::type() instead.
-
- \sa QTouchDevice::type(), QTouchEvent::device()
-*/
-
/*! \fn QTouchEvent::TouchPoint::TouchPoint(TouchPoint &&other)
Move-constructs a TouchPoint instance, making it point to the same
diff --git a/src/gui/kernel/qguiapplication.cpp b/src/gui/kernel/qguiapplication.cpp
index a7fe2ec50a..432618968f 100644
--- a/src/gui/kernel/qguiapplication.cpp
+++ b/src/gui/kernel/qguiapplication.cpp
@@ -146,6 +146,8 @@ QString QGuiApplicationPrivate::styleOverride;
Qt::ApplicationState QGuiApplicationPrivate::applicationState = Qt::ApplicationInactive;
+Qt::HighDpiScaleFactorRoundingPolicy QGuiApplicationPrivate::highDpiScaleFactorRoundingPolicy =
+ Qt::HighDpiScaleFactorRoundingPolicy::RoundPreferFloor;
bool QGuiApplicationPrivate::highDpiScalingUpdated = false;
QPointer<QWindow> QGuiApplicationPrivate::currentDragWindow;
@@ -687,6 +689,8 @@ QGuiApplication::~QGuiApplication()
QGuiApplicationPrivate::lastCursorPosition = {qInf(), qInf()};
QGuiApplicationPrivate::currentMousePressWindow = QGuiApplicationPrivate::currentMouseWindow = nullptr;
QGuiApplicationPrivate::applicationState = Qt::ApplicationInactive;
+ QGuiApplicationPrivate::highDpiScaleFactorRoundingPolicy =
+ Qt::HighDpiScaleFactorRoundingPolicy::RoundPreferFloor;
QGuiApplicationPrivate::highDpiScalingUpdated = false;
QGuiApplicationPrivate::currentDragWindow = nullptr;
QGuiApplicationPrivate::tabletDevicePoints.clear();
@@ -3495,6 +3499,46 @@ Qt::ApplicationState QGuiApplication::applicationState()
}
/*!
+ \since 5.14
+
+ Sets the high-DPI scale factor rounding policy for the application. The
+ policy decides how non-integer scale factors (such as Windows 150%) are
+ handled, for applications that have AA_EnableHighDpiScaling enabled.
+
+ The two principal options are whether fractional scale factors should
+ be rounded to an integer or not. Keeping the scale factor as-is will
+ make the user interface size match the OS setting exactly, but may cause
+ painting errors, for example with the Windows style.
+
+ If rounding is wanted, then which type of rounding should be decided
+ next. Mathematically correct rounding is supported but may not give
+ the best visual results: Consider if you want to render 1.5x as 1x
+ ("small UI") or as 2x ("large UI"). See the Qt::HighDpiScaleFactorRoundingPolicy
+ enum for a complete list of all options.
+
+ This function must be called before creating the application object,
+ and can be overridden by setting the QT_SCALE_FACTOR_ROUNDING_POLICY
+ environment variable. The QGuiApplication::highDpiScaleFactorRoundingPolicy()
+ accessor will reflect the environment, if set.
+
+ The default value is Qt::HighDpiScaleFactorRoundingPolicy::RoundPreferFloor.
+*/
+void QGuiApplication::setHighDpiScaleFactorRoundingPolicy(Qt::HighDpiScaleFactorRoundingPolicy policy)
+{
+ QGuiApplicationPrivate::highDpiScaleFactorRoundingPolicy = policy;
+}
+
+/*!
+ \since 5.14
+
+ Returns the high-DPI scale factor rounding policy.
+*/
+Qt::HighDpiScaleFactorRoundingPolicy QGuiApplication::highDpiScaleFactorRoundingPolicy()
+{
+ return QGuiApplicationPrivate::highDpiScaleFactorRoundingPolicy;
+}
+
+/*!
\since 5.2
\fn void QGuiApplication::applicationStateChanged(Qt::ApplicationState state)
diff --git a/src/gui/kernel/qguiapplication.h b/src/gui/kernel/qguiapplication.h
index 5ea72fa0f6..fc74c5299a 100644
--- a/src/gui/kernel/qguiapplication.h
+++ b/src/gui/kernel/qguiapplication.h
@@ -156,6 +156,9 @@ public:
static Qt::ApplicationState applicationState();
+ static void setHighDpiScaleFactorRoundingPolicy(Qt::HighDpiScaleFactorRoundingPolicy policy);
+ static Qt::HighDpiScaleFactorRoundingPolicy highDpiScaleFactorRoundingPolicy();
+
static int exec();
bool notify(QObject *, QEvent *) override;
diff --git a/src/gui/kernel/qguiapplication_p.h b/src/gui/kernel/qguiapplication_p.h
index afca7579ea..e28607bad6 100644
--- a/src/gui/kernel/qguiapplication_p.h
+++ b/src/gui/kernel/qguiapplication_p.h
@@ -223,6 +223,7 @@ public:
static QWindow *currentMouseWindow;
static QWindow *currentMousePressWindow;
static Qt::ApplicationState applicationState;
+ static Qt::HighDpiScaleFactorRoundingPolicy highDpiScaleFactorRoundingPolicy;
static bool highDpiScalingUpdated;
static QPointer<QWindow> currentDragWindow;
diff --git a/src/gui/kernel/qguivariant.cpp b/src/gui/kernel/qguivariant.cpp
index 090217187e..edca8d9423 100644
--- a/src/gui/kernel/qguivariant.cpp
+++ b/src/gui/kernel/qguivariant.cpp
@@ -68,7 +68,6 @@
#include "qdebug.h"
#include "qmap.h"
#include "qdatetime.h"
-#include "qeasingcurve.h"
#include "qlist.h"
#include "qstring.h"
#include "qstringlist.h"
diff --git a/src/gui/kernel/qhighdpiscaling.cpp b/src/gui/kernel/qhighdpiscaling.cpp
index 0fea416404..c031885d5d 100644
--- a/src/gui/kernel/qhighdpiscaling.cpp
+++ b/src/gui/kernel/qhighdpiscaling.cpp
@@ -46,6 +46,9 @@
#include <private/qguiapplication_p.h>
#include <QtCore/qdebug.h>
+#include <QtCore/qmetaobject.h>
+
+#include <algorithm>
QT_BEGIN_NAMESPACE
@@ -53,9 +56,29 @@ Q_LOGGING_CATEGORY(lcScaling, "qt.scaling");
#ifndef QT_NO_HIGHDPISCALING
static const char legacyDevicePixelEnvVar[] = "QT_DEVICE_PIXEL_RATIO";
+static const char legacyAutoScreenEnvVar[] = "QT_AUTO_SCREEN_SCALE_FACTOR";
+
+static const char enableHighDpiScalingEnvVar[] = "QT_ENABLE_HIGHDPI_SCALING";
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";
+
+// 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<QString, qreal> 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)
+{
+ bool ok = false;
+ int value = qEnvironmentVariableIntValue(name, &ok);
+ return ok ? value > 0 : defaultValue;
+}
static inline qreal initialGlobalScaleFactor()
{
@@ -69,17 +92,24 @@ static inline qreal initialGlobalScaleFactor()
result = f;
}
} else {
+ // Check for deprecated environment variables.
if (qEnvironmentVariableIsSet(legacyDevicePixelEnvVar)) {
qWarning("Warning: %s is deprecated. Instead use:\n"
" %s to enable platform plugin controlled per-screen factors.\n"
- " %s to set per-screen factors.\n"
+ " %s to set per-screen DPI.\n"
" %s to set the application global scale factor.",
- legacyDevicePixelEnvVar, autoScreenEnvVar, screenFactorsEnvVar, scaleFactorEnvVar);
+ legacyDevicePixelEnvVar, legacyAutoScreenEnvVar, screenFactorsEnvVar, scaleFactorEnvVar);
int dpr = qEnvironmentVariableIntValue(legacyDevicePixelEnvVar);
if (dpr > 0)
result = dpr;
}
+
+ if (qEnvironmentVariableIsSet(legacyAutoScreenEnvVar)) {
+ qWarning("Warning: %s is deprecated. Instead use:\n"
+ " %s to enable platform plugin controlled per-screen factors.",
+ legacyAutoScreenEnvVar, enableHighDpiScalingEnvVar);
+ }
}
return result;
}
@@ -226,7 +256,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
@@ -238,16 +267,214 @@ static inline bool usePixelDensity()
// Determine if we should set a scale factor based on the pixel density
// reported by the platform plugin. There are several enablers and several
// disablers. A single disable may veto all other enablers.
+
+ // First, check of there is an explicit disable.
if (QCoreApplication::testAttribute(Qt::AA_DisableHighDpiScaling))
return false;
bool screenEnvValueOk;
- const int screenEnvValue = qEnvironmentVariableIntValue(autoScreenEnvVar, &screenEnvValueOk);
+ const int screenEnvValue = qEnvironmentVariableIntValue(legacyAutoScreenEnvVar, &screenEnvValueOk);
if (screenEnvValueOk && screenEnvValue < 1)
return false;
+ bool enableEnvValueOk;
+ const int enableEnvValue = qEnvironmentVariableIntValue(enableHighDpiScalingEnvVar, &enableEnvValueOk);
+ if (enableEnvValueOk && enableEnvValue < 1)
+ return false;
+
+ // Then return if there was an enable.
return QCoreApplication::testAttribute(Qt::AA_EnableHighDpiScaling)
|| (screenEnvValueOk && screenEnvValue > 0)
- || (qEnvironmentVariableIsSet(legacyDevicePixelEnvVar) &&
- qgetenv(legacyDevicePixelEnvVar).compare("auto", Qt::CaseInsensitive) == 0);
+ || (enableEnvValueOk && enableEnvValue > 0)
+ || (qEnvironmentVariableIsSet(legacyDevicePixelEnvVar) && qgetenv(legacyDevicePixelEnvVar).toLower() == "auto");
+}
+
+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) {
+ qreal platformPhysicalDpi = screen->screen()->physicalDotsPerInch();
+ factor = qreal(platformPhysicalDpi) / qreal(platformBaseDpi.first);
+ } else {
+ const QDpi platformLogicalDpi = QPlatformScreen::overrideDpi(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<Qt::HighDpiScaleFactorRoundingPolicy>;
+
+static const ScaleFactorRoundingPolicyLookup scaleFactorRoundingPolicyLookup[] =
+{
+ {"Round", Qt::HighDpiScaleFactorRoundingPolicy::Round},
+ {"Ceil", Qt::HighDpiScaleFactorRoundingPolicy::Ceil},
+ {"Floor", Qt::HighDpiScaleFactorRoundingPolicy::Floor},
+ {"RoundPreferFloor", Qt::HighDpiScaleFactorRoundingPolicy::RoundPreferFloor},
+ {"PassThrough", Qt::HighDpiScaleFactorRoundingPolicy::PassThrough}
+};
+
+static Qt::HighDpiScaleFactorRoundingPolicy
+ lookupScaleFactorRoundingPolicy(const QByteArray &v)
+{
+ auto end = std::end(scaleFactorRoundingPolicyLookup);
+ auto it = std::find(std::begin(scaleFactorRoundingPolicyLookup), end,
+ ScaleFactorRoundingPolicyLookup{v.constData(), Qt::HighDpiScaleFactorRoundingPolicy::Unset});
+ return it != end ? it->value : Qt::HighDpiScaleFactorRoundingPolicy::Unset;
+}
+
+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::Unset});
+ return it != end ? it->value : QHighDpiScaling::DpiAdjustmentPolicy::Unset;
+}
+
+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 = 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);
+ }
+ }
+
+ // Apply rounding policy.
+ qreal roundedFactor = rawFactor;
+ switch (scaleFactorRoundingPolicy) {
+ case Qt::HighDpiScaleFactorRoundingPolicy::Round:
+ roundedFactor = qRound(rawFactor);
+ break;
+ case Qt::HighDpiScaleFactorRoundingPolicy::Ceil:
+ roundedFactor = qCeil(rawFactor);
+ break;
+ case Qt::HighDpiScaleFactorRoundingPolicy::Floor:
+ roundedFactor = qFloor(rawFactor);
+ break;
+ case Qt::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 Qt::HighDpiScaleFactorRoundingPolicy::PassThrough:
+ case Qt::HighDpiScaleFactorRoundingPolicy::Unset:
+ 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 != Qt::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::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)
+ return baseDpi;
+ if (dpiAdjustmentPolicy == DpiAdjustmentPolicy::UpOnly && dpiAdjustmentFactor < 1)
+ return baseDpi;
+
+ return QDpi(baseDpi.first * dpiAdjustmentFactor, baseDpi.second * dpiAdjustmentFactor);
}
void QHighDpiScaling::initHighDpiScaling()
@@ -260,8 +487,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;
}
@@ -283,20 +508,19 @@ void QHighDpiScaling::updateHighDpiScaling()
int i = 0;
const auto specs = qgetenv(screenFactorsEnvVar).split(';');
for (const QByteArray &spec : specs) {
- QScreen *screen = 0;
int equalsPos = spec.lastIndexOf('=');
- double factor = 0;
+ qreal factor = 0;
if (equalsPos > 0) {
// support "name=factor"
QByteArray name = spec.mid(0, equalsPos);
QByteArray f = spec.mid(equalsPos + 1);
bool ok;
factor = f.toDouble(&ok);
- if (ok) {
+ if (ok && factor > 0 ) {
const auto screens = QGuiApplication::screens();
for (QScreen *s : screens) {
if (s->name() == QString::fromLocal8Bit(name)) {
- screen = s;
+ setScreenFactor(s, factor);
break;
}
}
@@ -305,23 +529,15 @@ void QHighDpiScaling::updateHighDpiScaling()
// listing screens in order
bool ok;
factor = spec.toDouble(&ok);
- if (ok && i < QGuiApplication::screens().count())
- screen = QGuiApplication::screens().at(i);
+ if (ok && factor > 0 && i < QGuiApplication::screens().count()) {
+ QScreen *screen = QGuiApplication::screens().at(i);
+ setScreenFactor(screen, factor);
+ }
}
- if (screen)
- setScreenFactor(screen, factor);
++i;
}
}
- 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);
+ m_active = m_globalScalingActive || m_usePixelDensity;
}
/*
@@ -353,7 +569,14 @@ void QHighDpiScaling::setScreenFactor(QScreen *screen, qreal factor)
m_screenFactorSet = true;
m_active = true;
}
- screen->setProperty(scaleFactorProperty, QVariant(factor));
+
+ // Prefer associating the factor with screen name over the object
+ // since the screen object may be deleted on screen disconnects.
+ const QString name = screen->name();
+ if (name.isEmpty())
+ screen->setProperty(scaleFactorProperty, QVariant(factor));
+ else
+ qNamedScreenScaleFactors()->insert(name, factor);
// hack to force re-evaluation of screen geometry
if (screen->handle())
@@ -421,41 +644,55 @@ QPoint QHighDpiScaling::mapPositionFromGlobal(const QPoint &pos, const QPoint &w
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_screenFactorSet) {
- QVariant screenFactor = screen->screen()->property(scaleFactorProperty);
- if (screenFactor.isValid())
- factor *= screenFactor.toReal();
+ if (!screen)
+ return factor;
+
+ // Unlike the other code where factors are combined by multiplication,
+ // factors from QT_SCREEN_SCALE_FACTORS takes precedence over the factor
+ // computed from platform plugin DPI. The rationale is that the user is
+ // setting the factor to override erroneous DPI values.
+ bool screenPropertyUsed = false;
+ if (m_screenFactorSet) {
+ // Check if there is a factor set on the screen object or associated
+ // with the screen name. These are mutually exclusive, so checking
+ // order is not significant.
+ QVariant byIndex = screen->screen()->property(scaleFactorProperty);
+ auto byNameIt = qNamedScreenScaleFactors()->constFind(screen->name());
+ if (byIndex.isValid()) {
+ screenPropertyUsed = true;
+ factor = byIndex.toReal();
+ } else if (byNameIt != qNamedScreenScaleFactors()->cend()) {
+ screenPropertyUsed = true;
+ factor = *byNameIt;
}
}
+
+ if (!screenPropertyUsed && m_usePixelDensity)
+ factor = roundScaleFactor(rawScaleFactor(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 || !screen->handle())
+ return QDpi(96, 96);
+
+ if (!m_usePixelDensity)
+ return QPlatformScreen::overrideDpi(screen->handle()->logicalDpi());
+
+ const qreal scaleFactor = rawScaleFactor(screen->handle());
+ const qreal roundedScaleFactor = roundScaleFactor(scaleFactor);
+ return effectiveLogicalDpi(screen->handle(), scaleFactor, roundedScaleFactor);
}
QHighDpiScaling::ScaleAndOrigin QHighDpiScaling::scaleAndOrigin(const QPlatformScreen *platformScreen, QPoint *nativePosition)
{
if (!m_active)
return { qreal(1), QPoint() };
+ if (!platformScreen)
+ return { m_factor, QPoint() }; // the global factor
const QPlatformScreen *actualScreen = nativePosition ?
platformScreen->screenForPosition(*nativePosition) : platformScreen;
return { m_factor * screenSubfactor(actualScreen), actualScreen->geometry().topLeft() };
diff --git a/src/gui/kernel/qhighdpiscaling_p.h b/src/gui/kernel/qhighdpiscaling_p.h
index 50221926c6..f58944a7d2 100644
--- a/src/gui/kernel/qhighdpiscaling_p.h
+++ b/src/gui/kernel/qhighdpiscaling_p.h
@@ -59,6 +59,7 @@
#include <QtCore/qloggingcategory.h>
#include <QtGui/qregion.h>
#include <QtGui/qscreen.h>
+#include <QtGui/qvector2d.h>
#include <QtGui/qwindow.h>
QT_BEGIN_NAMESPACE
@@ -71,11 +72,27 @@ typedef QPair<qreal, qreal> QDpi;
#ifndef QT_NO_HIGHDPISCALING
class Q_GUI_EXPORT QHighDpiScaling {
+ Q_GADGET
public:
+ enum class DpiAdjustmentPolicy {
+ Unset,
+ 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);
- static void setScreenFactor(QScreen *window, qreal factor);
+ static void setScreenFactor(QScreen *screen, qreal factor);
static bool isActive() { return m_active; }
@@ -97,9 +114,12 @@ public:
static QPoint mapPositionToNative(const QPoint &pos, const QPlatformScreen *platformScreen);
static QPoint mapPositionToGlobal(const QPoint &pos, const QPoint &windowGlobalPosition, const QWindow *window);
static QPoint mapPositionFromGlobal(const QPoint &pos, const QPoint &windowGlobalPosition, const QWindow *window);
- static QDpi logicalDpi();
+ 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;
@@ -117,13 +137,26 @@ private:
namespace QHighDpi {
-template <typename T>
-inline T scale(const T &value, qreal scaleFactor, QPoint origin = QPoint(0, 0))
+inline qreal scale(qreal value, qreal scaleFactor, QPointF /* origin */ = QPointF(0, 0))
+{
+ return value * scaleFactor;
+}
+
+inline QSize scale(const QSize &value, qreal scaleFactor, QPointF /* origin */ = QPointF(0, 0))
+{
+ return value * scaleFactor;
+}
+
+inline QSizeF scale(const QSizeF &value, qreal scaleFactor, QPointF /* origin */ = QPointF(0, 0))
{
- Q_UNUSED(origin)
return value * scaleFactor;
}
+inline QVector2D scale(const QVector2D &value, qreal scaleFactor, QPointF /* origin */ = QPointF(0, 0))
+{
+ return value * float(scaleFactor);
+}
+
inline QPointF scale(const QPointF &pos, qreal scaleFactor, QPointF origin = QPointF(0, 0))
{
return (pos - origin) * scaleFactor + origin;
diff --git a/src/gui/kernel/qopenglcontext.cpp b/src/gui/kernel/qopenglcontext.cpp
index 10adee438b..6f51fe3095 100644
--- a/src/gui/kernel/qopenglcontext.cpp
+++ b/src/gui/kernel/qopenglcontext.cpp
@@ -976,11 +976,8 @@ bool QOpenGLContext::makeCurrent(QSurface *surface)
if (!surface->surfaceHandle())
return false;
if (!surface->supportsOpenGL()) {
-#ifndef Q_OS_WASM // ### work around the WASM platform plugin using QOpenGLContext with raster surfaces.
- // see QTBUG-70076
qWarning() << "QOpenGLContext::makeCurrent() called with non-opengl surface" << surface;
return false;
-#endif
}
if (!d->platformGLContext->makeCurrent(surface->surfaceHandle()))
diff --git a/src/gui/kernel/qplatformintegration.cpp b/src/gui/kernel/qplatformintegration.cpp
index 490cfc6178..b3d3db0751 100644
--- a/src/gui/kernel/qplatformintegration.cpp
+++ b/src/gui/kernel/qplatformintegration.cpp
@@ -244,6 +244,9 @@ QPlatformServices *QPlatformIntegration::services() const
\value TopStackedNativeChildWindows The platform supports native child windows via
QWindowContainer without having to punch a transparent hole in the
backingstore. (since 5.10)
+
+ \value OpenGLOnRasterSurface The platform supports making a QOpenGLContext current
+ in combination with a QWindow of type RasterSurface.
*/
/*!
diff --git a/src/gui/kernel/qplatformintegration.h b/src/gui/kernel/qplatformintegration.h
index b764bd2617..d9f349555a 100644
--- a/src/gui/kernel/qplatformintegration.h
+++ b/src/gui/kernel/qplatformintegration.h
@@ -105,7 +105,8 @@ public:
AllGLFunctionsQueryable,
ApplicationIcon,
SwitchableWidgetComposition,
- TopStackedNativeChildWindows
+ TopStackedNativeChildWindows,
+ OpenGLOnRasterSurface
};
virtual ~QPlatformIntegration() { }
diff --git a/src/gui/kernel/qplatformscreen.cpp b/src/gui/kernel/qplatformscreen.cpp
index 9c5876550a..f3213bf5ea 100644
--- a/src/gui/kernel/qplatformscreen.cpp
+++ b/src/gui/kernel/qplatformscreen.cpp
@@ -193,6 +193,28 @@ QDpi QPlatformScreen::logicalDpi() const
25.4 * s.height() / ps.height());
}
+// Helper function for accessing the platform screen logical dpi
+// which accounts for QT_FONT_DPI.
+QPair<qreal, qreal> QPlatformScreen::overrideDpi(const QPair<qreal, qreal> &in)
+{
+ static const int overrideDpi = qEnvironmentVariableIntValue("QT_FONT_DPI");
+ return overrideDpi > 0 ? QDpi(overrideDpi, overrideDpi) : in;
+}
+
+/*!
+ 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 b9ecc80320..d7378aed51 100644
--- a/src/gui/kernel/qplatformscreen.h
+++ b/src/gui/kernel/qplatformscreen.h
@@ -115,6 +115,7 @@ public:
virtual QSizeF physicalSize() const;
virtual QDpi logicalDpi() const;
+ virtual QDpi logicalBaseDpi() const;
virtual qreal devicePixelRatio() const;
virtual qreal pixelDensity() const;
@@ -160,6 +161,8 @@ public:
// The platform screen's geometry in device independent coordinates
QRect deviceIndependentGeometry() const;
+ static QDpi overrideDpi(const QDpi &in);
+
protected:
void resizeMaximizedWindows();
diff --git a/src/gui/kernel/qscreen.cpp b/src/gui/kernel/qscreen.cpp
index c79f597414..7adf3db1b8 100644
--- a/src/gui/kernel/qscreen.cpp
+++ b/src/gui/kernel/qscreen.cpp
@@ -84,8 +84,11 @@ void QScreenPrivate::setPlatformScreen(QPlatformScreen *screen)
platformScreen->d_func()->screen = q;
orientation = platformScreen->orientation();
geometry = platformScreen->deviceIndependentGeometry();
- availableGeometry = QHighDpi::fromNative(platformScreen->availableGeometry(), QHighDpiScaling::factor(platformScreen), geometry.topLeft());
- logicalDpi = platformScreen->logicalDpi();
+ availableGeometry = QHighDpi::fromNative(platformScreen->availableGeometry(),
+ QHighDpiScaling::factor(platformScreen), geometry.topLeft());
+
+ logicalDpi = QPlatformScreen::overrideDpi(platformScreen->logicalDpi());
+
refreshRate = platformScreen->refreshRate();
// safeguard ourselves against buggy platform behavior...
if (refreshRate < 1.0)
@@ -285,7 +288,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;
}
@@ -301,7 +304,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;
}
@@ -320,7 +323,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);
}
diff --git a/src/gui/kernel/qsurface.cpp b/src/gui/kernel/qsurface.cpp
index 415e64b39c..709f28d431 100644
--- a/src/gui/kernel/qsurface.cpp
+++ b/src/gui/kernel/qsurface.cpp
@@ -39,6 +39,8 @@
#include "qsurface.h"
#include "qopenglcontext.h"
+#include <qpa/qplatformintegration.h>
+#include <QtGui/private/qguiapplication_p.h>
QT_BEGIN_NAMESPACE
@@ -103,6 +105,10 @@ QT_BEGIN_NAMESPACE
bool QSurface::supportsOpenGL() const
{
SurfaceType type = surfaceType();
+ if (type == RasterSurface) {
+ QPlatformIntegration *integ = QGuiApplicationPrivate::instance()->platformIntegration();
+ return integ->hasCapability(QPlatformIntegration::OpenGLOnRasterSurface);
+ }
return type == OpenGLSurface || type == RasterGLSurface;
}
diff --git a/src/gui/kernel/qsurfaceformat.cpp b/src/gui/kernel/qsurfaceformat.cpp
index 2e2738ec81..238886220b 100644
--- a/src/gui/kernel/qsurfaceformat.cpp
+++ b/src/gui/kernel/qsurfaceformat.cpp
@@ -554,10 +554,6 @@ int QSurfaceFormat::alphaBufferSize() const
/*!
Set the desired \a size in bits of the red channel of the color buffer.
-
- \note On Mac OSX, be sure to set the buffer size of all color channels,
- otherwise this setting will have no effect. If one of the buffer sizes is not set,
- the current bit-depth of the screen is used.
*/
void QSurfaceFormat::setRedBufferSize(int size)
{
@@ -569,10 +565,6 @@ void QSurfaceFormat::setRedBufferSize(int size)
/*!
Set the desired \a size in bits of the green channel of the color buffer.
-
- \note On Mac OSX, be sure to set the buffer size of all color channels,
- otherwise this setting will have no effect. If one of the buffer sizes is not set,
- the current bit-depth of the screen is used.
*/
void QSurfaceFormat::setGreenBufferSize(int size)
{
@@ -584,10 +576,6 @@ void QSurfaceFormat::setGreenBufferSize(int size)
/*!
Set the desired \a size in bits of the blue channel of the color buffer.
-
- \note On Mac OSX, be sure to set the buffer size of all color channels,
- otherwise this setting will have no effect. If one of the buffer sizes is not set,
- the current bit-depth of the screen is used.
*/
void QSurfaceFormat::setBlueBufferSize(int size)
{
diff --git a/src/gui/kernel/qtouchdevice.cpp b/src/gui/kernel/qtouchdevice.cpp
index 511e92566e..ea187f54aa 100644
--- a/src/gui/kernel/qtouchdevice.cpp
+++ b/src/gui/kernel/qtouchdevice.cpp
@@ -44,6 +44,7 @@
#include <QCoreApplication>
#include <private/qdebug_p.h>
+#include <private/qlocking_p.h>
QT_BEGIN_NAMESPACE
@@ -201,15 +202,20 @@ void QTouchDevice::setName(const QString &name)
d->name = name;
}
-typedef QList<const QTouchDevice *> TouchDevices;
-Q_GLOBAL_STATIC(TouchDevices, deviceList)
static QBasicMutex devicesMutex;
-static void cleanupDevicesList()
+struct TouchDevices {
+ TouchDevices();
+ QList<const QTouchDevice *> list;
+};
+Q_GLOBAL_STATIC(TouchDevices, deviceList)
+
+TouchDevices::TouchDevices()
{
- QMutexLocker lock(&devicesMutex);
- qDeleteAll(*deviceList());
- deviceList()->clear();
+ qAddPostRoutine([]{
+ const auto locker = qt_scoped_lock(devicesMutex);
+ qDeleteAll(qExchange(deviceList->list, {}));
+ });
}
/*!
@@ -223,7 +229,7 @@ static void cleanupDevicesList()
QList<const QTouchDevice *> QTouchDevice::devices()
{
QMutexLocker lock(&devicesMutex);
- return *deviceList();
+ return deviceList->list;
}
/*!
@@ -232,13 +238,13 @@ QList<const QTouchDevice *> QTouchDevice::devices()
bool QTouchDevicePrivate::isRegistered(const QTouchDevice *dev)
{
QMutexLocker locker(&devicesMutex);
- return deviceList()->contains(dev);
+ return deviceList->list.contains(dev);
}
const QTouchDevice *QTouchDevicePrivate::deviceById(quint8 id)
{
QMutexLocker locker(&devicesMutex);
- for (const QTouchDevice *dev : *deviceList())
+ for (const QTouchDevice *dev : qAsConst(deviceList->list))
if (QTouchDevicePrivate::get(const_cast<QTouchDevice *>(dev))->id == id)
return dev;
return nullptr;
@@ -250,9 +256,7 @@ const QTouchDevice *QTouchDevicePrivate::deviceById(quint8 id)
void QTouchDevicePrivate::registerDevice(const QTouchDevice *dev)
{
QMutexLocker lock(&devicesMutex);
- if (deviceList()->isEmpty())
- qAddPostRoutine(cleanupDevicesList);
- deviceList()->append(dev);
+ deviceList->list.append(dev);
}
/*!
@@ -261,9 +265,7 @@ void QTouchDevicePrivate::registerDevice(const QTouchDevice *dev)
void QTouchDevicePrivate::unregisterDevice(const QTouchDevice *dev)
{
QMutexLocker lock(&devicesMutex);
- bool wasRemoved = deviceList()->removeOne(dev);
- if (wasRemoved && deviceList()->isEmpty())
- qRemovePostRoutine(cleanupDevicesList);
+ deviceList->list.removeOne(dev);
}
#ifndef QT_NO_DEBUG_STREAM
diff --git a/src/gui/kernel/qwindowsysteminterface.cpp b/src/gui/kernel/qwindowsysteminterface.cpp
index 4b8cb3646a..40a298226a 100644
--- a/src/gui/kernel/qwindowsysteminterface.cpp
+++ b/src/gui/kernel/qwindowsysteminterface.cpp
@@ -857,8 +857,8 @@ void QWindowSystemInterface::handleScreenGeometryChange(QScreen *screen, const Q
void QWindowSystemInterface::handleScreenLogicalDotsPerInchChange(QScreen *screen, qreal dpiX, qreal dpiY)
{
- QWindowSystemInterfacePrivate::ScreenLogicalDotsPerInchEvent *e =
- new QWindowSystemInterfacePrivate::ScreenLogicalDotsPerInchEvent(screen, dpiX, dpiY); // ### tja
+ const QDpi effectiveDpi = QPlatformScreen::overrideDpi(QDpi{dpiX, dpiY});
+ auto e = new QWindowSystemInterfacePrivate::ScreenLogicalDotsPerInchEvent(screen, effectiveDpi.first, effectiveDpi.second);
QWindowSystemInterfacePrivate::handleWindowSystemEvent(e);
}