diff options
author | Paul Olav Tvete <paul.tvete@gmail.com> | 2015-05-04 17:48:18 +0200 |
---|---|---|
committer | Paul Olav Tvete <paul.tvete@gmail.com> | 2015-05-04 17:55:02 +0200 |
commit | c05a8757b095cb554ea3e50f202a0683ca7d5bf7 (patch) | |
tree | 0cc94f6907d57030e7db4e67e59781c269ce9906 /src/gui/kernel/qhighdpiscaling_p.h | |
parent | 3110a6642cb9424069ad89666e3cca01d1d6b420 (diff) |
Multi-screen fixes
Various fixes, including:
* Resize backingstore properly if screen has changed
* Trigger resize event on screen change if necessary
* Fix yet another race condition in screen detection
* Trying to fix screen mapping
Not completely finished, but I think it's better to
keep in sync, and not diverge too much.
Diffstat (limited to 'src/gui/kernel/qhighdpiscaling_p.h')
-rw-r--r-- | src/gui/kernel/qhighdpiscaling_p.h | 278 |
1 files changed, 240 insertions, 38 deletions
diff --git a/src/gui/kernel/qhighdpiscaling_p.h b/src/gui/kernel/qhighdpiscaling_p.h index b29748fd29..f9b7b94a6f 100644 --- a/src/gui/kernel/qhighdpiscaling_p.h +++ b/src/gui/kernel/qhighdpiscaling_p.h @@ -49,6 +49,7 @@ #include <QtCore/qloggingcategory.h> #include <QtGui/qregion.h> #include <QtGui/qscreen.h> +#include <QtGui/qwindow.h> // This file implmements utility functions for high-dpi scaling on operating // systems that do not provide native scaling support. @@ -77,11 +78,19 @@ QT_BEGIN_NAMESPACE Q_DECLARE_LOGGING_CATEGORY(lcScaling); +class QScreen; +class QPlatformScreen; + class Q_GUI_EXPORT QHighDpiScaling { public: static bool isActive() { return m_active; } static qreal factor(const QWindow *window); static qreal factor(const QScreen *screen); + 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 void setFactor(qreal factor); static void setWindowFactor(QWindow *window, qreal factor); private: @@ -97,112 +106,283 @@ private: namespace QHighDpi { -inline QRect fromNativePixels(const QRect &pixelRect, const QWindow *window = 0) +// inline QRect fromNativeGeometry(const QRect &pixelRect, const QPlatformScreen *platformScreen) +// { +// return QRect(pixelRect.topLeft(), pixelRect.size() / QHighDpiScaling::factor(platformScreen)); +// } + +// inline QRect toNativeGeometry(const QRect &pointRect, const QPlatformScreen *platformScreen) +// { +// return QRect(pointRect.topLeft(), pointRect.size() * QHighDpiScaling::factor(platformScreen)); +// } + +inline QPoint fromNative(const QPoint &pos, qreal scaleFactor, const QPoint &origin) { - const qreal scaleFactor = QHighDpiScaling::factor(window); - return QRect(pixelRect.topLeft() / scaleFactor, pixelRect.size() / scaleFactor); + return (pos - origin) / scaleFactor + origin; +} + +inline QPoint toNative(const QPoint &pos, qreal scaleFactor, const QPoint &origin) +{ + return (pos - origin) * scaleFactor + origin; +} + +inline QPoint fromNative(const QPoint &pos, qreal scaleFactor) +{ + return pos / scaleFactor; +} + +inline QPoint toNative(const QPoint &pos, qreal scaleFactor) +{ + return pos * scaleFactor; +} + +inline QSize fromNative(const QSize &size, qreal scaleFactor) +{ + return size / scaleFactor; // TODO: ### round up ### +} + +inline QSize toNative(const QSize &size, qreal scaleFactor) +{ + return size * scaleFactor; +} + +inline QRect fromNative(const QRect &rect, qreal scaleFactor, const QPoint &origin) +{ + return QRect(fromNative(rect.topLeft(), scaleFactor, origin), fromNative(rect.size(), scaleFactor)); } -inline QRect toNativePixels(const QRect &pointRect, const QWindow *window = 0) +inline QRect toNative(const QRect &rect, qreal scaleFactor, const QPoint &origin) +{ + return QRect(toNative(rect.topLeft(), scaleFactor, origin), toNative(rect.size(), scaleFactor)); + +} + + +inline QRect fromNative(const QRect &rect, const QScreen *screen, const QPoint &screenOrigin) +{ + return toNative(rect, QHighDpiScaling::factor(screen), screenOrigin); +} + +inline QRect fromNativeScreenGeometry(const QRect &nativeScreenGeometry, const QScreen *screen) +{ + return QRect(nativeScreenGeometry.topLeft(), fromNative(nativeScreenGeometry.size(), QHighDpiScaling::factor(screen))); +} + +inline QPointF fromNativeLocalPosition(const QPointF &pos, const QWindow *window) { const qreal scaleFactor = QHighDpiScaling::factor(window); - return QRect(pointRect.topLeft() * scaleFactor, pointRect.size() * scaleFactor); + return pos / scaleFactor; } -inline QRectF fromNativePixels(const QRectF &pixelRect, const QWindow *window = 0) +inline QPointF toNativeLocalPosition(const QPointF &pos, const QWindow *window) { const qreal scaleFactor = QHighDpiScaling::factor(window); - return QRectF(pixelRect.topLeft() / scaleFactor, pixelRect.size() / scaleFactor); + return pos * scaleFactor; +} + +inline QRect fromNativePixels(const QRect &pixelRect, const QPlatformScreen *platformScreen) +{ + const qreal scaleFactor = QHighDpiScaling::factor(platformScreen); + const QPoint origin = QHighDpiScaling::origin(platformScreen); + return QRect(fromNative(pixelRect.topLeft(), scaleFactor, origin), + fromNative(pixelRect.size(), scaleFactor)); } -inline QRectF toNativePixels(const QRectF &pointRect, const QWindow *window = 0) +inline QRect toNativePixels(const QRect &pointRect, const QPlatformScreen *platformScreen) { - const qreal scaleFactor = QHighDpiScaling::factor(window); - return QRectF(pointRect.topLeft() * scaleFactor, pointRect.size() * scaleFactor); + const qreal scaleFactor = QHighDpiScaling::factor(platformScreen); + const QPoint origin = QHighDpiScaling::origin(platformScreen); + return QRect(toNative(pointRect.topLeft(), scaleFactor, origin), + toNative(pointRect.size(), scaleFactor)); } -inline QSize fromNativePixels(const QSize &pixelSize, const QWindow *window = 0) +inline QRect fromNativePixels(const QRect &pixelRect, const QScreen *screen) +{ + const qreal scaleFactor = QHighDpiScaling::factor(screen); + const QPoint origin = QHighDpiScaling::origin(screen); + return QRect(fromNative(pixelRect.topLeft(), scaleFactor, origin), + fromNative(pixelRect.size(), scaleFactor)); +} + +inline QRect toNativePixels(const QRect &pointRect, const QScreen *screen) +{ + const qreal scaleFactor = QHighDpiScaling::factor(screen); + const QPoint origin = QHighDpiScaling::origin(screen); + return QRect(toNative(pointRect.topLeft(), scaleFactor, origin), + toNative(pointRect.size(), scaleFactor)); +} + +inline QRect fromNativePixels(const QRect &pixelRect, const QWindow *window) +{ + if (window->isTopLevel() && window->screen()) { + return fromNativePixels(pixelRect, window->screen()); + } else { + const qreal scaleFactor = QHighDpiScaling::factor(window); + return QRect(pixelRect.topLeft() / scaleFactor, fromNative(pixelRect.size(), scaleFactor)); + } +} + +inline QRectF toNativePixels(const QRectF &pointRect, const QScreen *screen) +{ + //######## + return toNativePixels(pointRect.toRect(), screen); +} + +inline QRect toNativePixels(const QRect &pointRect, const QWindow *window) +{ + if (window->isTopLevel() && window->screen()) { + return toNativePixels(pointRect, window->screen()); + } else { + const qreal scaleFactor = QHighDpiScaling::factor(window); + return QRect(pointRect.topLeft() * scaleFactor, toNative(pointRect.size(), scaleFactor)); + } +} + +inline QRectF fromNativePixels(const QRectF &pixelRect, const QScreen *screen) +{ + //######## + return fromNativePixels(pixelRect.toRect(), screen); +} + +inline QRectF fromNativePixels(const QRectF &pixelRect, const QWindow *window) +{ + if (window->isTopLevel() && window->screen()) { + return fromNativePixels(pixelRect, window->screen()); + } else { + const qreal scaleFactor = QHighDpiScaling::factor(window); + return QRectF(pixelRect.topLeft() / scaleFactor, pixelRect.size() / scaleFactor); + } +} + +inline QRectF toNativePixels(const QRectF &pointRect, const QWindow *window) +{ + if (window->isTopLevel() && window->screen()) { + return toNativePixels(pointRect, window->screen()); + } else { + const qreal scaleFactor = QHighDpiScaling::factor(window); + return QRectF(pointRect.topLeft() * scaleFactor, pointRect.size() * scaleFactor); + } +} + +inline QSize fromNativePixels(const QSize &pixelSize, const QWindow *window) { return pixelSize / QHighDpiScaling::factor(window); } // For converting minimum/maximum sizes of QWindow, limits to 0..QWINDOWSIZE_MAX -Q_GUI_EXPORT QSize toNativePixelsConstrained(const QSize &size, const QWindow *window = 0); +Q_GUI_EXPORT QSize toNativePixelsConstrained(const QSize &size, const QWindow *window); -inline QSize toNativePixels(const QSize &pointSize, const QWindow *window = 0) +inline QSize toNativePixels(const QSize &pointSize, const QWindow *window) { return pointSize * QHighDpiScaling::factor(window); } -inline QSizeF fromNativePixels(const QSizeF &pixelSize, const QWindow *window = 0) +inline QSizeF fromNativePixels(const QSizeF &pixelSize, const QWindow *window) { return pixelSize / QHighDpiScaling::factor(window); } -inline QSizeF toNativePixels(const QSizeF &pointSize, const QWindow *window = 0) +inline QSizeF toNativePixels(const QSizeF &pointSize, const QWindow *window) { return pointSize * QHighDpiScaling::factor(window); } -inline QPoint fromNativePixels(const QPoint &pixelPoint, const QWindow *window = 0) +inline QPoint fromNativePixels(const QPoint &pixelPoint, const QScreen *screen) +{ + return fromNative(pixelPoint, QHighDpiScaling::factor(screen), QHighDpiScaling::origin(screen)); +} + +inline QPoint fromNativePixels(const QPoint &pixelPoint, const QWindow *window) +{ + if (window->isTopLevel() && window->screen()) + return fromNativePixels(pixelPoint, window->screen()); + else + return pixelPoint / QHighDpiScaling::factor(window); +} + +inline QPoint toNativePixels(const QPoint &pointPoint, const QScreen *screen) +{ + return toNative(pointPoint, QHighDpiScaling::factor(screen), QHighDpiScaling::origin(screen)); +} + +inline QPoint toNativePixels(const QPoint &pointPoint, const QWindow *window) +{ + if (window->isTopLevel() && window->screen()) + return toNativePixels(pointPoint, window->screen()); + else + return pointPoint * QHighDpiScaling::factor(window); +} + +inline QPointF fromNativePixels(const QPointF &pixelPoint, const QScreen *screen) { - return pixelPoint / QHighDpiScaling::factor(window); + return fromNativePixels(pixelPoint.toPoint(), screen); //############### } -inline QPoint toNativePixels(const QPoint &pointPoint, const QWindow *window = 0) +inline QPointF fromNativePixels(const QPointF &pixelPoint, const QWindow *window) { - return pointPoint * QHighDpiScaling::factor(window); + if (window->isTopLevel() && window->screen()) + return fromNativePixels(pixelPoint, window->screen()); + else + return pixelPoint / QHighDpiScaling::factor(window); } -inline QPointF fromNativePixels(const QPointF &pixelPoint, const QWindow *window = 0) +inline QPointF toNativePixels(const QPointF &pointPoint, const QScreen *screen) { - return pixelPoint / QHighDpiScaling::factor(window); + return toNativePixels(pointPoint.toPoint(), screen); //########### } -inline QPointF toNativePixels(const QPointF &pointPoint, const QWindow *window = 0) +inline QPointF toNativePixels(const QPointF &pointPoint, const QWindow *window) { - return pointPoint * QHighDpiScaling::factor(window); + if (window->isTopLevel() && window->screen()) + return toNativePixels(pointPoint, window->screen()); + else + return pointPoint * QHighDpiScaling::factor(window); } -inline QMargins fromNativePixels(const QMargins &pixelMargins, const QWindow *window = 0) +inline QMargins fromNativePixels(const QMargins &pixelMargins, const QWindow *window) { const qreal scaleFactor = QHighDpiScaling::factor(window); return QMargins(pixelMargins.left() / scaleFactor, pixelMargins.top() / scaleFactor, pixelMargins.right() / scaleFactor, pixelMargins.bottom() / scaleFactor); } -inline QMargins toNativePixels(const QMargins &pointMargins, const QWindow *window = 0) +inline QMargins toNativePixels(const QMargins &pointMargins, const QWindow *window) { const qreal scaleFactor = QHighDpiScaling::factor(window); return QMargins(pointMargins.left() * scaleFactor, pointMargins.top() * scaleFactor, pointMargins.right() * scaleFactor, pointMargins.bottom() * scaleFactor); } - -inline QRegion fromNativePixels(const QRegion &pixelRegion, const QWindow *window = 0) +#if 1 + //############## expose regions need special handling +inline QRegion fromNativeLocalRegion(const QRegion &pixelRegion, const QWindow *window) { if (!QHighDpiScaling::isActive()) return pixelRegion; + qreal scaleFactor = QHighDpiScaling::factor(window); QRegion pointRegion; foreach (const QRect &rect, pixelRegion.rects()) - pointRegion += fromNativePixels(rect, window); + pointRegion += QRect(fromNative(rect.topLeft(), scaleFactor), + fromNative(rect.size(), scaleFactor)); return pointRegion; } -inline QRegion toNativePixels(const QRegion &pointRegion, const QWindow *window = 0) +inline QRegion toNativeLocalRegion(const QRegion &pointRegion, const QWindow *window) { if (!QHighDpiScaling::isActive()) return pointRegion; + qreal scaleFactor = QHighDpiScaling::factor(window); QRegion pixelRegon; foreach (const QRect &rect, pointRegion.rects()) - pixelRegon += toNativePixels(rect, window); + pixelRegon += QRect(toNative(rect.topLeft(), scaleFactor), + toNative(rect.size(), scaleFactor)); return pixelRegon; } - +#endif // Any T that has operator/() template <typename T> -T fromNativePixels(const T &pixelValue, const QWindow *window = 0) +T fromNativePixels(const T &pixelValue, const QWindow *window) { if (!QHighDpiScaling::isActive()) return pixelValue; @@ -211,9 +391,20 @@ T fromNativePixels(const T &pixelValue, const QWindow *window = 0) } + //##### ????? +template <typename T> +T fromNativePixels(const T &pixelValue, const QScreen *screen) +{ + if (!QHighDpiScaling::isActive()) + return pixelValue; + + return pixelValue / QHighDpiScaling::factor(screen); + +} + // Any T that has operator*() template <typename T> -T toNativePixels(const T &pointValue, const QWindow *window = 0) +T toNativePixels(const T &pointValue, const QWindow *window) { if (!QHighDpiScaling::isActive()) return pointValue; @@ -221,9 +412,19 @@ T toNativePixels(const T &pointValue, const QWindow *window = 0) return pointValue * QHighDpiScaling::factor(window); } +template <typename T> +T toNativePixels(const T &pointValue, const QScreen *screen) +{ + if (!QHighDpiScaling::isActive()) + return pointValue; + + return pointValue * QHighDpiScaling::factor(screen); +} + + // Any QVector<T> where T has operator/() template <typename T> -QVector<T> fromNativePixels(const QVector<T> &pixelValues, const QWindow *window = 0) +QVector<T> fromNativePixels(const QVector<T> &pixelValues, const QWindow *window) { if (!QHighDpiScaling::isActive()) return pixelValues; @@ -236,7 +437,7 @@ QVector<T> fromNativePixels(const QVector<T> &pixelValues, const QWindow *window // Any QVector<T> where T has operator*() template <typename T> -QVector<T> toNativePixels(const QVector<T> &pointValues, const QWindow *window = 0) +QVector<T> toNativePixels(const QVector<T> &pointValues, const QWindow *window) { if (!QHighDpiScaling::isActive()) return pointValues; @@ -247,10 +448,10 @@ QVector<T> toNativePixels(const QVector<T> &pointValues, const QWindow *window = return pixelValues; } - +#if 0 // Any QPair<T, U> where T and U has operator/() template <typename T, typename U> -QPair<T, U> fromNativePixels(const QPair<T, U> &pixelPair, const QWindow *window = 0) +QPair<T, U> fromNativePixels(const QPair<T, U> &pixelPair, const QWindow *window) { return qMakePair(fromNativePixels(pixelPair.first, window), fromNativePixels(pixelPair.second, window)); @@ -258,11 +459,12 @@ QPair<T, U> fromNativePixels(const QPair<T, U> &pixelPair, const QWindow *window // Any QPair<T, U> where T and U has operator*() template <typename T, typename U> -QPair<T, U> toNativePixels(const QPair<T, U> &pointPair, const QWindow *window = 0) +QPair<T, U> toNativePixels(const QPair<T, U> &pointPair, const QWindow *window) { return qMakePair(QHighDpi::toNativePixels(pointPair.first, window), QHighDpi::toNativePixels(pointPair.second, window)); } +#endif } QT_END_NAMESPACE |