[server] Don't double buffer adding/removing of sub-surfaces
QtWayland doesn't commit the parent surface when creating a sub-surface. This results in a QtWayland application to freeze as it renders to the surface and waits for the frame rendered, which it will never get as the Compositor waits for the commit on the parent prior to mapping the sub-surface. To work around this behavior, we apply the adding/removing directly. The behavior around this is actually not fully documented, so QtWayland is not wrong per se. See: https://lists.freedesktop.org/archives/wayland-devel/2016-March/027540.html Once this is properly clarified and implemented in the Client, we should revert this change. Differential Revision: https://phabricator.kde.org/D1191
This commit is contained in:
parent
263e5d7969
commit
610fbc672f
2 changed files with 15 additions and 13 deletions
|
@ -207,6 +207,7 @@ void TestSubSurface::testCreate()
|
|||
QCOMPARE(serverSubSurface->surface().data(), serverSurface);
|
||||
QCOMPARE(serverSurface->subSurface().data(), serverSubSurface);
|
||||
// children are only added after committing the surface
|
||||
QEXPECT_FAIL("", "Incorrect adding of child windows to workaround QtWayland behavior", Continue);
|
||||
QCOMPARE(serverParentSurface->childSubSurfaces().count(), 0);
|
||||
// so let's commit the surface, to apply the stacking change
|
||||
parent->commit(Surface::CommitFlag::None);
|
||||
|
@ -222,9 +223,12 @@ void TestSubSurface::testCreate()
|
|||
QVERIFY(destroyedSpy.wait());
|
||||
QCOMPARE(serverSurface->subSurface(), QPointer<SubSurfaceInterface>());
|
||||
// only applied after next commit
|
||||
QEXPECT_FAIL("", "Incorrect removing of child windows to workaround QtWayland behavior", Continue);
|
||||
QCOMPARE(serverParentSurface->childSubSurfaces().count(), 1);
|
||||
// but the surface should be invalid
|
||||
QVERIFY(serverParentSurface->childSubSurfaces().first().isNull());
|
||||
if (!serverParentSurface->childSubSurfaces().isEmpty()) {
|
||||
QVERIFY(serverParentSurface->childSubSurfaces().first().isNull());
|
||||
}
|
||||
// committing the state should solve it
|
||||
parent->commit(Surface::CommitFlag::None);
|
||||
wl_display_flush(m_connection->display());
|
||||
|
@ -364,6 +368,7 @@ void TestSubSurface::testPlaceAbove()
|
|||
subSurfaceCreatedSpy.clear();
|
||||
|
||||
// so far the stacking order should still be empty
|
||||
QEXPECT_FAIL("", "Incorrect adding of child windows to workaround QtWayland behavior", Continue);
|
||||
QVERIFY(serverSubSurface1->parentSurface()->childSubSurfaces().isEmpty());
|
||||
|
||||
// committing the parent should create the stacking order
|
||||
|
@ -464,6 +469,7 @@ void TestSubSurface::testPlaceBelow()
|
|||
subSurfaceCreatedSpy.clear();
|
||||
|
||||
// so far the stacking order should still be empty
|
||||
QEXPECT_FAIL("", "Incorrect adding of child windows to workaround QtWayland behavior", Continue);
|
||||
QVERIFY(serverSubSurface1->parentSurface()->childSubSurfaces().isEmpty());
|
||||
|
||||
// committing the parent should create the stacking order
|
||||
|
|
|
@ -47,12 +47,10 @@ SurfaceInterface::Private::~Private()
|
|||
|
||||
void SurfaceInterface::Private::addChild(QPointer< SubSurfaceInterface > child)
|
||||
{
|
||||
// protocol is not precise on how to handle the addition of new sub surfaces, this follows Weston's behavior
|
||||
if (subSurface.isNull() || !subSurface->isSynchronized()) {
|
||||
pending.children.append(child);
|
||||
} else {
|
||||
subSurfacePending.children.append(child);
|
||||
}
|
||||
// protocol is not precise on how to handle the addition of new sub surfaces
|
||||
pending.children.append(child);
|
||||
subSurfacePending.children.append(child);
|
||||
current.children.append(child);
|
||||
Q_Q(SurfaceInterface);
|
||||
emit q->subSurfaceTreeChanged();
|
||||
QObject::connect(child.data(), &SubSurfaceInterface::positionChanged, q, &SurfaceInterface::subSurfaceTreeChanged);
|
||||
|
@ -63,12 +61,10 @@ void SurfaceInterface::Private::addChild(QPointer< SubSurfaceInterface > child)
|
|||
|
||||
void SurfaceInterface::Private::removeChild(QPointer< SubSurfaceInterface > child)
|
||||
{
|
||||
// protocol is not precise on how to handle the addition of new sub surfaces, this follows Weston's behavior
|
||||
if (subSurface.isNull() || !subSurface->isSynchronized()) {
|
||||
pending.children.removeAll(child);
|
||||
} else {
|
||||
subSurfacePending.children.removeAll(child);
|
||||
}
|
||||
// protocol is not precise on how to handle the addition of new sub surfaces
|
||||
pending.children.removeAll(child);
|
||||
subSurfacePending.children.removeAll(child);
|
||||
current.children.removeAll(child);
|
||||
Q_Q(SurfaceInterface);
|
||||
emit q->subSurfaceTreeChanged();
|
||||
QObject::disconnect(child.data(), &SubSurfaceInterface::positionChanged, q, &SurfaceInterface::subSurfaceTreeChanged);
|
||||
|
|
Loading…
Reference in a new issue