Hello community,

here is the log from the commit of package kwayland for openSUSE:Factory 
checked in at 2018-02-09 15:44:57
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/kwayland (Old)
 and      /work/SRC/openSUSE:Factory/.kwayland.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "kwayland"

Fri Feb  9 15:44:57 2018 rev:45 rq:573390 version:5.42.0

Changes:
--------
--- /work/SRC/openSUSE:Factory/kwayland/kwayland.changes        2018-01-22 
16:03:37.795727344 +0100
+++ /work/SRC/openSUSE:Factory/.kwayland.new/kwayland.changes   2018-02-09 
15:44:58.740921823 +0100
@@ -1,0 +2,7 @@
+Tue Feb  6 16:00:45 UTC 2018 - lbeltr...@kde.org
+
+- Add 0001-server-Don-t-crash-when-a-subsurface-gets-commited-w.patch
+  * Upstream fix to prevent kwin from crashing when opening
+    systemsettings (kde#389231)
+
+-------------------------------------------------------------------

New:
----
  0001-server-Don-t-crash-when-a-subsurface-gets-commited-w.patch

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ kwayland.spec ++++++
--- /var/tmp/diff_new_pack.GxHNWe/_old  2018-02-09 15:44:59.552892668 +0100
+++ /var/tmp/diff_new_pack.GxHNWe/_new  2018-02-09 15:44:59.552892668 +0100
@@ -30,6 +30,8 @@
 Url:            http://www.kde.org
 Source:         
http://download.kde.org/stable/frameworks/%{_tar_path}/%{name}-%{version}.tar.xz
 Source1:        baselibs.conf
+# PATCH-FIX-UPSTREAM
+Patch0:         0001-server-Don-t-crash-when-a-subsurface-gets-commited-w.patch
 BuildRequires:  cmake >= 3.0
 BuildRequires:  extra-cmake-modules >= %{_kf5_bugfix_version}
 BuildRequires:  fdupes
@@ -69,6 +71,7 @@
 
 %prep
 %setup -q
+%patch0 -p1
 
 %build
   %cmake_kf5 -d build

++++++ 0001-server-Don-t-crash-when-a-subsurface-gets-commited-w.patch ++++++
>From abfd8c2f896bf38c703755952bb3c955ff83a8f1 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Martin=20Fl=C3=B6ser?= <mgraess...@kde.org>
Date: Tue, 6 Feb 2018 16:57:59 +0100
Subject: [PATCH] [server] Don't crash when a subsurface gets commited whose
 parent surface got destroyed

Summary:
Qt seems to damage and commit child subsurfaces although their parent
got destroyed. This actually doesn't make any sense as without a parent
surface they cannot be shown. But nevertheless we should not crash in
such a situation.

This change guards the places in the commit handling code where the
parent gets accessed.

BUG: 389231

Test Plan: New test case which exposes the problem

Reviewers: #frameworks, #kwin, #plasma, davidedmundson

Reviewed By: #plasma, davidedmundson

Subscribers: plasma-devel

Tags: #frameworks, #plasma_on_wayland

Differential Revision: https://phabricator.kde.org/D10300
---
 autotests/client/test_wayland_subsurface.cpp | 47 ++++++++++++++++++++++++++++
 src/server/subcompositor_interface.cpp       |  3 ++
 src/server/surface_interface.cpp             |  7 +++--
 3 files changed, 55 insertions(+), 2 deletions(-)

diff --git a/autotests/client/test_wayland_subsurface.cpp 
b/autotests/client/test_wayland_subsurface.cpp
index 42c326a..dc53a1b 100644
--- a/autotests/client/test_wayland_subsurface.cpp
+++ b/autotests/client/test_wayland_subsurface.cpp
@@ -59,6 +59,7 @@ private Q_SLOTS:
     void testMappingOfSurfaceTree();
     void testSurfaceAt();
     void testDestroyAttachedBuffer();
+    void testDestroyParentSurface();
 
 private:
     KWayland::Server::Display *m_display;
@@ -1041,5 +1042,51 @@ void TestSubSurface::testDestroyAttachedBuffer()
     QVERIFY(destroySpy.wait());
 }
 
+void TestSubSurface::testDestroyParentSurface()
+{
+    // this test verifies that destroying a parent surface does not create 
problems
+    // see BUG 389231
+    using namespace KWayland::Client;
+    using namespace KWayland::Server;
+    // create surface
+    QSignalSpy serverSurfaceCreated(m_compositorInterface, 
&CompositorInterface::surfaceCreated);
+    QVERIFY(serverSurfaceCreated.isValid());
+    QScopedPointer<Surface> parent(m_compositor->createSurface());
+    QVERIFY(serverSurfaceCreated.wait());
+    SurfaceInterface *serverParentSurface = 
serverSurfaceCreated.last().first().value<KWayland::Server::SurfaceInterface*>();
+    QScopedPointer<Surface> child(m_compositor->createSurface());
+    QVERIFY(serverSurfaceCreated.wait());
+    SurfaceInterface *serverChildSurface = 
serverSurfaceCreated.last().first().value<KWayland::Server::SurfaceInterface*>();
+    QScopedPointer<Surface> grandChild(m_compositor->createSurface());
+    QVERIFY(serverSurfaceCreated.wait());
+    SurfaceInterface *serverGrandChildSurface = 
serverSurfaceCreated.last().first().value<KWayland::Server::SurfaceInterface*>();
+    // create sub-surface in desynchronized mode as Qt uses them
+    auto sub1 = m_subCompositor->createSubSurface(child.data(), parent.data());
+    sub1->setMode(SubSurface::Mode::Desynchronized);
+    auto sub2 = m_subCompositor->createSubSurface(grandChild.data(), 
child.data());
+    sub2->setMode(SubSurface::Mode::Desynchronized);
+
+    // let's damage this surface
+    // and at the same time delete the parent surface
+    parent.reset();
+    QSignalSpy parentDestroyedSpy(serverParentSurface, &QObject::destroyed);
+    QVERIFY(parentDestroyedSpy.isValid());
+    QVERIFY(parentDestroyedSpy.wait());
+    QImage image(QSize(100, 100), QImage::Format_ARGB32_Premultiplied);
+    image.fill(Qt::red);
+    grandChild->attachBuffer(m_shm->createBuffer(image));
+    grandChild->damage(QRect(0, 0, 100, 100));
+    grandChild->commit(Surface::CommitFlag::None);
+    QSignalSpy damagedSpy(serverGrandChildSurface, &SurfaceInterface::damaged);
+    QVERIFY(damagedSpy.isValid());
+    QVERIFY(damagedSpy.wait());
+
+    // Let's try to destroy it
+    QSignalSpy destroySpy(serverChildSurface, &QObject::destroyed);
+    QVERIFY(destroySpy.isValid());
+    child.reset();
+    QVERIFY(destroySpy.wait());
+}
+
 QTEST_GUILESS_MAIN(TestSubSurface)
 #include "test_wayland_subsurface.moc"
diff --git a/src/server/subcompositor_interface.cpp 
b/src/server/subcompositor_interface.cpp
index f829ab2..f2b6de9 100644
--- a/src/server/subcompositor_interface.cpp
+++ b/src/server/subcompositor_interface.cpp
@@ -360,6 +360,9 @@ bool SubSurfaceInterface::isSynchronized() const
 QPointer<SurfaceInterface> SubSurfaceInterface::mainSurface() const
 {
     Q_D();
+    if (!d->parent) {
+        return QPointer<SurfaceInterface>();
+    }
     if (d->parent->d_func()->subSurface) {
         return d->parent->d_func()->subSurface->mainSurface();
     }
diff --git a/src/server/surface_interface.cpp b/src/server/surface_interface.cpp
index 5102271..3787794 100644
--- a/src/server/surface_interface.cpp
+++ b/src/server/surface_interface.cpp
@@ -453,8 +453,11 @@ void SurfaceInterface::Private::swapStates(State *source, 
State *target, bool em
                     emit q->damaged(target->damage);
                     // workaround for 
https://bugreports.qt.io/browse/QTBUG-52092
                     // if the surface is a sub-surface, but the main surface 
is not yet mapped, fake frame rendered
-                    if (subSurface && !subSurface->mainSurface()->buffer()) {
-                        q->frameRendered(0);
+                    if (subSurface) {
+                        const auto mainSurface = subSurface->mainSurface();
+                        if (!mainSurface || !mainSurface->buffer()) {
+                            q->frameRendered(0);
+                        }
                     }
                 }
             }
-- 
2.16.1


Reply via email to