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,
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<QWindow*>(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);
}
/*!

View File

@ -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());
const QRect requestedNativeGeometry =
forceMaximize ? QRect() : QHighDpi::toNativePixels(window->geometry(), window);
const QRect availableDeviceIndependentGeometry = (window->parent())
? window->parent()->geometry()
: QHighDpi::fromNativePixels(platformScreen()->availableGeometry(), window);
if (requestedGeometry != finalGeometry)
setGeometry(QHighDpi::toNativePixels(finalGeometry, 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()