[server] Standardize the destructor request handling for Resources

Summary:
This change standardizes the behavior regarding the destructor request.

The destructor should destroy the resource and nothing else. The
Wayland library invokes the static unbind method once the resource is
destroyed. The implementation provided by Resource::Private::unbind
triggers a delete later on the Resource. So there is no need to trigger
a deleteLater from the destructor request callback.

This change adds a generic implementation to Resource::Private which is
now used by all inheriting classes replacing the custom implementations.

Test Plan:
For a few Resources the test is extended to ensure that the Resource
gets deleted on server side.

Reviewers: #plasma

Subscribers: plasma-devel

Tags: #plasma

Differential Revision: https://phabricator.kde.org/D1679
This commit is contained in:
Martin Gräßlin 2016-05-25 10:04:17 +02:00
parent 908f86f299
commit ab98448fec
24 changed files with 45 additions and 119 deletions

View file

@ -191,6 +191,12 @@ void TestDataDevice::testCreate()
QVERIFY(!deviceInterface->icon());
QVERIFY(!deviceInterface->selection());
QVERIFY(deviceInterface->parentResource());
// and destroy
QSignalSpy destroyedSpy(deviceInterface, &QObject::destroyed);
QVERIFY(destroyedSpy.isValid());
dataDevice.reset();
QVERIFY(destroyedSpy.wait());
}
void TestDataDevice::testDrag()

View file

@ -201,6 +201,12 @@ void TestServerSideDecoration::testCreate()
QVERIFY(modeChangedSpy.wait());
QCOMPARE(modeChangedSpy.count(), 1);
QTEST(serverSideDecoration->mode(), "clientMode");
// and destroy
QSignalSpy destroyedSpy(serverDeco, &QObject::destroyed);
QVERIFY(destroyedSpy.isValid());
serverSideDecoration.reset();
QVERIFY(destroyedSpy.wait());
}
void TestServerSideDecoration::testRequest_data()

View file

@ -163,6 +163,12 @@ void TestBlur::testCreate()
QVERIFY(blurChanged.wait());
QCOMPARE(serverSurface->blur()->region(), QRegion(0, 0, 10, 20));
// and destroy
QSignalSpy destroyedSpy(serverSurface->blur(), &QObject::destroyed);
QVERIFY(destroyedSpy.isValid());
delete blur;
QVERIFY(destroyedSpy.wait());
}
QTEST_GUILESS_MAIN(TestBlur)

View file

@ -174,6 +174,12 @@ void TestContrast::testCreate()
QCOMPARE(wl_fixed_from_double(serverSurface->contrast()->contrast()), wl_fixed_from_double(0.2));
QCOMPARE(wl_fixed_from_double(serverSurface->contrast()->intensity()), wl_fixed_from_double(2.0));
QCOMPARE(wl_fixed_from_double(serverSurface->contrast()->saturation()), wl_fixed_from_double(1.7));
// and destroy
QSignalSpy destroyedSpy(serverSurface->contrast(), &QObject::destroyed);
QVERIFY(destroyedSpy.isValid());
delete contrast;
QVERIFY(destroyedSpy.wait());
}
QTEST_GUILESS_MAIN(TestContrast)

View file

@ -153,7 +153,6 @@ private:
static void commitCallback(wl_client *client, wl_resource *resource);
static void setRegionCallback(wl_client *client, wl_resource *resource, wl_resource *region);
static void releaseCallback(wl_client *client, wl_resource *resource);
static const struct org_kde_kwin_blur_interface s_interface;
};
@ -162,7 +161,7 @@ private:
const struct org_kde_kwin_blur_interface BlurInterface::Private::s_interface = {
commitCallback,
setRegionCallback,
releaseCallback
resourceDestroyedCallback
};
#endif
@ -189,14 +188,6 @@ void BlurInterface::Private::setRegionCallback(wl_client *client, wl_resource *r
}
}
void BlurInterface::Private::releaseCallback(wl_client *client, wl_resource *resource)
{
Q_UNUSED(client);
Private *p = reinterpret_cast<Private*>(wl_resource_get_user_data(resource));
wl_resource_destroy(resource);
p->q->deleteLater();
}
BlurInterface::Private::Private(BlurInterface *q, BlurManagerInterface *c, wl_resource *parentResource)
: Resource::Private(q, c, parentResource, &org_kde_kwin_blur_interface, &s_interface)
{

View file

@ -162,7 +162,6 @@ private:
static void setContrastCallback(wl_client *client, wl_resource *resource, wl_fixed_t contrast);
static void setIntensityCallback(wl_client *client, wl_resource *resource, wl_fixed_t intensity);
static void setSaturationCallback(wl_client *client, wl_resource *resource, wl_fixed_t saturation);
static void releaseCallback(wl_client *client, wl_resource *resource);
static const struct org_kde_kwin_contrast_interface s_interface;
};
@ -174,7 +173,7 @@ const struct org_kde_kwin_contrast_interface ContrastInterface::Private::s_inter
setContrastCallback,
setIntensityCallback,
setSaturationCallback,
releaseCallback
resourceDestroyedCallback
};
#endif
@ -225,14 +224,6 @@ void ContrastInterface::Private::setSaturationCallback(wl_client *client, wl_res
p->pendingSaturation = wl_fixed_to_double(saturation);
}
void ContrastInterface::Private::releaseCallback(wl_client *client, wl_resource *resource)
{
Q_UNUSED(client);
Private *p = reinterpret_cast<Private*>(wl_resource_get_user_data(resource));
wl_resource_destroy(resource);
p->q->deleteLater();
}
ContrastInterface::Private::Private(ContrastInterface *q, ContrastManagerInterface *c, wl_resource *parentResource)
: Resource::Private(q, c, parentResource, &org_kde_kwin_contrast_interface, &s_interface)
{

View file

@ -65,7 +65,6 @@ private:
void setSelection(DataSourceInterface *dataSource);
static void startDragCallback(wl_client *client, wl_resource *resource, wl_resource *source, wl_resource *origin, wl_resource *icon, uint32_t serial);
static void setSelectionCallback(wl_client *client, wl_resource *resource, wl_resource *source, uint32_t serial);
static void releaseCallback(wl_client *client, wl_resource *resource);
static const struct wl_data_device_interface s_interface;
};
@ -74,7 +73,7 @@ private:
const struct wl_data_device_interface DataDeviceInterface::Private::s_interface = {
startDragCallback,
setSelectionCallback,
releaseCallback
resourceDestroyedCallback
};
#endif
@ -118,14 +117,6 @@ void DataDeviceInterface::Private::setSelectionCallback(wl_client *client, wl_re
cast<Private>(resource)->setSelection(DataSourceInterface::get(source));
}
void DataDeviceInterface::Private::releaseCallback(wl_client *client, wl_resource *resource)
{
Q_UNUSED(client);
Private *p = reinterpret_cast<Private*>(wl_resource_get_user_data(resource));
wl_resource_destroy(resource);
p->q->deleteLater();
}
void DataDeviceInterface::Private::setSelection(DataSourceInterface *dataSource)
{
Q_Q(DataDeviceInterface);

View file

@ -46,7 +46,6 @@ private:
void receive(const QString &mimeType, qint32 fd);
static void acceptCallback(wl_client *client, wl_resource *resource, uint32_t serial, const char *mimeType);
static void receiveCallback(wl_client *client, wl_resource *resource, const char *mimeType, int32_t fd);
static void destroyCallback(wl_client *client, wl_resource *resource);
static const struct wl_data_offer_interface s_interface;
};
@ -55,7 +54,7 @@ private:
const struct wl_data_offer_interface DataOfferInterface::Private::s_interface = {
acceptCallback,
receiveCallback,
destroyCallback
resourceDestroyedCallback
};
#endif
@ -80,12 +79,6 @@ void DataOfferInterface::Private::acceptCallback(wl_client *client, wl_resource
p->source->accept(mimeType ? QString::fromUtf8(mimeType) : QString());
}
void DataOfferInterface::Private::destroyCallback(wl_client *client, wl_resource *resource)
{
Q_UNUSED(client)
wl_resource_destroy(resource);
}
void DataOfferInterface::Private::receiveCallback(wl_client *client, wl_resource *resource, const char *mimeType, int32_t fd)
{
Q_UNUSED(client)

View file

@ -47,7 +47,6 @@ private:
void offer(const QString &mimeType);
static void offerCallback(wl_client *client, wl_resource *resource, const char *mimeType);
static void destroyCallack(wl_client *client, wl_resource *resource);
const static struct wl_data_source_interface s_interface;
};
@ -55,7 +54,7 @@ private:
#ifndef DOXYGEN_SHOULD_SKIP_THIS
const struct wl_data_source_interface DataSourceInterface::Private::s_interface = {
offerCallback,
destroyCallack
resourceDestroyedCallback
};
#endif
@ -66,15 +65,6 @@ DataSourceInterface::Private::Private(DataSourceInterface *q, DataDeviceManagerI
DataSourceInterface::Private::~Private() = default;
void DataSourceInterface::Private::destroyCallack(wl_client *client, wl_resource *resource)
{
Q_UNUSED(client)
auto p = cast<Private>(resource);
wl_resource_destroy(resource);
p->resource = nullptr;
p->q->deleteLater();
}
void DataSourceInterface::Private::offerCallback(wl_client *client, wl_resource *resource, const char *mimeType)
{
Q_UNUSED(client)

View file

@ -78,7 +78,7 @@ DpmsManagerInterface::~DpmsManagerInterface() = default;
#ifndef DOXYGEN_SHOULD_SKIP_THIS
const struct org_kde_kwin_dpms_interface DpmsInterface::Private::s_interface = {
setCallback,
releaseCallback
resourceDestroyedCallback
};
#endif
@ -111,14 +111,6 @@ void DpmsInterface::Private::setCallback(wl_client *client, wl_resource *resourc
emit cast<Private>(resource)->output->dpmsModeRequested(dpmsMode);
}
void DpmsInterface::Private::releaseCallback(wl_client *client, wl_resource *resource)
{
Q_UNUSED(client)
Private *p = reinterpret_cast<Private*>(wl_resource_get_user_data(resource));
wl_resource_destroy(resource);
p->q->deleteLater();
}
DpmsInterface::DpmsInterface(OutputInterface *output, wl_resource *parentResource, DpmsManagerInterface *manager)
: Resource(new Private(this, manager, parentResource, output))
{

View file

@ -75,7 +75,6 @@ public:
private:
static void setCallback(wl_client *client, wl_resource *resource, uint32_t mode);
static void releaseCallback(wl_client *client, wl_resource *resource);
static const struct org_kde_kwin_dpms_interface s_interface;
};

View file

@ -63,7 +63,6 @@ public:
QTimer *timer = nullptr;
private:
static void releaseCallback(wl_client *client, wl_resource *resource);
static void simulateUserActivityCallback(wl_client *client, wl_resource *resource);
IdleTimeoutInterface *q_func() {
return reinterpret_cast<IdleTimeoutInterface*>(q);
@ -126,7 +125,7 @@ IdleInterface::~IdleInterface() = default;
#ifndef DOXYGEN_SHOULD_SKIP_THIS
const struct org_kde_kwin_idle_timeout_interface IdleTimeoutInterface::Private::s_interface = {
releaseCallback,
resourceDestroyedCallback,
simulateUserActivityCallback
};
#endif
@ -139,14 +138,6 @@ IdleTimeoutInterface::Private::Private(SeatInterface *seat, IdleTimeoutInterface
IdleTimeoutInterface::Private::~Private() = default;
void IdleTimeoutInterface::Private::releaseCallback(wl_client* client, wl_resource* resource)
{
Q_UNUSED(client);
Private *p = reinterpret_cast<Private*>(wl_resource_get_user_data(resource));
wl_resource_destroy(resource);
p->q->deleteLater();
}
void IdleTimeoutInterface::Private::simulateUserActivityCallback(wl_client *client, wl_resource *resource)
{
Q_UNUSED(client);

View file

@ -79,7 +79,6 @@ public:
private:
// interface callbacks
static void destroyCallback(wl_client *client, wl_resource *resource);
static void setOutputCallback(wl_client *client, wl_resource *resource, wl_resource *output);
static void setPositionCallback(wl_client *client, wl_resource *resource, int32_t x, int32_t y);
static void setRoleCallback(wl_client *client, wl_resource *resource, uint32_t role);
@ -154,7 +153,7 @@ PlasmaShellSurfaceInterface::Private::Private(PlasmaShellSurfaceInterface *q, Pl
#ifndef DOXYGEN_SHOULD_SKIP_THIS
const struct org_kde_plasma_surface_interface PlasmaShellSurfaceInterface::Private::s_interface = {
destroyCallback,
resourceDestroyedCallback,
setOutputCallback,
setPositionCallback,
setRoleCallback,
@ -185,12 +184,6 @@ PlasmaShellSurfaceInterface::Private *PlasmaShellSurfaceInterface::d_func() cons
return reinterpret_cast<PlasmaShellSurfaceInterface::Private*>(d.data());
}
void PlasmaShellSurfaceInterface::Private::destroyCallback(wl_client *client, wl_resource *resource)
{
Q_UNUSED(client)
wl_resource_destroy(resource);
}
void PlasmaShellSurfaceInterface::Private::setOutputCallback(wl_client *client, wl_resource *resource, wl_resource *output)
{
Q_UNUSED(client)

View file

@ -42,7 +42,6 @@ private:
void add(const QRect &rect);
void subtract(const QRect &rect);
static void destroyCallback(wl_client *client, wl_resource *r);
static void addCallback(wl_client *client, wl_resource *r, int32_t x, int32_t y, int32_t width, int32_t height);
static void subtractCallback(wl_client *client, wl_resource *r, int32_t x, int32_t y, int32_t width, int32_t height);
@ -51,7 +50,7 @@ private:
#ifndef DOXYGEN_SHOULD_SKIP_THIS
const struct wl_region_interface RegionInterface::Private::s_interface = {
destroyCallback,
resourceDestroyedCallback,
addCallback,
subtractCallback
};
@ -93,12 +92,6 @@ void RegionInterface::Private::subtractCallback(wl_client *client, wl_resource *
cast<Private>(r)->subtract(QRect(x, y, width, height));
}
void RegionInterface::Private::destroyCallback(wl_client *client, wl_resource *r)
{
Q_UNUSED(client)
wl_resource_destroy(r);
}
RegionInterface::RegionInterface(CompositorInterface *parent, wl_resource *parentResource)
: Resource(new Private(parent, this, parentResource))
{

View file

@ -67,6 +67,13 @@ void Resource::Private::unbind(wl_resource *r)
p->q->deleteLater();
}
void Resource::Private::resourceDestroyedCallback(wl_client *client, wl_resource *resource)
{
Q_UNUSED(client)
wl_resource_destroy(resource);
}
Resource::Resource(Resource::Private *d, QObject *parent)
: QObject(parent)
, d(d)

View file

@ -79,6 +79,7 @@ protected:
return r ? reinterpret_cast<Derived*>(wl_resource_get_user_data(r)) : nullptr;
}
static void unbind(wl_resource *resource);
static void resourceDestroyedCallback(wl_client *client, wl_resource *resource);
Resource *q;
static QList<Private*> s_allResources;

View file

@ -34,12 +34,6 @@ namespace KWayland
namespace Server
{
void TextInputInterface::Private::destroyCallback(wl_client *client, wl_resource *resource)
{
Q_UNUSED(client)
wl_resource_destroy(resource);
}
void TextInputInterface::Private::activateCallback(wl_client *client, wl_resource *resource, wl_resource *seat, wl_resource *surface)
{
auto p = cast<Private>(resource);

View file

@ -86,7 +86,6 @@ public:
protected:
Private(TextInputInterface *q, Global *c, wl_resource *parentResource, const wl_interface *interface, const void *implementation);
static void destroyCallback(wl_client *client, wl_resource *resource);
static void activateCallback(wl_client *client, wl_resource *resource, wl_resource * seat, wl_resource * surface);
static void deactivateCallback(wl_client *client, wl_resource *resource, wl_resource * seat);
static void enableCallback(wl_client *client, wl_resource *resource, wl_resource * surface);

View file

@ -65,7 +65,7 @@ private:
#ifndef DOXYGEN_SHOULD_SKIP_THIS
const struct zwp_text_input_v2_interface TextInputUnstableV2Interface::Private::s_interface = {
destroyCallback,
resourceDestroyedCallback,
enableCallback,
disableCallback,
showInputPanelCallback,

View file

@ -183,7 +183,6 @@ public:
static ServerSideDecorationInterface *get(SurfaceInterface *s);
private:
static void releaseCallback(wl_client *client, wl_resource *resource);
static void requestModeCallback(wl_client *client, wl_resource *resource, uint32_t mode);
ServerSideDecorationInterface *q_func() {
@ -196,20 +195,12 @@ private:
#ifndef DOXYGEN_SHOULD_SKIP_THIS
const struct org_kde_kwin_server_decoration_interface ServerSideDecorationInterface::Private::s_interface = {
releaseCallback,
resourceDestroyedCallback,
requestModeCallback
};
QVector<ServerSideDecorationInterface::Private*> ServerSideDecorationInterface::Private::s_all;
#endif
void ServerSideDecorationInterface::Private::releaseCallback(wl_client *client, wl_resource *resource)
{
Q_UNUSED(client)
Private *p = cast<Private>(resource);
wl_resource_destroy(resource);
p->q->deleteLater();
}
void ServerSideDecorationInterface::Private::requestModeCallback(wl_client *client, wl_resource *resource, uint32_t mode)
{
Q_UNUSED(client)

View file

@ -129,7 +129,7 @@ SubCompositorInterface::~SubCompositorInterface() = default;
#ifndef DOXYGEN_SHOULD_SKIP_THIS
const struct wl_subsurface_interface SubSurfaceInterface::Private::s_interface = {
destroyCallback,
resourceDestroyedCallback,
setPositionCallback,
placeAboveCallback,
placeBelowCallback,
@ -204,12 +204,6 @@ void SubSurfaceInterface::Private::commit()
}
}
void SubSurfaceInterface::Private::destroyCallback(wl_client *client, wl_resource *resource)
{
Q_UNUSED(client)
wl_resource_destroy(resource);
}
void SubSurfaceInterface::Private::setPositionCallback(wl_client *client, wl_resource *resource, int32_t x, int32_t y)
{
Q_UNUSED(client)

View file

@ -58,7 +58,6 @@ private:
void placeAbove(SurfaceInterface *sibling);
void placeBelow(SurfaceInterface *sibling);
static void destroyCallback(wl_client *client, wl_resource *resource);
static void setPositionCallback(wl_client *client, wl_resource *resource, int32_t x, int32_t y);
static void placeAboveCallback(wl_client *client, wl_resource *resource, wl_resource *sibling);
static void placeBelowCallback(wl_client *client, wl_resource *resource, wl_resource *sibling);

View file

@ -176,7 +176,7 @@ void SurfaceInterface::Private::setContrast(const QPointer<ContrastInterface> &c
#ifndef DOXYGEN_SHOULD_SKIP_THIS
const struct wl_surface_interface SurfaceInterface::Private::s_interface = {
destroyCallback,
resourceDestroyedCallback,
attachCallback,
damageCallback,
frameCallaback,
@ -490,12 +490,6 @@ void SurfaceInterface::Private::destroyFrameCallback(wl_resource *r)
s->subSurfacePending.callbacks.removeAll(r);
}
void SurfaceInterface::Private::destroyCallback(wl_client *client, wl_resource *resource)
{
Q_UNUSED(client)
wl_resource_destroy(resource);
}
void SurfaceInterface::Private::attachCallback(wl_client *client, wl_resource *resource, wl_resource *buffer, int32_t sx, int32_t sy)
{
Q_UNUSED(client)

View file

@ -104,7 +104,6 @@ private:
static void destroyFrameCallback(wl_resource *r);
static void destroyCallback(wl_client *client, wl_resource *resource);
static void attachCallback(wl_client *client, wl_resource *resource, wl_resource *buffer, int32_t sx, int32_t sy);
static void damageCallback(wl_client *client, wl_resource *resource, int32_t x, int32_t y, int32_t width, int32_t height);
static void frameCallaback(wl_client *client, wl_resource *resource, uint32_t callback);