From 652652f3cee493239ef37758d5b9e39aa19002c2 Mon Sep 17 00:00:00 2001 From: Samuel Mira Date: Thu, 12 Jan 2023 13:32:51 +0200 Subject: [PATCH] Android: fix height calculation The application height calculation relied on the Display.getMetrics to obtain the size of the current app window. It works properly on stock android and Samsung devices, but not on some Huawei and it's unknown on other vendors. This patch changes the way the height and weight are calculated by using the provided values. Task-number: QTBUG-107604 Task-number: QTBUG-109268 Task-number: QTBUG-97503 Task-number: QTBUG-107923 Task-number: QTBUG-109351 Task-number: QTBUG-110501 Change-Id: I0b0d1a0e4688f10530054afd26e34f55a92ea2da Reviewed-by: Assam Boudjelthia (cherry picked from commit 48ebd4e318d5fb2d7ffe4b8215cd16cf5638215e) Reviewed-by: Qt Cherry-pick Bot --- .../org/qtproject/qt/android/QtLayout.java | 88 ++++--------------- 1 file changed, 15 insertions(+), 73 deletions(-) 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 80ba99f40db..d7207dc2c5d 100644 --- a/src/android/jar/src/org/qtproject/qt/android/QtLayout.java +++ b/src/android/jar/src/org/qtproject/qt/android/QtLayout.java @@ -70,8 +70,7 @@ public class QtLayout extends ViewGroup final WindowManager windowManager = activity.getWindowManager(); Display display; - int appWidth = 0; - int appHeight = 0; + final WindowInsets rootInsets = getRootWindowInsets(); int insetLeft = 0; int insetTop = 0; @@ -79,93 +78,36 @@ public class QtLayout extends ViewGroup int maxWidth = 0; int maxHeight = 0; - double xdpi = 0; - double ydpi = 0; - double scaledDensity = 0; - double density = 0; - if (android.os.Build.VERSION.SDK_INT < Build.VERSION_CODES.R) { - display = windowManager.getDefaultDisplay(); + display = windowManager.getDefaultDisplay(); - final DisplayMetrics appMetrics = new DisplayMetrics(); - display.getMetrics(appMetrics); - - final WindowInsets rootInsets = getRootWindowInsets(); - - insetLeft = rootInsets.getStableInsetLeft(); - insetTop = rootInsets.getStableInsetTop(); - - appWidth = appMetrics.widthPixels - rootInsets.getStableInsetRight() + rootInsets.getStableInsetLeft(); - - if (android.os.Build.VERSION.SDK_INT == Build.VERSION_CODES.Q) { - appHeight = appMetrics.heightPixels - rootInsets.getStableInsetTop(); - } else { - appHeight = appMetrics.heightPixels - rootInsets.getStableInsetTop() + rootInsets.getStableInsetBottom(); - } - - final DisplayMetrics maxMetrics = new DisplayMetrics(); - display.getRealMetrics(maxMetrics); - - maxWidth = maxMetrics.widthPixels; - maxHeight = maxMetrics.heightPixels; + final DisplayMetrics maxMetrics = new DisplayMetrics(); + display.getRealMetrics(maxMetrics); + maxWidth = maxMetrics.widthPixels; + maxHeight = maxMetrics.heightPixels; + insetLeft = rootInsets.getStableInsetLeft(); + insetTop = rootInsets.getStableInsetTop(); } else { - // after API 30 use getCurrentWindowMetrics for application metrics - // getMaximumWindowMetrics for the screen metrics - // resource configuration for density as best practice - // and the resource display metrics for the rest display = activity.getDisplay(); - final WindowMetrics appMetrics = windowManager.getCurrentWindowMetrics(); final WindowMetrics maxMetrics = windowManager.getMaximumWindowMetrics(); - - final WindowInsets windowInsets = appMetrics.getWindowInsets(); - Insets statusBarInsets = windowInsets.getInsetsIgnoringVisibility(WindowInsets.Type.statusBars()); - Insets cutoutInsets = windowInsets.getInsetsIgnoringVisibility(WindowInsets.Type.displayCutout()); - Insets imeInsets = windowInsets.getInsets(WindowInsets.Type.ime()); - - insetLeft = cutoutInsets.left; - insetTop = statusBarInsets.top; - - appWidth = w; - appHeight = h - imeInsets.bottom; - maxWidth = maxMetrics.getBounds().width(); maxHeight = maxMetrics.getBounds().height(); + insetLeft = rootInsets.getInsetsIgnoringVisibility(WindowInsets.Type.systemBars()).left; + insetTop = rootInsets.getInsetsIgnoringVisibility(WindowInsets.Type.systemBars()).top; } final DisplayMetrics displayMetrics = activity.getResources().getDisplayMetrics(); - xdpi = displayMetrics.xdpi; - ydpi = displayMetrics.ydpi; - density = displayMetrics.density; - scaledDensity = displayMetrics.scaledDensity; - + double xdpi = displayMetrics.xdpi; + double ydpi = displayMetrics.ydpi; + double density = displayMetrics.density; + double scaledDensity = displayMetrics.scaledDensity; float refreshRate = display.getRefreshRate(); - if ((appWidth > appHeight) != (w > h)) { - // This is an intermediate state during display rotation. - // The new size is still reported for old orientation, while - // realMetrics contain sizes for new orientation. Setting - // such parameters will produce inconsistent results, so - // we just skip them. - // We will have another onSizeChanged() with normal values - // a bit later. - return; - } - - final int flag = - activity.getWindow().getAttributes().flags & WindowManager.LayoutParams.FLAG_FULLSCREEN; - - if (flag == WindowManager.LayoutParams.FLAG_FULLSCREEN || h == maxHeight) { - // immersive mode uses the whole screen - appWidth = maxWidth; - appHeight = maxHeight; - insetLeft = insetTop = 0; - } - QtNative.setApplicationDisplayMetrics(maxWidth, maxHeight, insetLeft, - insetTop, appWidth, appHeight, + insetTop, w, h, xdpi,ydpi,scaledDensity, density, refreshRate);