summaryrefslogtreecommitdiffstats
path: root/src/gui/kernel
diff options
context:
space:
mode:
authorMorten Johan Sørvig <morten.sorvig@theqtcompany.com>2015-05-26 22:22:37 +0200
committerPaul Olav Tvete <paul.tvete@theqtcompany.com>2015-05-29 15:41:38 +0000
commitf9b1596fe1aeacf4f3d977c32e74b7ad585d3d3e (patch)
tree82c04fce2ef3a56540ebb6e06df5b29a4f1fa71b /src/gui/kernel
parentc2d5ecf8766d3da70b17348e92cda31b00e204a7 (diff)
Refactor QHighDpiScaling internals and usage
Overall goal is to simplify, separate concerns, and improve cross-platform-ness and testability. QT_SCALE_FACTOR is now a pure cross-platform global scale factor setter has no "auto". "auto" requires input from the platform plugin via QPlatformScreen:: pixelDensity() and gets a separate environment variable: QT_AUTO_SCREEN_SCALE_FACTOR The effective scale factor (aka devicePixelRatio) is now computed as the product of the global, screen, and window scale factors. This matches how devicePixelRatio is computed in general (the window system devicePixelRatio is also a factor), and makes QT_SCALE_FACTOR work consistently regardless if there is a window scale factor set or not. This also means we can remove the if/else casing from the nativePixels conversion functions. Add QHighDpiScaling initializer which reads the environment variables and sets the "active" variables. Call it during QGuiApplication construction, before the platform plugin is created Add per-screen scale factor setting capability to the manual test. This makes it possible to test this logic on all platforms. The command line argument is --screen-scale-factor. Change-Id: I054337cbae37a01cdd731d26d9cb628fcecdb652 Reviewed-by: Friedemann Kleint <Friedemann.Kleint@theqtcompany.com> Reviewed-by: Paul Olav Tvete <paul.tvete@theqtcompany.com>
Diffstat (limited to 'src/gui/kernel')
-rw-r--r--src/gui/kernel/qguiapplication.cpp3
-rw-r--r--src/gui/kernel/qhighdpiscaling.cpp80
-rw-r--r--src/gui/kernel/qhighdpiscaling_p.h12
-rw-r--r--src/gui/kernel/qplatformscreen.cpp18
-rw-r--r--src/gui/kernel/qwindow.cpp16
5 files changed, 87 insertions, 42 deletions
diff --git a/src/gui/kernel/qguiapplication.cpp b/src/gui/kernel/qguiapplication.cpp
index 8e4290b8e8..fe0bbbc15a 100644
--- a/src/gui/kernel/qguiapplication.cpp
+++ b/src/gui/kernel/qguiapplication.cpp
@@ -1118,6 +1118,9 @@ void QGuiApplicationPrivate::createPlatformIntegration()
// this flag.
QCoreApplication::setAttribute(Qt::AA_DontUseNativeMenuBar, true);
+
+ QHighDpiScaling::initHighDPiScaling();
+
// Load the platform integration
QString platformPluginPath = QLatin1String(qgetenv("QT_QPA_PLATFORM_PLUGIN_PATH"));
diff --git a/src/gui/kernel/qhighdpiscaling.cpp b/src/gui/kernel/qhighdpiscaling.cpp
index 54d06a8572..a1387f781b 100644
--- a/src/gui/kernel/qhighdpiscaling.cpp
+++ b/src/gui/kernel/qhighdpiscaling.cpp
@@ -43,6 +43,7 @@
#include "qwindow_p.h" // for QWINDOWSIZE_MAX
#include "qguiapplication.h"
#include "qscreen.h"
+#include "qplatformintegration.h"
#include "private/qscreen_p.h"
#include <QtCore/qdebug.h>
@@ -68,7 +69,7 @@ static inline qreal initialScaleFactor()
/*!
\class QHighDpiScaling
- \since 5.4
+ \since 5.6
\internal
\preliminary
\ingroup qpa
@@ -76,12 +77,26 @@ static inline qreal initialScaleFactor()
\brief Collection of utility functions for UI scaling.
*/
-qreal QHighDpiScaling::m_factor = initialScaleFactor();
-bool QHighDpiScaling::m_autoFactor = qgetenv("QT_SCALE_FACTOR").toLower() == "auto";
-bool QHighDpiScaling::m_active = m_autoFactor || !qFuzzyCompare(QHighDpiScaling::m_factor, qreal(1));
-bool QHighDpiScaling::m_perWindowActive = false;
-void QHighDpiScaling::setFactor(qreal factor)
+qreal QHighDpiScaling::m_factor;
+
+bool QHighDpiScaling::m_active; //"overall active" - is there any scale factor set.
+bool QHighDpiScaling::m_perScreenActive;
+
+void QHighDpiScaling::initHighDPiScaling()
+{
+ QHighDpiScaling::m_factor = initialScaleFactor();
+ bool usePlatformPluginPixelDensity = qEnvironmentVariableIsSet("QT_AUTO_SCREEN_SCALE_FACTOR");
+
+ // m_active below is "overall active" - is there any scale factor set.
+ QHighDpiScaling::m_active = !qFuzzyCompare(m_factor, qreal(1)) || usePlatformPluginPixelDensity;
+ QHighDpiScaling::m_perScreenActive = usePlatformPluginPixelDensity;
+}
+
+/*
+ Sets the global scale factor which is applied to all windows.
+*/
+void QHighDpiScaling::setGlobalFactor(qreal factor)
{
if (qFuzzyCompare(factor, QHighDpiScaling::m_factor))
return;
@@ -97,14 +112,16 @@ void QHighDpiScaling::setFactor(qreal factor)
static const char *scaleFactorProperty = "_q_scaleFactor";
-void QHighDpiScaling::setWindowFactor(QWindow *window, qreal factor)
+/*
+ Sets a per-screen scale factor.
+*/
+void QHighDpiScaling::setScreenFactor(QScreen *screen, qreal factor)
{
m_active = true;
- m_perWindowActive = true;
- window->setProperty(scaleFactorProperty, QVariant(factor));
+ m_perScreenActive = true;
+ screen->setProperty(scaleFactorProperty, QVariant(factor));
}
-
/*
QPoint QXcbScreen::mapToNative(const QPoint &pos) const
@@ -141,31 +158,46 @@ QPoint QHighDpiScaling::mapPositionFromNative(const QPoint &pos, const QPlatform
return (pos - topLeft) / scaleFactor + topLeft;
}
+qreal QHighDpiScaling::screenSubfactor(const QPlatformScreen *screen)
+{
+ qreal factor = qreal(1.0);
+ if (m_perScreenActive && screen) {
+ factor *= screen->pixelDensity();
+ QVariant screenFactor = screen->screen()->property(scaleFactorProperty);
+ if (screenFactor.isValid())
+ factor *= screenFactor.toReal();
+ }
+ return factor;
+}
qreal QHighDpiScaling::factor(const QScreen *screen)
{
- if (m_autoFactor && screen && screen->handle())
- return screen->handle()->pixelDensity();
- return m_factor;
+ // Fast path for when scaling in Qt is not used at all.
+ if (!m_active)
+ return qreal(1.0);
+
+ // The effective factor for a given screen is the product of the
+ // screen and global sub-factors
+ qreal factor = m_factor;
+ if (screen)
+ factor *= screenSubfactor(screen->handle());
+ return factor;
}
qreal QHighDpiScaling::factor(const QPlatformScreen *platformScreen)
{
- if (m_autoFactor && platformScreen)
- return platformScreen->pixelDensity();
- return m_factor;
+ if (!m_active)
+ return qreal(1.0);
+
+ return m_factor * screenSubfactor(platformScreen);
}
qreal QHighDpiScaling::factor(const QWindow *window)
{
- qreal f = m_factor;
- if (m_autoFactor && window && window->screen() && window->screen()->handle())
- f = window->screen()->handle()->pixelDensity();
- if (!m_perWindowActive || window == 0)
- return f;
-
- QVariant windowFactor = window->property(scaleFactorProperty);
- return f * (windowFactor.isValid() ? windowFactor.toReal() : 1);
+ if (!m_active || !window)
+ return qreal(1.0);
+
+ return factor(window->screen());
}
QPoint QHighDpiScaling::origin(const QScreen *screen)
diff --git a/src/gui/kernel/qhighdpiscaling_p.h b/src/gui/kernel/qhighdpiscaling_p.h
index 2350ca6fdb..a5d4c40a07 100644
--- a/src/gui/kernel/qhighdpiscaling_p.h
+++ b/src/gui/kernel/qhighdpiscaling_p.h
@@ -83,6 +83,10 @@ class QPlatformScreen;
class Q_GUI_EXPORT QHighDpiScaling {
public:
+ static void initHighDPiScaling();
+ static void setGlobalFactor(qreal factor);
+ static void setScreenFactor(QScreen *window, qreal factor);
+
static bool isActive() { return m_active; }
static qreal factor(const QWindow *window);
static qreal factor(const QScreen *screen);
@@ -91,13 +95,12 @@ 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 void setFactor(qreal factor);
- static void setWindowFactor(QWindow *window, qreal factor);
private:
+ static qreal screenSubfactor(const QPlatformScreen *screen);
+
static qreal m_factor;
- static bool m_autoFactor;
static bool m_active;
- static bool m_perWindowActive;
+ static bool m_perScreenActive;
};
// Coordinate system conversion functions:
@@ -157,7 +160,6 @@ inline QRect toNative(const QRect &rect, qreal scaleFactor, const QPoint &origin
}
-
inline QRect fromNative(const QRect &rect, const QScreen *screen, const QPoint &screenOrigin)
{
return toNative(rect, QHighDpiScaling::factor(screen), screenOrigin);
diff --git a/src/gui/kernel/qplatformscreen.cpp b/src/gui/kernel/qplatformscreen.cpp
index bda7280e81..ccb0452629 100644
--- a/src/gui/kernel/qplatformscreen.cpp
+++ b/src/gui/kernel/qplatformscreen.cpp
@@ -159,9 +159,11 @@ QDpi QPlatformScreen::logicalDpi() const
/*!
Reimplement this function in subclass to return the device pixel ratio
for the screen. This is the ratio between physical pixels and the
- device-independent pixels of the windowing system.
+ device-independent pixels of the windowing system. The default
+ implementation returns 1.0.
- \sa QPlatformWindow::devicePixelRatio();
+ \sa QPlatformWindow::devicePixelRatio()
+ \sa QPlatformScreen::pixelDensity()
*/
qreal QPlatformScreen::devicePixelRatio() const
{
@@ -171,7 +173,17 @@ qreal QPlatformScreen::devicePixelRatio() const
/*!
Reimplement this function in subclass to return the pixel density of the
screen. This is the scale factor needed to make a low-dpi application
- usable on this screen. The default implementation returns 1.0.
+ usable on this screen. The default implementation returns 1.0. In
+ addition the platform integration must return true for the PlatformScreenPixelDensity
+ Capability for this value to have an effect.
+
+ Returning something else than 1 from this function causes Qt to
+ apply the scale factor to the application's coordinate system.
+ This is different from devicePixelRatio, which reports a scale
+ factor already applied by the windowing system. A platform plugin
+ typically implements one (or none) of these two functions.
+
+ \sa QPlatformWindow::devicePixelRatio()
*/
qreal QPlatformScreen::pixelDensity() const
{
diff --git a/src/gui/kernel/qwindow.cpp b/src/gui/kernel/qwindow.cpp
index d84035e29c..4465a9aeb4 100644
--- a/src/gui/kernel/qwindow.cpp
+++ b/src/gui/kernel/qwindow.cpp
@@ -1086,17 +1086,13 @@ qreal QWindow::devicePixelRatio() const
{
Q_D(const QWindow);
- // Get the platform scale factor. If there is no platform window
- // use the app global devicePixelRatio, which is the the highest
- // devicePixelRatio found on the system screens, and will be
- // correct for single-display systems (a very common case).
- qreal ratio = d->platformWindow ? d->platformWindow->devicePixelRatio()
- : qApp->devicePixelRatio();
-
- //
- ratio *= QHighDpiScaling::factor(this);
+ // If there is no platform window use the app global devicePixelRatio,
+ // which is the the highest devicePixelRatio found on the system
+ // screens, and will be correct for single-display systems (a very common case).
+ if (!d->platformWindow)
+ return qApp->devicePixelRatio();
- return ratio;
+ return d->platformWindow->devicePixelRatio() * QHighDpiScaling::factor(this);
}
/*!