summaryrefslogtreecommitdiffstats
path: root/src/gui/kernel
diff options
context:
space:
mode:
authorMorten Johan Sørvig <morten.sorvig@digia.com>2014-05-21 13:52:53 +0200
committerMorten Johan Sørvig <morten.sorvig@digia.com>2015-03-26 11:00:14 +0100
commit70f565b6e43b6ab93b01112286a40869155207c8 (patch)
treeed4c7fee3fdc5a25bce1041e9aa4616155b8eabd /src/gui/kernel
parent3cede847c39269374c52dcf156dc982d7a51f29c (diff)
WIP: Add platform independent high-dpi support to QtGui
Add coordinate scaling support to the QWindow/ QWindowSystemInterface layer. The scale factor can be set with the QT_HIGHDPI_SCALE_FACTOR environment variable. Setting a scale factor different than the default (1) now has the following effects: QWindow::devicePixelRatio is set accordingly, enabling the high-dpi code paths. QWindow and related classes now return geometry in device independent pixels. This includes screen, desktop and window geometry as well as event coordinates. The platform plugins continue to operate in device pixels, unaware of the scaling. Task-number: QTBUG-38858 Change-Id: I85b0d1bc682b25196f6db286e672a64f8da0ae5c
Diffstat (limited to 'src/gui/kernel')
-rw-r--r--src/gui/kernel/kernel.pri8
-rw-r--r--src/gui/kernel/qcursor.cpp9
-rw-r--r--src/gui/kernel/qguiapplication.cpp3
-rw-r--r--src/gui/kernel/qhighdpiscaling.cpp102
-rw-r--r--src/gui/kernel/qhighdpiscaling_p.h251
-rw-r--r--src/gui/kernel/qscreen.cpp2
-rw-r--r--src/gui/kernel/qscreen.h1
-rw-r--r--src/gui/kernel/qscreen_p.h18
-rw-r--r--src/gui/kernel/qwindow.cpp17
-rw-r--r--src/gui/kernel/qwindowsysteminterface.cpp45
10 files changed, 418 insertions, 38 deletions
diff --git a/src/gui/kernel/kernel.pri b/src/gui/kernel/kernel.pri
index af6a417608..73a5a7b6ab 100644
--- a/src/gui/kernel/kernel.pri
+++ b/src/gui/kernel/kernel.pri
@@ -75,7 +75,9 @@ HEADERS += \
kernel/qplatformgraphicsbuffer.h \
kernel/qplatformgraphicsbufferhelper.h \
kernel/qinputdevicemanager_p.h \
- kernel/qinputdevicemanager_p_p.h
+ kernel/qinputdevicemanager_p_p.h \
+ kernel/qhighdpiscaling_p.h
+
SOURCES += \
kernel/qgenericpluginfactory.cpp \
@@ -131,7 +133,9 @@ SOURCES += \
kernel/qrasterwindow.cpp \
kernel/qplatformgraphicsbuffer.cpp \
kernel/qplatformgraphicsbufferhelper.cpp \
- kernel/qinputdevicemanager.cpp
+ kernel/qinputdevicemanager.cpp \
+ kernel/qhighdpiscaling.cpp
+
contains(QT_CONFIG, opengl)|contains(QT_CONFIG, opengles2) {
HEADERS += \
diff --git a/src/gui/kernel/qcursor.cpp b/src/gui/kernel/qcursor.cpp
index 7e073370f2..e6bf2b0be9 100644
--- a/src/gui/kernel/qcursor.cpp
+++ b/src/gui/kernel/qcursor.cpp
@@ -43,6 +43,7 @@
#include <qpa/qplatformcursor.h>
#include <private/qguiapplication_p.h>
+#include <private/qhighdpiscaling_p.h>
QT_BEGIN_NAMESPACE
@@ -179,7 +180,7 @@ QPoint QCursor::pos(const QScreen *screen)
{
if (screen)
if (const QPlatformCursor *cursor = screen->handle()->cursor())
- return cursor->pos();
+ return qHighDpiToDeviceIndependentPixels(cursor->pos());
return QGuiApplicationPrivate::lastCursorPosition.toPoint();
}
@@ -231,12 +232,12 @@ void QCursor::setPos(QScreen *screen, int x, int y)
{
if (screen) {
if (QPlatformCursor *cursor = screen->handle()->cursor()) {
- const QPoint pos = QPoint(x, y);
+ const QPoint devicePos = qHighDpiToDevicePixels(QPoint(x, y));
// Need to check, since some X servers generate null mouse move
// events, causing looping in applications which call setPos() on
// every mouse move event.
- if (pos != cursor->pos())
- cursor->setPos(pos);
+ if (devicePos != cursor->pos())
+ cursor->setPos(devicePos);
}
}
}
diff --git a/src/gui/kernel/qguiapplication.cpp b/src/gui/kernel/qguiapplication.cpp
index 3d21b4affc..7b8d5f823e 100644
--- a/src/gui/kernel/qguiapplication.cpp
+++ b/src/gui/kernel/qguiapplication.cpp
@@ -957,9 +957,10 @@ QWindow *QGuiApplication::topLevelAt(const QPoint &pos)
QList<QScreen *>::const_iterator screen = screens.constBegin();
QList<QScreen *>::const_iterator end = screens.constEnd();
+ const QPoint devicePosition = qHighDpiToDevicePixels(pos);
while (screen != end) {
if ((*screen)->geometry().contains(pos))
- return (*screen)->handle()->topLevelAt(pos);
+ return (*screen)->handle()->topLevelAt(devicePosition);
++screen;
}
return 0;
diff --git a/src/gui/kernel/qhighdpiscaling.cpp b/src/gui/kernel/qhighdpiscaling.cpp
new file mode 100644
index 0000000000..6cdfd93860
--- /dev/null
+++ b/src/gui/kernel/qhighdpiscaling.cpp
@@ -0,0 +1,102 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qhighdpiscaling_p.h"
+#include "qwindow_p.h" // for QWINDOWSIZE_MAX
+#include "qguiapplication.h"
+#include "qscreen.h"
+#include "private/qscreen_p.h"
+
+#include <QtCore/qdebug.h>
+
+QT_BEGIN_NAMESPACE
+
+static inline qreal initialScaleFactor()
+{
+ static const char envVar[] = "QT_HIGHDPI_SCALE_FACTOR";
+ qreal result = 1;
+ if (qEnvironmentVariableIsSet(envVar)) {
+ bool ok;
+ const qreal f = qgetenv(envVar).toDouble(&ok);
+ if (ok && f > 0)
+ result = f;
+ }
+ return result;
+}
+
+/*!
+ \class QHighDpiScaling
+ \since 5.4
+ \internal
+ \preliminary
+ \ingroup qpa
+
+ \brief Collection of utility functions for UI scaling.
+*/
+
+qreal QHighDpiScaling::m_factor = initialScaleFactor();
+bool QHighDpiScaling::m_active = !qFuzzyCompare(QHighDpiScaling::m_factor, qreal(1));
+
+void QHighDpiScaling::setFactor(qreal factor)
+{
+ if (qFuzzyCompare(factor, QHighDpiScaling::m_factor))
+ return;
+ if (!QGuiApplication::allWindows().isEmpty()) {
+ qWarning() << Q_FUNC_INFO << "QHighDpiScaling::setFactor: Should only be called when no windows exist.";
+ }
+
+ QHighDpiScaling::m_active = !qFuzzyCompare(factor, qreal(1));
+ QHighDpiScaling::m_factor = QHighDpiScaling::m_active ? factor : qreal(1);
+ Q_FOREACH (QScreen *screen, QGuiApplication::screens())
+ screen->d_func()->updateHighDpi();
+}
+
+Q_GUI_EXPORT QSize qHighDpiToDevicePixelsConstrained(const QSize &size)
+{
+ const int width = size.width();
+ const int height = size.height();
+ return QSize(width > 0 && width < QWINDOWSIZE_MAX ?
+ qHighDpiToDevicePixels(width) : width,
+ height > 0 && height < QWINDOWSIZE_MAX ?
+ qHighDpiToDevicePixels(height) : height);
+}
+
+QT_END_NAMESPACE
diff --git a/src/gui/kernel/qhighdpiscaling_p.h b/src/gui/kernel/qhighdpiscaling_p.h
new file mode 100644
index 0000000000..44382b7e88
--- /dev/null
+++ b/src/gui/kernel/qhighdpiscaling_p.h
@@ -0,0 +1,251 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QHIGHDPISCALING_P_H
+#define QHIGHDPISCALING_P_H
+
+#include <QtCore/qglobal.h>
+#include <QtCore/qmargins.h>
+#include <QtCore/qrect.h>
+#include <QtCore/qvector.h>
+#include <QtGui/qregion.h>
+
+// This file implmements utility functions for high-dpi scaling on operating
+// systems that do not provide native scaling support.
+//
+// The functions support creating a logical device-independent
+// coordinate system which is related to the device pixel coordinate
+// through a scaling factor. The scaling factor is set by the
+// QT_HIGHDPI_SCALE_FACTOR environment variable.
+//
+// With these functions in use most of the Qt API will then operate in
+// the device-independent coordinate system. For example, setting
+// the scale factor to 2.0 will make Qt see half of the "device"
+// window geometry. Desktop and event geometry will be scaled
+// to match.
+//
+// Integer scaling factors work best. Glitch-free graphics at non-integer
+// scaling factors can not be guaranteed.
+
+QT_BEGIN_NAMESPACE
+
+class Q_GUI_EXPORT QHighDpiScaling {
+public:
+ static bool isActive() { return m_active; }
+ static qreal factor() { return m_factor; }
+ static void setFactor(qreal factor);
+
+private:
+ static qreal m_factor;
+ static bool m_active;
+};
+
+// Coordinate system conversion functions:
+// qHighDpiToDeviceIndependentPixels : from physical(screen/backing) to logical pixels
+// qHighDpiToDevicePixels : from logical to physical pixels
+inline QRect qHighDpiToDeviceIndependentPixels(const QRect &pixelRect)
+{
+ const qreal scaleFactor = QHighDpiScaling::factor();
+ return QRect(pixelRect.topLeft() / scaleFactor, pixelRect.size() / scaleFactor);
+}
+
+inline QRect qHighDpiToDevicePixels(const QRect &pointRect)
+{
+ const qreal scaleFactor = QHighDpiScaling::factor();
+ return QRect(pointRect.topLeft() * scaleFactor, pointRect.size() * scaleFactor);
+}
+
+inline QRectF qHighDpiToDeviceIndependentPixels(const QRectF &pixelRect)
+{
+ const qreal scaleFactor = QHighDpiScaling::factor();
+ return QRectF(pixelRect.topLeft() / scaleFactor, pixelRect.size() / scaleFactor);
+}
+
+inline QRectF qHighDpiToDevicePixels(const QRectF &pointRect)
+{
+ const qreal scaleFactor = QHighDpiScaling::factor();
+ return QRectF(pointRect.topLeft() * scaleFactor, pointRect.size() * scaleFactor);
+}
+
+inline QSize qHighDpiToDeviceIndependentPixels(const QSize &pixelSize)
+{
+ return pixelSize / QHighDpiScaling::factor();
+}
+
+// For converting minimum/maximum sizes of QWindow, limits to 0..QWINDOWSIZE_MAX
+Q_GUI_EXPORT QSize qHighDpiToDevicePixelsConstrained(const QSize &size);
+
+inline QSize qHighDpiToDevicePixels(const QSize &pointSize)
+{
+ return pointSize * QHighDpiScaling::factor();
+}
+
+inline QSizeF qHighDpiToDeviceIndependentPixels(const QSizeF &pixelSize)
+{
+ return pixelSize / QHighDpiScaling::factor();
+}
+
+inline QSizeF qHighDpiToDevicePixels(const QSizeF &pointSize)
+{
+ return pointSize * QHighDpiScaling::factor();
+}
+
+inline QPoint qHighDpiToDeviceIndependentPixels(const QPoint &pixelPoint)
+{
+ return pixelPoint / QHighDpiScaling::factor();
+}
+
+inline QPoint qHighDpiToDevicePixels(const QPoint &pointPoint)
+{
+ return pointPoint * QHighDpiScaling::factor();
+}
+
+inline QPointF qHighDpiToDeviceIndependentPixels(const QPointF &pixelPoint)
+{
+ return pixelPoint / QHighDpiScaling::factor();
+}
+
+inline QPointF qHighDpiToDevicePixels(const QPointF &pointPoint)
+{
+ return pointPoint * QHighDpiScaling::factor();
+}
+
+inline QMargins qHighDpiToDeviceIndependentPixels(const QMargins &pixelMargins)
+{
+ const qreal scaleFactor = QHighDpiScaling::factor();
+ return QMargins(pixelMargins.left() / scaleFactor, pixelMargins.top() / scaleFactor,
+ pixelMargins.right() / scaleFactor, pixelMargins.bottom() / scaleFactor);
+}
+
+inline QMargins qHighDpiToDevicePixels(const QMargins &pointMargins)
+{
+ const qreal scaleFactor = QHighDpiScaling::factor();
+ return QMargins(pointMargins.left() * scaleFactor, pointMargins.top() * scaleFactor,
+ pointMargins.right() * scaleFactor, pointMargins.bottom() * scaleFactor);
+}
+
+inline QRegion qHighDpiToDeviceIndependentPixels(const QRegion &pixelRegion)
+{
+ if (!QHighDpiScaling::isActive())
+ return pixelRegion;
+
+ QRegion pointRegion;
+ foreach (const QRect &rect, pixelRegion.rects())
+ pointRegion += qHighDpiToDeviceIndependentPixels(rect);
+ return pointRegion;
+}
+
+inline QRegion qHighDpiToDevicePixels(const QRegion &pointRegion)
+{
+ if (!QHighDpiScaling::isActive())
+ return pointRegion;
+
+ QRegion pixelRegon;
+ foreach (const QRect &rect, pointRegion.rects())
+ pixelRegon += qHighDpiToDevicePixels(rect);
+ return pixelRegon;
+}
+
+// Any T that has operator/()
+template <typename T>
+T qHighDpiToDeviceIndependentPixels(const T &pixelValue)
+{
+ if (!QHighDpiScaling::isActive())
+ return pixelValue;
+
+ return pixelValue / QHighDpiScaling::factor();
+
+}
+
+// Any T that has operator*()
+template <typename T>
+T qHighDpiToDevicePixels(const T &pointValue)
+{
+ if (!QHighDpiScaling::isActive())
+ return pointValue;
+
+ return pointValue * QHighDpiScaling::factor();
+}
+
+// Any QVector<T> where T has operator/()
+template <typename T>
+QVector<T> qHighDpiToDeviceIndependentPixels(const QVector<T> &pixelValues)
+{
+ if (!QHighDpiScaling::isActive())
+ return pixelValues;
+
+ QVector<T> pointValues;
+ foreach (const T& pixelValue, pixelValues)
+ pointValues.append(pixelValue / QHighDpiScaling::factor());
+ return pointValues;
+}
+
+// Any QVector<T> where T has operator*()
+template <typename T>
+QVector<T> qHighDpiToDevicePixels(const QVector<T> &pointValues)
+{
+ if (!QHighDpiScaling::isActive())
+ return pointValues;
+
+ QVector<T> pixelValues;
+ foreach (const T& pointValue, pointValues)
+ pixelValues.append(pointValue * QHighDpiScaling::factor());
+ return pixelValues;
+}
+
+
+// Any QPair<T, U> where T and U has operator/()
+template <typename T, typename U>
+QPair<T, U> qHighDpiToDeviceIndependentPixels(const QPair<T, U> &pixelPair)
+{
+ return qMakePair(qHighDpiToDeviceIndependentPixels(pixelPair.first), qHighDpiToDeviceIndependentPixels(pixelPair.second));
+}
+
+// Any QPair<T, U> where T and U has operator*()
+template <typename T, typename U>
+QPair<T, U> qHighDpiToDevicePixels(const QPair<T, U> &pointPair)
+{
+ return qMakePair(qHighDpiToDevicePixels(pointPair.first), qHighDpiToDevicePixels(pointPair.second));
+}
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/gui/kernel/qscreen.cpp b/src/gui/kernel/qscreen.cpp
index 5785722918..684b298631 100644
--- a/src/gui/kernel/qscreen.cpp
+++ b/src/gui/kernel/qscreen.cpp
@@ -259,7 +259,7 @@ qreal QScreen::logicalDotsPerInch() const
qreal QScreen::devicePixelRatio() const
{
Q_D(const QScreen);
- return d->platformScreen->devicePixelRatio();
+ return d->platformScreen->devicePixelRatio() * QHighDpiScaling::factor();
}
/*!
diff --git a/src/gui/kernel/qscreen.h b/src/gui/kernel/qscreen.h
index f60fafcf63..a6018128e2 100644
--- a/src/gui/kernel/qscreen.h
+++ b/src/gui/kernel/qscreen.h
@@ -154,6 +154,7 @@ private:
friend class QGuiApplicationPrivate;
friend class QPlatformIntegration;
friend class QPlatformScreen;
+ friend class QHighDpiScaling;
};
#ifndef QT_NO_DEBUG_STREAM
diff --git a/src/gui/kernel/qscreen_p.h b/src/gui/kernel/qscreen_p.h
index d341b71932..3b97f265b5 100644
--- a/src/gui/kernel/qscreen_p.h
+++ b/src/gui/kernel/qscreen_p.h
@@ -47,6 +47,7 @@
#include <QtGui/qscreen.h>
#include <qpa/qplatformscreen.h>
+#include "qhighdpiscaling_p.h"
#include <QtCore/private/qobject_p.h>
@@ -60,8 +61,8 @@ public:
, orientationUpdateMask(0)
{
orientation = platformScreen->orientation();
- geometry = platformScreen->geometry();
- availableGeometry = platformScreen->availableGeometry();
+ geometry = qHighDpiToDeviceIndependentPixels(platformScreen->geometry());
+ availableGeometry = qHighDpiToDeviceIndependentPixels(platformScreen->availableGeometry());
logicalDpi = platformScreen->logicalDpi();
refreshRate = platformScreen->refreshRate();
// safeguard ourselves against buggy platform behavior...
@@ -73,6 +74,19 @@ public:
filteredOrientation = orientation;
if (filteredOrientation == Qt::PrimaryOrientation)
filteredOrientation = primaryOrientation;
+
+ updateHighDpi();
+ }
+
+ void updateHighDpi()
+ {
+ geometry = qHighDpiToDeviceIndependentPixels(platformScreen->geometry());
+ availableGeometry = qHighDpiToDeviceIndependentPixels(platformScreen->availableGeometry());
+ logicalDpi = platformScreen->logicalDpi();
+ if (QHighDpiScaling::isActive()) { // Apply factor to maintain point sizes of fonts.
+ logicalDpi.first /= QHighDpiScaling::factor();
+ logicalDpi.second /= QHighDpiScaling::factor();
+ }
}
void updatePrimaryOrientation();
diff --git a/src/gui/kernel/qwindow.cpp b/src/gui/kernel/qwindow.cpp
index fd4c769049..c75907a578 100644
--- a/src/gui/kernel/qwindow.cpp
+++ b/src/gui/kernel/qwindow.cpp
@@ -47,6 +47,7 @@
#ifndef QT_NO_ACCESSIBILITY
# include "qaccessible.h"
#endif
+#include "qhighdpiscaling_p.h"
#include <private/qevent_p.h>
@@ -1080,7 +1081,7 @@ qreal QWindow::devicePixelRatio() const
// correct for single-display systems (a very common case).
if (!d->platformWindow)
return qApp->devicePixelRatio();
- return d->platformWindow->devicePixelRatio();
+ return d->platformWindow->devicePixelRatio() * QHighDpiScaling::factor();
}
/*!
@@ -1420,7 +1421,7 @@ void QWindow::setGeometry(const QRect &rect)
d->positionPolicy = QWindowPrivate::WindowFrameExclusive;
if (d->platformWindow) {
- d->platformWindow->setGeometry(rect);
+ d->platformWindow->setGeometry(qHighDpiToDevicePixels(rect));
} else {
d->geometry = rect;
@@ -1444,7 +1445,7 @@ QRect QWindow::geometry() const
{
Q_D(const QWindow);
if (d->platformWindow)
- return d->platformWindow->geometry();
+ return qHighDpiToDeviceIndependentPixels(d->platformWindow->geometry());
return d->geometry;
}
@@ -1457,7 +1458,7 @@ QMargins QWindow::frameMargins() const
{
Q_D(const QWindow);
if (d->platformWindow)
- return d->platformWindow->frameMargins();
+ return qHighDpiToDeviceIndependentPixels(d->platformWindow->frameMargins());
return QMargins();
}
@@ -1471,7 +1472,7 @@ QRect QWindow::frameGeometry() const
Q_D(const QWindow);
if (d->platformWindow) {
QMargins m = frameMargins();
- return d->platformWindow->geometry().adjusted(-m.left(), -m.top(), m.right(), m.bottom());
+ return qHighDpiToDeviceIndependentPixels(d->platformWindow->geometry()).adjusted(-m.left(), -m.top(), m.right(), m.bottom());
}
return d->geometry;
}
@@ -1488,7 +1489,7 @@ QPoint QWindow::framePosition() const
Q_D(const QWindow);
if (d->platformWindow) {
QMargins margins = frameMargins();
- return d->platformWindow->geometry().topLeft() - QPoint(margins.left(), margins.top());
+ return qHighDpiToDeviceIndependentPixels(d->platformWindow->geometry().topLeft()) - QPoint(margins.left(), margins.top());
}
return d->geometry.topLeft();
}
@@ -1503,7 +1504,7 @@ void QWindow::setFramePosition(const QPoint &point)
Q_D(QWindow);
d->positionPolicy = QWindowPrivate::WindowFrameInclusive;
if (d->platformWindow) {
- d->platformWindow->setGeometry(QRect(point, size()));
+ d->platformWindow->setGeometry(qHighDpiToDevicePixels(QRect(point, size())));
} else {
d->positionAutomatic = false;
d->geometry.moveTopLeft(point);
@@ -1564,7 +1565,7 @@ void QWindow::resize(const QSize &newSize)
{
Q_D(QWindow);
if (d->platformWindow) {
- d->platformWindow->setGeometry(QRect(position(), newSize));
+ d->platformWindow->setGeometry(qHighDpiToDevicePixels(QRect(position(), newSize)));
} else {
const QSize oldSize = d->geometry.size();
d->geometry.setSize(newSize);
diff --git a/src/gui/kernel/qwindowsysteminterface.cpp b/src/gui/kernel/qwindowsysteminterface.cpp
index 7bf47a1dc8..da3b3e85e5 100644
--- a/src/gui/kernel/qwindowsysteminterface.cpp
+++ b/src/gui/kernel/qwindowsysteminterface.cpp
@@ -40,6 +40,7 @@
#include <qpa/qplatformdrag.h>
#include <qpa/qplatformintegration.h>
#include <qdebug.h>
+#include "qhighdpiscaling_p.h"
QT_BEGIN_NAMESPACE
@@ -138,7 +139,7 @@ void QWindowSystemInterface::handleApplicationStateChanged(Qt::ApplicationState
*/
void QWindowSystemInterface::handleGeometryChange(QWindow *tlw, const QRect &newRect, const QRect &oldRect)
{
- QWindowSystemInterfacePrivate::GeometryChangeEvent *e = new QWindowSystemInterfacePrivate::GeometryChangeEvent(tlw,newRect, oldRect);
+ QWindowSystemInterfacePrivate::GeometryChangeEvent *e = new QWindowSystemInterfacePrivate::GeometryChangeEvent(tlw, qHighDpiToDeviceIndependentPixels(newRect), qHighDpiToDeviceIndependentPixels(oldRect));
QWindowSystemInterfacePrivate::handleWindowSystemEvent(e);
}
@@ -167,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, local, global, b, mods, source);
+ new QWindowSystemInterfacePrivate::MouseEvent(w, timestamp, qHighDpiToDeviceIndependentPixels(local), qHighDpiToDeviceIndependentPixels(global), b, mods, source);
QWindowSystemInterfacePrivate::handleWindowSystemEvent(e);
}
@@ -184,7 +185,7 @@ void QWindowSystemInterface::handleFrameStrutMouseEvent(QWindow *w, ulong timest
QWindowSystemInterfacePrivate::MouseEvent * e =
new QWindowSystemInterfacePrivate::MouseEvent(w, timestamp,
QWindowSystemInterfacePrivate::FrameStrutMouse,
- local, global, b, mods, source);
+ qHighDpiToDeviceIndependentPixels(local), qHighDpiToDeviceIndependentPixels(global), b, mods, source);
QWindowSystemInterfacePrivate::handleWindowSystemEvent(e);
}
@@ -365,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, local, global, pixelDelta, angleDelta, angleDelta.y(), Qt::Vertical, mods, phase, source);
+ e = new QWindowSystemInterfacePrivate::WheelEvent(tlw, timestamp, qHighDpiToDeviceIndependentPixels(local), qHighDpiToDeviceIndependentPixels(global), 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, local, global, pixelDelta, angleDelta, angleDelta.x(), Qt::Horizontal, mods, phase, source);
+ e = new QWindowSystemInterfacePrivate::WheelEvent(tlw, timestamp, qHighDpiToDeviceIndependentPixels(local), qHighDpiToDeviceIndependentPixels(global), pixelDelta, angleDelta, angleDelta.x(), Qt::Horizontal, mods, phase, source);
QWindowSystemInterfacePrivate::handleWindowSystemEvent(e);
return;
}
@@ -380,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, local, global, pixelDelta, angleDelta, angleDelta.y(), Qt::Vertical, mods, phase, source);
+ e = new QWindowSystemInterfacePrivate::WheelEvent(tlw, timestamp, qHighDpiToDeviceIndependentPixels(local), qHighDpiToDeviceIndependentPixels(global), 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, local, global, QPoint(), QPoint(), angleDelta.x(), Qt::Horizontal, mods, phase, source);
+ e = new QWindowSystemInterfacePrivate::WheelEvent(tlw, timestamp, qHighDpiToDeviceIndependentPixels(local), qHighDpiToDeviceIndependentPixels(global), QPoint(), QPoint(), angleDelta.x(), Qt::Horizontal, mods, phase, source);
QWindowSystemInterfacePrivate::handleWindowSystemEvent(e);
}
@@ -463,16 +464,16 @@ QList<QTouchEvent::TouchPoint> QWindowSystemInterfacePrivate::convertTouchPoints
p.setState(point->state);
const QPointF screenPos = point->area.center();
- p.setScreenPos(screenPos);
- p.setScreenRect(point->area);
+ p.setScreenPos(qHighDpiToDeviceIndependentPixels(screenPos));
+ p.setScreenRect(qHighDpiToDeviceIndependentPixels(point->area));
// The local pos and rect are not set, they will be calculated
// when the event gets processed by QGuiApplication.
- p.setNormalizedPos(point->normalPosition);
- p.setVelocity(point->velocity);
+ p.setNormalizedPos(qHighDpiToDeviceIndependentPixels(point->normalPosition));
+ p.setVelocity(qHighDpiToDeviceIndependentPixels(point->velocity));
p.setFlags(point->flags);
- p.setRawScreenPositions(point->rawPositions);
+ p.setRawScreenPositions(qHighDpiToDeviceIndependentPixels(point->rawPositions));
touchPoints.append(p);
++point;
@@ -533,14 +534,14 @@ void QWindowSystemInterface::handleScreenOrientationChange(QScreen *screen, Qt::
void QWindowSystemInterface::handleScreenGeometryChange(QScreen *screen, const QRect &geometry, const QRect &availableGeometry)
{
QWindowSystemInterfacePrivate::ScreenGeometryEvent *e =
- new QWindowSystemInterfacePrivate::ScreenGeometryEvent(screen, geometry, availableGeometry);
+ new QWindowSystemInterfacePrivate::ScreenGeometryEvent(screen, qHighDpiToDeviceIndependentPixels(geometry), qHighDpiToDeviceIndependentPixels(availableGeometry));
QWindowSystemInterfacePrivate::handleWindowSystemEvent(e);
}
void QWindowSystemInterface::handleScreenLogicalDotsPerInchChange(QScreen *screen, qreal dpiX, qreal dpiY)
{
QWindowSystemInterfacePrivate::ScreenLogicalDotsPerInchEvent *e =
- new QWindowSystemInterfacePrivate::ScreenLogicalDotsPerInchEvent(screen, dpiX, dpiY);
+ new QWindowSystemInterfacePrivate::ScreenLogicalDotsPerInchEvent(screen, dpiX, dpiY); // ### tja
QWindowSystemInterfacePrivate::handleWindowSystemEvent(e);
}
@@ -559,7 +560,7 @@ void QWindowSystemInterface::handleThemeChange(QWindow *tlw)
void QWindowSystemInterface::handleExposeEvent(QWindow *tlw, const QRegion &region)
{
- QWindowSystemInterfacePrivate::ExposeEvent *e = new QWindowSystemInterfacePrivate::ExposeEvent(tlw, region);
+ QWindowSystemInterfacePrivate::ExposeEvent *e = new QWindowSystemInterfacePrivate::ExposeEvent(tlw, qHighDpiToDeviceIndependentPixels(region));
QWindowSystemInterfacePrivate::handleWindowSystemEvent(e);
}
@@ -626,12 +627,12 @@ int QWindowSystemInterface::windowSystemEventsQueued()
#ifndef QT_NO_DRAGANDDROP
QPlatformDragQtResponse QWindowSystemInterface::handleDrag(QWindow *w, const QMimeData *dropData, const QPoint &p, Qt::DropActions supportedActions)
{
- return QGuiApplicationPrivate::processDrag(w, dropData, p,supportedActions);
+ return QGuiApplicationPrivate::processDrag(w, dropData, qHighDpiToDeviceIndependentPixels(p),supportedActions);
}
QPlatformDropQtResponse QWindowSystemInterface::handleDrop(QWindow *w, const QMimeData *dropData, const QPoint &p, Qt::DropActions supportedActions)
{
- return QGuiApplicationPrivate::processDrop(w, dropData, p,supportedActions);
+ return QGuiApplicationPrivate::processDrop(w, dropData, qHighDpiToDeviceIndependentPixels(p),supportedActions);
}
#endif // QT_NO_DRAGANDDROP
@@ -665,8 +666,11 @@ void QWindowSystemInterface::handleTabletEvent(QWindow *w, ulong timestamp, cons
Qt::KeyboardModifiers modifiers)
{
QWindowSystemInterfacePrivate::TabletEvent *e =
- new QWindowSystemInterfacePrivate::TabletEvent(w, timestamp, local, global, device, pointerType, buttons, pressure,
- xTilt, yTilt, tangentialPressure, rotation, z, uid, modifiers);
+ new QWindowSystemInterfacePrivate::TabletEvent(w,timestamp,
+ qHighDpiToDeviceIndependentPixels(local),
+ qHighDpiToDeviceIndependentPixels(global),
+ device, pointerType, buttons, pressure,
+ xTilt, yTilt, tangentialPressure, rotation, z, uid, modifiers);
QWindowSystemInterfacePrivate::handleWindowSystemEvent(e);
}
@@ -790,7 +794,8 @@ Q_GUI_EXPORT QDebug operator<<(QDebug dbg, const QWindowSystemInterface::TouchPo
#endif
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, local, global, b, mods);
+
+ QWindowSystemInterface::handleMouseEvent(w, qHighDpiToDevicePixels(local), qHighDpiToDevicePixels(global), 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)