From 7833eae30499b29d810c2f105db1e56f905008c2 Mon Sep 17 00:00:00 2001 From: Andreas Buhr Date: Wed, 17 Feb 2021 20:15:04 +0100 Subject: Fix handling of virtual/native pixels in QAndroidPlatformWindow MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit f92e1953699b2529cc6ea2fd399fe4f2b887e83c made sure a new QAndroidPlatformWindow always has a geometry. However, it did not take into account HiDPI handling. This patch fixes it and introduces proper HiDPI handling. Fixes: QTBUG-91161 Change-Id: Iddf31b7abfd0a1bada3b051ed4de3bf6c2897d8e Reviewed-by: Tor Arne Vestbø (cherry picked from commit dec429e0778493bc4e85d6b18202804d0bbbe5f1) Reviewed-by: Qt Cherry-pick Bot --- src/gui/kernel/qplatformwindow.cpp | 37 +++++++++++++--------- .../platforms/android/qandroidplatformwindow.cpp | 21 ++++++++---- 2 files changed, 36 insertions(+), 22 deletions(-) diff --git a/src/gui/kernel/qplatformwindow.cpp b/src/gui/kernel/qplatformwindow.cpp index f9e984c9cb..0bee2968f7 100644 --- a/src/gui/kernel/qplatformwindow.cpp +++ b/src/gui/kernel/qplatformwindow.cpp @@ -678,16 +678,16 @@ void QPlatformWindow::invalidateSurface() { } -static QSize fixInitialSize(QSize size, const QWindow *w, - int defaultWidth, int defaultHeight) +static QSize fixInitialSize(QSize size, const QWindow *w, int deviceIndependentDefaultWidth, + int deviceIndependentDefaultHeight) { if (size.width() == 0) { const int minWidth = w->minimumWidth(); - size.setWidth(minWidth > 0 ? minWidth : defaultWidth); + size.setWidth(minWidth > 0 ? minWidth : deviceIndependentDefaultWidth); } if (size.height() == 0) { const int minHeight = w->minimumHeight(); - size.setHeight(minHeight > 0 ? minHeight : defaultHeight); + size.setHeight(minHeight > 0 ? minHeight : deviceIndependentDefaultHeight); } return size; } @@ -700,6 +700,10 @@ static QSize fixInitialSize(QSize size, const QWindow *w, layout new windows to optimize usage of the available desktop space. However if the given window already has geometry which the application has initialized, it takes priority. + + \a initialGeometry has to be provided in native pixels. + \a defaultWidth has to be provided in device independent pixels + \a defaultHeight has to be provided in device independent pixels */ QRect QPlatformWindow::initialGeometry(const QWindow *w, const QRect &initialGeometry, int defaultWidth, int defaultHeight, @@ -709,9 +713,10 @@ QRect QPlatformWindow::initialGeometry(const QWindow *w, const QRect &initialGeo *resultingScreenReturn = w->screen(); if (!w->isTopLevel()) { const qreal factor = QHighDpiScaling::factor(w); - const QSize size = fixInitialSize(QHighDpi::fromNative(initialGeometry.size(), factor), - w, defaultWidth, defaultHeight); - return QRect(initialGeometry.topLeft(), QHighDpi::toNative(size, factor)); + const QSize deviceIndependentSize = + fixInitialSize(QHighDpi::fromNative(initialGeometry.size(), factor), w, + defaultWidth, defaultHeight); + return QRect(initialGeometry.topLeft(), QHighDpi::toNative(deviceIndependentSize, factor)); } const auto *wp = qt_window_private(const_cast(w)); const bool position = wp->positionAutomatic && w->type() != Qt::Popup; @@ -725,26 +730,28 @@ QRect QPlatformWindow::initialGeometry(const QWindow *w, const QRect &initialGeo if (resultingScreenReturn) *resultingScreenReturn = screen; // initialGeometry refers to window's screen - QRect rect(QHighDpi::fromNativePixels(initialGeometry, w)); + QRect deviceIndependentRect(QHighDpi::fromNativePixels(initialGeometry, w)); if (wp->resizeAutomatic) - rect.setSize(fixInitialSize(rect.size(), w, defaultWidth, defaultHeight)); + deviceIndependentRect.setSize( + fixInitialSize(deviceIndependentRect.size(), w, defaultWidth, defaultHeight)); if (position) { - const QRect availableGeometry = screen->availableGeometry(); + const QRect availableDeviceIndependentGeometry = screen->availableGeometry(); // Center unless the geometry ( + unknown window frame) is too large for the screen). - if (rect.height() < (availableGeometry.height() * 8) / 9 - && rect.width() < (availableGeometry.width() * 8) / 9) { + if (deviceIndependentRect.height() < (availableDeviceIndependentGeometry.height() * 8) / 9 + && deviceIndependentRect.width() + < (availableDeviceIndependentGeometry.width() * 8) / 9) { const QWindow *tp = w->transientParent(); if (tp) { // A transient window should be centered w.r.t. its transient parent. - rect.moveCenter(tp->geometry().center()); + deviceIndependentRect.moveCenter(tp->geometry().center()); } else { // Center the window on the screen. (Only applicable on platforms // which do not provide a better way.) - rect.moveCenter(availableGeometry.center()); + deviceIndependentRect.moveCenter(availableDeviceIndependentGeometry.center()); } } } - return QHighDpi::toNativePixels(rect, screen); + return QHighDpi::toNativePixels(deviceIndependentRect, screen); } /*! diff --git a/src/plugins/platforms/android/qandroidplatformwindow.cpp b/src/plugins/platforms/android/qandroidplatformwindow.cpp index c64805b4e2..e1cf2487fe 100644 --- a/src/plugins/platforms/android/qandroidplatformwindow.cpp +++ b/src/plugins/platforms/android/qandroidplatformwindow.cpp @@ -60,14 +60,21 @@ QAndroidPlatformWindow::QAndroidPlatformWindow(QWindow *window) m_windowId = winIdGenerator.fetchAndAddRelaxed(1) + 1; setWindowState(window->windowStates()); + // the following is in relation to the virtual geometry const bool forceMaximize = m_windowState & (Qt::WindowMaximized | Qt::WindowFullScreen); - const QRect requestedGeometry = forceMaximize ? QRect() : window->geometry(); - const QRect availableGeometry = (window->parent()) ? window->parent()->geometry() : platformScreen()->availableGeometry(); - const QRect finalGeometry = QPlatformWindow::initialGeometry(window, requestedGeometry, - availableGeometry.width(), availableGeometry.height()); - - if (requestedGeometry != finalGeometry) - setGeometry(QHighDpi::toNativePixels(finalGeometry, window)); + const QRect requestedNativeGeometry = + forceMaximize ? QRect() : QHighDpi::toNativePixels(window->geometry(), window); + const QRect availableDeviceIndependentGeometry = (window->parent()) + ? window->parent()->geometry() + : QHighDpi::fromNativePixels(platformScreen()->availableGeometry(), window); + + // initialGeometry returns in native pixels + const QRect finalNativeGeometry = QPlatformWindow::initialGeometry( + window, requestedNativeGeometry, availableDeviceIndependentGeometry.width(), + availableDeviceIndependentGeometry.height()); + + if (requestedNativeGeometry != finalNativeGeometry) + setGeometry(finalNativeGeometry); } void QAndroidPlatformWindow::lower() -- cgit v1.2.3