diff --git a/src/android/jar/src/org/qtproject/qt/android/QtLayout.java b/src/android/jar/src/org/qtproject/qt/android/QtLayout.java index 7cb694dacfc..6c52a004220 100644 --- a/src/android/jar/src/org/qtproject/qt/android/QtLayout.java +++ b/src/android/jar/src/org/qtproject/qt/android/QtLayout.java @@ -49,6 +49,7 @@ import android.view.Display; import android.view.View; import android.view.ViewGroup; import android.view.WindowInsets; +import android.view.WindowManager; public class QtLayout extends ViewGroup { @@ -112,11 +113,25 @@ public class QtLayout extends ViewGroup } boolean isFullScreenView = h == realMetrics.heightPixels; - - int insetLeft = isFullScreenView ? insets.getSystemWindowInsetLeft() : 0; - int insetTop = isFullScreenView ? insets.getSystemWindowInsetTop() : 0; - int insetRight = isFullScreenView ? insets.getSystemWindowInsetRight() : 0; - int insetBottom = isFullScreenView ? insets.getSystemWindowInsetBottom() : 0; + // The code uses insets for fullscreen mode only. However in practice + // the insets can be reported incorrectly. Both on Android 6 and Android 11 + // a non-zero bottom inset is reported even when the + // WindowManager.LayoutParams.FLAG_FULLSCREEN flag is set. + // To avoid that, add an extra check for the fullscreen mode. + // The insets-related logic is not removed for the case when + // isFullScreenView == true, but hasFlagFullscreen == false, although + // I can't get such case in my tests. + final int windowFlags = ((Activity)getContext()).getWindow().getAttributes().flags; + final boolean hasFlagFullscreen = + (windowFlags & WindowManager.LayoutParams.FLAG_FULLSCREEN) != 0; + int insetLeft = + (isFullScreenView && !hasFlagFullscreen) ? insets.getSystemWindowInsetLeft() : 0; + int insetTop = + (isFullScreenView && !hasFlagFullscreen) ? insets.getSystemWindowInsetTop() : 0; + int insetRight = + (isFullScreenView && !hasFlagFullscreen) ? insets.getSystemWindowInsetRight() : 0; + int insetBottom = + (isFullScreenView && !hasFlagFullscreen) ? insets.getSystemWindowInsetBottom() : 0; int usableAreaWidth = w - insetLeft - insetRight; int usableAreaHeight = h - insetTop - insetBottom; diff --git a/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp b/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp index 3e6fd735d95..432b1e91892 100644 --- a/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp +++ b/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp @@ -445,6 +445,10 @@ private slots: void activateWhileModalHidden(); +#ifdef Q_OS_ANDROID + void showFullscreenAndroid(); +#endif + private: const QString m_platform; QSize m_testWidgetSize; @@ -12693,5 +12697,38 @@ void tst_QWidget::activateWhileModalHidden() QCOMPARE(QApplication::activeWindow(), &window); } +#ifdef Q_OS_ANDROID +void tst_QWidget::showFullscreenAndroid() +{ + QWidget w; + w.setAutoFillBackground(true); + QPalette p = w.palette(); + p.setColor(QPalette::Window, Qt::red); + w.setPalette(p); + + // Need to toggle showFullScreen() twice, see QTBUG-101968 + w.showFullScreen(); + QVERIFY(QTest::qWaitForWindowExposed(&w)); + w.show(); + QVERIFY(QTest::qWaitForWindowExposed(&w)); + w.showFullScreen(); + QVERIFY(QTest::qWaitForWindowExposed(&w)); + + // Make sure that the lower part of the screen contains the red widget, not + // the buttons. + + const QRect fullGeometry = w.screen()->geometry(); + // Take a rect of (20 x 20) from the bottom area + const QRect grabArea(10, fullGeometry.height() - 30, 20, 20); + const QImage img = grabFromWidget(&w, grabArea).toImage().convertedTo(QImage::Format_RGB32); + + QPixmap expectedPix(20, 20); + expectedPix.fill(Qt::red); + const QImage expectedImg = expectedPix.toImage().convertedTo(QImage::Format_RGB32); + + QCOMPARE(img, expectedImg); +} +#endif // Q_OS_ANDROID + QTEST_MAIN(tst_QWidget) #include "tst_qwidget.moc"