Changeset View
Changeset View
Standalone View
Standalone View
3rdparty/ext_qt/0034-Update-QT_SCREEN_SCALE_FACTORS.patch
- This file was added.
1 | From f58ea52d89d9230ab9d441d96f6884044c4c686d Mon Sep 17 00:00:00 2001 | ||||
---|---|---|---|---|---|
2 | From: Friedemann Kleint <Friedemann.Kleint@qt.io> | ||||
3 | Date: Wed, 27 Feb 2019 08:46:47 +0100 | ||||
4 | Subject: [PATCH 34/36] Update QT_SCREEN_SCALE_FACTORS | ||||
5 | MIME-Version: 1.0 | ||||
6 | Content-Type: text/plain; charset=UTF-8 | ||||
7 | Content-Transfer-Encoding: 8bit | ||||
8 | | ||||
9 | Store name->factor associations in a global QHash instead of on the | ||||
10 | QScreen object, making them survive QScreen object deletion, for | ||||
11 | example on disconnect/ connect cycles. | ||||
12 | | ||||
13 | Make factors set with QT_SCREEN_SCALE_FACTORS override the screen | ||||
14 | factors computed from platform plugin DPI values. This matches the use | ||||
15 | case for QT_SCREEN_SCALE_FACTORS (but not the general scale factors | ||||
16 | combine by multiplication?rinciple) | ||||
17 | | ||||
18 | Done-with: Friedemann Kleint <Friedemann.Kleint@qt.io> | ||||
19 | Task-number: QTBUG-53022 | ||||
20 | Change-Id: I12771249314ab0c073e609d62f57ac0d18d3b6ce | ||||
21 | --- | ||||
22 | src/gui/kernel/qhighdpiscaling.cpp | 62 ++++++++++++++++++++++-------- | ||||
23 | src/gui/kernel/qhighdpiscaling_p.h | 2 +- | ||||
24 | 2 files changed, 47 insertions(+), 17 deletions(-) | ||||
25 | | ||||
26 | diff --git a/src/gui/kernel/qhighdpiscaling.cpp b/src/gui/kernel/qhighdpiscaling.cpp | ||||
27 | index fc8084c45a..b1350599b7 100644 | ||||
28 | --- a/src/gui/kernel/qhighdpiscaling.cpp | ||||
29 | +++ b/src/gui/kernel/qhighdpiscaling.cpp | ||||
30 | @@ -61,6 +61,12 @@ static const char scaleFactorRoundingPolicyEnvVar[] = "QT_SCALE_FACTOR_ROUNDING_ | ||||
31 | static const char dpiAdjustmentPolicyEnvVar[] = "QT_DPI_ADJUSTMENT_POLICY"; | ||||
32 | static const char usePhysicalDpiEnvVar[] = "QT_USE_PHYSICAL_DPI"; | ||||
33 | | ||||
34 | +// Per-screen scale factors for named screens set with QT_SCREEN_SCALE_FACTORS | ||||
35 | +// are stored here. Use a global hash to keep the factor across screen | ||||
36 | +// disconnect/connect cycles where the screen object may be deleted. | ||||
37 | +typedef QHash<QString, qreal> QScreenScaleFactorHash; | ||||
38 | +Q_GLOBAL_STATIC(QScreenScaleFactorHash, qNamedScreenScaleFactors); | ||||
39 | + | ||||
40 | // Reads and interprets the given environment variable as a bool, | ||||
41 | // returns the default value if not set. | ||||
42 | static bool qEnvironmentVariableAsBool(const char *name, bool defaultValue) | ||||
43 | @@ -478,20 +484,19 @@ void QHighDpiScaling::updateHighDpiScaling() | ||||
44 | int i = 0; | ||||
45 | const auto specs = qgetenv(screenFactorsEnvVar).split(';'); | ||||
46 | for (const QByteArray &spec : specs) { | ||||
47 | - QScreen *screen = 0; | ||||
48 | int equalsPos = spec.lastIndexOf('='); | ||||
49 | - double factor = 0; | ||||
50 | + qreal factor = 0; | ||||
51 | if (equalsPos > 0) { | ||||
52 | // support "name=factor" | ||||
53 | QByteArray name = spec.mid(0, equalsPos); | ||||
54 | QByteArray f = spec.mid(equalsPos + 1); | ||||
55 | bool ok; | ||||
56 | factor = f.toDouble(&ok); | ||||
57 | - if (ok) { | ||||
58 | + if (ok && factor > 0 ) { | ||||
59 | const auto screens = QGuiApplication::screens(); | ||||
60 | for (QScreen *s : screens) { | ||||
61 | if (s->name() == QString::fromLocal8Bit(name)) { | ||||
62 | - screen = s; | ||||
63 | + setScreenFactor(s, factor); | ||||
64 | break; | ||||
65 | } | ||||
66 | } | ||||
67 | @@ -500,11 +505,11 @@ void QHighDpiScaling::updateHighDpiScaling() | ||||
68 | // listing screens in order | ||||
69 | bool ok; | ||||
70 | factor = spec.toDouble(&ok); | ||||
71 | - if (ok && i < QGuiApplication::screens().count()) | ||||
72 | - screen = QGuiApplication::screens().at(i); | ||||
73 | + if (ok && factor > 0 && i < QGuiApplication::screens().count()) { | ||||
74 | + QScreen *screen = QGuiApplication::screens().at(i); | ||||
75 | + setScreenFactor(screen, factor); | ||||
76 | + } | ||||
77 | } | ||||
78 | - if (screen) | ||||
79 | - setScreenFactor(screen, factor); | ||||
80 | ++i; | ||||
81 | } | ||||
82 | } | ||||
83 | @@ -540,7 +545,14 @@ void QHighDpiScaling::setScreenFactor(QScreen *screen, qreal factor) | ||||
84 | m_screenFactorSet = true; | ||||
85 | m_active = true; | ||||
86 | } | ||||
87 | - screen->setProperty(scaleFactorProperty, QVariant(factor)); | ||||
88 | + | ||||
89 | + // Prefer associating the factor with screen name over the object | ||||
90 | + // since the screen object may be deleted on screen disconnects. | ||||
91 | + const QString name = screen->name(); | ||||
92 | + if (!name.isEmpty()) | ||||
93 | + qNamedScreenScaleFactors()->insert(name, factor); | ||||
94 | + else | ||||
95 | + screen->setProperty(scaleFactorProperty, QVariant(factor)); | ||||
96 | | ||||
97 | // hack to force re-evaluation of screen geometry | ||||
98 | if (screen->handle()) | ||||
99 | @@ -568,15 +580,33 @@ QPoint QHighDpiScaling::mapPositionFromNative(const QPoint &pos, const QPlatform | ||||
100 | qreal QHighDpiScaling::screenSubfactor(const QPlatformScreen *screen) | ||||
101 | { | ||||
102 | qreal factor = qreal(1.0); | ||||
103 | - if (screen) { | ||||
104 | - if (m_usePixelDensity) | ||||
105 | - factor *= roundScaleFactor(rawScaleFactor(screen)); | ||||
106 | - if (m_screenFactorSet) { | ||||
107 | - QVariant screenFactor = screen->screen()->property(scaleFactorProperty); | ||||
108 | - if (screenFactor.isValid()) | ||||
109 | - factor *= screenFactor.toReal(); | ||||
110 | + if (!screen) | ||||
111 | + return factor; | ||||
112 | + | ||||
113 | + // Unlike the other code where factors are combined | ||||
114 | + // by multiplication, factors from QT_SCREEN_SCALE_FACTORS takes | ||||
115 | + // precedence over the factor computed from platform plugin | ||||
116 | + // DPI. The rationale is that the user is setting the factor | ||||
117 | + // to override erroneous DPI values. | ||||
118 | + bool screenPropertyUsed = false; | ||||
119 | + if (m_screenFactorSet) { | ||||
120 | + // Check if there is a factor set on the screen object or | ||||
121 | + // associated with the screen name. These are mutually | ||||
122 | + // exclusive, so checking order is not significant. | ||||
123 | + QVariant byIndex = screen->screen()->property(scaleFactorProperty); | ||||
124 | + auto byName = qNamedScreenScaleFactors()->find(screen->name()); | ||||
125 | + if (byIndex.isValid()) { | ||||
126 | + screenPropertyUsed = true; | ||||
127 | + factor = byIndex.toReal(); | ||||
128 | + } else if (byName != qNamedScreenScaleFactors()->end()) { | ||||
129 | + screenPropertyUsed = true; | ||||
130 | + factor = *byName; | ||||
131 | } | ||||
132 | } | ||||
133 | + | ||||
134 | + if (!screenPropertyUsed && m_usePixelDensity) | ||||
135 | + factor = roundScaleFactor(rawScaleFactor(screen)); | ||||
136 | + | ||||
137 | return factor; | ||||
138 | } | ||||
139 | | ||||
140 | diff --git a/src/gui/kernel/qhighdpiscaling_p.h b/src/gui/kernel/qhighdpiscaling_p.h | ||||
141 | index 55bddfeb88..d3f71854a8 100644 | ||||
142 | --- a/src/gui/kernel/qhighdpiscaling_p.h | ||||
143 | +++ b/src/gui/kernel/qhighdpiscaling_p.h | ||||
144 | @@ -101,7 +101,7 @@ public: | ||||
145 | static void initHighDpiScaling(); | ||||
146 | static void updateHighDpiScaling(); | ||||
147 | static void setGlobalFactor(qreal factor); | ||||
148 | - static void setScreenFactor(QScreen *window, qreal factor); | ||||
149 | + static void setScreenFactor(QScreen *screen, qreal factor); | ||||
150 | | ||||
151 | static bool isActive() { return m_active; } | ||||
152 | static qreal factor(const QWindow *window); | ||||
153 | -- | ||||
154 | 2.18.0.windows.1 | ||||
155 | |