summaryrefslogtreecommitdiffstats
path: root/src/gui
diff options
context:
space:
mode:
authorPaul Olav Tvete <paul.tvete@gmail.com>2015-05-04 17:48:18 +0200
committerPaul Olav Tvete <paul.tvete@gmail.com>2015-05-04 17:55:02 +0200
commitc05a8757b095cb554ea3e50f202a0683ca7d5bf7 (patch)
tree0cc94f6907d57030e7db4e67e59781c269ce9906 /src/gui
parent3110a6642cb9424069ad89666e3cca01d1d6b420 (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')
-rw-r--r--src/gui/kernel/qcursor.cpp4
-rw-r--r--src/gui/kernel/qguiapplication.cpp12
-rw-r--r--src/gui/kernel/qhighdpiscaling.cpp57
-rw-r--r--src/gui/kernel/qhighdpiscaling_p.h278
-rw-r--r--src/gui/kernel/qplatformscreen.cpp18
-rw-r--r--src/gui/kernel/qplatformscreen.h5
-rw-r--r--src/gui/kernel/qplatformwindow.cpp10
-rw-r--r--src/gui/kernel/qscreen_p.h8
-rw-r--r--src/gui/kernel/qwindow.cpp28
-rw-r--r--src/gui/kernel/qwindow_p.h1
-rw-r--r--src/gui/kernel/qwindowsysteminterface.cpp34
-rw-r--r--src/gui/kernel/qwindowsysteminterface_p.h2
-rw-r--r--src/gui/painting/qbackingstore.cpp9
13 files changed, 388 insertions, 78 deletions
diff --git a/src/gui/kernel/qcursor.cpp b/src/gui/kernel/qcursor.cpp
index 92e591f8ac..236b3b0565 100644
--- a/src/gui/kernel/qcursor.cpp
+++ b/src/gui/kernel/qcursor.cpp
@@ -180,7 +180,7 @@ QPoint QCursor::pos(const QScreen *screen)
{
if (screen)
if (const QPlatformCursor *cursor = screen->handle()->cursor())
- return QHighDpi::fromNativePixels(cursor->pos());
+ return QHighDpi::fromNativePixels(cursor->pos(), screen);
return QGuiApplicationPrivate::lastCursorPosition.toPoint();
}
@@ -232,7 +232,7 @@ void QCursor::setPos(QScreen *screen, int x, int y)
{
if (screen) {
if (QPlatformCursor *cursor = screen->handle()->cursor()) {
- const QPoint devicePos = QHighDpi::toNativePixels(QPoint(x, y));
+ const QPoint devicePos = QHighDpi::toNativePixels(QPoint(x, y), screen);
// Need to check, since some X servers generate null mouse move
// events, causing looping in applications which call setPos() on
// every mouse move event.
diff --git a/src/gui/kernel/qguiapplication.cpp b/src/gui/kernel/qguiapplication.cpp
index 1665909814..3415d015b7 100644
--- a/src/gui/kernel/qguiapplication.cpp
+++ b/src/gui/kernel/qguiapplication.cpp
@@ -957,10 +957,11 @@ QWindow *QGuiApplication::topLevelAt(const QPoint &pos)
QList<QScreen *>::const_iterator screen = screens.constBegin();
QList<QScreen *>::const_iterator end = screens.constEnd();
- const QPoint devicePosition = QHighDpi::toNativePixels(pos);
while (screen != end) {
- if ((*screen)->geometry().contains(pos))
+ if ((*screen)->geometry().contains(pos)) {
+ const QPoint devicePosition = QHighDpi::toNativePixels(pos, *screen);
return (*screen)->handle()->topLevelAt(devicePosition);
+ }
++screen;
}
return 0;
@@ -1814,7 +1815,7 @@ void QGuiApplicationPrivate::processMouseEvent(QWindowSystemInterfacePrivate::Mo
points << point;
QEvent::Type type;
- QList<QTouchEvent::TouchPoint> touchPoints = QWindowSystemInterfacePrivate::convertTouchPoints(points, &type);
+ QList<QTouchEvent::TouchPoint> touchPoints = QWindowSystemInterfacePrivate::convertTouchPoints(points, &type, window);
QWindowSystemInterfacePrivate::TouchEvent fake(window, e->timestamp, type, m_fakeTouchDevice, touchPoints, e->modifiers);
fake.flags |= QWindowSystemInterfacePrivate::WindowSystemEvent::Synthetic;
@@ -2025,6 +2026,11 @@ void QGuiApplicationPrivate::processWindowScreenChangedEvent(QWindowSystemInterf
window->d_func()->setTopLevelScreen(screen, false /* recreate */);
else // Fall back to default behavior, and try to find some appropriate screen
window->setScreen(0);
+ // we may have changed scaling, so trigger resize event if needed
+ if (window->handle()) {
+ QWindowSystemInterfacePrivate::GeometryChangeEvent gce(window, QHighDpi::fromNativePixels(window->handle()->geometry(), window), QRect());
+ processGeometryChangeEvent(&gce);
+ }
}
}
diff --git a/src/gui/kernel/qhighdpiscaling.cpp b/src/gui/kernel/qhighdpiscaling.cpp
index ff3f48b33f..54d06a8572 100644
--- a/src/gui/kernel/qhighdpiscaling.cpp
+++ b/src/gui/kernel/qhighdpiscaling.cpp
@@ -78,7 +78,7 @@ static inline qreal initialScaleFactor()
qreal QHighDpiScaling::m_factor = initialScaleFactor();
bool QHighDpiScaling::m_autoFactor = qgetenv("QT_SCALE_FACTOR").toLower() == "auto";
-bool QHighDpiScaling::m_active = !qFuzzyCompare(QHighDpiScaling::m_factor, qreal(1));
+bool QHighDpiScaling::m_active = m_autoFactor || !qFuzzyCompare(QHighDpiScaling::m_factor, qreal(1));
bool QHighDpiScaling::m_perWindowActive = false;
void QHighDpiScaling::setFactor(qreal factor)
@@ -104,6 +104,44 @@ void QHighDpiScaling::setWindowFactor(QWindow *window, qreal factor)
window->setProperty(scaleFactorProperty, QVariant(factor));
}
+
+/*
+
+QPoint QXcbScreen::mapToNative(const QPoint &pos) const
+{
+ const int dpr = int(devicePixelRatio());
+ return (pos - m_geometry.topLeft()) * dpr + m_nativeGeometry.topLeft();
+}
+
+QPoint QXcbScreen::mapFromNative(const QPoint &pos) const
+{
+ const int dpr = int(devicePixelRatio());
+ return (pos - m_nativeGeometry.topLeft()) / dpr + m_geometry.topLeft();
+}
+
+
+ */
+
+
+QPoint QHighDpiScaling::mapPositionToNative(const QPoint &pos, const QPlatformScreen *platformScreen)
+{
+ if (!platformScreen)
+ return pos;
+ const qreal scaleFactor = factor(platformScreen);
+ const QPoint topLeft = platformScreen->geometry().topLeft();
+ return (pos - topLeft) * scaleFactor + topLeft;
+}
+
+QPoint QHighDpiScaling::mapPositionFromNative(const QPoint &pos, const QPlatformScreen *platformScreen)
+{
+ if (!platformScreen)
+ return pos;
+ const qreal scaleFactor = factor(platformScreen);
+ const QPoint topLeft = platformScreen->geometry().topLeft();
+ return (pos - topLeft) / scaleFactor + topLeft;
+}
+
+
qreal QHighDpiScaling::factor(const QScreen *screen)
{
if (m_autoFactor && screen && screen->handle())
@@ -111,6 +149,12 @@ qreal QHighDpiScaling::factor(const QScreen *screen)
return m_factor;
}
+qreal QHighDpiScaling::factor(const QPlatformScreen *platformScreen)
+{
+ if (m_autoFactor && platformScreen)
+ return platformScreen->pixelDensity();
+ return m_factor;
+}
qreal QHighDpiScaling::factor(const QWindow *window)
{
@@ -124,6 +168,17 @@ qreal QHighDpiScaling::factor(const QWindow *window)
return f * (windowFactor.isValid() ? windowFactor.toReal() : 1);
}
+QPoint QHighDpiScaling::origin(const QScreen *screen)
+{
+ return screen->geometry().topLeft();
+}
+
+QPoint QHighDpiScaling::origin(const QPlatformScreen *platformScreen)
+{
+ return platformScreen->geometry().topLeft();
+}
+
+
Q_GUI_EXPORT QSize QHighDpi::toNativePixelsConstrained(const QSize &size, const QWindow *window)
{
const int width = size.width();
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
diff --git a/src/gui/kernel/qplatformscreen.cpp b/src/gui/kernel/qplatformscreen.cpp
index f545009f3a..bda7280e81 100644
--- a/src/gui/kernel/qplatformscreen.cpp
+++ b/src/gui/kernel/qplatformscreen.cpp
@@ -301,8 +301,8 @@ void QPlatformScreen::resizeMaximizedWindows()
// 'screen()' still has the old geometry info while 'this' has the new geometry info
const QRect oldGeometry = screen()->geometry();
const QRect oldAvailableGeometry = screen()->availableGeometry();
- const QRect newGeometry = QHighDpi::fromNativePixels(geometry());
- const QRect newAvailableGeometry = QHighDpi::fromNativePixels(availableGeometry());
+ const QRect newGeometry = deviceIndependentGeometry();
+ const QRect newAvailableGeometry = QHighDpi::fromNative(availableGeometry(), QHighDpiScaling::factor(this), newGeometry.topLeft());
// make sure maximized and fullscreen windows are updated
for (int i = 0; i < windows.size(); ++i) {
@@ -404,14 +404,24 @@ QRect QPlatformScreen::mapBetween(Qt::ScreenOrientation a, Qt::ScreenOrientation
return rect;
}
+QRect QPlatformScreen::deviceIndependentGeometry() const
+{
+ qreal scaleFactor = QHighDpiScaling::factor(this);
+ QRect nativeGeometry = geometry();
+ return QRect(nativeGeometry.topLeft(), QHighDpi::fromNative(nativeGeometry.size(), scaleFactor));
+}
+
+
QRect QPlatformScreen::screenGeometry() const
{
- return QHighDpi::toNativePixels(screen()->geometry());
+ qreal scaleFactor = QHighDpiScaling::factor(this);
+ QRect geometry = screen()->geometry();
+ return QRect(geometry.topLeft(), QHighDpi::toNative(geometry.size(), scaleFactor));
}
QRect QPlatformScreen::screenAvailableGeometry() const
{
- return QHighDpi::toNativePixels(screen()->availableGeometry());
+ return QHighDpi::toNativePixels(screen()->availableGeometry(), this);
}
/*!
diff --git a/src/gui/kernel/qplatformscreen.h b/src/gui/kernel/qplatformscreen.h
index 8dceef26eb..b7bd157717 100644
--- a/src/gui/kernel/qplatformscreen.h
+++ b/src/gui/kernel/qplatformscreen.h
@@ -122,7 +122,10 @@ public:
static QTransform transformBetween(Qt::ScreenOrientation a, Qt::ScreenOrientation b, const QRect &target);
static QRect mapBetween(Qt::ScreenOrientation a, Qt::ScreenOrientation b, const QRect &rect);
- // Screen property accessors. Platform plugins should use these
+ // The platform screen's geometry in device independent coordinates
+ QRect deviceIndependentGeometry() const;
+
+ // Accessors for QScreen geometry in native coordinates. Platform plugins should use these
// instead of accessing QScreen directly.
QRect screenGeometry() const;
QRect screenAvailableGeometry() const;
diff --git a/src/gui/kernel/qplatformwindow.cpp b/src/gui/kernel/qplatformwindow.cpp
index 22523ec21f..08f7cacc26 100644
--- a/src/gui/kernel/qplatformwindow.cpp
+++ b/src/gui/kernel/qplatformwindow.cpp
@@ -483,13 +483,17 @@ QString QPlatformWindow::formatWindowTitle(const QString &title, const QString &
QPlatformScreen *QPlatformWindow::screenForGeometry(const QRect &newGeometry) const
{
QPlatformScreen *currentScreen = screen();
- if (!parent() && currentScreen && !currentScreen->geometry().intersects(newGeometry)) {
+ QPlatformScreen *fallback = currentScreen;
+ QPoint center = newGeometry.center();
+ if (!parent() && currentScreen && !currentScreen->geometry().contains(center)) {
Q_FOREACH (QPlatformScreen* screen, currentScreen->virtualSiblings()) {
- if (screen->geometry().intersects(newGeometry))
+ if (screen->geometry().contains(center))
return screen;
+ if (screen->geometry().intersects(newGeometry))
+ fallback = screen;
}
}
- return currentScreen;
+ return fallback;
}
/*!
diff --git a/src/gui/kernel/qscreen_p.h b/src/gui/kernel/qscreen_p.h
index 45c8746131..7a5fc88068 100644
--- a/src/gui/kernel/qscreen_p.h
+++ b/src/gui/kernel/qscreen_p.h
@@ -61,8 +61,8 @@ public:
, orientationUpdateMask(0)
{
orientation = platformScreen->orientation();
- geometry = QHighDpi::fromNativePixels(platformScreen->geometry());
- availableGeometry = QHighDpi::fromNativePixels(platformScreen->availableGeometry());
+ geometry = platformScreen->deviceIndependentGeometry();
+ availableGeometry = QHighDpi::fromNative(platformScreen->availableGeometry(), QHighDpiScaling::factor(platformScreen), geometry.topLeft());
logicalDpi = platformScreen->logicalDpi();
refreshRate = platformScreen->refreshRate();
// safeguard ourselves against buggy platform behavior...
@@ -80,8 +80,8 @@ public:
void updateHighDpi()
{
- geometry = QHighDpi::fromNativePixels(platformScreen->geometry());
- availableGeometry = QHighDpi::fromNativePixels(platformScreen->availableGeometry());
+ geometry = platformScreen->deviceIndependentGeometry();
+ availableGeometry = QHighDpi::fromNative(platformScreen->availableGeometry(), QHighDpiScaling::factor(platformScreen), geometry.topLeft());
}
void updatePrimaryOrientation();
diff --git a/src/gui/kernel/qwindow.cpp b/src/gui/kernel/qwindow.cpp
index 920119464f..d29470b3ed 100644
--- a/src/gui/kernel/qwindow.cpp
+++ b/src/gui/kernel/qwindow.cpp
@@ -1432,7 +1432,13 @@ void QWindow::setGeometry(const QRect &rect)
d->positionPolicy = QWindowPrivate::WindowFrameExclusive;
if (d->platformWindow) {
- d->platformWindow->setGeometry(QHighDpi::toNativePixels(rect, this));
+ QRect nativeRect;
+ QScreen *newScreen = d->screenForGeometry(rect);
+ if (newScreen && isTopLevel())
+ nativeRect = QHighDpi::toNativePixels(rect, newScreen);
+ else
+ nativeRect = QHighDpi::toNativePixels(rect, this);
+ d->platformWindow->setGeometry(nativeRect);
} else {
d->geometry = rect;
@@ -1447,6 +1453,26 @@ void QWindow::setGeometry(const QRect &rect)
}
}
+//######### This logic duplicated three times!!!!!
+// equivalent to QPlatformWindow::screenForGeometry, but in platform independent coordinates
+QScreen *QWindowPrivate::screenForGeometry(const QRect &newGeometry)
+{
+ Q_Q(QWindow);
+ QScreen *currentScreen = q->screen();
+ QScreen *fallback = currentScreen;
+ QPoint center = newGeometry.center();
+ if (!q->parent() && currentScreen && !currentScreen->geometry().contains(center)) {
+ Q_FOREACH (QScreen* screen, currentScreen->virtualSiblings()) {
+ if (screen->geometry().contains(center))
+ return screen;
+ if (screen->geometry().intersects(newGeometry))
+ fallback = screen;
+ }
+ }
+ return fallback;
+}
+
+
/*!
Returns the geometry of the window, excluding its window frame.
diff --git a/src/gui/kernel/qwindow_p.h b/src/gui/kernel/qwindow_p.h
index 4fc63acf28..23a6d800c0 100644
--- a/src/gui/kernel/qwindow_p.h
+++ b/src/gui/kernel/qwindow_p.h
@@ -136,6 +136,7 @@ public:
void connectToScreen(QScreen *topLevelScreen);
void disconnectFromScreen();
void emitScreenChangedRecursion(QScreen *newScreen);
+ QScreen *screenForGeometry(const QRect &rect);
virtual void clearFocusObject();
virtual QRectF closestAcceptableGeometry(const QRectF &rect) const;
diff --git a/src/gui/kernel/qwindowsysteminterface.cpp b/src/gui/kernel/qwindowsysteminterface.cpp
index a08708269b..74d302dcbd 100644
--- a/src/gui/kernel/qwindowsysteminterface.cpp
+++ b/src/gui/kernel/qwindowsysteminterface.cpp
@@ -168,7 +168,7 @@ void QWindowSystemInterface::handleMouseEvent(QWindow *w, ulong timestamp, const
Qt::KeyboardModifiers mods, Qt::MouseEventSource source)
{
QWindowSystemInterfacePrivate::MouseEvent * e =
- new QWindowSystemInterfacePrivate::MouseEvent(w, timestamp, QHighDpi::fromNativePixels(local, w), QHighDpi::fromNativePixels(global, w), b, mods, source);
+ new QWindowSystemInterfacePrivate::MouseEvent(w, timestamp, QHighDpi::fromNativeLocalPosition(local, w), QHighDpi::fromNativePixels(global, w), b, mods, source);
QWindowSystemInterfacePrivate::handleWindowSystemEvent(e);
}
@@ -185,7 +185,7 @@ void QWindowSystemInterface::handleFrameStrutMouseEvent(QWindow *w, ulong timest
QWindowSystemInterfacePrivate::MouseEvent * e =
new QWindowSystemInterfacePrivate::MouseEvent(w, timestamp,
QWindowSystemInterfacePrivate::FrameStrutMouse,
- QHighDpi::fromNativePixels(local, w), QHighDpi::fromNativePixels(global, w), b, mods, source);
+ QHighDpi::fromNativeLocalPosition(local, w), QHighDpi::fromNativePixels(global, w), b, mods, source);
QWindowSystemInterfacePrivate::handleWindowSystemEvent(e);
}
@@ -366,14 +366,14 @@ void QWindowSystemInterface::handleWheelEvent(QWindow *tlw, ulong timestamp, con
// Simple case: vertical deltas only:
if (angleDelta.y() != 0 && angleDelta.x() == 0) {
- e = new QWindowSystemInterfacePrivate::WheelEvent(tlw, timestamp, QHighDpi::fromNativePixels(local, tlw), QHighDpi::fromNativePixels(global, tlw), pixelDelta, angleDelta, angleDelta.y(), Qt::Vertical, mods, phase, source);
+ e = new QWindowSystemInterfacePrivate::WheelEvent(tlw, timestamp, QHighDpi::fromNativeLocalPosition(local, tlw), QHighDpi::fromNativePixels(global, tlw), pixelDelta, angleDelta, angleDelta.y(), Qt::Vertical, mods, phase, source);
QWindowSystemInterfacePrivate::handleWindowSystemEvent(e);
return;
}
// Simple case: horizontal deltas only:
if (angleDelta.y() == 0 && angleDelta.x() != 0) {
- e = new QWindowSystemInterfacePrivate::WheelEvent(tlw, timestamp, QHighDpi::fromNativePixels(local, tlw), QHighDpi::fromNativePixels(global, tlw), pixelDelta, angleDelta, angleDelta.x(), Qt::Horizontal, mods, phase, source);
+ e = new QWindowSystemInterfacePrivate::WheelEvent(tlw, timestamp, QHighDpi::fromNativeLocalPosition(local, tlw), QHighDpi::fromNativePixels(global, tlw), pixelDelta, angleDelta, angleDelta.x(), Qt::Horizontal, mods, phase, source);
QWindowSystemInterfacePrivate::handleWindowSystemEvent(e);
return;
}
@@ -381,12 +381,12 @@ void QWindowSystemInterface::handleWheelEvent(QWindow *tlw, ulong timestamp, con
// Both horizontal and vertical deltas: Send two wheel events.
// The first event contains the Qt 5 pixel and angle delta as points,
// and in addition the Qt 4 compatibility vertical angle delta.
- e = new QWindowSystemInterfacePrivate::WheelEvent(tlw, timestamp, QHighDpi::fromNativePixels(local, tlw), QHighDpi::fromNativePixels(global, tlw), pixelDelta, angleDelta, angleDelta.y(), Qt::Vertical, mods, phase, source);
+ e = new QWindowSystemInterfacePrivate::WheelEvent(tlw, timestamp, QHighDpi::fromNativeLocalPosition(local, tlw), QHighDpi::fromNativePixels(global, tlw), pixelDelta, angleDelta, angleDelta.y(), Qt::Vertical, mods, phase, source);
QWindowSystemInterfacePrivate::handleWindowSystemEvent(e);
// The second event contains null pixel and angle points and the
// Qt 4 compatibility horizontal angle delta.
- e = new QWindowSystemInterfacePrivate::WheelEvent(tlw, timestamp, QHighDpi::fromNativePixels(local, tlw), QHighDpi::fromNativePixels(global, tlw), QPoint(), QPoint(), angleDelta.x(), Qt::Horizontal, mods, phase, source);
+ e = new QWindowSystemInterfacePrivate::WheelEvent(tlw, timestamp, QHighDpi::fromNativeLocalPosition(local, tlw), QHighDpi::fromNativePixels(global, tlw), QPoint(), QPoint(), angleDelta.x(), Qt::Horizontal, mods, phase, source);
QWindowSystemInterfacePrivate::handleWindowSystemEvent(e);
}
@@ -449,7 +449,7 @@ void QWindowSystemInterface::handleTouchEvent(QWindow *w, QTouchDevice *device,
handleTouchEvent(w, time, device, points, mods);
}
-QList<QTouchEvent::TouchPoint> QWindowSystemInterfacePrivate::convertTouchPoints(const QList<QWindowSystemInterface::TouchPoint> &points, QEvent::Type *type)
+QList<QTouchEvent::TouchPoint> QWindowSystemInterfacePrivate::convertTouchPoints(const QList<QWindowSystemInterface::TouchPoint> &points, QEvent::Type *type, const QWindow *window)
{
QList<QTouchEvent::TouchPoint> touchPoints;
Qt::TouchPointStates states;
@@ -464,16 +464,16 @@ QList<QTouchEvent::TouchPoint> QWindowSystemInterfacePrivate::convertTouchPoints
p.setState(point->state);
const QPointF screenPos = point->area.center();
- p.setScreenPos(QHighDpi::fromNativePixels(screenPos));
- p.setScreenRect(QHighDpi::fromNativePixels(point->area));
+ p.setScreenPos(QHighDpi::fromNativePixels(screenPos, window));
+ p.setScreenRect(QHighDpi::fromNativePixels(point->area, window));
// The local pos and rect are not set, they will be calculated
// when the event gets processed by QGuiApplication.
- p.setNormalizedPos(QHighDpi::fromNativePixels(point->normalPosition));
- p.setVelocity(QHighDpi::fromNativePixels(point->velocity));
+ p.setNormalizedPos(QHighDpi::fromNativePixels(point->normalPosition, window));
+ p.setVelocity(QHighDpi::fromNativePixels(point->velocity, window));
p.setFlags(point->flags);
- p.setRawScreenPositions(QHighDpi::fromNativePixels(point->rawPositions));
+ p.setRawScreenPositions(QHighDpi::fromNativePixels(point->rawPositions, window));
touchPoints.append(p);
++point;
@@ -501,7 +501,7 @@ void QWindowSystemInterface::handleTouchEvent(QWindow *tlw, ulong timestamp, QTo
return;
QEvent::Type type;
- QList<QTouchEvent::TouchPoint> touchPoints = QWindowSystemInterfacePrivate::convertTouchPoints(points, &type);
+ QList<QTouchEvent::TouchPoint> touchPoints = QWindowSystemInterfacePrivate::convertTouchPoints(points, &type, tlw);
QWindowSystemInterfacePrivate::TouchEvent *e =
new QWindowSystemInterfacePrivate::TouchEvent(tlw, timestamp, type, device, touchPoints, mods);
@@ -534,7 +534,7 @@ void QWindowSystemInterface::handleScreenOrientationChange(QScreen *screen, Qt::
void QWindowSystemInterface::handleScreenGeometryChange(QScreen *screen, const QRect &geometry, const QRect &availableGeometry)
{
QWindowSystemInterfacePrivate::ScreenGeometryEvent *e =
- new QWindowSystemInterfacePrivate::ScreenGeometryEvent(screen, QHighDpi::fromNativePixels(geometry), QHighDpi::fromNativePixels(availableGeometry));
+ new QWindowSystemInterfacePrivate::ScreenGeometryEvent(screen, QHighDpi::fromNativeScreenGeometry(geometry, screen), QHighDpi::fromNative(availableGeometry, screen, geometry.topLeft()));
QWindowSystemInterfacePrivate::handleWindowSystemEvent(e);
}
@@ -560,7 +560,7 @@ void QWindowSystemInterface::handleThemeChange(QWindow *tlw)
void QWindowSystemInterface::handleExposeEvent(QWindow *tlw, const QRegion &region)
{
- QWindowSystemInterfacePrivate::ExposeEvent *e = new QWindowSystemInterfacePrivate::ExposeEvent(tlw, QHighDpi::fromNativePixels(region, tlw));
+ QWindowSystemInterfacePrivate::ExposeEvent *e = new QWindowSystemInterfacePrivate::ExposeEvent(tlw, QHighDpi::fromNativeLocalRegion(region, tlw));
QWindowSystemInterfacePrivate::handleWindowSystemEvent(e);
}
@@ -667,7 +667,7 @@ void QWindowSystemInterface::handleTabletEvent(QWindow *w, ulong timestamp, cons
{
QWindowSystemInterfacePrivate::TabletEvent *e =
new QWindowSystemInterfacePrivate::TabletEvent(w,timestamp,
- QHighDpi::fromNativePixels(local, w),
+ QHighDpi::fromNativeLocalPosition(local, w),
QHighDpi::fromNativePixels(global, w),
device, pointerType, buttons, pressure,
xTilt, yTilt, tangentialPressure, rotation, z, uid, modifiers);
@@ -797,7 +797,7 @@ Q_GUI_EXPORT QDebug operator<<(QDebug dbg, const QWindowSystemInterface::TouchPo
Q_GUI_EXPORT void qt_handleMouseEvent(QWindow *w, const QPointF & local, const QPointF & global, Qt::MouseButtons b, Qt::KeyboardModifiers mods = Qt::NoModifier) {
- QWindowSystemInterface::handleMouseEvent(w, QHighDpi::toNativePixels(local, w), QHighDpi::toNativePixels(global, w), b, mods);
+ QWindowSystemInterface::handleMouseEvent(w, QHighDpi::toNativeLocalPosition(local, w), QHighDpi::toNativePixels(global, w), b, mods);
}
Q_GUI_EXPORT void qt_handleKeyEvent(QWindow *w, QEvent::Type t, int k, Qt::KeyboardModifiers mods, const QString & text = QString(), bool autorep = false, ushort count = 1)
diff --git a/src/gui/kernel/qwindowsysteminterface_p.h b/src/gui/kernel/qwindowsysteminterface_p.h
index 2ec402a1e9..0c87c191f3 100644
--- a/src/gui/kernel/qwindowsysteminterface_p.h
+++ b/src/gui/kernel/qwindowsysteminterface_p.h
@@ -486,7 +486,7 @@ public:
static QWaitCondition eventsFlushed;
static QMutex flushEventMutex;
- static QList<QTouchEvent::TouchPoint> convertTouchPoints(const QList<QWindowSystemInterface::TouchPoint> &points, QEvent::Type *type);
+ static QList<QTouchEvent::TouchPoint> convertTouchPoints(const QList<QWindowSystemInterface::TouchPoint> &points, QEvent::Type *type, const QWindow *window);
};
QT_END_NAMESPACE
diff --git a/src/gui/painting/qbackingstore.cpp b/src/gui/painting/qbackingstore.cpp
index cff99722f3..65a108f7ee 100644
--- a/src/gui/painting/qbackingstore.cpp
+++ b/src/gui/painting/qbackingstore.cpp
@@ -106,7 +106,7 @@ void QBackingStore::flush(const QRegion &region, QWindow *win, const QPoint &off
}
#endif
- d_ptr->platformBackingStore->flush(win, QHighDpi::toNativePixels(region, d_ptr->window), offset);
+ d_ptr->platformBackingStore->flush(win, QHighDpi::toNativeLocalRegion(region, d_ptr->window), offset);
}
/*!
@@ -182,7 +182,10 @@ QWindow* QBackingStore::window() const
void QBackingStore::beginPaint(const QRegion &region)
{
- d_ptr->platformBackingStore->beginPaint(QHighDpi::toNativePixels(region, d_ptr->window));
+ if (d_ptr->highDpiBackingstore &&
+ d_ptr->highDpiBackingstore->devicePixelRatio() != d_ptr->window->devicePixelRatio())
+ resize(size());
+ d_ptr->platformBackingStore->beginPaint(QHighDpi::toNativeLocalRegion(region, d_ptr->window));
}
/*!
@@ -226,7 +229,7 @@ bool QBackingStore::scroll(const QRegion &area, int dx, int dy)
Q_UNUSED(dx);
Q_UNUSED(dy);
- return d_ptr->platformBackingStore->scroll(QHighDpi::toNativePixels(area, d_ptr->window), QHighDpi::toNativePixels(dx, d_ptr->window), QHighDpi::toNativePixels(dy, d_ptr->window));
+ return d_ptr->platformBackingStore->scroll(QHighDpi::toNativeLocalRegion(area, d_ptr->window), QHighDpi::toNativePixels(dx, d_ptr->window), QHighDpi::toNativePixels(dy, d_ptr->window));
}
void QBackingStore::setStaticContents(const QRegion &region)