summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorTinja Paavoseppä <tinja.paavoseppa@qt.io>2023-12-08 11:24:43 +0200
committerTinja Paavoseppä <tinja.paavoseppa@qt.io>2023-12-08 15:53:37 +0200
commit2bc7d38bd63843c4598ed501e3adbf0e39162c61 (patch)
treed3d9ffb035add93e032661095e2ec399b8da3526 /src
parent6ff88f97a6d24d1098583421161f8f903f9dafde (diff)
Android: Make QtWindow wrap the QtLayout instead of inherit it
The layout is a ViewGroup, and should be created in the Android UI thread, while for ease of use on C++ side we should be able to construct the Java object in the platform window constructor to avoid later calls not having a valid object reference. Trying to make a blocking call to Android thread from Qt thread can lead to dead locks, so move only the creation of the layout itself into Android thread, making the QtWindow a wrapper for it, which we can immediately return to C++/Qt thread. Most of the calls made to QtWindow are anyway already passed to the Android UI thread. As a drive by, add a missing QtNative.runAction() to bringChildToFront(). Change-Id: Ib2495ddda8267384656557cbe40be5da869f82c3 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/QtActivityDelegate.java12
-rw-r--r--src/android/jar/src/org/qtproject/qt/android/QtWindow.java69
-rw-r--r--src/plugins/platforms/android/qandroidplatformwindow.cpp10
3 files changed, 52 insertions, 39 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 b7d1f207daf..8f6114a7c2f 100644
--- a/src/android/jar/src/org/qtproject/qt/android/QtActivityDelegate.java
+++ b/src/android/jar/src/org/qtproject/qt/android/QtActivityDelegate.java
@@ -386,11 +386,11 @@ class QtActivityDelegate
}
}
- window.setLayoutParams(new ViewGroup.LayoutParams(
+ window.getLayout().setLayoutParams(new ViewGroup.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT));
- m_layout.addView(window, m_topLevelWindows.size());
+ m_layout.addView(window.getLayout(), m_topLevelWindows.size());
m_topLevelWindows.put(window.getId(), window);
if (!m_splashScreenSticky)
hideSplashScreen();
@@ -406,9 +406,9 @@ class QtActivityDelegate
if (m_topLevelWindows.isEmpty()) {
// Keep last frame in stack until it is replaced to get correct
// shutdown transition
- m_dummyView = window;
+ m_dummyView = window.getLayout();
} else {
- m_layout.removeView(window);
+ m_layout.removeView(window.getLayout());
}
}
});
@@ -420,7 +420,7 @@ class QtActivityDelegate
QtNative.runAction(() -> {
QtWindow window = m_topLevelWindows.get(id);
if (window != null) {
- m_layout.moveChild(window, m_topLevelWindows.size() - 1);
+ m_layout.moveChild(window.getLayout(), m_topLevelWindows.size() - 1);
}
});
}
@@ -431,7 +431,7 @@ class QtActivityDelegate
QtNative.runAction(() -> {
QtWindow window = m_topLevelWindows.get(id);
if (window != null)
- m_layout.moveChild(window, 0);
+ m_layout.moveChild(window.getLayout(), 0);
});
}
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 757b00d93f8..79e7b96cb9b 100644
--- a/src/android/jar/src/org/qtproject/qt/android/QtWindow.java
+++ b/src/android/jar/src/org/qtproject/qt/android/QtWindow.java
@@ -11,33 +11,46 @@ import android.view.ViewGroup;
import java.util.HashMap;
-public class QtWindow extends QtLayout implements QtSurface.SurfaceChangedCallback {
+public class QtWindow implements QtSurface.SurfaceChangedCallback {
private final static String TAG = "QtWindow";
+ private QtLayout m_layout;
private QtSurface m_surface;
private View m_nativeView;
private HashMap<Integer, QtWindow> m_childWindows = new HashMap<Integer, QtWindow>();
private QtWindow m_parentWindow;
+ private int m_id;
private static native void setSurface(int windowId, Surface surface);
public QtWindow(Context context, QtWindow parentWindow)
{
- super(context);
- setId(View.generateViewId());
-
- setParent(parentWindow);
+ m_id = View.generateViewId();
+ QtNative.runAction(() -> {
+ m_layout = new QtLayout(context);
+ setParent(parentWindow);
+ });
}
void setVisible(boolean visible) {
QtNative.runAction(() -> {
if (visible)
- setVisibility(View.VISIBLE);
+ m_layout.setVisibility(View.VISIBLE);
else
- setVisibility(View.INVISIBLE);
+ m_layout.setVisibility(View.INVISIBLE);
});
}
+ public int getId()
+ {
+ return m_id;
+ }
+
+ public QtLayout getLayout()
+ {
+ return m_layout;
+ }
+
@Override
public void onSurfaceChanged(Surface surface)
{
@@ -58,15 +71,15 @@ public class QtWindow extends QtLayout implements QtSurface.SurfaceChangedCallba
@Override
public void run() {
if (m_surface != null)
- removeView(m_surface);
+ m_layout.removeView(m_surface);
- setLayoutParams(new QtLayout.LayoutParams(w, h, x, y));
+ m_layout.setLayoutParams(new QtLayout.LayoutParams(w, h, x, y));
// TODO currently setting child windows to onTop, since their surfaces
// now get created earlier than the parents -> they are behind the parent window
// without this, and SurfaceView z-ordering is limited
boolean tempOnTop = onTop || (m_parentWindow != null);
- QtSurface surface = new QtSurface(getContext(), QtWindow.this,
+ QtSurface surface = new QtSurface(m_layout.getContext(), QtWindow.this,
QtWindow.this.getId(), tempOnTop, imageDepth);
surface.setLayoutParams(new QtLayout.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
@@ -74,7 +87,7 @@ public class QtWindow extends QtLayout implements QtSurface.SurfaceChangedCallba
// The QtSurface of this window will be added as the first of the stack.
// All other views are stacked based on the order they are created.
- addView(surface, 0);
+ m_layout.addView(surface, 0);
m_surface = surface;
}
});
@@ -86,7 +99,7 @@ public class QtWindow extends QtLayout implements QtSurface.SurfaceChangedCallba
@Override
public void run() {
if (m_surface != null) {
- removeView(m_surface);
+ m_layout.removeView(m_surface);
m_surface = null;
}
}
@@ -98,7 +111,7 @@ public class QtWindow extends QtLayout implements QtSurface.SurfaceChangedCallba
QtNative.runAction(new Runnable() {
@Override
public void run() {
- QtWindow.this.setLayoutParams(new QtLayout.LayoutParams(w, h, x, y));
+ m_layout.setLayoutParams(new QtLayout.LayoutParams(w, h, x, y));
}
});
}
@@ -109,7 +122,7 @@ public class QtWindow extends QtLayout implements QtSurface.SurfaceChangedCallba
@Override
public void run() {
m_childWindows.put(window.getId(), window);
- addView(window, getChildCount());
+ m_layout.addView(window.getLayout(), m_layout.getChildCount());
}
});
}
@@ -120,7 +133,7 @@ public class QtWindow extends QtLayout implements QtSurface.SurfaceChangedCallba
@Override
public void run() {
if (m_childWindows.containsKey(id))
- removeView(m_childWindows.remove(id));
+ m_layout.removeView(m_childWindows.remove(id).getLayout());
}
});
}
@@ -132,33 +145,35 @@ public class QtWindow extends QtLayout implements QtSurface.SurfaceChangedCallba
@Override
public void run() {
if (m_nativeView != null)
- removeView(m_nativeView);
+ m_layout.removeView(m_nativeView);
m_nativeView = view;
- QtWindow.this.setLayoutParams(new QtLayout.LayoutParams(w, h, x, y));
+ m_layout.setLayoutParams(new QtLayout.LayoutParams(w, h, x, y));
m_nativeView.setLayoutParams(new QtLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT));
- addView(m_nativeView);
+ m_layout.addView(m_nativeView);
}
});
}
public void bringChildToFront(int id)
{
- View view = m_childWindows.get(id);
- if (view != null) {
- if (getChildCount() > 0)
- moveChild(view, getChildCount() - 1);
- }
+ QtNative.runAction(()-> {
+ QtWindow window = m_childWindows.get(id);
+ if (window != null) {
+ if (m_layout.getChildCount() > 0)
+ m_layout.moveChild(window.getLayout(), m_layout.getChildCount() - 1);
+ }
+ });
}
public void bringChildToBack(int id) {
QtNative.runAction(new Runnable() {
@Override
public void run() {
- View view = m_childWindows.get(id);
- if (view != null) {
- moveChild(view, 0);
+ QtWindow window = m_childWindows.get(id);
+ if (window != null) {
+ m_layout.moveChild(window.getLayout(), 0);
}
}
});
@@ -170,7 +185,7 @@ public class QtWindow extends QtLayout implements QtSurface.SurfaceChangedCallba
@Override
public void run() {
if (m_nativeView != null) {
- removeView(m_nativeView);
+ m_layout.removeView(m_nativeView);
m_nativeView = null;
}
}
diff --git a/src/plugins/platforms/android/qandroidplatformwindow.cpp b/src/plugins/platforms/android/qandroidplatformwindow.cpp
index 9a633e97afe..84a4eab3892 100644
--- a/src/plugins/platforms/android/qandroidplatformwindow.cpp
+++ b/src/plugins/platforms/android/qandroidplatformwindow.cpp
@@ -51,12 +51,10 @@ QAndroidPlatformWindow::QAndroidPlatformWindow(QWindow *window)
if (parent())
m_nativeParentQtWindow = static_cast<QAndroidPlatformWindow*>(parent())->nativeWindow();
- QNativeInterface::QAndroidApplication::runOnAndroidMainThread([this]() {
- m_nativeQtWindow = QJniObject::construct<QtJniTypes::QtWindow>(
- QNativeInterface::QAndroidApplication::context(),
- m_nativeParentQtWindow);
- m_nativeViewId = m_nativeQtWindow.callMethod<jint>("getId");
- }).waitForFinished();
+ m_nativeQtWindow = QJniObject::construct<QtJniTypes::QtWindow>(
+ QNativeInterface::QAndroidApplication::context(),
+ m_nativeParentQtWindow);
+ m_nativeViewId = m_nativeQtWindow.callMethod<jint>("getId");
if (window->isTopLevel())
platformScreen()->addWindow(this);