From e3feb85abc67b32ffaa4cd20cbc0a5789c7d5583 Mon Sep 17 00:00:00 2001 From: Assam Boudjelthia Date: Mon, 30 Dec 2024 16:11:23 +0200 Subject: [PATCH] Android: pass safe area margins to relevant windows only MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Instead of passing the safe area margins to all windows or top windows, we can instead call the listener for setOnApplyWindowInsetsListener() on specific QtWindow and have it pass the windowId with the callback to C++. What was missing before was that the listner was not reset after removing the window and also, we don't need to necessarily require a window matching the id to be found, so that if no window is found we can assume that the callback is not valid. Task-number: QTBUG-131519 Change-Id: Idd411e407ac8f5992aa6684ece70329198de1bc2 Reviewed-by: Tor Arne Vestbø (cherry picked from commit d7860d445d462dae853358c8b956fa6b1b6a2fc7) Reviewed-by: Qt Cherry-pick Bot --- .../qt/android/QtActivityDelegate.java | 1 + .../src/org/qtproject/qt/android/QtWindow.java | 9 +++++---- .../android/qandroidplatformwindow.cpp | 17 +++++++---------- .../platforms/android/qandroidplatformwindow.h | 2 +- 4 files changed, 14 insertions(+), 15 deletions(-) diff --git a/src/android/jar/src/org/qtproject/qt/android/QtActivityDelegate.java b/src/android/jar/src/org/qtproject/qt/android/QtActivityDelegate.java index e1292eed87a..9f2f4eecd1c 100644 --- a/src/android/jar/src/org/qtproject/qt/android/QtActivityDelegate.java +++ b/src/android/jar/src/org/qtproject/qt/android/QtActivityDelegate.java @@ -396,6 +396,7 @@ class QtActivityDelegate extends QtActivityDelegateBase QtNative.runAction(()-> { if (m_topLevelWindows.containsKey(id)) { QtWindow window = m_topLevelWindows.remove(id); + window.setOnApplyWindowInsetsListener(null); // Set in QtWindow for safe margins if (m_topLevelWindows.isEmpty()) { // Keep last frame in stack until it is replaced to get correct // shutdown transition 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 cb7a6404e80..a9a7fa3f81b 100644 --- a/src/android/jar/src/org/qtproject/qt/android/QtWindow.java +++ b/src/android/jar/src/org/qtproject/qt/android/QtWindow.java @@ -32,7 +32,7 @@ class QtWindow extends QtLayout implements QtSurfaceInterface { private final QtInputConnection.QtInputConnectionListener m_inputConnectionListener; private static native void setSurface(int windowId, Surface surface); - private static native void safeAreaMarginsChanged(Insets insets); + private static native void safeAreaMarginsChanged(Insets insets, int id); static native void windowFocusChanged(boolean hasFocus, int id); static native void updateWindows(); @@ -77,8 +77,7 @@ class QtWindow extends QtLayout implements QtSurfaceInterface { }); if (getContext() instanceof QtActivityBase) { - View decorView = ((Activity) context).getWindow().getDecorView(); - decorView.setOnApplyWindowInsetsListener((view, insets) -> { + setOnApplyWindowInsetsListener((view, insets) -> { Insets safeInsets; if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { int types = WindowInsets.Type.displayCutout() | WindowInsets.Type.systemBars(); @@ -110,10 +109,12 @@ class QtWindow extends QtLayout implements QtSurfaceInterface { safeInsets = Insets.of(left, top, right, bottom); } - safeAreaMarginsChanged(safeInsets); + QtNative.runAction(() -> safeAreaMarginsChanged(safeInsets, getId())); return insets; }); + + QtNative.runAction(() -> requestApplyInsets()); } } diff --git a/src/plugins/platforms/android/qandroidplatformwindow.cpp b/src/plugins/platforms/android/qandroidplatformwindow.cpp index 51e5f95605f..b83b1df88f1 100644 --- a/src/plugins/platforms/android/qandroidplatformwindow.cpp +++ b/src/plugins/platforms/android/qandroidplatformwindow.cpp @@ -383,7 +383,8 @@ void QAndroidPlatformWindow::windowFocusChanged(JNIEnv *env, jobject object, } } -void QAndroidPlatformWindow::safeAreaMarginsChanged(JNIEnv *env, jobject object, QtJniTypes::Insets insets) +void QAndroidPlatformWindow::safeAreaMarginsChanged(JNIEnv *env, jobject object, + QtJniTypes::Insets insets, jint id) { Q_UNUSED(env) Q_UNUSED(object) @@ -391,10 +392,6 @@ void QAndroidPlatformWindow::safeAreaMarginsChanged(JNIEnv *env, jobject object, if (!qGuiApp) return; - const auto tlw = qGuiApp->topLevelWindows(); - if (tlw.isEmpty()) - return; - QMargins safeMargins; if (insets.isValid()) { safeMargins = QMargins( @@ -404,17 +401,17 @@ void QAndroidPlatformWindow::safeAreaMarginsChanged(JNIEnv *env, jobject object, insets.getField("bottom")); } - for (QWindow *window : qGuiApp->topLevelWindows()) { + for (QWindow *window : qGuiApp->allWindows()) { if (!window->handle()) continue; - - auto *pWindow = static_cast(window->handle()); - if (!pWindow) - return; + QAndroidPlatformWindow *pWindow = static_cast(window->handle()); + if (pWindow->nativeViewId() != id) + continue; if (safeMargins != pWindow->safeAreaMargins()) { pWindow->setSafeAreaMargins(safeMargins); QWindowSystemInterface::handleSafeAreaMarginsChanged(window); + break; } } } diff --git a/src/plugins/platforms/android/qandroidplatformwindow.h b/src/plugins/platforms/android/qandroidplatformwindow.h index 39010879608..504181406d0 100644 --- a/src/plugins/platforms/android/qandroidplatformwindow.h +++ b/src/plugins/platforms/android/qandroidplatformwindow.h @@ -108,7 +108,7 @@ private: Q_DECLARE_JNI_NATIVE_METHOD_IN_CURRENT_SCOPE(setSurface) static void windowFocusChanged(JNIEnv *env, jobject object, jboolean focus, jint windowId); Q_DECLARE_JNI_NATIVE_METHOD_IN_CURRENT_SCOPE(windowFocusChanged) - static void safeAreaMarginsChanged(JNIEnv *env, jobject obj, QtJniTypes::Insets insets); + static void safeAreaMarginsChanged(JNIEnv *env, jobject obj, QtJniTypes::Insets insets, jint id); Q_DECLARE_JNI_NATIVE_METHOD_IN_CURRENT_SCOPE(safeAreaMarginsChanged) [[nodiscard]] QMutexLocker destructionGuard();