QHighDpi: window geometry scaling functions

Add functions which scales window geometry:

	framNativeWindowGeometry()
	toNativeWindowGeometry()

These correctly handles top-level and child windows,
where top-level window positions scale around the screen
origin while child window positions scale around (0, 0).

Modify call cites to use the new functions. We no longer
need the isTopLevel checks at the call site.

Change-Id: I0158672d46a3f52dfc7d37d021fc5cebd7859200
Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
Reviewed-by: Friedemann Kleint <Friedemann.Kleint@qt.io>
bb10
Morten Johan Sørvig 2020-05-27 10:57:08 +02:00
parent 73a93981ca
commit 95bce5b185
5 changed files with 27 additions and 17 deletions

View File

@ -279,6 +279,22 @@ T toNativeGlobalPosition(const T &value, const C *context)
return scale(value, so.factor, so.origin);
}
template <typename T, typename C>
T fromNativeWindowGeometry(const T &value, const C *context)
{
QHighDpiScaling::ScaleAndOrigin so = QHighDpiScaling::scaleAndOrigin(context);
QPoint effectiveOrigin = (context && context->isTopLevel()) ? so.origin : QPoint(0,0);
return scale(value, qreal(1) / so.factor, effectiveOrigin);
}
template <typename T, typename C>
T toNativeWindowGeometry(const T &value, const C *context)
{
QHighDpiScaling::ScaleAndOrigin so = QHighDpiScaling::scaleAndOrigin(context);
QPoint effectiveOrigin = (context && context->isTopLevel()) ? so.origin : QPoint(0,0);
return scale(value, so.factor, effectiveOrigin);
}
template <typename T>
inline T fromNative(const T &value, qreal scaleFactor, QPoint origin = QPoint(0, 0))
{

View File

@ -849,7 +849,7 @@ QSize QPlatformWindow::windowSizeIncrement() const
*/
QRect QPlatformWindow::windowGeometry() const
{
return QHighDpi::toNativePixels(window()->geometry(), window());
return QHighDpi::toNativeWindowGeometry(window()->geometry(), window());
}
/*!
@ -857,7 +857,7 @@ QRect QPlatformWindow::windowGeometry() const
*/
QRect QPlatformWindow::windowFrameGeometry() const
{
return QHighDpi::toNativePixels(window()->frameGeometry(), window());
return QHighDpi::toNativeWindowGeometry(window()->frameGeometry(), window());
}
/*!
@ -868,10 +868,10 @@ QRect QPlatformWindow::windowFrameGeometry() const
QRectF QPlatformWindow::closestAcceptableGeometry(const QWindow *qWindow, const QRectF &nativeRect)
{
const QRectF rectF = QHighDpi::fromNativePixels(nativeRect, qWindow);
const QRectF rectF = QHighDpi::fromNativeWindowGeometry(nativeRect, qWindow);
const QRectF correctedGeometryF = qt_window_private(const_cast<QWindow *>(qWindow))->closestAcceptableGeometry(rectF);
return !correctedGeometryF.isEmpty() && rectF != correctedGeometryF
? QHighDpi::toNativePixels(correctedGeometryF, qWindow) : nativeRect;
? QHighDpi::toNativeWindowGeometry(correctedGeometryF, qWindow) : nativeRect;
}
QRectF QPlatformWindow::windowClosestAcceptableGeometry(const QRectF &nativeRect) const

View File

@ -1784,9 +1784,7 @@ QRect QWindow::geometry() const
Q_D(const QWindow);
if (d->platformWindow) {
const auto nativeGeometry = d->platformWindow->geometry();
return isTopLevel()
? QHighDpi::fromNativePixels(nativeGeometry, this)
: QHighDpi::fromNativeLocalPosition(nativeGeometry, this);
return QHighDpi::fromNativeWindowGeometry(nativeGeometry, this);
}
return d->geometry;
}
@ -1816,7 +1814,7 @@ QRect QWindow::frameGeometry() const
Q_D(const QWindow);
if (d->platformWindow) {
QMargins m = frameMargins();
return QHighDpi::fromNativePixels(d->platformWindow->geometry(), this).adjusted(-m.left(), -m.top(), m.right(), m.bottom());
return QHighDpi::fromNativeWindowGeometry(d->platformWindow->geometry(), this).adjusted(-m.left(), -m.top(), m.right(), m.bottom());
}
return d->geometry;
}
@ -1833,7 +1831,7 @@ QPoint QWindow::framePosition() const
Q_D(const QWindow);
if (d->platformWindow) {
QMargins margins = frameMargins();
return QHighDpi::fromNativePixels(d->platformWindow->geometry().topLeft(), this) - QPoint(margins.left(), margins.top());
return QHighDpi::fromNativeWindowGeometry(d->platformWindow->geometry().topLeft(), this) - QPoint(margins.left(), margins.top());
}
return d->geometry.topLeft();
}
@ -1851,7 +1849,7 @@ void QWindow::setFramePosition(const QPoint &point)
d->positionPolicy = QWindowPrivate::WindowFrameInclusive;
d->positionAutomatic = false;
if (d->platformWindow) {
d->platformWindow->setGeometry(QHighDpi::toNativePixels(QRect(point, size()), this));
d->platformWindow->setGeometry(QHighDpi::toNativeWindowGeometry(QRect(point, size()), this));
} else {
d->geometry.moveTopLeft(point);
}

View File

@ -300,18 +300,14 @@ QWindowSystemInterfacePrivate::GeometryChangeEvent::GeometryChangeEvent(QWindow
{
if (const QPlatformWindow *pw = window->handle()) {
const auto nativeGeometry = pw->QPlatformWindow::geometry();
requestedGeometry = window->isTopLevel()
? QHighDpi::fromNativePixels(nativeGeometry, window)
: QHighDpi::fromNativeLocalPosition(nativeGeometry, window);
requestedGeometry = QHighDpi::fromNativeWindowGeometry(nativeGeometry, window);
}
}
QT_DEFINE_QPA_EVENT_HANDLER(void, handleGeometryChange, QWindow *window, const QRect &newRect)
{
Q_ASSERT(window);
const auto newRectDi = window->isTopLevel()
? QHighDpi::fromNativePixels(newRect, window)
: QHighDpi::fromNativeLocalPosition(newRect, window);
const auto newRectDi = QHighDpi::fromNativeWindowGeometry(newRect, window);
auto e = new QWindowSystemInterfacePrivate::GeometryChangeEvent(window, newRectDi);
if (window->handle()) {
// Persist the new geometry so that QWindow::geometry() can be queried in the resize event

View File

@ -720,7 +720,7 @@ QRect QEvdevTouchScreenData::screenGeometry() const
{
if (m_forceToActiveWindow) {
QWindow *win = QGuiApplication::focusWindow();
return win ? QHighDpi::toNativePixels(win->geometry(), win) : QRect();
return win ? QHighDpi::toNativeWindowGeometry(win->geometry(), win) : QRect();
}
// Now it becomes tricky. Traditionally we picked the primaryScreen()