Differential D20607 Diff 56529 3rdparty/ext_qt/0036-Add-high-DPI-scale-factor-rounding-policy-C-API.patch
Changeset View
Changeset View
Standalone View
Standalone View
3rdparty/ext_qt/0036-Add-high-DPI-scale-factor-rounding-policy-C-API.patch
- This file was added.
1 | From 8e4d9b59af6b64345dd2a23656cf157ad76614eb Mon Sep 17 00:00:00 2001 | ||||
---|---|---|---|---|---|
2 | From: =?UTF-8?q?Morten=20Johan=20S=C3=B8rvig?= <morten.sorvig@qt.io> | ||||
3 | Date: Sat, 7 Oct 2017 01:35:29 +0200 | ||||
4 | Subject: [PATCH 36/36] Add high-DPI scale factor rounding policy C++ API | ||||
5 | | ||||
6 | This API enables tuning of how Qt rounds fractional scale factors, and | ||||
7 | corresponds to the QT_SCALE_FACTOR_ROUNDING_POLICY environment | ||||
8 | variable | ||||
9 | | ||||
10 | New API: | ||||
11 | Qt::HighDPiScaleFactorRoundingPolicy | ||||
12 | QGuiApplication::setHighDpiScaleFactorRoundingPolicy() | ||||
13 | QGuiApplication::highDpiScaleFactorRoundingPolicy() | ||||
14 | | ||||
15 | Done-with: Friedemann Kleint <Friedemann.Kleint@qt.io> | ||||
16 | Task-number: QTBUG-53022 | ||||
17 | Change-Id: Ic360f26a173caa757e4ebde35ce08a6b74290b7d | ||||
18 | --- | ||||
19 | src/corelib/global/qnamespace.h | 10 +++++++ | ||||
20 | src/corelib/global/qnamespace.qdoc | 22 ++++++++++++++ | ||||
21 | src/gui/kernel/qguiapplication.cpp | 44 ++++++++++++++++++++++++++++ | ||||
22 | src/gui/kernel/qguiapplication.h | 3 ++ | ||||
23 | src/gui/kernel/qguiapplication_p.h | 1 + | ||||
24 | src/gui/kernel/qhighdpiscaling.cpp | 47 +++++++++++++++++------------- | ||||
25 | src/gui/kernel/qhighdpiscaling_p.h | 10 ------- | ||||
26 | 7 files changed, 106 insertions(+), 31 deletions(-) | ||||
27 | | ||||
28 | diff --git a/src/corelib/global/qnamespace.h b/src/corelib/global/qnamespace.h | ||||
29 | index 3ab9921986..fea3d4d8da 100644 | ||||
30 | --- a/src/corelib/global/qnamespace.h | ||||
31 | +++ b/src/corelib/global/qnamespace.h | ||||
32 | @@ -1728,6 +1728,15 @@ public: | ||||
33 | ChecksumItuV41 | ||||
34 | }; | ||||
35 | | ||||
36 | + enum class HighDpiScaleFactorRoundingPolicy { | ||||
37 | + NotSet, | ||||
38 | + Round, | ||||
39 | + Ceil, | ||||
40 | + Floor, | ||||
41 | + RoundPreferFloor, | ||||
42 | + PassThrough | ||||
43 | + }; | ||||
44 | + | ||||
45 | #ifndef Q_QDOC | ||||
46 | // NOTE: Generally, do not add QT_Q_ENUM if a corresponding Q_Q_FLAG exists. | ||||
47 | QT_Q_ENUM(ScrollBarPolicy) | ||||
48 | @@ -1813,6 +1822,7 @@ public: | ||||
49 | QT_Q_ENUM(MouseEventSource) | ||||
50 | QT_Q_FLAG(MouseEventFlag) | ||||
51 | QT_Q_ENUM(ChecksumType) | ||||
52 | + QT_Q_ENUM(HighDpiScaleFactorRoundingPolicy) | ||||
53 | QT_Q_ENUM(TabFocusBehavior) | ||||
54 | #endif // Q_DOC | ||||
55 | | ||||
56 | diff --git a/src/corelib/global/qnamespace.qdoc b/src/corelib/global/qnamespace.qdoc | ||||
57 | index 5bba8c5fe5..a3ca70a74d 100644 | ||||
58 | --- a/src/corelib/global/qnamespace.qdoc | ||||
59 | +++ b/src/corelib/global/qnamespace.qdoc | ||||
60 | @@ -3252,3 +3252,25 @@ | ||||
61 | | ||||
62 | \value ChecksumItuV41 Checksum calculation based on ITU-V.41. | ||||
63 | */ | ||||
64 | + | ||||
65 | +/*! | ||||
66 | + \enum Qt::HighDpiScaleFactorRoundingPolicy | ||||
67 | + \since 5.14 | ||||
68 | + | ||||
69 | + This enum describes the possible High-DPI scale factor rounding policies, which | ||||
70 | + decide how non-integer scale factors (such as Windows 150%) are handled. | ||||
71 | + | ||||
72 | + The active policy is set by calling QGuiApplication::setHighDdpiScaleFactorRoundingPolicy() before | ||||
73 | + the application object is created, or by setting the QT_SCALE_FACTOR_ROUNDING_POLICY | ||||
74 | + environment variable. | ||||
75 | + | ||||
76 | + \sa QGuiApplication::setHighDdpiScaleFactorRoundingPolicy() | ||||
77 | + \sa AA_EnableHighDpiScaling. | ||||
78 | + | ||||
79 | + \omitvalue NotSet | ||||
80 | + \value Round Round up for .5 and above. | ||||
81 | + \value Ceil Always round up. | ||||
82 | + \value Floor Always round down. | ||||
83 | + \value RoundPreferFloor Round up for .75 and above. | ||||
84 | + \value PassThrough Don't round. | ||||
85 | +*/ | ||||
86 | diff --git a/src/gui/kernel/qguiapplication.cpp b/src/gui/kernel/qguiapplication.cpp | ||||
87 | index fd01f8bb7b..3541c1ae59 100644 | ||||
88 | --- a/src/gui/kernel/qguiapplication.cpp | ||||
89 | +++ b/src/gui/kernel/qguiapplication.cpp | ||||
90 | @@ -146,6 +146,8 @@ QString QGuiApplicationPrivate::styleOverride; | ||||
91 | | ||||
92 | Qt::ApplicationState QGuiApplicationPrivate::applicationState = Qt::ApplicationInactive; | ||||
93 | | ||||
94 | +Qt::HighDpiScaleFactorRoundingPolicy QGuiApplicationPrivate::highDpiScaleFactorRoundingPolicy = | ||||
95 | + Qt::HighDpiScaleFactorRoundingPolicy::RoundPreferFloor; | ||||
96 | bool QGuiApplicationPrivate::highDpiScalingUpdated = false; | ||||
97 | | ||||
98 | QPointer<QWindow> QGuiApplicationPrivate::currentDragWindow; | ||||
99 | @@ -677,6 +679,8 @@ QGuiApplication::~QGuiApplication() | ||||
100 | QGuiApplicationPrivate::lastCursorPosition = {qInf(), qInf()}; | ||||
101 | QGuiApplicationPrivate::currentMousePressWindow = QGuiApplicationPrivate::currentMouseWindow = nullptr; | ||||
102 | QGuiApplicationPrivate::applicationState = Qt::ApplicationInactive; | ||||
103 | + QGuiApplicationPrivate::highDpiScaleFactorRoundingPolicy = | ||||
104 | + Qt::HighDpiScaleFactorRoundingPolicy::RoundPreferFloor; | ||||
105 | QGuiApplicationPrivate::highDpiScalingUpdated = false; | ||||
106 | QGuiApplicationPrivate::currentDragWindow = nullptr; | ||||
107 | QGuiApplicationPrivate::tabletDevicePoints.clear(); | ||||
108 | @@ -3448,6 +3452,46 @@ Qt::ApplicationState QGuiApplication::applicationState() | ||||
109 | return QGuiApplicationPrivate::applicationState; | ||||
110 | } | ||||
111 | | ||||
112 | +/*! | ||||
113 | + \since 5.14 | ||||
114 | + | ||||
115 | + Sets the high-DPI scale factor rounding policy for the application. The | ||||
116 | + policy decides how non-integer scale factors (such as Windows 150%) are | ||||
117 | + handled, for applications that have AA_EnableHighDpiScaling enabled. | ||||
118 | + | ||||
119 | + The two principal options are whether fractional scale factors should | ||||
120 | + be rounded to an integer or not. Keeping the scale factor as-is will | ||||
121 | + make the user interface size match the OS setting exactly, but may cause | ||||
122 | + painting errors, for example with the Windows style. | ||||
123 | + | ||||
124 | + If rounding is wanted, then which type of rounding should be decided | ||||
125 | + next. Mathematically correct rounding is supported but may not give | ||||
126 | + the best visual results: Consider if you want to render 1.5x as 1x | ||||
127 | + ("small UI") or as 2x ("large UI"). See the Qt::HighDpiScaleFactorRoundingPolicy | ||||
128 | + enum for a complete list of all options. | ||||
129 | + | ||||
130 | + This function must be called before creating the application object, | ||||
131 | + and can be overridden by setting the QT_SCALE_FACTOR_ROUNDING_POLICY | ||||
132 | + environment variable. The QGuiApplication::highDpiScaleFactorRoundingPolicy() | ||||
133 | + accessor will reflect the environment, if set. | ||||
134 | + | ||||
135 | + The default value is Qt::HighDpiScaleFactorRoundingPolicy::RoundPreferFloor. | ||||
136 | +*/ | ||||
137 | +void QGuiApplication::setHighDpiScaleFactorRoundingPolicy(Qt::HighDpiScaleFactorRoundingPolicy policy) | ||||
138 | +{ | ||||
139 | + QGuiApplicationPrivate::highDpiScaleFactorRoundingPolicy = policy; | ||||
140 | +} | ||||
141 | + | ||||
142 | +/*! | ||||
143 | + \since 5.14 | ||||
144 | + | ||||
145 | + Returns the high-DPI scale factor rounding policy. | ||||
146 | +*/ | ||||
147 | +Qt::HighDpiScaleFactorRoundingPolicy QGuiApplication::highDpiScaleFactorRoundingPolicy() | ||||
148 | +{ | ||||
149 | + return QGuiApplicationPrivate::highDpiScaleFactorRoundingPolicy; | ||||
150 | +} | ||||
151 | + | ||||
152 | /*! | ||||
153 | \since 5.2 | ||||
154 | \fn void QGuiApplication::applicationStateChanged(Qt::ApplicationState state) | ||||
155 | diff --git a/src/gui/kernel/qguiapplication.h b/src/gui/kernel/qguiapplication.h | ||||
156 | index 02dffef0fe..2814ba1d1b 100644 | ||||
157 | --- a/src/gui/kernel/qguiapplication.h | ||||
158 | +++ b/src/gui/kernel/qguiapplication.h | ||||
159 | @@ -156,6 +156,9 @@ public: | ||||
160 | | ||||
161 | static Qt::ApplicationState applicationState(); | ||||
162 | | ||||
163 | + static void setHighDpiScaleFactorRoundingPolicy(Qt::HighDpiScaleFactorRoundingPolicy policy); | ||||
164 | + static Qt::HighDpiScaleFactorRoundingPolicy highDpiScaleFactorRoundingPolicy(); | ||||
165 | + | ||||
166 | static int exec(); | ||||
167 | bool notify(QObject *, QEvent *) override; | ||||
168 | | ||||
169 | diff --git a/src/gui/kernel/qguiapplication_p.h b/src/gui/kernel/qguiapplication_p.h | ||||
170 | index 042a36c31f..7962bb0177 100644 | ||||
171 | --- a/src/gui/kernel/qguiapplication_p.h | ||||
172 | +++ b/src/gui/kernel/qguiapplication_p.h | ||||
173 | @@ -216,6 +216,7 @@ public: | ||||
174 | static QWindow *currentMouseWindow; | ||||
175 | static QWindow *currentMousePressWindow; | ||||
176 | static Qt::ApplicationState applicationState; | ||||
177 | + static Qt::HighDpiScaleFactorRoundingPolicy highDpiScaleFactorRoundingPolicy; | ||||
178 | static bool highDpiScalingUpdated; | ||||
179 | static QPointer<QWindow> currentDragWindow; | ||||
180 | | ||||
181 | diff --git a/src/gui/kernel/qhighdpiscaling.cpp b/src/gui/kernel/qhighdpiscaling.cpp | ||||
182 | index 52c0665b5b..29b6d7e7c2 100644 | ||||
183 | --- a/src/gui/kernel/qhighdpiscaling.cpp | ||||
184 | +++ b/src/gui/kernel/qhighdpiscaling.cpp | ||||
185 | @@ -329,24 +329,24 @@ static QByteArray joinEnumValues(const EnumLookup<EnumType> *i1, const EnumLooku | ||||
186 | return result; | ||||
187 | } | ||||
188 | | ||||
189 | -using ScaleFactorRoundingPolicyLookup = EnumLookup<QHighDpiScaling::HighDpiScaleFactorRoundingPolicy>; | ||||
190 | +using ScaleFactorRoundingPolicyLookup = EnumLookup<Qt::HighDpiScaleFactorRoundingPolicy>; | ||||
191 | | ||||
192 | static const ScaleFactorRoundingPolicyLookup scaleFactorRoundingPolicyLookup[] = | ||||
193 | { | ||||
194 | - {"Round", QHighDpiScaling::HighDpiScaleFactorRoundingPolicy::Round}, | ||||
195 | - {"Ceil", QHighDpiScaling::HighDpiScaleFactorRoundingPolicy::Ceil}, | ||||
196 | - {"Floor", QHighDpiScaling::HighDpiScaleFactorRoundingPolicy::Floor}, | ||||
197 | - {"RoundPreferFloor", QHighDpiScaling::HighDpiScaleFactorRoundingPolicy::RoundPreferFloor}, | ||||
198 | - {"PassThrough", QHighDpiScaling::HighDpiScaleFactorRoundingPolicy::PassThrough} | ||||
199 | + {"Round", Qt::HighDpiScaleFactorRoundingPolicy::Round}, | ||||
200 | + {"Ceil", Qt::HighDpiScaleFactorRoundingPolicy::Ceil}, | ||||
201 | + {"Floor", Qt::HighDpiScaleFactorRoundingPolicy::Floor}, | ||||
202 | + {"RoundPreferFloor", Qt::HighDpiScaleFactorRoundingPolicy::RoundPreferFloor}, | ||||
203 | + {"PassThrough", Qt::HighDpiScaleFactorRoundingPolicy::PassThrough} | ||||
204 | }; | ||||
205 | | ||||
206 | -static QHighDpiScaling::HighDpiScaleFactorRoundingPolicy | ||||
207 | +static Qt::HighDpiScaleFactorRoundingPolicy | ||||
208 | lookupScaleFactorRoundingPolicy(const QByteArray &v) | ||||
209 | { | ||||
210 | auto end = std::end(scaleFactorRoundingPolicyLookup); | ||||
211 | auto it = std::find(std::begin(scaleFactorRoundingPolicyLookup), end, | ||||
212 | - ScaleFactorRoundingPolicyLookup{v.constData(), QHighDpiScaling::HighDpiScaleFactorRoundingPolicy::NotSet}); | ||||
213 | - return it != end ? it->value : QHighDpiScaling::HighDpiScaleFactorRoundingPolicy::NotSet; | ||||
214 | + ScaleFactorRoundingPolicyLookup{v.constData(), Qt::HighDpiScaleFactorRoundingPolicy::NotSet}); | ||||
215 | + return it != end ? it->value : Qt::HighDpiScaleFactorRoundingPolicy::NotSet; | ||||
216 | } | ||||
217 | | ||||
218 | using DpiAdjustmentPolicyLookup = EnumLookup<QHighDpiScaling::DpiAdjustmentPolicy>; | ||||
219 | @@ -375,15 +375,15 @@ qreal QHighDpiScaling::roundScaleFactor(qreal rawFactor) | ||||
220 | // sizes that are smaller than the ideal size, and opposite for rounding up. | ||||
221 | // Rounding down is then preferable since "small UI" is a more acceptable | ||||
222 | // high-DPI experience than "large UI". | ||||
223 | - static auto scaleFactorRoundingPolicy = HighDpiScaleFactorRoundingPolicy::NotSet; | ||||
224 | + static auto scaleFactorRoundingPolicy = Qt::HighDpiScaleFactorRoundingPolicy::NotSet; | ||||
225 | | ||||
226 | // Determine rounding policy | ||||
227 | - if (scaleFactorRoundingPolicy == HighDpiScaleFactorRoundingPolicy::NotSet) { | ||||
228 | + if (scaleFactorRoundingPolicy == Qt::HighDpiScaleFactorRoundingPolicy::NotSet) { | ||||
229 | // Check environment | ||||
230 | if (qEnvironmentVariableIsSet(scaleFactorRoundingPolicyEnvVar)) { | ||||
231 | QByteArray policyText = qgetenv(scaleFactorRoundingPolicyEnvVar); | ||||
232 | auto policyEnumValue = lookupScaleFactorRoundingPolicy(policyText); | ||||
233 | - if (policyEnumValue != HighDpiScaleFactorRoundingPolicy::NotSet) { | ||||
234 | + if (policyEnumValue != Qt::HighDpiScaleFactorRoundingPolicy::NotSet) { | ||||
235 | scaleFactorRoundingPolicy = policyEnumValue; | ||||
236 | } else { | ||||
237 | auto values = joinEnumValues(std::begin(scaleFactorRoundingPolicyLookup), | ||||
238 | @@ -391,38 +391,43 @@ qreal QHighDpiScaling::roundScaleFactor(qreal rawFactor) | ||||
239 | qWarning("Unknown scale factor rounding policy: %s. Supported values are: %s.", | ||||
240 | policyText.constData(), values.constData()); | ||||
241 | } | ||||
242 | + } | ||||
243 | + | ||||
244 | + // Check application object if no environment value was set. | ||||
245 | + if (scaleFactorRoundingPolicy == Qt::HighDpiScaleFactorRoundingPolicy::NotSet) { | ||||
246 | + scaleFactorRoundingPolicy = QGuiApplication::highDpiScaleFactorRoundingPolicy(); | ||||
247 | } else { | ||||
248 | - // Set default policy if no environment variable is set. | ||||
249 | - scaleFactorRoundingPolicy = HighDpiScaleFactorRoundingPolicy::RoundPreferFloor; | ||||
250 | + // Make application setting reflect environment | ||||
251 | + QGuiApplication::setHighDpiScaleFactorRoundingPolicy(scaleFactorRoundingPolicy); | ||||
252 | } | ||||
253 | } | ||||
254 | | ||||
255 | // Apply rounding policy. | ||||
256 | qreal roundedFactor = rawFactor; | ||||
257 | switch (scaleFactorRoundingPolicy) { | ||||
258 | - case HighDpiScaleFactorRoundingPolicy::Round: | ||||
259 | + case Qt::HighDpiScaleFactorRoundingPolicy::Round: | ||||
260 | roundedFactor = qRound(rawFactor); | ||||
261 | break; | ||||
262 | - case HighDpiScaleFactorRoundingPolicy::Ceil: | ||||
263 | + case Qt::HighDpiScaleFactorRoundingPolicy::Ceil: | ||||
264 | roundedFactor = qCeil(rawFactor); | ||||
265 | break; | ||||
266 | - case HighDpiScaleFactorRoundingPolicy::Floor: | ||||
267 | + case Qt::HighDpiScaleFactorRoundingPolicy::Floor: | ||||
268 | roundedFactor = qFloor(rawFactor); | ||||
269 | break; | ||||
270 | - case HighDpiScaleFactorRoundingPolicy::RoundPreferFloor: | ||||
271 | + case Qt::HighDpiScaleFactorRoundingPolicy::RoundPreferFloor: | ||||
272 | // Round up for .75 and higher. This favors "small UI" over "large UI". | ||||
273 | roundedFactor = rawFactor - qFloor(rawFactor) < 0.75 | ||||
274 | ? qFloor(rawFactor) : qCeil(rawFactor); | ||||
275 | break; | ||||
276 | - case HighDpiScaleFactorRoundingPolicy::PassThrough: | ||||
277 | - case HighDpiScaleFactorRoundingPolicy::NotSet: | ||||
278 | + case Qt::HighDpiScaleFactorRoundingPolicy::PassThrough: | ||||
279 | + case Qt::HighDpiScaleFactorRoundingPolicy::NotSet: | ||||
280 | break; | ||||
281 | } | ||||
282 | | ||||
283 | // Don't round down to to zero; clamp the minimum (rounded) factor to 1. | ||||
284 | // This is not a common case but can happen if a display reports a very | ||||
285 | // low DPI. | ||||
286 | - if (scaleFactorRoundingPolicy != HighDpiScaleFactorRoundingPolicy::PassThrough) | ||||
287 | + if (scaleFactorRoundingPolicy != Qt::HighDpiScaleFactorRoundingPolicy::PassThrough) | ||||
288 | roundedFactor = qMax(roundedFactor, qreal(1)); | ||||
289 | | ||||
290 | return roundedFactor; | ||||
291 | diff --git a/src/gui/kernel/qhighdpiscaling_p.h b/src/gui/kernel/qhighdpiscaling_p.h | ||||
292 | index d3f71854a8..ae361a9ddb 100644 | ||||
293 | --- a/src/gui/kernel/qhighdpiscaling_p.h | ||||
294 | +++ b/src/gui/kernel/qhighdpiscaling_p.h | ||||
295 | @@ -73,16 +73,6 @@ typedef QPair<qreal, qreal> QDpi; | ||||
296 | class Q_GUI_EXPORT QHighDpiScaling { | ||||
297 | Q_GADGET | ||||
298 | public: | ||||
299 | - enum class HighDpiScaleFactorRoundingPolicy { | ||||
300 | - NotSet, | ||||
301 | - Round, | ||||
302 | - Ceil, | ||||
303 | - Floor, | ||||
304 | - RoundPreferFloor, | ||||
305 | - PassThrough | ||||
306 | - }; | ||||
307 | - Q_ENUM(HighDpiScaleFactorRoundingPolicy) | ||||
308 | - | ||||
309 | enum class DpiAdjustmentPolicy { | ||||
310 | NotSet, | ||||
311 | Enabled, | ||||
312 | -- | ||||
313 | 2.18.0.windows.1 | ||||
314 | |