summaryrefslogtreecommitdiffstats
path: root/src/gui
diff options
context:
space:
mode:
authorMorten Johan Sørvig <morten.sorvig@qt.io>2017-10-07 01:35:29 +0200
committerMorten Johan Sørvig <morten.sorvig@qt.io>2019-08-23 03:41:23 +0200
commitf1e40dd6d6968c59885231f61f94787abd4cf783 (patch)
treec5f4b93f25a2a542f9f889a3c8b9eb395f984728 /src/gui
parent1de8b01d2b6db8a4fe2eddd0c595d9e680964db5 (diff)
Add high-DPI scale factor rounding policy C++ API
This API enables tuning of how Qt rounds fractional scale factors, and corresponds to the QT_SCALE_FACTOR_ROUNDING_POLICY environment variable New API: Qt::HighDPiScaleFactorRoundingPolicy QGuiApplication::setHighDpiScaleFactorRoundingPolicy() QGuiApplication::highDpiScaleFactorRoundingPolicy() Done-with: Friedemann Kleint <Friedemann.Kleint@qt.io> Task-number: QTBUG-53022 Change-Id: Ic360f26a173caa757e4ebde35ce08a6b74290b7d Reviewed-by: Friedemann Kleint <Friedemann.Kleint@qt.io>
Diffstat (limited to 'src/gui')
-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/qhighdpiscaling.cpp47
-rw-r--r--src/gui/kernel/qhighdpiscaling_p.h10
5 files changed, 74 insertions, 31 deletions
diff --git a/src/gui/kernel/qguiapplication.cpp b/src/gui/kernel/qguiapplication.cpp
index 426f2aeece..ddd6726299 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();
@@ -3491,6 +3495,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/qhighdpiscaling.cpp b/src/gui/kernel/qhighdpiscaling.cpp
index 4a9c9a9934..c031885d5d 100644
--- a/src/gui/kernel/qhighdpiscaling.cpp
+++ b/src/gui/kernel/qhighdpiscaling.cpp
@@ -331,24 +331,24 @@ static QByteArray joinEnumValues(const EnumLookup<EnumType> *i1, const EnumLooku
return result;
}
-using ScaleFactorRoundingPolicyLookup = EnumLookup<QHighDpiScaling::HighDpiScaleFactorRoundingPolicy>;
+using ScaleFactorRoundingPolicyLookup = EnumLookup<Qt::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}
+ {"Round", Qt::HighDpiScaleFactorRoundingPolicy::Round},
+ {"Ceil", Qt::HighDpiScaleFactorRoundingPolicy::Ceil},
+ {"Floor", Qt::HighDpiScaleFactorRoundingPolicy::Floor},
+ {"RoundPreferFloor", Qt::HighDpiScaleFactorRoundingPolicy::RoundPreferFloor},
+ {"PassThrough", Qt::HighDpiScaleFactorRoundingPolicy::PassThrough}
};
-static QHighDpiScaling::HighDpiScaleFactorRoundingPolicy
+static Qt::HighDpiScaleFactorRoundingPolicy
lookupScaleFactorRoundingPolicy(const QByteArray &v)
{
auto end = std::end(scaleFactorRoundingPolicyLookup);
auto it = std::find(std::begin(scaleFactorRoundingPolicyLookup), end,
- ScaleFactorRoundingPolicyLookup{v.constData(), QHighDpiScaling::HighDpiScaleFactorRoundingPolicy::Unset});
- return it != end ? it->value : QHighDpiScaling::HighDpiScaleFactorRoundingPolicy::Unset;
+ ScaleFactorRoundingPolicyLookup{v.constData(), Qt::HighDpiScaleFactorRoundingPolicy::Unset});
+ return it != end ? it->value : Qt::HighDpiScaleFactorRoundingPolicy::Unset;
}
using DpiAdjustmentPolicyLookup = EnumLookup<QHighDpiScaling::DpiAdjustmentPolicy>;
@@ -377,15 +377,15 @@ 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 = HighDpiScaleFactorRoundingPolicy::Unset;
+ static auto scaleFactorRoundingPolicy = Qt::HighDpiScaleFactorRoundingPolicy::Unset;
// Determine rounding policy
- if (scaleFactorRoundingPolicy == HighDpiScaleFactorRoundingPolicy::Unset) {
+ if (scaleFactorRoundingPolicy == Qt::HighDpiScaleFactorRoundingPolicy::Unset) {
// Check environment
if (qEnvironmentVariableIsSet(scaleFactorRoundingPolicyEnvVar)) {
QByteArray policyText = qgetenv(scaleFactorRoundingPolicyEnvVar);
auto policyEnumValue = lookupScaleFactorRoundingPolicy(policyText);
- if (policyEnumValue != HighDpiScaleFactorRoundingPolicy::Unset) {
+ if (policyEnumValue != Qt::HighDpiScaleFactorRoundingPolicy::Unset) {
scaleFactorRoundingPolicy = policyEnumValue;
} else {
auto values = joinEnumValues(std::begin(scaleFactorRoundingPolicyLookup),
@@ -393,38 +393,43 @@ qreal QHighDpiScaling::roundScaleFactor(qreal rawFactor)
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 {
- // Set default policy if no environment variable is set.
- scaleFactorRoundingPolicy = HighDpiScaleFactorRoundingPolicy::RoundPreferFloor;
+ // Make application setting reflect environment
+ QGuiApplication::setHighDpiScaleFactorRoundingPolicy(scaleFactorRoundingPolicy);
}
}
// Apply rounding policy.
qreal roundedFactor = rawFactor;
switch (scaleFactorRoundingPolicy) {
- case HighDpiScaleFactorRoundingPolicy::Round:
+ case Qt::HighDpiScaleFactorRoundingPolicy::Round:
roundedFactor = qRound(rawFactor);
break;
- case HighDpiScaleFactorRoundingPolicy::Ceil:
+ case Qt::HighDpiScaleFactorRoundingPolicy::Ceil:
roundedFactor = qCeil(rawFactor);
break;
- case HighDpiScaleFactorRoundingPolicy::Floor:
+ case Qt::HighDpiScaleFactorRoundingPolicy::Floor:
roundedFactor = qFloor(rawFactor);
break;
- case HighDpiScaleFactorRoundingPolicy::RoundPreferFloor:
+ 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 HighDpiScaleFactorRoundingPolicy::PassThrough:
- case HighDpiScaleFactorRoundingPolicy::Unset:
+ 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 != HighDpiScaleFactorRoundingPolicy::PassThrough)
+ if (scaleFactorRoundingPolicy != Qt::HighDpiScaleFactorRoundingPolicy::PassThrough)
roundedFactor = qMax(roundedFactor, qreal(1));
return roundedFactor;
diff --git a/src/gui/kernel/qhighdpiscaling_p.h b/src/gui/kernel/qhighdpiscaling_p.h
index 9c24fa506d..f58944a7d2 100644
--- a/src/gui/kernel/qhighdpiscaling_p.h
+++ b/src/gui/kernel/qhighdpiscaling_p.h
@@ -74,16 +74,6 @@ typedef QPair<qreal, qreal> QDpi;
class Q_GUI_EXPORT QHighDpiScaling {
Q_GADGET
public:
- enum class HighDpiScaleFactorRoundingPolicy {
- Unset,
- Round,
- Ceil,
- Floor,
- RoundPreferFloor,
- PassThrough
- };
- Q_ENUM(HighDpiScaleFactorRoundingPolicy)
-
enum class DpiAdjustmentPolicy {
Unset,
Enabled,