diff --git a/autotests/client/test_wayland_seat.cpp b/autotests/client/test_wayland_seat.cpp --- a/autotests/client/test_wayland_seat.cpp +++ b/autotests/client/test_wayland_seat.cpp @@ -1400,7 +1400,8 @@ Touch *touch = m_seat->createTouch(m_seat); QVERIFY(touch->isValid()); QVERIFY(touchCreatedSpy.wait()); - QVERIFY(m_seatInterface->focusedTouch()); + auto serverTouch = m_seatInterface->focusedTouch(); + QVERIFY(serverTouch); QCOMPARE(touchCreatedSpy.first().first().value(), m_seatInterface->focusedTouch()); QSignalSpy sequenceStartedSpy(touch, SIGNAL(sequenceStarted(KWayland::Client::TouchPoint*))); @@ -1559,6 +1560,31 @@ QCOMPARE(pointMovedSpy.count(), 1); QCOMPARE(pointRemovedSpy.count(), 3); QCOMPARE(touch->sequence().first()->position(), QPointF(0, 0)); + + // destroy touch on client side + QSignalSpy unboundSpy(serverTouch, &TouchInterface::unbound); + QVERIFY(unboundSpy.isValid()); + QSignalSpy destroyedSpy(serverTouch, &TouchInterface::destroyed); + QVERIFY(destroyedSpy.isValid()); + delete touch; + QVERIFY(unboundSpy.wait()); + QCOMPARE(unboundSpy.count(), 1); + QCOMPARE(destroyedSpy.count(), 0); + QVERIFY(!serverTouch->resource()); + // try to call into all the the methods of the touch interface, should not crash + QCOMPARE(m_seatInterface->focusedTouch(), serverTouch); + m_seatInterface->setTimestamp(8); + QCOMPARE(m_seatInterface->touchDown(QPointF(15, 26)), 0); + m_seatInterface->touchFrame(); + m_seatInterface->touchMove(0, QPointF(0, 0)); + QCOMPARE(m_seatInterface->touchDown(QPointF(15, 26)), 1); + m_seatInterface->cancelTouchSequence(); + QVERIFY(destroyedSpy.wait()); + QCOMPARE(destroyedSpy.count(), 1); + // should have unset the focused touch + QVERIFY(!m_seatInterface->focusedTouch()); + // but not the focused touch surface + QCOMPARE(m_seatInterface->focusedTouchSurface(), serverSurface); } void TestWaylandSeat::testDisconnect() diff --git a/src/client/touch.cpp b/src/client/touch.cpp --- a/src/client/touch.cpp +++ b/src/client/touch.cpp @@ -37,7 +37,7 @@ public: Private(Touch *q); void setup(wl_touch *t); - WaylandPointer touch; + WaylandPointer touch; bool active = false; QVector sequence; TouchPoint *getActivePoint(qint32 id) const; diff --git a/src/server/touch_interface.cpp b/src/server/touch_interface.cpp --- a/src/server/touch_interface.cpp +++ b/src/server/touch_interface.cpp @@ -44,16 +44,13 @@ TouchInterface *q_func() { return reinterpret_cast(q); } - // interface - // since version 3 - static void releaseCallback(wl_client *client, wl_resource *resource); static const struct wl_touch_interface s_interface; }; #ifndef DOXYGEN_SHOULD_SKIP_THIS const struct wl_touch_interface TouchInterface::Private::s_interface = { - releaseCallback + resourceDestroyedCallback }; #endif @@ -63,12 +60,6 @@ { } -void TouchInterface::Private::releaseCallback(wl_client *client, wl_resource *resource) -{ - Q_UNUSED(client) - unbind(resource); -} - TouchInterface::TouchInterface(SeatInterface *parent, wl_resource *parentResource) : Resource(new Private(parent, parentResource, this)) {