Hello community, here is the log from the commit of package kwayland for openSUSE:Factory checked in at 2018-03-20 21:48:03 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/kwayland (Old) and /work/SRC/openSUSE:Factory/.kwayland.new (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "kwayland" Tue Mar 20 21:48:03 2018 rev:47 rq:586860 version:5.44.0 Changes: -------- --- /work/SRC/openSUSE:Factory/kwayland/kwayland.changes 2018-02-16 21:34:41.796684570 +0100 +++ /work/SRC/openSUSE:Factory/.kwayland.new/kwayland.changes 2018-03-20 21:48:07.776105717 +0100 @@ -1,0 +2,14 @@ +Mon Mar 12 23:29:42 CET 2018 - [email protected] + +- Update to 5.44.0 + * New feature release + * For more details please see: + * https://www.kde.org/announcements/kde-frameworks-5.44.0.php +- Changes since 5.43.0: + * Implement releasing of client-freed output + * [server] Properly handle the situation when the DataSource for a drag gets destroyed (kde#389221) + * [server] Don't crash when a subsurface gets commited whose parent surface got destroyed (kde#389231) +- Dropped patches, now upstream: + * 0001-server-Don-t-crash-when-a-subsurface-gets-commited-w.patch + +------------------------------------------------------------------- Old: ---- 0001-server-Don-t-crash-when-a-subsurface-gets-commited-w.patch kwayland-5.43.0.tar.xz New: ---- kwayland-5.44.0.tar.xz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ kwayland.spec ++++++ --- /var/tmp/diff_new_pack.Pdb92l/_old 2018-03-20 21:48:08.536078349 +0100 +++ /var/tmp/diff_new_pack.Pdb92l/_new 2018-03-20 21:48:08.536078349 +0100 @@ -16,22 +16,20 @@ # -%define _tar_path 5.43 +%define _tar_path 5.44 # Full KF5 version (e.g. 5.33.0) %{!?_kf5_version: %global _kf5_version %{version}} # Last major and minor KF5 version (e.g. 5.33) %{!?_kf5_bugfix_version: %global _kf5_bugfix_version %(echo %{_kf5_version} | awk -F. '{print $1"."$2}')} Name: kwayland -Version: 5.43.0 +Version: 5.44.0 Release: 0 Summary: KDE Wayland library -License: LGPL-2.1+ +License: LGPL-2.1-or-later Group: Development/Libraries/KDE 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 @@ -71,7 +69,6 @@ %prep %setup -q -%patch0 -p1 %build %cmake_kf5 -d build ++++++ kwayland-5.43.0.tar.xz -> kwayland-5.44.0.tar.xz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kwayland-5.43.0/CMakeLists.txt new/kwayland-5.44.0/CMakeLists.txt --- old/kwayland-5.43.0/CMakeLists.txt 2018-02-05 09:12:05.000000000 +0100 +++ new/kwayland-5.44.0/CMakeLists.txt 2018-03-03 10:53:50.000000000 +0100 @@ -1,11 +1,11 @@ cmake_minimum_required(VERSION 3.0) -set(KF5_VERSION "5.43.0") # handled by release scripts +set(KF5_VERSION "5.44.0") # handled by release scripts project(KWayland VERSION ${KF5_VERSION}) # ECM setup include(FeatureSummary) -find_package(ECM 5.43.0 NO_MODULE) +find_package(ECM 5.44.0 NO_MODULE) set_package_properties(ECM PROPERTIES TYPE REQUIRED DESCRIPTION "Extra CMake Modules." URL "https://projects.kde.org/projects/kdesupport/extra-cmake-modules") feature_summary(WHAT REQUIRED_PACKAGES_NOT_FOUND FATAL_ON_MISSING_REQUIRED_PACKAGES) set(CMAKE_MODULE_PATH ${ECM_MODULE_PATH} ${ECM_KDE_MODULE_DIR}) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kwayland-5.43.0/autotests/client/test_drag_drop.cpp new/kwayland-5.44.0/autotests/client/test_drag_drop.cpp --- old/kwayland-5.43.0/autotests/client/test_drag_drop.cpp 2018-02-05 09:12:05.000000000 +0100 +++ new/kwayland-5.44.0/autotests/client/test_drag_drop.cpp 2018-03-03 10:53:50.000000000 +0100 @@ -35,6 +35,7 @@ #include "../../src/server/display.h" #include "../../src/server/compositor_interface.h" #include "../../src/server/datadevicemanager_interface.h" +#include "../../src/server/datasource_interface.h" #include "../../src/server/seat_interface.h" #include "../../src/server/shell_interface.h" @@ -47,6 +48,7 @@ void cleanup(); void testDragAndDrop(); + void testDragAndDropWithCancelByDestroyDataSource(); void testPointerEventsIgnored(); private: @@ -301,6 +303,99 @@ QCOMPARE(buttonPressSpy.count(), 1); } + +void TestDragAndDrop::testDragAndDropWithCancelByDestroyDataSource() +{ + // this test simulates the problem from BUG 389221 + using namespace KWayland::Server; + using namespace KWayland::Client; + // first create a window + QScopedPointer<Surface> s(createSurface()); + auto serverSurface = getServerSurface(); + QVERIFY(serverSurface); + + QSignalSpy dataSourceSelectedActionChangedSpy(m_dataSource, &DataSource::selectedDragAndDropActionChanged); + QVERIFY(dataSourceSelectedActionChangedSpy.isValid()); + + // now we need to pass pointer focus to the Surface and simulate a button press + QSignalSpy buttonPressSpy(m_pointer, &Pointer::buttonStateChanged); + QVERIFY(buttonPressSpy.isValid()); + m_seatInterface->setFocusedPointerSurface(serverSurface); + m_seatInterface->setTimestamp(2); + m_seatInterface->pointerButtonPressed(1); + QVERIFY(buttonPressSpy.wait()); + QCOMPARE(buttonPressSpy.first().at(1).value<quint32>(), quint32(2)); + + // add some signal spies for client side + QSignalSpy dragEnteredSpy(m_dataDevice, &DataDevice::dragEntered); + QVERIFY(dragEnteredSpy.isValid()); + QSignalSpy dragMotionSpy(m_dataDevice, &DataDevice::dragMotion); + QVERIFY(dragMotionSpy.isValid()); + QSignalSpy pointerMotionSpy(m_pointer, &Pointer::motion); + QVERIFY(pointerMotionSpy.isValid()); + QSignalSpy dragLeftSpy(m_dataDevice, &DataDevice::dragLeft); + QVERIFY(dragLeftSpy.isValid()); + + // now we can start the drag and drop + QSignalSpy dragStartedSpy(m_seatInterface, &SeatInterface::dragStarted); + QVERIFY(dragStartedSpy.isValid()); + m_dataSource->setDragAndDropActions(DataDeviceManager::DnDAction::Copy | DataDeviceManager::DnDAction::Move); + m_dataDevice->startDrag(buttonPressSpy.first().first().value<quint32>(), m_dataSource, s.data()); + QVERIFY(dragStartedSpy.wait()); + QCOMPARE(m_seatInterface->dragSurface(), serverSurface); + QCOMPARE(m_seatInterface->dragSurfaceTransformation(), QMatrix4x4()); + QVERIFY(!m_seatInterface->dragSource()->icon()); + QCOMPARE(m_seatInterface->dragSource()->dragImplicitGrabSerial(), buttonPressSpy.first().first().value<quint32>()); + QVERIFY(dragEnteredSpy.wait()); + QCOMPARE(dragEnteredSpy.count(), 1); + QCOMPARE(dragEnteredSpy.first().first().value<quint32>(), m_display->serial()); + QCOMPARE(dragEnteredSpy.first().last().toPointF(), QPointF(0, 0)); + QCOMPARE(m_dataDevice->dragSurface().data(), s.data()); + auto offer = m_dataDevice->dragOffer(); + QVERIFY(offer); + QCOMPARE(offer->selectedDragAndDropAction(), DataDeviceManager::DnDAction::None); + QSignalSpy offerActionChangedSpy(offer, &DataOffer::selectedDragAndDropActionChanged); + QVERIFY(offerActionChangedSpy.isValid()); + QCOMPARE(m_dataDevice->dragOffer()->offeredMimeTypes().count(), 1); + QCOMPARE(m_dataDevice->dragOffer()->offeredMimeTypes().first().name(), QStringLiteral("text/plain")); + QTRY_COMPARE(offer->sourceDragAndDropActions(), DataDeviceManager::DnDAction::Copy | DataDeviceManager::DnDAction::Move); + offer->setDragAndDropActions(DataDeviceManager::DnDAction::Copy | DataDeviceManager::DnDAction::Move, DataDeviceManager::DnDAction::Move); + QVERIFY(offerActionChangedSpy.wait()); + QCOMPARE(offerActionChangedSpy.count(), 1); + QCOMPARE(offer->selectedDragAndDropAction(), DataDeviceManager::DnDAction::Move); + QCOMPARE(dataSourceSelectedActionChangedSpy.count(), 1); + QCOMPARE(m_dataSource->selectedDragAndDropAction(), DataDeviceManager::DnDAction::Move); + + // simulate motion + m_seatInterface->setTimestamp(3); + m_seatInterface->setPointerPos(QPointF(3, 3)); + QVERIFY(dragMotionSpy.wait()); + QCOMPARE(dragMotionSpy.count(), 1); + QCOMPARE(dragMotionSpy.first().first().toPointF(), QPointF(3, 3)); + QCOMPARE(dragMotionSpy.first().last().toUInt(), 3u); + + // now delete the DataSource + delete m_dataSource; + m_dataSource = nullptr; + QSignalSpy serverDragEndedSpy(m_seatInterface, &SeatInterface::dragEnded); + QVERIFY(serverDragEndedSpy.isValid()); + QVERIFY(dragLeftSpy.isEmpty()); + QVERIFY(dragLeftSpy.wait()); + QTRY_COMPARE(dragLeftSpy.count(), 1); + QTRY_COMPARE(serverDragEndedSpy.count(), 1); + + // simulate drop + QSignalSpy droppedSpy(m_dataDevice, &DataDevice::dropped); + QVERIFY(droppedSpy.isValid()); + m_seatInterface->setTimestamp(4); + m_seatInterface->pointerButtonReleased(1); + QVERIFY(!droppedSpy.wait()); + + // verify that we did not get any further input events + QVERIFY(pointerMotionSpy.isEmpty()); + QCOMPARE(buttonPressSpy.count(), 2); +} + void TestDragAndDrop::testPointerEventsIgnored() { // this test verifies that all pointer events are ignored on the focused Pointer device during drag diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kwayland-5.43.0/autotests/client/test_wayland_subsurface.cpp new/kwayland-5.44.0/autotests/client/test_wayland_subsurface.cpp --- old/kwayland-5.43.0/autotests/client/test_wayland_subsurface.cpp 2018-02-05 09:12:05.000000000 +0100 +++ new/kwayland-5.44.0/autotests/client/test_wayland_subsurface.cpp 2018-03-03 10:53:50.000000000 +0100 @@ -59,6 +59,7 @@ void testMappingOfSurfaceTree(); void testSurfaceAt(); void testDestroyAttachedBuffer(); + void testDestroyParentSurface(); private: KWayland::Server::Display *m_display; @@ -1040,6 +1041,52 @@ child.reset(); 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 -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kwayland-5.43.0/src/client/output.cpp new/kwayland-5.44.0/src/client/output.cpp --- old/kwayland-5.43.0/src/client/output.cpp 2018-02-05 09:12:05.000000000 +0100 +++ new/kwayland-5.44.0/src/client/output.cpp 2018-03-03 10:53:50.000000000 +0100 @@ -44,7 +44,7 @@ ~Private(); void setup(wl_output *o); - WaylandPointer<wl_output, wl_output_destroy> output; + WaylandPointer<wl_output, wl_output_release> output; EventQueue *queue = nullptr; QSize physicalSize; QPoint globalPosition; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kwayland-5.43.0/src/client/registry.cpp new/kwayland-5.44.0/src/client/registry.cpp --- old/kwayland-5.43.0/src/client/registry.cpp 2018-02-05 09:12:05.000000000 +0100 +++ new/kwayland-5.44.0/src/client/registry.cpp 2018-03-03 10:53:50.000000000 +0100 @@ -124,7 +124,7 @@ &Registry::dataDeviceManagerRemoved }}, {Registry::Interface::Output, { - 2, + 3, QByteArrayLiteral("wl_output"), &wl_output_interface, &Registry::outputAnnounced, diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kwayland-5.43.0/src/server/datadevice_interface.cpp new/kwayland-5.44.0/src/server/datadevice_interface.cpp --- old/kwayland-5.43.0/src/server/datadevice_interface.cpp 2018-02-05 09:12:05.000000000 +0100 +++ new/kwayland-5.44.0/src/server/datadevice_interface.cpp 2018-03-03 10:53:50.000000000 +0100 @@ -105,11 +105,14 @@ return; } // TODO: source is allowed to be null, handled client internally! + Q_Q(DataDeviceInterface); source = dataSource; + if (dataSource) { + QObject::connect(dataSource, &Resource::aboutToBeUnbound, q, [this] { source = nullptr; }); + } surface = origin; icon = i; drag.serial = serial; - Q_Q(DataDeviceInterface); emit q->dragStarted(); } @@ -273,7 +276,9 @@ // don't update serial, we need it } if (!surface) { - d->seat->dragSource()->dragSource()->dndAction(DataDeviceManagerInterface::DnDAction::None); + if (auto s = d->seat->dragSource()->dragSource()) { + s->dndAction(DataDeviceManagerInterface::DnDAction::None); + } return; } auto *source = d->seat->dragSource()->dragSource(); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kwayland-5.43.0/src/server/output_interface.cpp new/kwayland-5.44.0/src/server/output_interface.cpp --- old/kwayland-5.43.0/src/server/output_interface.cpp 2018-02-05 09:12:05.000000000 +0100 +++ new/kwayland-5.44.0/src/server/output_interface.cpp 2018-03-03 10:53:50.000000000 +0100 @@ -62,6 +62,7 @@ private: static Private *cast(wl_resource *native); + static void releaseCallback(wl_client *client, wl_resource *resource); static void unbind(wl_resource *resource); void bind(wl_client *client, uint32_t version, uint32_t id) override; int32_t toTransform() const; @@ -71,11 +72,12 @@ OutputInterface *q; static QVector<Private*> s_privates; + static const struct wl_output_interface s_interface; static const quint32 s_version; }; QVector<OutputInterface::Private*> OutputInterface::Private::s_privates; -const quint32 OutputInterface::Private::s_version = 2; +const quint32 OutputInterface::Private::s_version = 3; OutputInterface::Private::Private(OutputInterface *q, Display *d) : Global::Private(d, &wl_output_interface, s_version) @@ -89,6 +91,18 @@ s_privates.removeAll(this); } +#ifndef DOXYGEN_SHOULD_SKIP_THIS +const struct wl_output_interface OutputInterface::Private::s_interface = { + releaseCallback +}; +#endif + +void OutputInterface::Private::releaseCallback(wl_client *client, wl_resource *resource) +{ + Q_UNUSED(client); + unbind(resource); +} + OutputInterface *OutputInterface::Private::get(wl_resource *native) { if (Private *p = cast(native)) { @@ -303,7 +317,7 @@ return; } wl_resource_set_user_data(resource, this); - wl_resource_set_destructor(resource, unbind); + wl_resource_set_implementation(resource, &s_interface, this, unbind); ResourceData r; r.resource = resource; r.version = version; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kwayland-5.43.0/src/server/seat_interface.cpp new/kwayland-5.44.0/src/server/seat_interface.cpp --- old/kwayland-5.43.0/src/server/seat_interface.cpp 2018-02-05 09:12:05.000000000 +0100 +++ new/kwayland-5.44.0/src/server/seat_interface.cpp 2018-03-03 10:53:50.000000000 +0100 @@ -302,6 +302,20 @@ endDrag(display->nextSerial()); } ); + if (dataDevice->dragSource()) { + drag.dragSourceDestroyConnection = QObject::connect(dataDevice->dragSource(), &Resource::aboutToBeUnbound, q, + [this] { + const auto serial = display->nextSerial(); + if (drag.target) { + drag.target->updateDragTarget(nullptr, serial); + drag.target = nullptr; + } + endDrag(serial); + } + ); + } else { + drag.dragSourceDestroyConnection = QMetaObject::Connection(); + } dataDevice->updateDragTarget(dataDevice->origin(), dataDevice->dragImplicitGrabSerial()); emit q->dragStarted(); emit q->dragSurfaceChanged(); @@ -350,7 +364,8 @@ { auto target = drag.target; QObject::disconnect(drag.destroyConnection); - if (drag.source) { + QObject::disconnect(drag.dragSourceDestroyConnection); + if (drag.source && drag.source->dragSource()) { drag.source->dragSource()->dropPerformed(); } if (target) { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kwayland-5.43.0/src/server/seat_interface_p.h new/kwayland-5.44.0/src/server/seat_interface_p.h --- old/kwayland-5.43.0/src/server/seat_interface_p.h 2018-02-05 09:12:05.000000000 +0100 +++ new/kwayland-5.44.0/src/server/seat_interface_p.h 2018-03-03 10:53:50.000000000 +0100 @@ -165,6 +165,7 @@ PointerInterface *sourcePointer = nullptr; QMatrix4x4 transformation; QMetaObject::Connection destroyConnection; + QMetaObject::Connection dragSourceDestroyConnection; }; Drag drag; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kwayland-5.43.0/src/server/subcompositor_interface.cpp new/kwayland-5.44.0/src/server/subcompositor_interface.cpp --- old/kwayland-5.43.0/src/server/subcompositor_interface.cpp 2018-02-05 09:12:05.000000000 +0100 +++ new/kwayland-5.44.0/src/server/subcompositor_interface.cpp 2018-03-03 10:53:50.000000000 +0100 @@ -360,6 +360,9 @@ 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 -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kwayland-5.43.0/src/server/surface_interface.cpp new/kwayland-5.44.0/src/server/surface_interface.cpp --- old/kwayland-5.43.0/src/server/surface_interface.cpp 2018-02-05 09:12:05.000000000 +0100 +++ new/kwayland-5.44.0/src/server/surface_interface.cpp 2018-03-03 10:53:50.000000000 +0100 @@ -453,8 +453,11 @@ 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); + } } } }
