diff --git a/src/android/jar/src/org/qtproject/qt/android/QtActivityBase.java b/src/android/jar/src/org/qtproject/qt/android/QtActivityBase.java index 248c0696680..79c67d87823 100644 --- a/src/android/jar/src/org/qtproject/qt/android/QtActivityBase.java +++ b/src/android/jar/src/org/qtproject/qt/android/QtActivityBase.java @@ -157,7 +157,7 @@ public class QtActivityBase extends Activity m_delegate.displayManager().registerDisplayListener(); QtNative.updateWindow(); // Suspending the app clears the immersive mode, so we need to set it again. - m_delegate.displayManager().updateFullScreen(); + m_delegate.displayManager().reinstateFullScreen(); } } @@ -290,8 +290,9 @@ public class QtActivityBase extends Activity { super.onRestoreInstanceState(savedInstanceState); QtNative.setStarted(savedInstanceState.getBoolean("Started")); - int savedSystemUiVisibility = savedInstanceState.getInt("SystemUiVisibility"); - m_delegate.displayManager().setSystemUiVisibility(savedSystemUiVisibility); + boolean isFullScreen = savedInstanceState.getBoolean("isFullScreen"); + boolean expandedToCutout = savedInstanceState.getBoolean("expandedToCutout"); + m_delegate.displayManager().setSystemUiVisibility(isFullScreen, expandedToCutout); // FIXME restore all surfaces } @@ -307,7 +308,8 @@ public class QtActivityBase extends Activity protected void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); - outState.putInt("SystemUiVisibility", m_delegate.displayManager().systemUiVisibility()); + outState.putBoolean("isFullScreen", m_delegate.displayManager().isFullScreen()); + outState.putBoolean("expandedToCutout", m_delegate.displayManager().expandedToCutout()); outState.putBoolean("Started", QtNative.getStateDetails().isStarted); } @@ -316,7 +318,7 @@ public class QtActivityBase extends Activity { super.onWindowFocusChanged(hasFocus); if (hasFocus) - m_delegate.displayManager().updateFullScreen(); + m_delegate.displayManager().reinstateFullScreen(); } @Override 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 fdee51e419f..123f25596cc 100644 --- a/src/android/jar/src/org/qtproject/qt/android/QtActivityDelegate.java +++ b/src/android/jar/src/org/qtproject/qt/android/QtActivityDelegate.java @@ -88,14 +88,14 @@ class QtActivityDelegate extends QtActivityDelegateBase } @Override - public void setSystemUiVisibility(int systemUiVisibility) + public void setSystemUiVisibility(boolean isFullScreen, boolean expandedToCutout) { if (m_layout == null) return; QtNative.runAction(() -> { if (m_layout != null) { - m_displayManager.setSystemUiVisibility(systemUiVisibility); + m_displayManager.setSystemUiVisibility(isFullScreen, expandedToCutout); m_layout.requestLayout(); QtNative.updateWindow(); } diff --git a/src/android/jar/src/org/qtproject/qt/android/QtActivityDelegateBase.java b/src/android/jar/src/org/qtproject/qt/android/QtActivityDelegateBase.java index 5bca2bca975..773ec0afca7 100644 --- a/src/android/jar/src/org/qtproject/qt/android/QtActivityDelegateBase.java +++ b/src/android/jar/src/org/qtproject/qt/android/QtActivityDelegateBase.java @@ -60,7 +60,7 @@ abstract class QtActivityDelegateBase m_activity = activity; QtNative.setActivity(m_activity); m_displayManager = new QtDisplayManager(m_activity); - m_inputDelegate = new QtInputDelegate(m_displayManager::updateFullScreen); + m_inputDelegate = new QtInputDelegate(m_displayManager::reinstateFullScreen); m_accessibilityDelegate = new QtAccessibilityDelegate(); } diff --git a/src/android/jar/src/org/qtproject/qt/android/QtDisplayManager.java b/src/android/jar/src/org/qtproject/qt/android/QtDisplayManager.java index 6c8fbfd50bf..6f97f052aae 100644 --- a/src/android/jar/src/org/qtproject/qt/android/QtDisplayManager.java +++ b/src/android/jar/src/org/qtproject/qt/android/QtDisplayManager.java @@ -16,12 +16,19 @@ import android.view.Surface; import android.view.View; import android.view.WindowInsets; import android.view.WindowManager; +import android.view.WindowManager.LayoutParams; import android.view.WindowMetrics; +import android.view.WindowInsetsController; +import android.view.Window; import java.util.ArrayList; import java.util.Arrays; import java.util.List; +import android.graphics.Color; +import android.util.TypedValue; +import android.content.res.Resources.Theme; + class QtDisplayManager { // screen methods @@ -38,11 +45,8 @@ class QtDisplayManager { static native void handleScreenRemoved(int displayId); // screen methods - // Keep in sync with QtAndroid::SystemUiVisibility in androidjnimain.h - static final int SYSTEM_UI_VISIBILITY_NORMAL = 0; - static final int SYSTEM_UI_VISIBILITY_FULLSCREEN = 1; - static final int SYSTEM_UI_VISIBILITY_TRANSLUCENT = 2; - private int m_systemUiVisibility = SYSTEM_UI_VISIBILITY_NORMAL; + private boolean m_isFullScreen = false; + private boolean m_expandedToCutout = false; private static int m_previousRotation = -1; @@ -123,62 +127,96 @@ class QtDisplayManager { displayManager.unregisterDisplayListener(m_displayListener); } - void setSystemUiVisibility(int systemUiVisibility) + void setSystemUiVisibility(boolean isFullScreen, boolean expandedToCutout) { - if (m_systemUiVisibility == systemUiVisibility) + if (m_isFullScreen == isFullScreen && m_expandedToCutout == expandedToCutout) return; - m_systemUiVisibility = systemUiVisibility; + m_isFullScreen = isFullScreen; + m_expandedToCutout = expandedToCutout; + Window window = m_activity.getWindow(); + View decorView = window.getDecorView(); - int systemUiVisibilityFlags = View.SYSTEM_UI_FLAG_VISIBLE; - switch (m_systemUiVisibility) { - case SYSTEM_UI_VISIBILITY_NORMAL: - m_activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN); - m_activity.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN); - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { - m_activity.getWindow().getAttributes().layoutInDisplayCutoutMode = - WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER; + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { + int cutoutMode; + if (m_isFullScreen || m_expandedToCutout) { + window.setDecorFitsSystemWindows(false); + cutoutMode = LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES; + } else { + window.setDecorFitsSystemWindows(true); + cutoutMode = LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_DEFAULT; + } + LayoutParams layoutParams = window.getAttributes(); + layoutParams.layoutInDisplayCutoutMode = cutoutMode; + window.setAttributes(layoutParams); + + final WindowInsetsController insetsControl = window.getInsetsController(); + if (insetsControl != null) { + int sysBarsBehavior; + if (m_isFullScreen) { + insetsControl.hide(WindowInsets.Type.systemBars()); + sysBarsBehavior = WindowInsetsController.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE; + } else { + insetsControl.show(WindowInsets.Type.systemBars()); + sysBarsBehavior = WindowInsetsController.BEHAVIOR_DEFAULT; } - break; - case SYSTEM_UI_VISIBILITY_FULLSCREEN: - m_activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN); - m_activity.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN); - systemUiVisibilityFlags = View.SYSTEM_UI_FLAG_HIDE_NAVIGATION - | View.SYSTEM_UI_FLAG_LAYOUT_STABLE - | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION - | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN - | View.SYSTEM_UI_FLAG_FULLSCREEN - | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY - | View.INVISIBLE; - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { - m_activity.getWindow().getAttributes().layoutInDisplayCutoutMode = - WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_DEFAULT; + insetsControl.setSystemBarsBehavior(sysBarsBehavior); + } + + + } else { + int systemUiVisibility; + + if (m_isFullScreen || m_expandedToCutout) { + systemUiVisibility = View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN + | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION; + if (m_isFullScreen) { + systemUiVisibility |= View.SYSTEM_UI_FLAG_LAYOUT_STABLE + | View.SYSTEM_UI_FLAG_FULLSCREEN + | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION + | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY; } - break; - case SYSTEM_UI_VISIBILITY_TRANSLUCENT: - m_activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN - | WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION - | WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS); - m_activity.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN); - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { - m_activity.getWindow().getAttributes().layoutInDisplayCutoutMode = - WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS; - } - break; + } else { + systemUiVisibility = View.SYSTEM_UI_FLAG_VISIBLE; + } + + decorView.setSystemUiVisibility(systemUiVisibility); + } + + // Handle transparent status and navigation bars + if (m_expandedToCutout) { + window.setStatusBarColor(Color.TRANSPARENT); + window.setNavigationBarColor(Color.TRANSPARENT); + } else { + // Restore theme's system bars colors + Theme theme = m_activity.getTheme(); + TypedValue typedValue = new TypedValue(); + + theme.resolveAttribute(android.R.attr.statusBarColor, typedValue, true); + int defaultStatusBarColor = typedValue.data; + window.setStatusBarColor(defaultStatusBarColor); + + theme.resolveAttribute(android.R.attr.navigationBarColor, typedValue, true); + int defaultNavigationBarColor = typedValue.data; + window.setNavigationBarColor(defaultNavigationBarColor); } - m_activity.getWindow().getDecorView().setSystemUiVisibility(systemUiVisibilityFlags); } - int systemUiVisibility() + boolean isFullScreen() { - return m_systemUiVisibility; + return m_isFullScreen; } - void updateFullScreen() + boolean expandedToCutout() { - if (m_systemUiVisibility == SYSTEM_UI_VISIBILITY_FULLSCREEN) { - m_systemUiVisibility = SYSTEM_UI_VISIBILITY_NORMAL; - setSystemUiVisibility(SYSTEM_UI_VISIBILITY_FULLSCREEN); + return m_expandedToCutout; + } + + void reinstateFullScreen() + { + if (m_isFullScreen) { + m_isFullScreen = false; + setSystemUiVisibility(true, m_expandedToCutout); } } diff --git a/src/android/jar/src/org/qtproject/qt/android/QtWindowInterface.java b/src/android/jar/src/org/qtproject/qt/android/QtWindowInterface.java index 1fb312786ff..d42b3e6821e 100644 --- a/src/android/jar/src/org/qtproject/qt/android/QtWindowInterface.java +++ b/src/android/jar/src/org/qtproject/qt/android/QtWindowInterface.java @@ -7,5 +7,5 @@ interface QtWindowInterface { default void removeTopLevelWindow(final int id) { } default void bringChildToFront(final int id) { } default void bringChildToBack(int id) { } - default void setSystemUiVisibility(int systemUiVisibility) { } + default void setSystemUiVisibility(boolean isFullScreen, boolean expandedToCutout) { } } diff --git a/src/plugins/platforms/android/qandroidplatformwindow.cpp b/src/plugins/platforms/android/qandroidplatformwindow.cpp index 00e82f93bbd..eb1fdab20d1 100644 --- a/src/plugins/platforms/android/qandroidplatformwindow.cpp +++ b/src/plugins/platforms/android/qandroidplatformwindow.cpp @@ -3,6 +3,7 @@ // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only #include "qandroidplatformwindow.h" +#include "androidbackendregister.h" #include "qandroidplatformopenglcontext.h" #include "qandroidplatformscreen.h" @@ -255,19 +256,13 @@ void QAndroidPlatformWindow::requestActivateWindow() void QAndroidPlatformWindow::updateSystemUiVisibility() { - Qt::WindowFlags flags = window()->flags(); - bool isNonRegularWindow = flags & (Qt::Popup | Qt::Dialog | Qt::Sheet) & ~Qt::Window; + const int flags = window()->flags(); + const bool isNonRegularWindow = flags & (Qt::Popup | Qt::Dialog | Qt::Sheet) & ~Qt::Window; if (!isNonRegularWindow) { - SystemUiVisibility visibility; - if (m_windowState & Qt::WindowFullScreen) - visibility = SYSTEM_UI_VISIBILITY_FULLSCREEN; - else if (flags & Qt::MaximizeUsingFullscreenGeometryHint) - visibility = SYSTEM_UI_VISIBILITY_TRANSLUCENT; - else - visibility = SYSTEM_UI_VISIBILITY_NORMAL; - + const bool isFullScreen = (m_windowState & Qt::WindowFullScreen); + const bool expandedToCutout = (flags & Qt::MaximizeUsingFullscreenGeometryHint); QtAndroid::backendRegister()->callInterface( - "setSystemUiVisibility", jint(visibility)); + "setSystemUiVisibility", isFullScreen, expandedToCutout); } } diff --git a/src/plugins/platforms/android/qandroidplatformwindow.h b/src/plugins/platforms/android/qandroidplatformwindow.h index 4c6fb1f1c3c..c282adb9b0e 100644 --- a/src/plugins/platforms/android/qandroidplatformwindow.h +++ b/src/plugins/platforms/android/qandroidplatformwindow.h @@ -31,13 +31,6 @@ public: TextureView }; - // Keep synchronized with flags in ActivityDelegate.java - enum SystemUiVisibility { - SYSTEM_UI_VISIBILITY_NORMAL = 0, - SYSTEM_UI_VISIBILITY_FULLSCREEN = 1, - SYSTEM_UI_VISIBILITY_TRANSLUCENT = 2 - }; - explicit QAndroidPlatformWindow(QWindow *window); void initialize() override;