Hello community, here is the log from the commit of package kwayland for openSUSE:Factory checked in at 2019-06-22 11:14:44 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/kwayland (Old) and /work/SRC/openSUSE:Factory/.kwayland.new.4615 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "kwayland" Sat Jun 22 11:14:44 2019 rev:63 rq:710772 version:5.59.0 Changes: -------- --- /work/SRC/openSUSE:Factory/kwayland/kwayland.changes 2019-05-21 10:32:42.727383377 +0200 +++ /work/SRC/openSUSE:Factory/.kwayland.new.4615/kwayland.changes 2019-06-22 11:14:45.808798108 +0200 @@ -1,0 +2,13 @@ +Sun Jun 09 07:35:13 UTC 2019 - [email protected] + +- Update to 5.59.0 + * New feature release + * For more details please see: + * https://www.kde.org/announcements/kde-frameworks-5.59.0.php +- Changes since 5.58.0: + * Allow compositors to send discrete axis values + * Use QVariant::fromValue directly + * Implement set_window_geometry + * Implement wl_surface::damage_buffer + +------------------------------------------------------------------- Old: ---- kwayland-5.58.0.tar.xz New: ---- kwayland-5.59.0.tar.xz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ kwayland.spec ++++++ --- /var/tmp/diff_new_pack.cPwH72/_old 2019-06-22 11:14:46.296798697 +0200 +++ /var/tmp/diff_new_pack.cPwH72/_new 2019-06-22 11:14:46.296798697 +0200 @@ -16,13 +16,13 @@ # -%define _tar_path 5.58 +%define _tar_path 5.59 # 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: %define _kf5_bugfix_version %(echo %{_kf5_version} | awk -F. '{print $1"."$2}')} Name: kwayland -Version: 5.58.0 +Version: 5.59.0 Release: 0 Summary: KDE Wayland library License: LGPL-2.1-or-later ++++++ kwayland-5.58.0.tar.xz -> kwayland-5.59.0.tar.xz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kwayland-5.58.0/CMakeLists.txt new/kwayland-5.59.0/CMakeLists.txt --- old/kwayland-5.58.0/CMakeLists.txt 2019-05-05 00:46:03.000000000 +0200 +++ new/kwayland-5.59.0/CMakeLists.txt 2019-06-01 18:40:52.000000000 +0200 @@ -1,11 +1,11 @@ cmake_minimum_required(VERSION 3.5) -set(KF5_VERSION "5.58.0") # handled by release scripts +set(KF5_VERSION "5.59.0") # handled by release scripts project(KWayland VERSION ${KF5_VERSION}) # ECM setup include(FeatureSummary) -find_package(ECM 5.58.0 NO_MODULE) +find_package(ECM 5.59.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.58.0/autotests/client/test_plasma_window_model.cpp new/kwayland-5.59.0/autotests/client/test_plasma_window_model.cpp --- old/kwayland-5.58.0/autotests/client/test_plasma_window_model.cpp 2019-05-05 00:46:03.000000000 +0200 +++ new/kwayland-5.59.0/autotests/client/test_plasma_window_model.cpp 2019-06-01 18:40:52.000000000 +0200 @@ -861,29 +861,29 @@ QTest::addColumn<QVariant>("setter"); QTest::addColumn<QVariant>("value"); - QTest::newRow("active") << &PlasmaWindow::activeChanged << qVariantFromValue(&PlasmaWindowInterface::setActive) << QVariant(true); - QTest::newRow("minimized") << &PlasmaWindow::minimizedChanged << qVariantFromValue(&PlasmaWindowInterface::setMinimized) << QVariant(true); - QTest::newRow("fullscreen") << &PlasmaWindow::fullscreenChanged << qVariantFromValue(&PlasmaWindowInterface::setFullscreen) << QVariant(true); - QTest::newRow("keepAbove") << &PlasmaWindow::keepAboveChanged << qVariantFromValue(&PlasmaWindowInterface::setKeepAbove) << QVariant(true); - QTest::newRow("keepBelow") << &PlasmaWindow::keepBelowChanged << qVariantFromValue(&PlasmaWindowInterface::setKeepBelow) << QVariant(true); - QTest::newRow("maximized") << &PlasmaWindow::maximizedChanged << qVariantFromValue(&PlasmaWindowInterface::setMaximized) << QVariant(true); - QTest::newRow("demandsAttention") << &PlasmaWindow::demandsAttentionChanged << qVariantFromValue(&PlasmaWindowInterface::setDemandsAttention) << QVariant(true); - QTest::newRow("closeable") << &PlasmaWindow::closeableChanged << qVariantFromValue(&PlasmaWindowInterface::setCloseable) << QVariant(true); - QTest::newRow("minimizeable") << &PlasmaWindow::minimizeableChanged << qVariantFromValue(&PlasmaWindowInterface::setMinimizeable) << QVariant(true); - QTest::newRow("maximizeable") << &PlasmaWindow::maximizeableChanged << qVariantFromValue(&PlasmaWindowInterface::setMaximizeable) << QVariant(true); - QTest::newRow("fullscreenable") << &PlasmaWindow::fullscreenableChanged << qVariantFromValue(&PlasmaWindowInterface::setFullscreenable) << QVariant(true); - QTest::newRow("skipTaskbar") << &PlasmaWindow::skipTaskbarChanged << qVariantFromValue(&PlasmaWindowInterface::setSkipTaskbar) << QVariant(true); - QTest::newRow("shadeable") << &PlasmaWindow::shadeableChanged << qVariantFromValue(&PlasmaWindowInterface::setShadeable) << QVariant(true); - QTest::newRow("shaded") << &PlasmaWindow::shadedChanged << qVariantFromValue(&PlasmaWindowInterface::setShaded) << QVariant(true); - QTest::newRow("movable") << &PlasmaWindow::movableChanged << qVariantFromValue(&PlasmaWindowInterface::setMovable) << QVariant(true); - QTest::newRow("resizable") << &PlasmaWindow::resizableChanged << qVariantFromValue(&PlasmaWindowInterface::setResizable) << QVariant(true); - QTest::newRow("vdChangeable") << &PlasmaWindow::virtualDesktopChangeableChanged << qVariantFromValue(&PlasmaWindowInterface::setVirtualDesktopChangeable) << QVariant(true); - QTest::newRow("onallDesktop") << &PlasmaWindow::onAllDesktopsChanged << qVariantFromValue(&PlasmaWindowInterface::setOnAllDesktops) << QVariant(true); - QTest::newRow("title") << &PlasmaWindow::titleChanged << qVariantFromValue(&PlasmaWindowInterface::setTitle) << QVariant(QStringLiteral("foo")); - QTest::newRow("appId") << &PlasmaWindow::appIdChanged << qVariantFromValue(&PlasmaWindowInterface::setAppId) << QVariant(QStringLiteral("foo")); - QTest::newRow("icon" ) << &PlasmaWindow::iconChanged << qVariantFromValue(&PlasmaWindowInterface::setThemedIconName) << QVariant(QStringLiteral("foo")); - QTest::newRow("vd") << &PlasmaWindow::virtualDesktopChanged << qVariantFromValue(&PlasmaWindowInterface::setVirtualDesktop) << QVariant(2u); - QTest::newRow("unmapped") << &PlasmaWindow::unmapped << qVariantFromValue(&PlasmaWindowInterface::unmap) << QVariant(); + QTest::newRow("active") << &PlasmaWindow::activeChanged << QVariant::fromValue(&PlasmaWindowInterface::setActive) << QVariant(true); + QTest::newRow("minimized") << &PlasmaWindow::minimizedChanged << QVariant::fromValue(&PlasmaWindowInterface::setMinimized) << QVariant(true); + QTest::newRow("fullscreen") << &PlasmaWindow::fullscreenChanged << QVariant::fromValue(&PlasmaWindowInterface::setFullscreen) << QVariant(true); + QTest::newRow("keepAbove") << &PlasmaWindow::keepAboveChanged << QVariant::fromValue(&PlasmaWindowInterface::setKeepAbove) << QVariant(true); + QTest::newRow("keepBelow") << &PlasmaWindow::keepBelowChanged << QVariant::fromValue(&PlasmaWindowInterface::setKeepBelow) << QVariant(true); + QTest::newRow("maximized") << &PlasmaWindow::maximizedChanged << QVariant::fromValue(&PlasmaWindowInterface::setMaximized) << QVariant(true); + QTest::newRow("demandsAttention") << &PlasmaWindow::demandsAttentionChanged << QVariant::fromValue(&PlasmaWindowInterface::setDemandsAttention) << QVariant(true); + QTest::newRow("closeable") << &PlasmaWindow::closeableChanged << QVariant::fromValue(&PlasmaWindowInterface::setCloseable) << QVariant(true); + QTest::newRow("minimizeable") << &PlasmaWindow::minimizeableChanged << QVariant::fromValue(&PlasmaWindowInterface::setMinimizeable) << QVariant(true); + QTest::newRow("maximizeable") << &PlasmaWindow::maximizeableChanged << QVariant::fromValue(&PlasmaWindowInterface::setMaximizeable) << QVariant(true); + QTest::newRow("fullscreenable") << &PlasmaWindow::fullscreenableChanged << QVariant::fromValue(&PlasmaWindowInterface::setFullscreenable) << QVariant(true); + QTest::newRow("skipTaskbar") << &PlasmaWindow::skipTaskbarChanged << QVariant::fromValue(&PlasmaWindowInterface::setSkipTaskbar) << QVariant(true); + QTest::newRow("shadeable") << &PlasmaWindow::shadeableChanged << QVariant::fromValue(&PlasmaWindowInterface::setShadeable) << QVariant(true); + QTest::newRow("shaded") << &PlasmaWindow::shadedChanged << QVariant::fromValue(&PlasmaWindowInterface::setShaded) << QVariant(true); + QTest::newRow("movable") << &PlasmaWindow::movableChanged << QVariant::fromValue(&PlasmaWindowInterface::setMovable) << QVariant(true); + QTest::newRow("resizable") << &PlasmaWindow::resizableChanged << QVariant::fromValue(&PlasmaWindowInterface::setResizable) << QVariant(true); + QTest::newRow("vdChangeable") << &PlasmaWindow::virtualDesktopChangeableChanged << QVariant::fromValue(&PlasmaWindowInterface::setVirtualDesktopChangeable) << QVariant(true); + QTest::newRow("onallDesktop") << &PlasmaWindow::onAllDesktopsChanged << QVariant::fromValue(&PlasmaWindowInterface::setOnAllDesktops) << QVariant(true); + QTest::newRow("title") << &PlasmaWindow::titleChanged << QVariant::fromValue(&PlasmaWindowInterface::setTitle) << QVariant(QStringLiteral("foo")); + QTest::newRow("appId") << &PlasmaWindow::appIdChanged << QVariant::fromValue(&PlasmaWindowInterface::setAppId) << QVariant(QStringLiteral("foo")); + QTest::newRow("icon" ) << &PlasmaWindow::iconChanged << QVariant::fromValue(&PlasmaWindowInterface::setThemedIconName) << QVariant(QStringLiteral("foo")); + QTest::newRow("vd") << &PlasmaWindow::virtualDesktopChanged << QVariant::fromValue(&PlasmaWindowInterface::setVirtualDesktop) << QVariant(2u); + QTest::newRow("unmapped") << &PlasmaWindow::unmapped << QVariant::fromValue(&PlasmaWindowInterface::unmap) << QVariant(); } void PlasmaWindowModelTest::testChangeWindowAfterModelDestroy() diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kwayland-5.58.0/autotests/client/test_wayland_seat.cpp new/kwayland-5.59.0/autotests/client/test_wayland_seat.cpp --- old/kwayland-5.58.0/autotests/client/test_wayland_seat.cpp 2019-05-05 00:46:03.000000000 +0200 +++ new/kwayland-5.59.0/autotests/client/test_wayland_seat.cpp 2019-06-01 18:40:52.000000000 +0200 @@ -78,6 +78,7 @@ void testPointerSwipeGesture(); void testPointerPinchGesture_data(); void testPointerPinchGesture(); + void testPointerAxis(); void testKeyboardSubSurfaceTreeFromPointer(); void testCursor(); void testCursorDamage(); @@ -1151,6 +1152,103 @@ QVERIFY(spy->wait()); } +void TestWaylandSeat::testPointerAxis() +{ + using namespace KWayland::Client; + using namespace KWayland::Server; + + // first create the pointer + QSignalSpy hasPointerChangedSpy(m_seat, &Seat::hasPointerChanged); + QVERIFY(hasPointerChangedSpy.isValid()); + m_seatInterface->setHasPointer(true); + QVERIFY(hasPointerChangedSpy.wait()); + QScopedPointer<Pointer> pointer(m_seat->createPointer()); + QVERIFY(pointer); + + // now create a surface + QSignalSpy surfaceCreatedSpy(m_compositorInterface, &CompositorInterface::surfaceCreated); + QVERIFY(surfaceCreatedSpy.isValid()); + QScopedPointer<Surface> surface(m_compositor->createSurface()); + QVERIFY(surfaceCreatedSpy.wait()); + auto serverSurface = surfaceCreatedSpy.first().first().value<SurfaceInterface*>(); + QVERIFY(serverSurface); + m_seatInterface->setFocusedPointerSurface(serverSurface); + QCOMPARE(m_seatInterface->focusedPointerSurface(), serverSurface); + QVERIFY(m_seatInterface->focusedPointer()); + QSignalSpy frameSpy(pointer.data(), &Pointer::frame); + QVERIFY(frameSpy.isValid()); + QVERIFY(frameSpy.wait()); + QCOMPARE(frameSpy.count(), 1); + + // let's scroll vertically + QSignalSpy axisSourceSpy(pointer.data(), &Pointer::axisSourceChanged); + QVERIFY(axisSourceSpy.isValid()); + QSignalSpy axisSpy(pointer.data(), &Pointer::axisChanged); + QVERIFY(axisSpy.isValid()); + QSignalSpy axisDiscreteSpy(pointer.data(), &Pointer::axisDiscreteChanged); + QVERIFY(axisDiscreteSpy.isValid()); + QSignalSpy axisStoppedSpy(pointer.data(), &Pointer::axisStopped); + QVERIFY(axisStoppedSpy.isValid()); + + quint32 timestamp = 1; + m_seatInterface->setTimestamp(timestamp++); + m_seatInterface->pointerAxisV5(Qt::Vertical, 10, 1, PointerAxisSource::Wheel); + QVERIFY(frameSpy.wait()); + QCOMPARE(frameSpy.count(), 2); + QCOMPARE(axisSourceSpy.count(), 1); + QCOMPARE(axisSourceSpy.last().at(0).value<Pointer::AxisSource>(), Pointer::AxisSource::Wheel); + QCOMPARE(axisDiscreteSpy.count(), 1); + QCOMPARE(axisDiscreteSpy.last().at(0).value<Pointer::Axis>(), Pointer::Axis::Vertical); + QCOMPARE(axisDiscreteSpy.last().at(1).value<qint32>(), 1); + QCOMPARE(axisSpy.count(), 1); + QCOMPARE(axisSpy.last().at(0).value<quint32>(), quint32(1)); + QCOMPARE(axisSpy.last().at(1).value<Pointer::Axis>(), Pointer::Axis::Vertical); + QCOMPARE(axisSpy.last().at(2).value<qreal>(), 10.0); + QCOMPARE(axisStoppedSpy.count(), 0); + + // let's scroll using fingers + m_seatInterface->setTimestamp(timestamp++); + m_seatInterface->pointerAxisV5(Qt::Horizontal, 42, 0, PointerAxisSource::Finger); + QVERIFY(frameSpy.wait()); + QCOMPARE(frameSpy.count(), 3); + QCOMPARE(axisSourceSpy.count(), 2); + QCOMPARE(axisSourceSpy.last().at(0).value<Pointer::AxisSource>(), Pointer::AxisSource::Finger); + QCOMPARE(axisDiscreteSpy.count(), 1); + QCOMPARE(axisSpy.count(), 2); + QCOMPARE(axisSpy.last().at(0).value<quint32>(), quint32(2)); + QCOMPARE(axisSpy.last().at(1).value<Pointer::Axis>(), Pointer::Axis::Horizontal); + QCOMPARE(axisSpy.last().at(2).value<qreal>(), 42.0); + QCOMPARE(axisStoppedSpy.count(), 0); + + // lift the fingers off the device + m_seatInterface->setTimestamp(timestamp++); + m_seatInterface->pointerAxisV5(Qt::Horizontal, 0, 0, PointerAxisSource::Finger); + QVERIFY(frameSpy.wait()); + QCOMPARE(frameSpy.count(), 4); + QCOMPARE(axisSourceSpy.count(), 3); + QCOMPARE(axisSourceSpy.last().at(0).value<Pointer::AxisSource>(), Pointer::AxisSource::Finger); + QCOMPARE(axisDiscreteSpy.count(), 1); + QCOMPARE(axisSpy.count(), 2); + QCOMPARE(axisStoppedSpy.count(), 1); + QCOMPARE(axisStoppedSpy.last().at(0).value<quint32>(), 3); + QCOMPARE(axisStoppedSpy.last().at(1).value<Pointer::Axis>(), Pointer::Axis::Horizontal); + + // if the device is unknown, no axis_source event should be sent + m_seatInterface->setTimestamp(timestamp++); + m_seatInterface->pointerAxisV5(Qt::Horizontal, 42, 1, PointerAxisSource::Unknown); + QVERIFY(frameSpy.wait()); + QCOMPARE(frameSpy.count(), 5); + QCOMPARE(axisSourceSpy.count(), 3); + QCOMPARE(axisDiscreteSpy.count(), 2); + QCOMPARE(axisDiscreteSpy.last().at(0).value<Pointer::Axis>(), Pointer::Axis::Horizontal); + QCOMPARE(axisDiscreteSpy.last().at(1).value<qint32>(), 1); + QCOMPARE(axisSpy.count(), 3); + QCOMPARE(axisSpy.last().at(0).value<quint32>(), quint32(4)); + QCOMPARE(axisSpy.last().at(1).value<Pointer::Axis>(), Pointer::Axis::Horizontal); + QCOMPARE(axisSpy.last().at(2).value<qreal>(), 42.0); + QCOMPARE(axisStoppedSpy.count(), 1); +} + void TestWaylandSeat::testKeyboardSubSurfaceTreeFromPointer() { // this test verifies that when clicking on a sub-surface the keyboard focus passes to it diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kwayland-5.58.0/autotests/client/test_wayland_surface.cpp new/kwayland-5.59.0/autotests/client/test_wayland_surface.cpp --- old/kwayland-5.58.0/autotests/client/test_wayland_surface.cpp 2019-05-05 00:46:03.000000000 +0200 +++ new/kwayland-5.59.0/autotests/client/test_wayland_surface.cpp 2019-06-01 18:40:52.000000000 +0200 @@ -264,6 +264,7 @@ QSignalSpy serverSurfaceCreated(m_compositorInterface, SIGNAL(surfaceCreated(KWayland::Server::SurfaceInterface*))); QVERIFY(serverSurfaceCreated.isValid()); KWayland::Client::Surface *s = m_compositor->createSurface(); + s->setScale(2); QVERIFY(serverSurfaceCreated.wait()); KWayland::Server::SurfaceInterface *serverSurface = serverSurfaceCreated.first().first().value<KWayland::Server::SurfaceInterface*>(); QVERIFY(serverSurface); @@ -292,14 +293,14 @@ s->damage(QRect(0, 0, 10, 10)); s->commit(KWayland::Client::Surface::CommitFlag::None); QVERIFY(damageSpy.wait()); - QCOMPARE(serverSurface->damage(), QRegion(0, 0, 10, 10)); - QCOMPARE(damageSpy.first().first().value<QRegion>(), QRegion(0, 0, 10, 10)); + QCOMPARE(serverSurface->damage(), QRegion(0, 0, 5, 5)); // scale is 2 + QCOMPARE(damageSpy.first().first().value<QRegion>(), QRegion(0, 0, 5, 5)); QVERIFY(serverSurface->isMapped()); QCOMPARE(committedSpy.count(), 2); // damage multiple times QRegion testRegion(5, 8, 3, 6); - testRegion = testRegion.united(QRect(10, 20, 30, 15)); + testRegion = testRegion.united(QRect(10, 11, 6, 1)); img = QImage(QSize(40, 35), QImage::Format_ARGB32_Premultiplied); img.fill(Qt::black); b = m_shm->createBuffer(img); @@ -312,6 +313,39 @@ QCOMPARE(damageSpy.first().first().value<QRegion>(), testRegion); QVERIFY(serverSurface->isMapped()); QCOMPARE(committedSpy.count(), 3); + + // damage buffer + const QRegion testRegion2(30, 40, 22, 4); + const QRegion cmpRegion2(15, 20, 11, 2); // divided by scale factor + img = QImage(QSize(80, 70), QImage::Format_ARGB32_Premultiplied); + img.fill(Qt::black); + b = m_shm->createBuffer(img); + s->attachBuffer(b); + s->damageBuffer(testRegion2); + damageSpy.clear(); + s->commit(KWayland::Client::Surface::CommitFlag::None); + QVERIFY(damageSpy.wait()); + QCOMPARE(serverSurface->damage(), cmpRegion2); + QCOMPARE(damageSpy.first().first().value<QRegion>(), cmpRegion2); + QVERIFY(serverSurface->isMapped()); + + // combined regular damage and damaged buffer + const QRegion testRegion3 = testRegion.united(cmpRegion2); + img = QImage(QSize(80, 70), QImage::Format_ARGB32_Premultiplied); + img.fill(Qt::black); + b = m_shm->createBuffer(img); + s->attachBuffer(b); + s->damage(testRegion); + s->damageBuffer(testRegion2); + damageSpy.clear(); + s->commit(KWayland::Client::Surface::CommitFlag::None); + QVERIFY(damageSpy.wait()); + QVERIFY(serverSurface->damage() != testRegion); + QVERIFY(serverSurface->damage() != testRegion2); + QVERIFY(serverSurface->damage() != cmpRegion2); + QCOMPARE(serverSurface->damage(), testRegion3); + QCOMPARE(damageSpy.first().first().value<QRegion>(), testRegion3); + QVERIFY(serverSurface->isMapped()); } void TestWaylandSurface::testFrameCallback() diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kwayland-5.58.0/autotests/client/test_xdg_shell_stable.cpp new/kwayland-5.59.0/autotests/client/test_xdg_shell_stable.cpp --- old/kwayland-5.58.0/autotests/client/test_xdg_shell_stable.cpp 2019-05-05 00:46:03.000000000 +0200 +++ new/kwayland-5.59.0/autotests/client/test_xdg_shell_stable.cpp 2019-06-01 18:40:52.000000000 +0200 @@ -37,6 +37,8 @@ void testMultipleRoles1(); void testMultipleRoles2(); + + void testWindowGeometry(); }; void XdgShellTestStable::testMaxSize() @@ -217,6 +219,31 @@ xdg_surface_destroy(xdgSurface); } +void XdgShellTestStable::testWindowGeometry() +{ + SURFACE + QSignalSpy windowGeometryChangedSpy(serverXdgSurface, &XdgShellSurfaceInterface::windowGeometryChanged); + xdgSurface->setWindowGeometry(QRect(50, 50, 400, 400)); + + windowGeometryChangedSpy.wait(); + QCOMPARE(serverXdgSurface->windowGeometry(), QRect(50, 50, 400, 400)); + + + //add a popup to this surface + XdgPositioner positioner(QSize(10,10), QRect(100,100,50,50)); + QSignalSpy xdgPopupCreatedSpy(m_xdgShellInterface, &XdgShellInterface::xdgPopupCreated); + QScopedPointer<Surface> popupSurface(m_compositor->createSurface()); + QScopedPointer<XdgShellPopup> xdgPopupSurface(m_xdgShell->createPopup(popupSurface.data(), xdgSurface.data(), positioner)); + QVERIFY(xdgPopupCreatedSpy.wait()); + auto serverXdgPopup = xdgPopupCreatedSpy.first().first().value<XdgShellPopupInterface*>(); + QVERIFY(serverXdgPopup); + + QSignalSpy popupWindowGeometryChangedSpy(serverXdgPopup, &XdgShellPopupInterface::windowGeometryChanged); + xdgPopupSurface->setWindowGeometry(QRect(60, 60, 300, 300)); + popupWindowGeometryChangedSpy.wait(); + QCOMPARE(serverXdgPopup->windowGeometry(), QRect(60, 60, 300, 300)); +} + QTEST_GUILESS_MAIN(XdgShellTestStable) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kwayland-5.58.0/src/client/pointer.cpp new/kwayland-5.59.0/src/client/pointer.cpp --- old/kwayland-5.58.0/src/client/pointer.cpp 2019-05-05 00:46:03.000000000 +0200 +++ new/kwayland-5.59.0/src/client/pointer.cpp 2019-06-01 18:40:52.000000000 +0200 @@ -31,6 +31,18 @@ namespace Client { +static Pointer::Axis wlAxisToPointerAxis(uint32_t axis) +{ + switch (axis) { + case WL_POINTER_AXIS_VERTICAL_SCROLL: + return Pointer::Axis::Vertical; + case WL_POINTER_AXIS_HORIZONTAL_SCROLL: + return Pointer::Axis::Horizontal; + } + + Q_UNREACHABLE(); +} + class Q_DECL_HIDDEN Pointer::Private { public: @@ -164,14 +176,7 @@ { auto p = reinterpret_cast<Pointer::Private*>(data); Q_ASSERT(p->pointer == pointer); - auto toAxis = [axis] { - if (axis == WL_POINTER_AXIS_HORIZONTAL_SCROLL) { - return Axis::Horizontal; - } else { - return Axis::Vertical; - } - }; - emit p->q->axisChanged(time, toAxis(), wl_fixed_to_double(value)); + emit p->q->axisChanged(time, wlAxisToPointerAxis(axis), wl_fixed_to_double(value)); } void Pointer::Private::frameCallback(void *data, wl_pointer *pointer) @@ -183,28 +188,41 @@ void Pointer::Private::axisSourceCallback(void *data, wl_pointer *pointer, uint32_t axis_source) { - Q_UNUSED(data) - Q_UNUSED(pointer) - Q_UNUSED(axis_source) - // TODO: implement + auto p = reinterpret_cast<Pointer::Private*>(data); + Q_ASSERT(p->pointer == pointer); + AxisSource source; + switch (axis_source) { + case WL_POINTER_AXIS_SOURCE_WHEEL: + source = AxisSource::Wheel; + break; + case WL_POINTER_AXIS_SOURCE_FINGER: + source = AxisSource::Finger; + break; + case WL_POINTER_AXIS_SOURCE_CONTINUOUS: + source = AxisSource::Continuous; + break; + case WL_POINTER_AXIS_SOURCE_WHEEL_TILT: + source = AxisSource::WheelTilt; + break; + default: + Q_UNREACHABLE(); + break; + } + emit p->q->axisSourceChanged(source); } void Pointer::Private::axisStopCallback(void *data, wl_pointer *pointer, uint32_t time, uint32_t axis) { - Q_UNUSED(data) - Q_UNUSED(pointer) - Q_UNUSED(time) - Q_UNUSED(axis) - // TODO: implement + auto p = reinterpret_cast<Pointer::Private*>(data); + Q_ASSERT(p->pointer == pointer); + emit p->q->axisStopped(time, wlAxisToPointerAxis(axis)); } void Pointer::Private::axisDiscreteCallback(void *data, wl_pointer *pointer, uint32_t axis, int32_t discrete) { - Q_UNUSED(data) - Q_UNUSED(pointer) - Q_UNUSED(axis) - Q_UNUSED(discrete) - // TODO: implement + auto p = reinterpret_cast<Pointer::Private*>(data); + Q_ASSERT(p->pointer == pointer); + emit p->q->axisDiscreteChanged(wlAxisToPointerAxis(axis), discrete); } void Pointer::setCursor(Surface *surface, const QPoint &hotspot) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kwayland-5.58.0/src/client/pointer.h new/kwayland-5.59.0/src/client/pointer.h --- old/kwayland-5.58.0/src/client/pointer.h 2019-05-05 00:46:03.000000000 +0200 +++ new/kwayland-5.59.0/src/client/pointer.h 2019-06-01 18:40:52.000000000 +0200 @@ -55,6 +55,12 @@ Vertical, Horizontal }; + enum class AxisSource { + Wheel, + Finger, + Continuous, + WheelTilt + }; explicit Pointer(QObject *parent = nullptr); virtual ~Pointer(); @@ -169,6 +175,24 @@ * @param delta **/ void axisChanged(quint32 time, KWayland::Client::Pointer::Axis axis, qreal delta); + /** + * Indicates the source of scroll and other axes. + * + * @since 5.59 + **/ + void axisSourceChanged(KWayland::Client::Pointer::AxisSource source); + /** + * Discrete step information for scroll and other axes. + * + * @since 5.59 + **/ + void axisDiscreteChanged(KWayland::Client::Pointer::Axis axis, qint32 discreteDelta); + /** + * Stop notification for scroll and other axes. + * + * @since 5.59 + **/ + void axisStopped(quint32 time, KWayland::Client::Pointer::Axis axis); /** * Indicates the end of a set of events that logically belong together. @@ -188,5 +212,6 @@ Q_DECLARE_METATYPE(KWayland::Client::Pointer::ButtonState) Q_DECLARE_METATYPE(KWayland::Client::Pointer::Axis) +Q_DECLARE_METATYPE(KWayland::Client::Pointer::AxisSource) #endif diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kwayland-5.58.0/src/client/registry.cpp new/kwayland-5.59.0/src/client/registry.cpp --- old/kwayland-5.58.0/src/client/registry.cpp 2019-05-05 00:46:03.000000000 +0200 +++ new/kwayland-5.59.0/src/client/registry.cpp 2019-06-01 18:40:52.000000000 +0200 @@ -120,7 +120,7 @@ }; static const QMap<Registry::Interface, SuppertedInterfaceData> s_interfaces = { {Registry::Interface::Compositor, { - 3, + 4, QByteArrayLiteral("wl_compositor"), &wl_compositor_interface, &Registry::compositorAnnounced, diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kwayland-5.58.0/src/client/surface.cpp new/kwayland-5.59.0/src/client/surface.cpp --- old/kwayland-5.58.0/src/client/surface.cpp 2019-05-05 00:46:03.000000000 +0200 +++ new/kwayland-5.59.0/src/client/surface.cpp 2019-06-01 18:40:52.000000000 +0200 @@ -239,6 +239,19 @@ wl_surface_damage(d->surface, rect.x(), rect.y(), rect.width(), rect.height()); } +void Surface::damageBuffer(const QRegion ®ion) +{ + for (const QRect &r : region) { + damageBuffer(r); + } +} + +void Surface::damageBuffer(const QRect &rect) +{ + Q_ASSERT(isValid()); + wl_surface_damage_buffer(d->surface, rect.x(), rect.y(), rect.width(), rect.height()); +} + void Surface::attachBuffer(wl_buffer *buffer, const QPoint &offset) { Q_ASSERT(isValid()); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kwayland-5.58.0/src/client/surface.h new/kwayland-5.59.0/src/client/surface.h --- old/kwayland-5.58.0/src/client/surface.h 2019-05-05 00:46:03.000000000 +0200 +++ new/kwayland-5.59.0/src/client/surface.h 2019-06-01 18:40:52.000000000 +0200 @@ -149,13 +149,27 @@ void commit(CommitFlag flag = CommitFlag::FrameCallback); /** * Mark @p rect as damaged for the next frame. + * @see damageBuffer **/ void damage(const QRect &rect); /** * Mark @p region as damaged for the next frame. + * @see damageBuffer **/ void damage(const QRegion ®ion); /** + * Mark @p rect in buffer coordinates as damaged for the next frame. + * @see damage + * @since 5.59 + **/ + void damageBuffer(const QRect &rect); + /** + * Mark @p region in buffer coordinates as damaged for the next frame. + * @see damage + * @since 5.59 + **/ + void damageBuffer(const QRegion ®ion); + /** * Attaches the @p buffer to this Surface for the next frame. * @param buffer The buffer to attach to this Surface * @param offset Position of the new upper-left corner in relation to previous frame diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kwayland-5.58.0/src/client/xdgshell.cpp new/kwayland-5.59.0/src/client/xdgshell.cpp --- old/kwayland-5.58.0/src/client/xdgshell.cpp 2019-05-05 00:46:03.000000000 +0200 +++ new/kwayland-5.59.0/src/client/xdgshell.cpp 2019-06-01 18:40:52.000000000 +0200 @@ -282,6 +282,11 @@ d->setMinSize(size); } +void XdgShellSurface::setWindowGeometry(const QRect &windowGeometry) +{ + d->setWindowGeometry(windowGeometry); +} + void XdgShellSurface::requestMinimize() { d->setMinimized(); @@ -365,6 +370,11 @@ d->ackConfigure(serial); } +void XdgShellPopup::setWindowGeometry(const QRect &windowGeometry) +{ + d->setWindowGeometry(windowGeometry); +} + XdgShellPopup::operator xdg_surface*() { return *(d.data()); } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kwayland-5.58.0/src/client/xdgshell.h new/kwayland-5.59.0/src/client/xdgshell.h --- old/kwayland-5.58.0/src/client/xdgshell.h 2019-05-05 00:46:03.000000000 +0200 +++ new/kwayland-5.59.0/src/client/xdgshell.h 2019-06-01 18:40:52.000000000 +0200 @@ -468,6 +468,12 @@ */ void setMinSize(const QSize &size); + /** + * Sets the position of the window contents within the buffer + * @since 5.59 + */ + void setWindowGeometry(const QRect &windowGeometry); + operator xdg_surface*(); operator xdg_surface*() const; operator xdg_toplevel*(); @@ -596,6 +602,12 @@ **/ void ackConfigure(quint32 serial); + /** + * Sets the position of the window contents within the buffer + * @since 5.59 + */ + void setWindowGeometry(const QRect &windowGeometry); + operator xdg_surface*(); operator xdg_surface*() const; operator xdg_popup*(); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kwayland-5.58.0/src/client/xdgshell_p.h new/kwayland-5.59.0/src/client/xdgshell_p.h --- old/kwayland-5.58.0/src/client/xdgshell_p.h 2019-05-05 00:46:03.000000000 +0200 +++ new/kwayland-5.59.0/src/client/xdgshell_p.h 2019-06-01 18:40:52.000000000 +0200 @@ -235,6 +235,9 @@ virtual void setMinimized() = 0; virtual void setMaxSize(const QSize &size) = 0; virtual void setMinSize(const QSize &size) = 0; + virtual void setWindowGeometry(const QRect &windowGeometry) { + Q_UNUSED(windowGeometry); + } protected: Private(XdgShellSurface *q); @@ -272,6 +275,10 @@ Q_UNUSED(serial); } + virtual void setWindowGeometry(const QRect &windowGeometry) { + Q_UNUSED(windowGeometry); + } + virtual operator xdg_surface*() { return nullptr; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kwayland-5.58.0/src/client/xdgshell_stable.cpp new/kwayland-5.59.0/src/client/xdgshell_stable.cpp --- old/kwayland-5.58.0/src/client/xdgshell_stable.cpp 2019-05-05 00:46:03.000000000 +0200 +++ new/kwayland-5.59.0/src/client/xdgshell_stable.cpp 2019-06-01 18:40:52.000000000 +0200 @@ -281,6 +281,7 @@ void setMinimized() override; void setMaxSize(const QSize &size) override; void setMinSize(const QSize &size) override; + void setWindowGeometry(const QRect &windowGeometry) override; private: QSize pendingSize; @@ -481,6 +482,11 @@ xdg_toplevel_set_min_size(xdgtoplevel, size.width(), size.height()); } +void XdgTopLevelStable::Private::setWindowGeometry(const QRect &windowGeometry) +{ + xdg_surface_set_window_geometry(xdgsurface, windowGeometry.x(), windowGeometry.y(), windowGeometry.width(), windowGeometry.height()); +} + XdgTopLevelStable::XdgTopLevelStable(QObject *parent) : XdgShellSurface(new Private(this), parent) { @@ -499,6 +505,7 @@ bool isValid() const override; void requestGrab(Seat *seat, quint32 serial) override; void ackConfigure(quint32 serial) override; + void setWindowGeometry(const QRect &windowGeometry) override; using XdgShellPopup::Private::operator zxdg_popup_v6*; using XdgShellPopup::Private::operator zxdg_surface_v6*; @@ -601,6 +608,11 @@ xdg_surface_ack_configure(xdgsurface, serial); } +void XdgShellPopupStable::Private::setWindowGeometry(const QRect &windowGeometry) +{ + xdg_surface_set_window_geometry(xdgsurface, windowGeometry.x(), windowGeometry.y(), windowGeometry.width(), windowGeometry.height()); +} + XdgShellPopupStable::XdgShellPopupStable(QObject *parent) : XdgShellPopup(new Private(this), parent) { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kwayland-5.58.0/src/server/compositor_interface.cpp new/kwayland-5.59.0/src/server/compositor_interface.cpp --- old/kwayland-5.58.0/src/server/compositor_interface.cpp 2019-05-05 00:46:03.000000000 +0200 +++ new/kwayland-5.59.0/src/server/compositor_interface.cpp 2019-06-01 18:40:52.000000000 +0200 @@ -51,7 +51,7 @@ static const quint32 s_version; }; -const quint32 CompositorInterface::Private::s_version = 3; +const quint32 CompositorInterface::Private::s_version = 4; CompositorInterface::Private::Private(CompositorInterface *q, Display *d) : Global::Private(d, &wl_compositor_interface, s_version) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kwayland-5.58.0/src/server/pointer_interface.cpp new/kwayland-5.59.0/src/server/pointer_interface.cpp --- old/kwayland-5.58.0/src/server/pointer_interface.cpp 2019-05-05 00:46:03.000000000 +0200 +++ new/kwayland-5.59.0/src/server/pointer_interface.cpp 2019-06-01 18:40:52.000000000 +0200 @@ -322,6 +322,54 @@ d->sendFrame(); } +void PointerInterface::axis(Qt::Orientation orientation, qreal delta, qint32 discreteDelta, PointerAxisSource source) +{ + Q_D(); + Q_ASSERT(d->focusedSurface); + if (!d->resource) { + return; + } + + const quint32 version = wl_resource_get_version(d->resource); + + const auto wlOrientation = (orientation == Qt::Vertical) + ? WL_POINTER_AXIS_VERTICAL_SCROLL + : WL_POINTER_AXIS_HORIZONTAL_SCROLL; + + if (source != PointerAxisSource::Unknown && version >= WL_POINTER_AXIS_SOURCE_SINCE_VERSION) { + wl_pointer_axis_source wlSource; + switch (source) { + case PointerAxisSource::Wheel: + wlSource = WL_POINTER_AXIS_SOURCE_WHEEL; + break; + case PointerAxisSource::Finger: + wlSource = WL_POINTER_AXIS_SOURCE_FINGER; + break; + case PointerAxisSource::Continuous: + wlSource = WL_POINTER_AXIS_SOURCE_CONTINUOUS; + break; + case PointerAxisSource::WheelTilt: + wlSource = WL_POINTER_AXIS_SOURCE_WHEEL_TILT; + break; + default: + Q_UNREACHABLE(); + break; + } + wl_pointer_send_axis_source(d->resource, wlSource); + } + + if (delta != 0.0) { + if (discreteDelta && version >= WL_POINTER_AXIS_DISCRETE_SINCE_VERSION) { + wl_pointer_send_axis_discrete(d->resource, wlOrientation, discreteDelta); + } + wl_pointer_send_axis(d->resource, d->seat->timestamp(), wlOrientation, wl_fixed_from_double(delta)); + } else if (version >= WL_POINTER_AXIS_STOP_SINCE_VERSION) { + wl_pointer_send_axis_stop(d->resource, d->seat->timestamp(), wlOrientation); + } + + d->sendFrame(); +} + void PointerInterface::axis(Qt::Orientation orientation, quint32 delta) { Q_D(); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kwayland-5.58.0/src/server/pointer_interface.h new/kwayland-5.59.0/src/server/pointer_interface.h --- old/kwayland-5.58.0/src/server/pointer_interface.h 2019-05-05 00:46:03.000000000 +0200 +++ new/kwayland-5.59.0/src/server/pointer_interface.h 2019-06-01 18:40:52.000000000 +0200 @@ -35,6 +35,8 @@ class SeatInterface; class SurfaceInterface; +enum class PointerAxisSource; + /** * @brief Resource for the wl_pointer interface. * @@ -73,6 +75,7 @@ void setFocusedSurface(SurfaceInterface *surface, quint32 serial); void buttonPressed(quint32 button, quint32 serial); void buttonReleased(quint32 button, quint32 serial); + void axis(Qt::Orientation orientation, qreal delta, qint32 discreteDelta, PointerAxisSource source); void axis(Qt::Orientation orientation, quint32 delta); void relativeMotion(const QSizeF &delta, const QSizeF &deltaNonAccelerated, quint64 microseconds); friend class SeatInterface; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kwayland-5.58.0/src/server/seat_interface.cpp new/kwayland-5.59.0/src/server/seat_interface.cpp --- old/kwayland-5.58.0/src/server/seat_interface.cpp 2019-05-05 00:46:03.000000000 +0200 +++ new/kwayland-5.59.0/src/server/seat_interface.cpp 2019-06-01 18:40:52.000000000 +0200 @@ -846,6 +846,20 @@ return it.value() == Private::Pointer::State::Pressed ? true : false; } +void SeatInterface::pointerAxisV5(Qt::Orientation orientation, qreal delta, qint32 discreteDelta, PointerAxisSource source) +{ + Q_D(); + if (d->drag.mode == Private::Drag::Mode::Pointer) { + // ignore + return; + } + if (d->globalPointer.focus.surface) { + for (auto it = d->globalPointer.focus.pointers.constBegin(), end = d->globalPointer.focus.pointers.constEnd(); it != end; ++it) { + (*it)->axis(orientation, delta, discreteDelta, source); + } + } +} + void SeatInterface::pointerAxis(Qt::Orientation orientation, quint32 delta) { Q_D(); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kwayland-5.58.0/src/server/seat_interface.h new/kwayland-5.59.0/src/server/seat_interface.h --- old/kwayland-5.58.0/src/server/seat_interface.h 2019-05-05 00:46:03.000000000 +0200 +++ new/kwayland-5.59.0/src/server/seat_interface.h 2019-06-01 18:40:52.000000000 +0200 @@ -44,6 +44,34 @@ class TextInputInterface; /** + * Describes the source types for axis events. This indicates to the + * client how an axis event was physically generated; a client may + * adjust the user interface accordingly. For example, scroll events + * from a "finger" source may be in a smooth coordinate space with + * kinetic scrolling whereas a "wheel" source may be in discrete steps + * of a number of lines. + * + * The "continuous" axis source is a device generating events in a + * continuous coordinate space, but using something other than a + * finger. One example for this source is button-based scrolling where + * the vertical motion of a device is converted to scroll events while + * a button is held down. + * + * The "wheel tilt" axis source indicates that the actual device is a + * wheel but the scroll event is not caused by a rotation but a + * (usually sideways) tilt of the wheel. + * + * @since 5.59 + **/ +enum class PointerAxisSource { + Unknown, + Wheel, + Finger, + Continuous, + WheelTilt +}; + +/** * @brief Represents a Seat on the Wayland Display. * * A Seat is a set of input devices (e.g. Keyboard, Pointer and Touch) the client can connect @@ -361,6 +389,20 @@ * @returns the last serial for @p button. **/ quint32 pointerButtonSerial(Qt::MouseButton button) const; + /** + * Sends axis events to the currently focused pointer surface. + * + * @param orientation The scroll axis. + * @param delta The length of a vector along the specified axis @p orientation. + * @param discreteDelta The number of discrete steps, e.g. mouse wheel clicks. + * @param source Describes how the axis event was physically generated. + * @since 5.59 + * @todo Drop V5 suffix with KF6. + **/ + void pointerAxisV5(Qt::Orientation orientation, qreal delta, qint32 discreteDelta, PointerAxisSource source); + /** + * @see pointerAxisV5 + **/ void pointerAxis(Qt::Orientation orientation, quint32 delta); /** * @returns true if there is a pressed button with the given @p serial diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kwayland-5.58.0/src/server/surface_interface.cpp new/kwayland-5.59.0/src/server/surface_interface.cpp --- old/kwayland-5.58.0/src/server/surface_interface.cpp 2019-05-05 00:46:03.000000000 +0200 +++ new/kwayland-5.59.0/src/server/surface_interface.cpp 2019-06-01 18:40:52.000000000 +0200 @@ -274,7 +274,8 @@ inputRegionCallback, commitCallback, bufferTransformCallback, - bufferScaleCallback + bufferScaleCallback, + damageBufferCallback }; #endif @@ -373,6 +374,7 @@ if (bufferChanged) { target->buffer = buffer; target->damage = source->damage; + target->bufferDamage = source->bufferDamage; target->bufferIsSet = source->bufferIsSet; } if (childrenChanged) { @@ -439,10 +441,32 @@ emit q->transformChanged(target->transform); } if (bufferChanged && emitChanged) { - if (target->buffer && !target->damage.isEmpty()) { + if (target->buffer && (!target->damage.isEmpty() || !target->bufferDamage.isEmpty())) { const QRegion windowRegion = QRegion(0, 0, q->size().width(), q->size().height()); if (!windowRegion.isEmpty()) { - target->damage = windowRegion.intersected(target->damage); + QRegion bufferDamage; + if (!target->bufferDamage.isEmpty()) { + typedef OutputInterface::Transform Tr; + const Tr tr = target->transform; + const qint32 sc = target->scale; + if (tr == Tr::Rotated90 || tr == Tr::Rotated270 || + tr == Tr::Flipped90 || tr == Tr::Flipped270) { + // calculate transformed + scaled buffer damage + for (const auto &rect : target->bufferDamage) { + const auto add = QRegion(rect.x() / sc, rect.y() / sc, rect.height() / sc, rect.width() / sc); + bufferDamage = bufferDamage.united(add); + } + } else if (sc != 1) { + // calculate scaled buffer damage + for (const auto &rect : target->bufferDamage) { + const auto add = QRegion(rect.x() / sc, rect.y() / sc, rect.width() / sc, rect.height() / sc); + bufferDamage = bufferDamage.united(add); + } + } else { + bufferDamage = target->bufferDamage; + } + } + target->damage = windowRegion.intersected(target->damage.united(bufferDamage)); if (emitChanged) { subSurfaceIsMapped = true; trackedDamage = trackedDamage.united(target->damage); @@ -529,6 +553,15 @@ pending.damage = pending.damage.united(rect); } +void SurfaceInterface::Private::damageBuffer(const QRect &rect) +{ + if (!pending.bufferIsSet || (pending.bufferIsSet && !pending.buffer)) { + // TODO: should we send an error? + return; + } + pending.bufferDamage = pending.bufferDamage.united(rect); +} + void SurfaceInterface::Private::setScale(qint32 scale) { pending.scale = scale; @@ -562,6 +595,7 @@ // got a null buffer, deletes content in next frame pending.buffer = nullptr; pending.damage = QRegion(); + pending.bufferDamage = QRegion(); return; } Q_Q(SurfaceInterface); @@ -602,6 +636,12 @@ cast<Private>(resource)->damage(QRect(x, y, width, height)); } +void SurfaceInterface::Private::damageBufferCallback(wl_client *client, wl_resource *resource, int32_t x, int32_t y, int32_t width, int32_t height) +{ + Q_UNUSED(client) + cast<Private>(resource)->damageBuffer(QRect(x, y, width, height)); +} + void SurfaceInterface::Private::frameCallback(wl_client *client, wl_resource *resource, uint32_t callback) { auto s = cast<Private>(resource); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kwayland-5.58.0/src/server/surface_interface_p.h new/kwayland-5.59.0/src/server/surface_interface_p.h --- old/kwayland-5.58.0/src/server/surface_interface_p.h 2019-05-05 00:46:03.000000000 +0200 +++ new/kwayland-5.59.0/src/server/surface_interface_p.h 2019-06-01 18:40:52.000000000 +0200 @@ -39,6 +39,7 @@ public: struct State { QRegion damage = QRegion(); + QRegion bufferDamage = QRegion(); QRegion opaque = QRegion(); QRegion input = QRegion(); bool inputIsSet = false; @@ -114,6 +115,7 @@ } void swapStates(State *source, State *target, bool emitChanged); void damage(const QRect &rect); + void damageBuffer(const QRect &rect); void setScale(qint32 scale); void setTransform(OutputInterface::Transform transform); void addFrameCallback(uint32_t callback); @@ -133,6 +135,8 @@ static void bufferTransformCallback(wl_client *client, wl_resource *resource, int32_t transform); // since version 3 static void bufferScaleCallback(wl_client *client, wl_resource *resource, int32_t scale); + // since version 4 + static void damageBufferCallback(wl_client *client, wl_resource *resource, int32_t x, int32_t y, int32_t width, int32_t height); static const struct wl_surface_interface s_interface; }; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kwayland-5.58.0/src/server/xdgshell_interface.cpp new/kwayland-5.59.0/src/server/xdgshell_interface.cpp --- old/kwayland-5.58.0/src/server/xdgshell_interface.cpp 2019-05-05 00:46:03.000000000 +0200 +++ new/kwayland-5.59.0/src/server/xdgshell_interface.cpp 2019-06-01 18:40:52.000000000 +0200 @@ -154,6 +154,12 @@ d->close(); } +QRect XdgShellSurfaceInterface::windowGeometry() const +{ + Q_D(); + return d->windowGeometry; +} + XdgShellSurfaceInterface::Private *XdgShellSurfaceInterface::d_func() const { return reinterpret_cast<Private*>(d.data()); @@ -252,6 +258,12 @@ return d->constraintAdjustments; } +QRect XdgShellPopupInterface::windowGeometry() const +{ + Q_D(); + return d->windowGeometry; +} + void XdgShellPopupInterface::popupDone() { Q_D(); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kwayland-5.58.0/src/server/xdgshell_interface.h new/kwayland-5.59.0/src/server/xdgshell_interface.h --- old/kwayland-5.58.0/src/server/xdgshell_interface.h 2019-05-05 00:46:03.000000000 +0200 +++ new/kwayland-5.59.0/src/server/xdgshell_interface.h 2019-06-01 18:40:52.000000000 +0200 @@ -278,6 +278,15 @@ **/ void close(); + /** + * @brief windowGeometry + * The geometry of the window within the buffer + * + * If invalid, the geometry of the bufer should be used instead + * @since 5.59 + */ + QRect windowGeometry() const; + Q_SIGNALS: /** * Emitted whenever the title changes. @@ -346,6 +355,13 @@ */ void minSizeChanged(const QSize &size); + /** + * @brief windowGeometryChanged + * @param windowGeometry the newly changed windowGeometry + * @since 5.59 + */ + void windowGeometryChanged(const QRect &windowGeometry); + protected: class Private; explicit XdgShellSurfaceInterface(Private *p); @@ -444,6 +460,13 @@ **/ void popupDone(); + /** + * @brief windowGeometryChanged + * @param windowGeometry the newly changed geometry of the window contents within the buffer + * @since 5.59 + */ + QRect windowGeometry()const; + Q_SIGNALS: /** * A configure event with @p serial got acknowledged. @@ -462,6 +485,13 @@ */ void grabRequested(KWayland::Server::SeatInterface *seat, quint32 serial); + /** + * @brief windowGeometryChanged + * @param windowGeometry the newly changed windowGeometry + * @since 5.59 + */ + void windowGeometryChanged(const QRect &windowGeometry); + protected: class Private; explicit XdgShellPopupInterface(Private *p); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kwayland-5.58.0/src/server/xdgshell_interface_p.h new/kwayland-5.59.0/src/server/xdgshell_interface_p.h --- old/kwayland-5.58.0/src/server/xdgshell_interface_p.h 2019-05-05 00:46:03.000000000 +0200 +++ new/kwayland-5.59.0/src/server/xdgshell_interface_p.h 2019-06-01 18:40:52.000000000 +0200 @@ -60,6 +60,7 @@ QVector<quint32> configureSerials; QPointer<XdgShellSurfaceInterface> parent; + QRect windowGeometry; XdgShellInterfaceVersion interfaceVersion; protected: @@ -93,6 +94,7 @@ Qt::Edges gravity; PositionerConstraints constraintAdjustments; QPoint anchorOffset; + QRect windowGeometry; XdgShellInterfaceVersion interfaceVersion; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/kwayland-5.58.0/src/server/xdgshell_stable_interface.cpp new/kwayland-5.59.0/src/server/xdgshell_stable_interface.cpp --- old/kwayland-5.58.0/src/server/xdgshell_stable_interface.cpp 2019-05-05 00:46:03.000000000 +0200 +++ new/kwayland-5.59.0/src/server/xdgshell_stable_interface.cpp 2019-06-01 18:40:52.000000000 +0200 @@ -515,13 +515,18 @@ void XdgSurfaceStableInterface::Private::setWindowGeometryCallback(wl_client *client, wl_resource *resource, int32_t x, int32_t y, int32_t width, int32_t height) { - // TODO: implement - not done for v5 either - Q_UNUSED(client) - Q_UNUSED(resource) - Q_UNUSED(x) - Q_UNUSED(y) - Q_UNUSED(width) - Q_UNUSED(height) + auto s = cast<Private>(resource); + Q_ASSERT(client == *s->client); + + const QRect windowRect(x, y, width, height); + + if (s->m_topLevel) { + s->m_topLevel->d_func()->windowGeometry = windowRect; + emit s->m_topLevel->windowGeometryChanged(windowRect); + } else if (s->m_popup) { + s->m_popup->d_func()->windowGeometry = windowRect; + emit s->m_popup->windowGeometryChanged(windowRect); + } } XdgSurfaceStableInterface::Private::Private(XdgSurfaceStableInterface *q, XdgShellStableInterface *c, SurfaceInterface *surface, wl_resource *parentResource)
