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>
This commit is contained in:
parent
6ff88f97a6
commit
2bc7d38bd6
@ -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);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user