File 3007-high-dpi-Re-implement-mapToGlobal-and-mapFromGlobal.patch of Package libqt5-qtbase

From dbe23a4c8b85f4470e0dc80453dd09840f0222ee Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Morten=20Johan=20S=C3=B8rvig?= <morten.sorvig@qt.io>
Date: Wed, 20 May 2020 14:27:16 +0200
Subject: [PATCH 3007/3009] high-dpi: Re-implement mapToGlobal and
 mapFromGlobal
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

(This code is required to handle corner cases such as a QWindow
covering multiple screens, where the normal code path does not
give correct results.)

Move the map[to|from]Global implementation from qhighdpiscaling.cpp,
and implement it in terms of [to|from]NativeGlobalPosition. These
functions implement the required screenAt()-type searching.

The implementation strategy for both mapping functions is to first
map to the native coordinate system, perform the globalPos addition
or subtraction, and then map the result back to device independent
coordinates.

Task-number: QTBUG-81695
Change-Id: I44e9e68651634650964e839b1e564b50f434553f
Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
Reviewed-by: Friedemann Kleint <Friedemann.Kleint@qt.io>
(cherry picked from commit 0ab89881c5aecc31e44fd83b1a63bd4de52ebe4a)
---
 src/gui/kernel/qhighdpiscaling_p.h |  2 --
 src/gui/kernel/qhighdpiscaling.cpp | 40 ------------------------------
 src/gui/kernel/qwindow.cpp         | 28 ++++++++++++++++-----
 3 files changed, 22 insertions(+), 48 deletions(-)

diff --git a/src/gui/kernel/qhighdpiscaling_p.h b/src/gui/kernel/qhighdpiscaling_p.h
index 82d424183c..20e0521030 100644
--- a/src/gui/kernel/qhighdpiscaling_p.h
+++ b/src/gui/kernel/qhighdpiscaling_p.h
@@ -123,8 +123,6 @@ public:
 
     static QPoint mapPositionFromNative(const QPoint &pos, const QPlatformScreen *platformScreen);
     static QPoint mapPositionToNative(const QPoint &pos, const QPlatformScreen *platformScreen);
-    static QPoint mapPositionToGlobal(const QPoint &pos, const QPoint &windowGlobalPosition, const QWindow *window);
-    static QPoint mapPositionFromGlobal(const QPoint &pos, const QPoint &windowGlobalPosition, const QWindow *window);
     static QDpi logicalDpi(const QScreen *screen);
 
 private:
diff --git a/src/gui/kernel/qhighdpiscaling.cpp b/src/gui/kernel/qhighdpiscaling.cpp
index d34b2a5dc6..c89122a5a5 100644
--- a/src/gui/kernel/qhighdpiscaling.cpp
+++ b/src/gui/kernel/qhighdpiscaling.cpp
@@ -603,46 +603,6 @@ QPoint QHighDpiScaling::mapPositionFromNative(const QPoint &pos, const QPlatform
     return (pos - topLeft) / scaleFactor + topLeft;
 }
 
-QPoint QHighDpiScaling::mapPositionToGlobal(const QPoint &pos, const QPoint &windowGlobalPosition, const QWindow *window)
-{
-    QPoint globalPosCandidate = pos + windowGlobalPosition;
-    if (QGuiApplicationPrivate::screen_list.size() <= 1)
-        return globalPosCandidate;
-
-    // The global position may be outside device independent screen geometry
-    // in cases where a window spans screens. Detect this case and map via
-    // native coordinates to the correct screen.
-    auto currentScreen = window->screen();
-    if (currentScreen && !currentScreen->geometry().contains(globalPosCandidate)) {
-        auto nativeGlobalPos = QHighDpi::toNativePixels(globalPosCandidate, currentScreen);
-        if (auto actualPlatformScreen = currentScreen->handle()->screenForPosition(nativeGlobalPos))
-            return QHighDpi::fromNativePixels(nativeGlobalPos, actualPlatformScreen->screen());
-    }
-
-    return globalPosCandidate;
-}
-
-QPoint QHighDpiScaling::mapPositionFromGlobal(const QPoint &pos, const QPoint &windowGlobalPosition, const QWindow *window)
-{
-    QPoint windowPosCandidate = pos - windowGlobalPosition;
-    if (QGuiApplicationPrivate::screen_list.size() <= 1 || window->handle() == nullptr)
-        return windowPosCandidate;
-
-    // Device independent global (screen) space may discontiguous when high-dpi scaling
-    // is active. This means that the normal subtracting of the window global position from the
-    // position-to-be-mapped may not work in cases where a window spans multiple screens.
-    // Map both positions to native global space (using the correct screens), subtract there,
-    // and then map the difference back using the scale factor for the window.
-    QScreen *posScreen = QGuiApplication::screenAt(pos);
-    if (posScreen && posScreen != window->screen()) {
-        QPoint nativePos = QHighDpi::toNativePixels(pos, posScreen);
-        QPoint windowNativePos = window->handle()->geometry().topLeft();
-        return QHighDpi::fromNativeLocalPosition(nativePos - windowNativePos, window);
-    }
-
-    return windowPosCandidate;
-}
-
 qreal QHighDpiScaling::screenSubfactor(const QPlatformScreen *screen)
 {
     auto factor = qreal(1.0);
diff --git a/src/gui/kernel/qwindow.cpp b/src/gui/kernel/qwindow.cpp
index 0e44c384be..36b95d8348 100644
--- a/src/gui/kernel/qwindow.cpp
+++ b/src/gui/kernel/qwindow.cpp
@@ -2653,10 +2653,20 @@ QPoint QWindow::mapToGlobal(const QPoint &pos) const
         return QHighDpi::fromNativeLocalPosition(d->platformWindow->mapToGlobal(QHighDpi::toNativeLocalPosition(pos, this)), this);
     }
 
-    if (QHighDpiScaling::isActive())
-        return QHighDpiScaling::mapPositionToGlobal(pos, d->globalPosition(), this);
+    if (!QHighDpiScaling::isActive())
+        return pos + d->globalPosition();
 
-    return pos + d->globalPosition();
+    // The normal pos + windowGlobalPos calculation may give a point which is outside
+    // screen geometry for windows which span multiple screens, due to the way QHighDpiScaling
+    // creates gaps between screens in the the device indendent cooordinate system.
+    //
+    // Map the position (and the window's global position) to native coordinates, perform
+    // the addition, and then map back to device independent coordinates.
+    QPointF nativeLocalPos = QHighDpi::toNativeLocalPosition(pos, this);
+    QPointF nativeWindowGlobalPos = QHighDpi::toNativeGlobalPosition(QPointF(d->globalPosition()), this);
+    QPointF nativeGlobalPos = nativeLocalPos + nativeWindowGlobalPos;
+    QPointF deviceIndependentGlobalPos = QHighDpi::fromNativeGlobalPosition(nativeGlobalPos, this);
+    return deviceIndependentGlobalPos.toPoint();
 }
 
 
@@ -2677,10 +2687,16 @@ QPoint QWindow::mapFromGlobal(const QPoint &pos) const
         return QHighDpi::fromNativeLocalPosition(d->platformWindow->mapFromGlobal(QHighDpi::toNativeLocalPosition(pos, this)), this);
     }
 
-    if (QHighDpiScaling::isActive())
-        return QHighDpiScaling::mapPositionFromGlobal(pos, d->globalPosition(), this);
+    if (!QHighDpiScaling::isActive())
+        return pos - d->globalPosition();
 
-    return pos - d->globalPosition();
+    // Calculate local position in the native coordinate system. (See comment for the
+    // correspinding mapToGlobal() code above).
+    QPointF nativeGlobalPos = QHighDpi::toNativeGlobalPosition(pos, this);
+    QPointF nativeWindowGlobalPos = QHighDpi::toNativeGlobalPosition(QPointF(d->globalPosition()), this);
+    QPointF nativeLocalPos = nativeGlobalPos - nativeWindowGlobalPos;
+    QPointF deviceIndependentLocalPos = QHighDpi::fromNativeLocalPosition(nativeLocalPos, this);
+    return deviceIndependentLocalPos.toPoint();
 }
 
 QPoint QWindowPrivate::globalPosition() const
-- 
2.29.2

openSUSE Build Service is sponsored by