Properly handle release of a touch resource
Summary: On client side use wl_touch_release to get into the proper destroy handler on server side. There the shared destroy implementation is used. The test case is extended to verify the condition and ensure that our code doesn't crash in case SeatInterface calls into the already unbound TouchInterface. Reviewers: #plasma_on_wayland Subscribers: plasma-devel Tags: #plasma_on_wayland Differential Revision: https://phabricator.kde.org/D2035
This commit is contained in:
parent
f53bc666eb
commit
34df9d8b2e
2 changed files with 28 additions and 11 deletions
|
@ -1400,7 +1400,8 @@ void TestWaylandSeat::testTouch()
|
|||
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<KWayland::Server::TouchInterface*>(), m_seatInterface->focusedTouch());
|
||||
|
||||
QSignalSpy sequenceStartedSpy(touch, SIGNAL(sequenceStarted(KWayland::Client::TouchPoint*)));
|
||||
|
@ -1559,6 +1560,31 @@ void TestWaylandSeat::testTouch()
|
|||
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()
|
||||
|
|
|
@ -44,16 +44,13 @@ private:
|
|||
TouchInterface *q_func() {
|
||||
return reinterpret_cast<TouchInterface *>(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 @@ TouchInterface::Private::Private(SeatInterface *parent, wl_resource *parentResou
|
|||
{
|
||||
}
|
||||
|
||||
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))
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue