Fix handling of virtual/native pixels in QAndroidPlatformWindow

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ø <tor.arne.vestbo@qt.io>
(cherry picked from commit dec429e0778493bc4e85d6b18202804d0bbbe5f1)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
This commit is contained in:
Andreas Buhr 2021-02-17 20:15:04 +01:00 committed by Qt Cherry-pick Bot
parent 7f22edc00c
commit 7898f6a6aa
2 changed files with 35 additions and 21 deletions

View File

@ -678,16 +678,16 @@ void QPlatformWindow::invalidateSurface()
{ {
} }
static QSize fixInitialSize(QSize size, const QWindow *w, static QSize fixInitialSize(QSize size, const QWindow *w, int deviceIndependentDefaultWidth,
int defaultWidth, int defaultHeight) int deviceIndependentDefaultHeight)
{ {
if (size.width() == 0) { if (size.width() == 0) {
const int minWidth = w->minimumWidth(); const int minWidth = w->minimumWidth();
size.setWidth(minWidth > 0 ? minWidth : defaultWidth); size.setWidth(minWidth > 0 ? minWidth : deviceIndependentDefaultWidth);
} }
if (size.height() == 0) { if (size.height() == 0) {
const int minHeight = w->minimumHeight(); const int minHeight = w->minimumHeight();
size.setHeight(minHeight > 0 ? minHeight : defaultHeight); size.setHeight(minHeight > 0 ? minHeight : deviceIndependentDefaultHeight);
} }
return size; 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. layout new windows to optimize usage of the available desktop space.
However if the given window already has geometry which the application has However if the given window already has geometry which the application has
initialized, it takes priority. 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, QRect QPlatformWindow::initialGeometry(const QWindow *w, const QRect &initialGeometry,
int defaultWidth, int defaultHeight, int defaultWidth, int defaultHeight,
@ -709,9 +713,10 @@ QRect QPlatformWindow::initialGeometry(const QWindow *w, const QRect &initialGeo
*resultingScreenReturn = w->screen(); *resultingScreenReturn = w->screen();
if (!w->isTopLevel()) { if (!w->isTopLevel()) {
const qreal factor = QHighDpiScaling::factor(w); const qreal factor = QHighDpiScaling::factor(w);
const QSize size = fixInitialSize(QHighDpi::fromNative(initialGeometry.size(), factor), const QSize deviceIndependentSize =
w, defaultWidth, defaultHeight); fixInitialSize(QHighDpi::fromNative(initialGeometry.size(), factor), w,
return QRect(initialGeometry.topLeft(), QHighDpi::toNative(size, factor)); defaultWidth, defaultHeight);
return QRect(initialGeometry.topLeft(), QHighDpi::toNative(deviceIndependentSize, factor));
} }
const auto *wp = qt_window_private(const_cast<QWindow*>(w)); const auto *wp = qt_window_private(const_cast<QWindow*>(w));
const bool position = wp->positionAutomatic && w->type() != Qt::Popup; const bool position = wp->positionAutomatic && w->type() != Qt::Popup;
@ -725,26 +730,28 @@ QRect QPlatformWindow::initialGeometry(const QWindow *w, const QRect &initialGeo
if (resultingScreenReturn) if (resultingScreenReturn)
*resultingScreenReturn = screen; *resultingScreenReturn = screen;
// initialGeometry refers to window's screen // initialGeometry refers to window's screen
QRect rect(QHighDpi::fromNativePixels(initialGeometry, w)); QRect deviceIndependentRect(QHighDpi::fromNativePixels(initialGeometry, w));
if (wp->resizeAutomatic) if (wp->resizeAutomatic)
rect.setSize(fixInitialSize(rect.size(), w, defaultWidth, defaultHeight)); deviceIndependentRect.setSize(
fixInitialSize(deviceIndependentRect.size(), w, defaultWidth, defaultHeight));
if (position) { 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). // Center unless the geometry ( + unknown window frame) is too large for the screen).
if (rect.height() < (availableGeometry.height() * 8) / 9 if (deviceIndependentRect.height() < (availableDeviceIndependentGeometry.height() * 8) / 9
&& rect.width() < (availableGeometry.width() * 8) / 9) { && deviceIndependentRect.width()
< (availableDeviceIndependentGeometry.width() * 8) / 9) {
const QWindow *tp = w->transientParent(); const QWindow *tp = w->transientParent();
if (tp) { if (tp) {
// A transient window should be centered w.r.t. its transient parent. // A transient window should be centered w.r.t. its transient parent.
rect.moveCenter(tp->geometry().center()); deviceIndependentRect.moveCenter(tp->geometry().center());
} else { } else {
// Center the window on the screen. (Only applicable on platforms // Center the window on the screen. (Only applicable on platforms
// which do not provide a better way.) // 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);
} }
/*! /*!

View File

@ -60,14 +60,21 @@ QAndroidPlatformWindow::QAndroidPlatformWindow(QWindow *window)
m_windowId = winIdGenerator.fetchAndAddRelaxed(1) + 1; m_windowId = winIdGenerator.fetchAndAddRelaxed(1) + 1;
setWindowState(window->windowStates()); setWindowState(window->windowStates());
// the following is in relation to the virtual geometry
const bool forceMaximize = m_windowState & (Qt::WindowMaximized | Qt::WindowFullScreen); const bool forceMaximize = m_windowState & (Qt::WindowMaximized | Qt::WindowFullScreen);
const QRect requestedGeometry = forceMaximize ? QRect() : window->geometry(); const QRect requestedNativeGeometry =
const QRect availableGeometry = (window->parent()) ? window->parent()->geometry() : platformScreen()->availableGeometry(); forceMaximize ? QRect() : QHighDpi::toNativePixels(window->geometry(), window);
const QRect finalGeometry = QPlatformWindow::initialGeometry(window, requestedGeometry, const QRect availableDeviceIndependentGeometry = (window->parent())
availableGeometry.width(), availableGeometry.height()); ? window->parent()->geometry()
: QHighDpi::fromNativePixels(platformScreen()->availableGeometry(), window);
if (requestedGeometry != finalGeometry) // initialGeometry returns in native pixels
setGeometry(QHighDpi::toNativePixels(finalGeometry, window)); const QRect finalNativeGeometry = QPlatformWindow::initialGeometry(
window, requestedNativeGeometry, availableDeviceIndependentGeometry.width(),
availableDeviceIndependentGeometry.height());
if (requestedNativeGeometry != finalNativeGeometry)
setGeometry(finalNativeGeometry);
} }
void QAndroidPlatformWindow::lower() void QAndroidPlatformWindow::lower()