Android: pass safe area margins to relevant windows only

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ø <tor.arne.vestbo@qt.io>
(cherry picked from commit d7860d445d462dae853358c8b956fa6b1b6a2fc7)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
This commit is contained in:
Assam Boudjelthia 2024-12-30 16:11:23 +02:00 committed by Qt Cherry-pick Bot
parent bded4bd5fc
commit e3feb85abc
4 changed files with 14 additions and 15 deletions

View File

@ -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

View File

@ -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());
}
}

View File

@ -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<int>("bottom"));
}
for (QWindow *window : qGuiApp->topLevelWindows()) {
for (QWindow *window : qGuiApp->allWindows()) {
if (!window->handle())
continue;
auto *pWindow = static_cast<QAndroidPlatformWindow *>(window->handle());
if (!pWindow)
return;
QAndroidPlatformWindow *pWindow = static_cast<QAndroidPlatformWindow *>(window->handle());
if (pWindow->nativeViewId() != id)
continue;
if (safeMargins != pWindow->safeAreaMargins()) {
pWindow->setSafeAreaMargins(safeMargins);
QWindowSystemInterface::handleSafeAreaMarginsChanged(window);
break;
}
}
}

View File

@ -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<QMutex> destructionGuard();