Android: Fix incorrect fullscreen dimensions
The insets used to calculate the correct height were not the best choice. It used display cutout insets which would work correctly on most devices, but in the case of an emulator or a device without a camera, it could fail to calculate correctly. Task-number: QTBUG-107604 Task-number: QTBUG-107709 Task-number: QTBUG-107523 Change-Id: I8c4da83ae7359a0c133dbeb02dbd2cd260565f78 Reviewed-by: Ville Voutilainen <ville.voutilainen@qt.io> (cherry picked from commit d53ea82950e0662b8265642b840a12d9f9556888) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
This commit is contained in:
parent
87a8f36ff7
commit
58482c63f0
@ -90,8 +90,16 @@ public class QtLayout extends ViewGroup
|
||||
final DisplayMetrics appMetrics = new DisplayMetrics();
|
||||
display.getMetrics(appMetrics);
|
||||
|
||||
appWidth = appMetrics.widthPixels;
|
||||
appHeight = appMetrics.heightPixels;
|
||||
final WindowInsets rootInsets = getRootWindowInsets();
|
||||
|
||||
insetLeft = rootInsets.getStableInsetLeft();
|
||||
insetTop = rootInsets.getStableInsetTop();
|
||||
|
||||
int insetsWidth = rootInsets.getStableInsetRight() + rootInsets.getStableInsetLeft();
|
||||
int insetsHeight = rootInsets.getStableInsetTop() + rootInsets.getStableInsetBottom();
|
||||
|
||||
appWidth = appMetrics.widthPixels - insetsWidth;
|
||||
appHeight = appMetrics.heightPixels - insetsHeight;
|
||||
|
||||
final DisplayMetrics maxMetrics = new DisplayMetrics();
|
||||
display.getRealMetrics(maxMetrics);
|
||||
@ -104,9 +112,6 @@ public class QtLayout extends ViewGroup
|
||||
ydpi = appMetrics.ydpi;
|
||||
scaledDensity = appMetrics.scaledDensity;
|
||||
|
||||
final WindowInsets rootInsets = getRootWindowInsets();
|
||||
insetLeft = rootInsets.getSystemWindowInsetLeft();
|
||||
insetTop = rootInsets.getSystemWindowInsetTop();
|
||||
} else {
|
||||
// after API 30 use getCurrentWindowMetrics for application metrics
|
||||
// getMaximumWindowMetrics for the screen metrics
|
||||
@ -115,10 +120,10 @@ public class QtLayout extends ViewGroup
|
||||
display = activity.getDisplay();
|
||||
|
||||
final WindowMetrics appMetrics = windowManager.getCurrentWindowMetrics();
|
||||
final WindowMetrics maxMetrics = windowManager.getMaximumWindowMetrics();
|
||||
|
||||
final WindowInsets windowInsets = appMetrics.getWindowInsets();
|
||||
Insets insets = windowInsets.getInsetsIgnoringVisibility(WindowInsets.Type.navigationBars()
|
||||
| WindowInsets.Type.displayCutout());
|
||||
Insets insets = windowInsets.getInsetsIgnoringVisibility(WindowInsets.Type.tappableElement());
|
||||
|
||||
insetLeft = insets.left;
|
||||
insetTop = insets.top;
|
||||
@ -126,10 +131,14 @@ public class QtLayout extends ViewGroup
|
||||
int insetsWidth = insets.right + insets.left;
|
||||
int insetsHeight = insets.top + insets.bottom;
|
||||
|
||||
if (h == maxMetrics.getBounds().height()){
|
||||
//when h == maxheight the system is ignoring insets
|
||||
insetsWidth = insetsHeight = insetLeft = insetTop = 0;
|
||||
}
|
||||
|
||||
appWidth = appMetrics.getBounds().width() - insetsWidth;
|
||||
appHeight = appMetrics.getBounds().height() - insetsHeight;
|
||||
|
||||
final WindowMetrics maxMetrics = windowManager.getMaximumWindowMetrics();
|
||||
maxWidth = maxMetrics.getBounds().width();
|
||||
maxHeight = maxMetrics.getBounds().height();
|
||||
|
||||
|
@ -7,6 +7,10 @@
|
||||
qt_internal_add_test(tst_android
|
||||
SOURCES
|
||||
tst_android.cpp
|
||||
LIBRARIES
|
||||
Qt::CorePrivate
|
||||
Qt::Gui
|
||||
Qt::GuiPrivate
|
||||
)
|
||||
|
||||
if(ANDROID)
|
||||
|
@ -4,8 +4,12 @@
|
||||
#include <jni.h>
|
||||
|
||||
#include <QTest>
|
||||
#include <QGuiApplication>
|
||||
#include <QtCore/qnativeinterface.h>
|
||||
#include <QtCore/qjniobject.h>
|
||||
#include <QScreen>
|
||||
#include <qpa/qplatformscreen.h>
|
||||
#include <qpa/qplatformnativeinterface.h>
|
||||
|
||||
class tst_Android : public QObject
|
||||
{
|
||||
@ -16,6 +20,7 @@ private slots:
|
||||
void testAndroidSdkVersion();
|
||||
void testAndroidActivity();
|
||||
void testRunOnAndroidMainThread();
|
||||
void testFullScreenDimensions();
|
||||
};
|
||||
|
||||
void tst_Android::assetsRead()
|
||||
@ -164,6 +169,103 @@ void tst_Android::testRunOnAndroidMainThread()
|
||||
}
|
||||
}
|
||||
|
||||
void setSystemUiVisibility(int visibility)
|
||||
{
|
||||
QNativeInterface::QAndroidApplication::runOnAndroidMainThread([visibility] {
|
||||
QJniObject::callStaticMethod<void>("org/qtproject/qt/android/QtNative",
|
||||
"setSystemUiVisibility", "(I)V", visibility);
|
||||
}).waitForFinished();
|
||||
}
|
||||
|
||||
// QTBUG-107604
|
||||
void tst_Android::testFullScreenDimensions()
|
||||
{
|
||||
static int SYSTEM_UI_VISIBILITY_NORMAL = 0;
|
||||
static int SYSTEM_UI_VISIBILITY_FULLSCREEN = 1;
|
||||
static int SYSTEM_UI_VISIBILITY_TRANSLUCENT = 2;
|
||||
|
||||
// this will trigger new layout updates
|
||||
setSystemUiVisibility(SYSTEM_UI_VISIBILITY_FULLSCREEN);
|
||||
setSystemUiVisibility(SYSTEM_UI_VISIBILITY_NORMAL);
|
||||
|
||||
QJniObject activity = QNativeInterface::QAndroidApplication::context();
|
||||
QVERIFY(activity.isValid());
|
||||
|
||||
QJniObject windowManager =
|
||||
activity.callObjectMethod("getWindowManager", "()Landroid/view/WindowManager;");
|
||||
QVERIFY(windowManager.isValid());
|
||||
|
||||
QJniObject display = windowManager.callObjectMethod("getDefaultDisplay", "()Landroid/view/Display;");
|
||||
QVERIFY(display.isValid());
|
||||
|
||||
QJniObject appSize("android/graphics/Point");
|
||||
QVERIFY(appSize.isValid());
|
||||
|
||||
display.callMethod<void>("getSize", "(Landroid/graphics/Point;)V", appSize.object());
|
||||
|
||||
QJniObject realSize("android/graphics/Point");
|
||||
QVERIFY(realSize.isValid());
|
||||
|
||||
display.callMethod<void>("getRealSize", "(Landroid/graphics/Point;)V", realSize.object());
|
||||
|
||||
QPlatformScreen *screen = QGuiApplication::primaryScreen()->handle();
|
||||
|
||||
{
|
||||
// Normal -
|
||||
// available geometry == app size (system bars visible and removed from available geometry)
|
||||
QCoreApplication::processEvents();
|
||||
QJniObject window = activity.callObjectMethod("getWindow", "()Landroid/view/Window;");
|
||||
QVERIFY(window.isValid());
|
||||
|
||||
QJniObject decorView = window.callObjectMethod("getDecorView", "()Landroid/view/View;");
|
||||
QVERIFY(decorView.isValid());
|
||||
|
||||
QJniObject insets =
|
||||
decorView.callObjectMethod("getRootWindowInsets", "()Landroid/view/WindowInsets;");
|
||||
QVERIFY(insets.isValid());
|
||||
|
||||
int insetsWidth = insets.callMethod<jint>("getSystemWindowInsetRight")
|
||||
+ insets.callMethod<jint>("getSystemWindowInsetLeft");
|
||||
|
||||
int insetsHeight = insets.callMethod<jint>("getSystemWindowInsetTop")
|
||||
+ insets.callMethod<jint>("getSystemWindowInsetBottom");
|
||||
|
||||
QTRY_COMPARE(screen->availableGeometry().width(),
|
||||
int(appSize.getField<jint>("x")) - insetsWidth);
|
||||
QTRY_COMPARE(screen->availableGeometry().height(),
|
||||
int(appSize.getField<jint>("y")) - insetsHeight);
|
||||
|
||||
QTRY_COMPARE(screen->geometry().width(), int(realSize.getField<jint>("x")));
|
||||
QTRY_COMPARE(screen->geometry().height(), int(realSize.getField<jint>("y")));
|
||||
}
|
||||
|
||||
{
|
||||
setSystemUiVisibility(SYSTEM_UI_VISIBILITY_FULLSCREEN);
|
||||
|
||||
// Fullscreen
|
||||
// available geometry == full display size (system bars hidden)
|
||||
QCoreApplication::processEvents();
|
||||
QTRY_COMPARE(screen->availableGeometry().width(), int(realSize.getField<jint>("x")));
|
||||
QTRY_COMPARE(screen->availableGeometry().height(), int(realSize.getField<jint>("y")));
|
||||
|
||||
QTRY_COMPARE(screen->geometry().width(), int(realSize.getField<jint>("x")));
|
||||
QTRY_COMPARE(screen->geometry().height(), int(realSize.getField<jint>("y")));
|
||||
}
|
||||
|
||||
{
|
||||
setSystemUiVisibility(SYSTEM_UI_VISIBILITY_TRANSLUCENT);
|
||||
|
||||
// Translucent
|
||||
// available geometry == full display size (system bars visible but drawable under)
|
||||
QCoreApplication::processEvents();
|
||||
QTRY_COMPARE(screen->availableGeometry().width(), int(realSize.getField<jint>("x")));
|
||||
QTRY_COMPARE(screen->availableGeometry().height(), int(realSize.getField<jint>("y")));
|
||||
|
||||
QTRY_COMPARE(screen->geometry().width(), int(realSize.getField<jint>("x")));
|
||||
QTRY_COMPARE(screen->geometry().height(), int(realSize.getField<jint>("y")));
|
||||
}
|
||||
}
|
||||
|
||||
QTEST_MAIN(tst_Android)
|
||||
#include "tst_android.moc"
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user