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 Pick-to: 6.5 6.4 6.2 5.15 Change-Id: I0b0d1a0e4688f10530054afd26e34f55a92ea2da Reviewed-by: Assam Boudjelthia <assam.boudjelthia@qt.io>
This commit is contained in:
parent
46af1fe49f
commit
48ebd4e318
@ -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);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user