diff options
| author | Assam Boudjelthia <assam.boudjelthia@qt.io> | 2025-05-20 15:49:13 +0300 |
|---|---|---|
| committer | Assam Boudjelthia <assam.boudjelthia@qt.io> | 2025-05-23 11:42:02 +0300 |
| commit | e96a4b84e136d065054600c07bf5fae17f3049ce (patch) | |
| tree | 1954c5c775de913f0e905463e8f21f200c906c31 /src | |
| parent | 6de8ce2af383c8d164c65ffca7dc845c52e4f2d2 (diff) | |
Android: consider DecorView insets at app startup
Set the initial safe area margins based on the decor view as a
workaround since setOnApplyWindowInsetsListener() is not being called
reliably at startups. This way we can get the app's initial insets at
startup, then after that rely on each window reporting its insets.
And apply this initial inset only for top level windows that match
the screen size, i.e. we assume edge-to-edge is enable in that case.
Pick-to: 6.9
Task-number: QTBUG-135808
Fixes: QTBUG-135283
Fixes: QTBUG-135227
Change-Id: Ic5771809c94302b927ccc67ccc07c73ccc73b91d
Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
Diffstat (limited to 'src')
| -rw-r--r-- | src/android/jar/src/org/qtproject/qt/android/QtWindow.java | 58 | ||||
| -rw-r--r-- | src/plugins/platforms/android/qandroidplatformwindow.cpp | 5 |
2 files changed, 49 insertions, 14 deletions
diff --git a/src/android/jar/src/org/qtproject/qt/android/QtWindow.java b/src/android/jar/src/org/qtproject/qt/android/QtWindow.java index a0c10321f82..e4f489a39da 100644 --- a/src/android/jar/src/org/qtproject/qt/android/QtWindow.java +++ b/src/android/jar/src/org/qtproject/qt/android/QtWindow.java @@ -75,27 +75,57 @@ class QtWindow extends QtLayout implements QtSurfaceInterface { }); m_gestureDetector.setIsLongpressEnabled(true); }); + } - if (getContext() instanceof QtActivityBase) { - setOnApplyWindowInsetsListener((view, insets) -> { - Insets safeInsets; - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { - int types = WindowInsets.Type.displayCutout() | WindowInsets.Type.systemBars(); - safeInsets = insets.getInsets(types); - } else { - safeInsets = getSafeInsetsPreAndroidR(view, insets); - } - QtNative.runAction(() -> safeAreaMarginsChanged(safeInsets, getId())); - return insets; - }); + @UsedFromNativeCode + void registerSafeAreaMarginsListner(boolean isTopLevel, boolean isSameWindowAndScreenSize) + { + if (!(getContext() instanceof QtActivityBase)) + return; + + setOnApplyWindowInsetsListener((view, insets) -> { + Insets safeInsets = getSafeInsets(view, insets); + safeAreaMarginsChanged(safeInsets, getId()); + return getConsumedInsets(insets); + }); - QtNative.runAction(() -> requestApplyInsets()); + // NOTE: if the window size fits the screen geometry (i.e. edge-to-edge case), + // assume this window is the main window and initialize its safe margins with + // the insets of the decor view. + if (isTopLevel && isSameWindowAndScreenSize) { + QtNative.runAction(() -> { + // NOTE: The callback onApplyWindowInsetsListener() is not being triggered during + // startup, so this is a Workaround to get the safe area margins at startup. + // Initially, set the root view insets to the current window, then if the insets + // change later, we can rely on setOnApplyWindowInsetsListener() being called. + View decorView = ((Activity) getContext()).getWindow().getDecorView(); + WindowInsets rootInsets = decorView.getRootWindowInsets(); + Insets rootSafeInsets = getSafeInsets(decorView, rootInsets); + safeAreaMarginsChanged(rootSafeInsets, getId()); + }); } + + QtNative.runAction(() -> requestApplyInsets()); + } + + @SuppressWarnings("deprecation") + WindowInsets getConsumedInsets(WindowInsets insets) + { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) + return WindowInsets.CONSUMED; + else + return insets.consumeSystemWindowInsets(); } @SuppressWarnings("deprecation") - Insets getSafeInsetsPreAndroidR(View view, WindowInsets insets) + Insets getSafeInsets(View view, WindowInsets insets) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { + int types = WindowInsets.Type.displayCutout() | WindowInsets.Type.systemBars(); + return insets.getInsets(types); + } + + // Android R and older int left = 0; int top = 0; int right = 0; diff --git a/src/plugins/platforms/android/qandroidplatformwindow.cpp b/src/plugins/platforms/android/qandroidplatformwindow.cpp index cb252d1f084..194a08ee09f 100644 --- a/src/plugins/platforms/android/qandroidplatformwindow.cpp +++ b/src/plugins/platforms/android/qandroidplatformwindow.cpp @@ -96,6 +96,11 @@ void QAndroidPlatformWindow::initialize() } qCDebug(lcQpaWindow) << "Window" << m_nativeViewId << "using surface container type" << static_cast<int>(m_surfaceContainerType); + + const bool isSameWindowAndScreenSize = geometry().size() == screen()->geometry().size(); + m_nativeQtWindow.callMethod("registerSafeAreaMarginsListner", + window->isTopLevel(), isSameWindowAndScreenSize); + } QAndroidPlatformWindow::~QAndroidPlatformWindow() |
