summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/gui/kernel/qhighdpiscaling.cpp61
-rw-r--r--src/gui/kernel/qhighdpiscaling_p.h42
2 files changed, 84 insertions, 19 deletions
diff --git a/src/gui/kernel/qhighdpiscaling.cpp b/src/gui/kernel/qhighdpiscaling.cpp
index 53ecf8e0ad..6a47372b0b 100644
--- a/src/gui/kernel/qhighdpiscaling.cpp
+++ b/src/gui/kernel/qhighdpiscaling.cpp
@@ -649,34 +649,77 @@ QDpi QHighDpiScaling::logicalDpi(const QScreen *screen)
return effectiveLogicalDpi(screen->handle(), scaleFactor, roundedScaleFactor);
}
-QHighDpiScaling::ScaleAndOrigin QHighDpiScaling::scaleAndOrigin(const QPlatformScreen *platformScreen, QPoint *nativePosition)
+// Returns the screen containing \a position, using \a guess as a starting point
+// for the search. \a guess might be nullptr. Returns nullptr if \a position is outside
+// of all screens.
+QScreen *QHighDpiScaling::screenForPosition(QHighDpiScaling::Point position, QScreen *guess)
{
+ if (position.kind == QHighDpiScaling::Point::Invalid)
+ return nullptr;
+
+ auto getPlatformScreenGuess = [](QScreen *maybeScreen) -> QPlatformScreen * {
+ if (maybeScreen)
+ return maybeScreen->handle();
+ if (QScreen *primary = QGuiApplication::primaryScreen())
+ return primary->handle();
+ return nullptr;
+ };
+
+ QPlatformScreen *platformGuess = getPlatformScreenGuess(guess);
+ if (!platformGuess)
+ return nullptr;
+
+ auto onScreen = [](QHighDpiScaling::Point position, const QPlatformScreen *platformScreen) -> bool {
+ return position.kind == Point::Native
+ ? platformScreen->geometry().contains(position.point)
+ : platformScreen->screen()->geometry().contains(position.point);
+ };
+
+ // is the guessed screen correct?
+ if (onScreen(position, platformGuess))
+ return platformGuess->screen();
+
+ // search sibling screens
+ const auto screens = platformGuess->virtualSiblings();
+ for (const QPlatformScreen *screen : screens) {
+ if (onScreen(position, screen))
+ return screen->screen();
+ }
+
+ return nullptr;
+}
+
+QHighDpiScaling::ScaleAndOrigin QHighDpiScaling::scaleAndOrigin(const QPlatformScreen *platformScreen, QHighDpiScaling::Point position)
+{
+ Q_UNUSED(position)
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() };
+ return { m_factor * screenSubfactor(platformScreen), platformScreen->geometry().topLeft() };
}
-QHighDpiScaling::ScaleAndOrigin QHighDpiScaling::scaleAndOrigin(const QScreen *screen, QPoint *nativePosition)
+QHighDpiScaling::ScaleAndOrigin QHighDpiScaling::scaleAndOrigin(const QScreen *screen, QHighDpiScaling::Point position)
{
+ Q_UNUSED(position)
if (!m_active)
return { qreal(1), QPoint() };
if (!screen)
return { m_factor, QPoint() }; // the global factor
- return scaleAndOrigin(screen->handle(), nativePosition);
+ return scaleAndOrigin(screen->handle(), position);
}
-QHighDpiScaling::ScaleAndOrigin QHighDpiScaling::scaleAndOrigin(const QWindow *window, QPoint *nativePosition)
+QHighDpiScaling::ScaleAndOrigin QHighDpiScaling::scaleAndOrigin(const QWindow *window, QHighDpiScaling::Point position)
{
if (!m_active)
return { qreal(1), QPoint() };
+ // Determine correct screen; use the screen which contains the given
+ // position if a valid position is passed.
QScreen *screen = window ? window->screen() : QGuiApplication::primaryScreen();
- const bool searchScreen = !window || window->isTopLevel();
- return scaleAndOrigin(screen, searchScreen ? nativePosition : nullptr);
+ QScreen *overrideScreen = QHighDpiScaling::screenForPosition(position, screen);
+ QScreen *targetScreen = overrideScreen ? overrideScreen : screen;
+ return scaleAndOrigin(targetScreen, position);
}
#else
diff --git a/src/gui/kernel/qhighdpiscaling_p.h b/src/gui/kernel/qhighdpiscaling_p.h
index 86f74b26a9..92a9a6929d 100644
--- a/src/gui/kernel/qhighdpiscaling_p.h
+++ b/src/gui/kernel/qhighdpiscaling_p.h
@@ -96,18 +96,29 @@ public:
static bool isActive() { return m_active; }
+ struct Point {
+ enum Kind {
+ Invalid,
+ DeviceIndependent,
+ Native
+ };
+ Kind kind;
+ QPoint point;
+ };
+
struct ScaleAndOrigin
{
qreal factor;
QPoint origin;
};
- static ScaleAndOrigin scaleAndOrigin(const QPlatformScreen *platformScreen, QPoint *nativePosition = nullptr);
- static ScaleAndOrigin scaleAndOrigin(const QScreen *screen, QPoint *nativePosition = nullptr);
- static ScaleAndOrigin scaleAndOrigin(const QWindow *platformScreen, QPoint *nativePosition = nullptr);
+
+ static ScaleAndOrigin scaleAndOrigin(const QPlatformScreen *platformScreen, Point position = Point{ Point::Invalid, QPoint() });
+ static ScaleAndOrigin scaleAndOrigin(const QScreen *screen, Point position = Point{ Point::Invalid, QPoint() });
+ static ScaleAndOrigin scaleAndOrigin(const QWindow *platformScreen, Point position = Point{ Point::Invalid, QPoint() });
template<typename C>
- static qreal factor(C *context, QPoint *nativePosition = nullptr) {
- return scaleAndOrigin(context, nativePosition).factor;
+ static qreal factor(C *context) {
+ return scaleAndOrigin(context).factor;
}
static QPoint mapPositionFromNative(const QPoint &pos, const QPlatformScreen *platformScreen);
@@ -121,6 +132,7 @@ private:
static qreal roundScaleFactor(qreal rawFactor);
static QDpi effectiveLogicalDpi(const QPlatformScreen *screen, qreal rawFactor, qreal roundedFactor);
static qreal screenSubfactor(const QPlatformScreen *screen);
+ static QScreen *screenForPosition(Point position, QScreen *guess);
static qreal m_factor;
static bool m_active;
@@ -209,11 +221,21 @@ inline QRegion scale(const QRegion &region, qreal scaleFactor, QPoint origin = Q
}
template <typename T>
-inline QPoint position(T) { return QPoint(); }
-inline QPoint position(QPoint point) { return point; }
-inline QPoint position(QPointF point) { return point.toPoint(); }
-inline QPoint position(QRect rect) { return rect.center(); }
-inline QPoint position(QRectF rect) { return rect.center().toPoint(); }
+inline QHighDpiScaling::Point position(T, QHighDpiScaling::Point::Kind) {
+ return QHighDpiScaling::Point{ QHighDpiScaling::Point::Invalid, QPoint() };
+}
+inline QHighDpiScaling::Point position(QPoint point, QHighDpiScaling::Point::Kind kind) {
+ return QHighDpiScaling::Point{ kind, point };
+}
+inline QHighDpiScaling::Point position(QPointF point, QHighDpiScaling::Point::Kind kind) {
+ return QHighDpiScaling::Point{ kind, point.toPoint() };
+}
+inline QHighDpiScaling::Point position(QRect rect, QHighDpiScaling::Point::Kind kind) {
+ return QHighDpiScaling::Point{ kind, rect.topLeft() };
+}
+inline QHighDpiScaling::Point position(QRectF rect, QHighDpiScaling::Point::Kind kind) {
+ return QHighDpiScaling::Point{ kind, rect.topLeft().toPoint() };
+}
template <typename T, typename C>
T fromNativePixels(const T &value, const C *context)