diff options
author | Liang Qi <liang.qi@qt.io> | 2019-05-15 07:11:41 +0200 |
---|---|---|
committer | Liang Qi <liang.qi@qt.io> | 2019-05-15 07:11:41 +0200 |
commit | c0359bd3c3a098ace9d2fa7ee91c33b24a8d9477 (patch) | |
tree | 9bcae3bff2ccef2b020c7a9ef25b3643e9ae556f /src/gui/kernel | |
parent | 68eea0196ebf30617e7d837ac5f61aaeeb814692 (diff) | |
parent | 1e5deb06416b6efc33a2009d9678fd8f743c5ce7 (diff) |
Merge remote-tracking branch 'origin/5.13' into dev
Conflicts:
src/corelib/global/qfloat16.cpp
src/corelib/global/qfloat16.h
src/plugins/platforms/windows/qwindowswindow.cpp
Change-Id: I0938aaa6a9771f55e48c95ed29f6f5291431b947
Diffstat (limited to 'src/gui/kernel')
-rw-r--r-- | src/gui/kernel/qhighdpiscaling.cpp | 42 | ||||
-rw-r--r-- | src/gui/kernel/qhighdpiscaling_p.h | 4 | ||||
-rw-r--r-- | src/gui/kernel/qwindow.cpp | 12 | ||||
-rw-r--r-- | src/gui/kernel/qwindow_p.h | 2 |
4 files changed, 56 insertions, 4 deletions
diff --git a/src/gui/kernel/qhighdpiscaling.cpp b/src/gui/kernel/qhighdpiscaling.cpp index 22e46e0851..4b85973e92 100644 --- a/src/gui/kernel/qhighdpiscaling.cpp +++ b/src/gui/kernel/qhighdpiscaling.cpp @@ -41,7 +41,9 @@ #include "qguiapplication.h" #include "qscreen.h" #include "qplatformintegration.h" +#include "qplatformwindow.h" #include "private/qscreen_p.h" +#include <private/qguiapplication_p.h> #include <QtCore/qdebug.h> @@ -376,6 +378,46 @@ 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) + 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) { qreal factor = qreal(1.0); diff --git a/src/gui/kernel/qhighdpiscaling_p.h b/src/gui/kernel/qhighdpiscaling_p.h index 83fc9452c5..28cf7de75b 100644 --- a/src/gui/kernel/qhighdpiscaling_p.h +++ b/src/gui/kernel/qhighdpiscaling_p.h @@ -83,8 +83,10 @@ public: static qreal factor(const QPlatformScreen *platformScreen); static QPoint origin(const QScreen *screen); 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 QPoint mapPositionFromNative(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(); private: diff --git a/src/gui/kernel/qwindow.cpp b/src/gui/kernel/qwindow.cpp index 6bcc22ec7b..aad5f856be 100644 --- a/src/gui/kernel/qwindow.cpp +++ b/src/gui/kernel/qwindow.cpp @@ -1682,9 +1682,9 @@ void QWindow::setGeometry(const QRect &rect) chicken and egg problem here: we cannot convert to native coordinates before we know which screen we are on. */ -QScreen *QWindowPrivate::screenForGeometry(const QRect &newGeometry) +QScreen *QWindowPrivate::screenForGeometry(const QRect &newGeometry) const { - Q_Q(QWindow); + Q_Q(const QWindow); QScreen *currentScreen = q->screen(); QScreen *fallback = currentScreen; QPoint center = newGeometry.center(); @@ -2559,6 +2559,10 @@ QPoint QWindow::mapToGlobal(const QPoint &pos) const && (d->platformWindow->isForeignWindow() || d->platformWindow->isEmbedded())) { return QHighDpi::fromNativeLocalPosition(d->platformWindow->mapToGlobal(QHighDpi::toNativeLocalPosition(pos, this)), this); } + + if (QHighDpiScaling::isActive()) + return QHighDpiScaling::mapPositionToGlobal(pos, d->globalPosition(), this); + return pos + d->globalPosition(); } @@ -2579,6 +2583,10 @@ QPoint QWindow::mapFromGlobal(const QPoint &pos) const && (d->platformWindow->isForeignWindow() || d->platformWindow->isEmbedded())) { return QHighDpi::fromNativeLocalPosition(d->platformWindow->mapFromGlobal(QHighDpi::toNativeLocalPosition(pos, this)), this); } + + if (QHighDpiScaling::isActive()) + return QHighDpiScaling::mapPositionFromGlobal(pos, d->globalPosition(), this); + return pos - d->globalPosition(); } diff --git a/src/gui/kernel/qwindow_p.h b/src/gui/kernel/qwindow_p.h index d918ed5b52..9b433bed76 100644 --- a/src/gui/kernel/qwindow_p.h +++ b/src/gui/kernel/qwindow_p.h @@ -113,7 +113,7 @@ public: void connectToScreen(QScreen *topLevelScreen); void disconnectFromScreen(); void emitScreenChangedRecursion(QScreen *newScreen); - QScreen *screenForGeometry(const QRect &rect); + QScreen *screenForGeometry(const QRect &rect) const; void setTransientParent(QWindow *parent); virtual void clearFocusObject(); |