summaryrefslogtreecommitdiffstats
path: root/src/android/jar/src/org/qtproject/qt/android/QtLayout.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/android/jar/src/org/qtproject/qt/android/QtLayout.java')
-rw-r--r--src/android/jar/src/org/qtproject/qt/android/QtLayout.java142
1 files changed, 107 insertions, 35 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 6c52a00422..5ff46fc96b 100644
--- a/src/android/jar/src/org/qtproject/qt/android/QtLayout.java
+++ b/src/android/jar/src/org/qtproject/qt/android/QtLayout.java
@@ -42,7 +42,9 @@ package org.qtproject.qt.android;
import android.app.Activity;
import android.content.Context;
+import android.graphics.Rect;
import android.os.Build;
+import android.util.Log;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.view.Display;
@@ -50,6 +52,10 @@ import android.view.View;
import android.view.ViewGroup;
import android.view.WindowInsets;
import android.view.WindowManager;
+import android.graphics.Insets;
+import android.view.WindowMetrics;
+import android.content.res.Configuration;
+import android.content.res.Resources;
public class QtLayout extends ViewGroup
{
@@ -93,15 +99,95 @@ public class QtLayout extends ViewGroup
@Override
protected void onSizeChanged (int w, int h, int oldw, int oldh)
{
- WindowInsets insets = getRootWindowInsets();
+ Activity activity = (Activity)getContext();
+ if (activity == null)
+ return;
+
+ final WindowManager windowManager = activity.getWindowManager();
+ Display display;
+
+ int appWidth = 0;
+ int appHeight = 0;
+
+ int insetLeft = 0;
+ int insetTop = 0;
+
+ 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();
+
+ final DisplayMetrics appMetrics = new DisplayMetrics();
+ display.getMetrics(appMetrics);
+
+ final WindowInsets rootInsets = getRootWindowInsets();
+
+ insetLeft = rootInsets.getStableInsetLeft();
+ insetTop = rootInsets.getStableInsetTop();
- DisplayMetrics realMetrics = new DisplayMetrics();
- Display display = (Build.VERSION.SDK_INT < Build.VERSION_CODES.R)
- ? ((Activity)getContext()).getWindowManager().getDefaultDisplay()
- : ((Activity)getContext()).getDisplay();
- display.getRealMetrics(realMetrics);
+ appWidth = appMetrics.widthPixels - rootInsets.getStableInsetRight() + rootInsets.getStableInsetLeft();
- if ((realMetrics.widthPixels > realMetrics.heightPixels) != (w > h)) {
+ 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;
+
+ density = appMetrics.density;
+ xdpi = appMetrics.xdpi;
+ ydpi = appMetrics.ydpi;
+ scaledDensity = appMetrics.scaledDensity;
+
+ } 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();
+
+ final Resources resources = activity.getResources();
+ final Configuration configuration = resources.getConfiguration();
+ density = configuration.densityDpi / (float) DisplayMetrics.DENSITY_DEFAULT;
+
+ final DisplayMetrics displayMetrics = resources.getDisplayMetrics();
+ xdpi = displayMetrics.xdpi;
+ ydpi = displayMetrics.ydpi;
+ density = displayMetrics.density;
+ 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
@@ -112,34 +198,20 @@ public class QtLayout extends ViewGroup
return;
}
- boolean isFullScreenView = h == realMetrics.heightPixels;
- // 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;
-
- QtNative.setApplicationDisplayMetrics(
- realMetrics.widthPixels, realMetrics.heightPixels, insetLeft, insetTop,
- usableAreaWidth, usableAreaHeight, realMetrics.xdpi, realMetrics.ydpi,
- realMetrics.scaledDensity, realMetrics.density, display.getRefreshRate());
+ 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,
+ xdpi,ydpi,scaledDensity, density,
+ refreshRate);
int newRotation = display.getRotation();
if (m_ownDisplayRotation != m_activityDisplayRotation