diff options
Diffstat (limited to 'src')
3 files changed, 87 insertions, 21 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 7dd00358546..038aff3c0b1 100644 --- a/src/android/jar/src/org/qtproject/qt/android/QtActivityDelegate.java +++ b/src/android/jar/src/org/qtproject/qt/android/QtActivityDelegate.java @@ -9,9 +9,11 @@ import android.app.Activity; import android.content.pm.ActivityInfo; import android.content.pm.PackageManager; import android.content.res.Configuration; +import android.content.res.TypedArray; import android.graphics.drawable.ColorDrawable; import android.graphics.drawable.Drawable; import android.graphics.Rect; +import android.graphics.Color; import android.util.DisplayMetrics; import android.util.Log; import android.util.TypedValue; @@ -39,7 +41,6 @@ class QtActivityDelegate extends QtActivityDelegateBase private boolean m_splashScreenSticky = false; private boolean m_backendsRegistered = false; - private View m_dummyView = null; private final HashMap<Integer, View> m_nativeViews = new HashMap<>(); QtActivityDelegate(Activity activity) @@ -197,6 +198,19 @@ class QtActivityDelegate extends QtActivityDelegateBase ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT)); m_layout.addView(m_splashScreen); + + // Set DayNight theme as layout background so splash screen + // is not visible with opaque windows. + TypedArray typedArray = m_activity.getTheme().obtainStyledAttributes( + android.R.style.Theme_DeviceDefault_DayNight, + new int[]{ android.R.attr.colorBackground }); + try { + int backgroundColor = typedArray.getColor(0, Color.WHITE); + Drawable background = new ColorDrawable(backgroundColor); + m_layout.setBackground(background); + } finally { + typedArray.recycle(); + } } } catch (Exception e) { e.printStackTrace(); @@ -368,15 +382,9 @@ class QtActivityDelegate extends QtActivityDelegateBase if (m_layout == null) return; - if (m_topLevelWindows.isEmpty()) { - if (m_dummyView != null) { - m_layout.removeView(m_dummyView); - m_dummyView = null; - } - } - m_layout.addView(window, m_topLevelWindows.size()); m_topLevelWindows.put(window.getId(), window); + window.setToDestroy(false); if (!m_splashScreenSticky) hideSplashScreen(); }); @@ -390,13 +398,13 @@ class QtActivityDelegate extends QtActivityDelegateBase 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 - m_dummyView = window; - } else if (m_layout != null) { - m_layout.removeView(window); - } + if (window.isFrontmostVisibleWindow()) { + window.setToDestroy(true); + // Keep current shown window open during shutdown transition + m_layout.postDelayed(() -> { window.destroySurface(); }, 500); + } else if (m_layout != null) { + m_layout.removeView(window); + } } }); } @@ -452,11 +460,6 @@ class QtActivityDelegate extends QtActivityDelegateBase return; QtNative.runAction(()-> { - if (m_dummyView != null) { - m_layout.removeView(m_dummyView); - m_dummyView = null; - } - if (m_nativeViews.containsKey(id)) m_layout.removeView(m_nativeViews.remove(id)); 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 e4f489a39da..905803750e8 100644 --- a/src/android/jar/src/org/qtproject/qt/android/QtWindow.java +++ b/src/android/jar/src/org/qtproject/qt/android/QtWindow.java @@ -20,6 +20,7 @@ import android.view.WindowInsets; import android.os.Build; import java.util.HashMap; +import java.util.concurrent.atomic.AtomicBoolean; @SuppressLint("ViewConstructor") class QtWindow extends QtLayout implements QtSurfaceInterface { @@ -30,6 +31,7 @@ class QtWindow extends QtLayout implements QtSurfaceInterface { private GestureDetector m_gestureDetector; private final QtEditText m_editText; private final QtInputConnection.QtInputConnectionListener m_inputConnectionListener; + private final AtomicBoolean m_canBeDestroyed = new AtomicBoolean(true); private static native void setSurface(int windowId, Surface surface); private static native void safeAreaMarginsChanged(Insets insets, int id); @@ -157,6 +159,60 @@ class QtWindow extends QtLayout implements QtSurfaceInterface { QtNative.runAction(() -> setVisibility(visible ? View.VISIBLE : View.INVISIBLE)); } + // Use only for Qt for Android and not Qt Quick for Android + @UsedFromNativeCode + public void setToDestroy(boolean destroy) + { + m_canBeDestroyed.set(destroy); + } + + // Use only for Qt for Android and not Qt Quick for Android + private QtLayout getParentContainer() + { + if (!(getParent() instanceof QtLayout)) + return null; + return (QtLayout) getParent(); + } + + // Use only for Qt for Android and not Qt Quick for Android + public boolean isFrontmostVisibleWindow() + { + QtLayout parent = getParentContainer(); + if (getVisibility() != View.VISIBLE || parent == null) + return false; + + for (int index = parent.indexOfChild(this) + 1; index < parent.getChildCount(); index ++) { + View child = parent.getChildAt(index); + if (child instanceof QtWindow && child.isShown()) + return false; + } + + return true; + } + + // Use only for Qt for Android and not Qt Quick for Android + @UsedFromNativeCode + public boolean isLastVisibleTopLevelWindow() + { + QtLayout parent = getParentContainer(); + if (getVisibility() != View.VISIBLE || parent == null) + return false; + + for (int index = parent.indexOfChild(this) - 1; index >= 0; index--) { + View child = parent.getChildAt(index); + if (child instanceof QtWindow) { + QtWindow childWindow = (QtWindow) child; + if (child.getVisibility() == View.VISIBLE && !childWindow.m_canBeDestroyed.get()) + return false; + } + } + + if (parent.getChildCount() > 1 && !isFrontmostVisibleWindow()) + return false; + + return true; + } + @Override public void onSurfaceChanged(Surface surface) { @@ -223,7 +279,7 @@ class QtWindow extends QtLayout implements QtSurfaceInterface { void destroySurface() { QtNative.runAction(()-> { - if (m_surfaceContainer != null) { + if (m_surfaceContainer != null && m_canBeDestroyed.get()) { removeView(m_surfaceContainer); m_surfaceContainer = null; } diff --git a/src/plugins/platforms/android/qandroidplatformwindow.cpp b/src/plugins/platforms/android/qandroidplatformwindow.cpp index 194a08ee09f..efc62047e3e 100644 --- a/src/plugins/platforms/android/qandroidplatformwindow.cpp +++ b/src/plugins/platforms/android/qandroidplatformwindow.cpp @@ -168,6 +168,13 @@ void QAndroidPlatformWindow::setVisible(bool visible) return; if (window()->isTopLevel()) { + // Do not hide last Qt for Android window. + // We don't want the splash screen to be shown during the app's + // exit because it would be the foremost visible screen. + if (QtAndroid::isQtApplication() && !visible) { + visible = m_nativeQtWindow.callMethod<bool>("isLastVisibleTopLevelWindow"); + m_nativeQtWindow.callMethod<void>("setToDestroy", !visible); + } if (!visible && window() == qGuiApp->focusWindow()) { platformScreen()->topVisibleWindowChanged(); } else { |
