Migrate Migrate XdgForeign to new approach

This commit is contained in:
Adrien Faveraux 2020-07-28 13:21:29 +02:00 committed by Vlad Zahorodnii
parent ed264e2c55
commit 389aec2156
8 changed files with 276 additions and 461 deletions

View file

@ -62,7 +62,6 @@ set(SERVER_LIB_SRCS
touch_interface.cpp
viewporter_interface.cpp
xdgdecoration_v1_interface.cpp
xdgforeign_interface.cpp
xdgforeign_v2_interface.cpp
xdgoutput_interface.cpp
xdgshell_interface.cpp
@ -177,7 +176,7 @@ ecm_add_wayland_server_protocol(SERVER_LIB_SRCS
BASENAME pointer-constraints-unstable-v1
)
ecm_add_wayland_server_protocol(SERVER_LIB_SRCS
ecm_add_qtwayland_server_protocol(SERVER_LIB_SRCS
PROTOCOL ${WaylandProtocols_DATADIR}/unstable/xdg-foreign/xdg-foreign-unstable-v2.xml
BASENAME xdg-foreign-unstable-v2
)
@ -410,7 +409,7 @@ set(SERVER_LIB_HEADERS
touch_interface.h
viewporter_interface.h
xdgdecoration_v1_interface.h
xdgforeign_interface.h
xdgforeign_v2_interface.h
xdgoutput_interface.h
xdgshell_interface.h
)

View file

@ -17,7 +17,7 @@
#include "../../src/server/display.h"
#include "../../src/server/compositor_interface.h"
#include "../../src/server/surface_interface.h"
#include "../../src/server/xdgforeign_interface.h"
#include "../../src/server/xdgforeign_v2_interface.h"
using namespace KWayland::Client;
@ -43,7 +43,7 @@ private:
KWaylandServer::Display *m_display;
QPointer<KWaylandServer::CompositorInterface> m_compositorInterface;
KWaylandServer::XdgForeignInterface *m_foreignInterface;
KWaylandServer::XdgForeignV2Interface *m_foreignInterface;
KWayland::Client::ConnectionThread *m_connection;
KWayland::Client::Compositor *m_compositor;
KWayland::Client::EventQueue *m_queue;
@ -86,8 +86,7 @@ void TestForeign::init()
m_display->start();
QVERIFY(m_display->isRunning());
qRegisterMetaType<KWaylandServer::SurfaceInterface*>("KWaylandServer::SurfaceInterface");
qRegisterMetaType<SurfaceInterface*>();
// setup connection
m_connection = new KWayland::Client::ConnectionThread;
QSignalSpy connectedSpy(m_connection, &ConnectionThread::connected);
@ -127,9 +126,7 @@ void TestForeign::init()
QVERIFY(compositorSpy.wait());
m_compositor = registry.createCompositor(compositorSpy.first().first().value<quint32>(), compositorSpy.first().last().value<quint32>(), this);
m_foreignInterface = m_display->createXdgForeignInterface(m_display);
m_foreignInterface->create();
QVERIFY(m_foreignInterface->isValid());
m_foreignInterface = m_display->createXdgForeignV2Interface(m_display);
QVERIFY(exporterSpy.wait());
//Both importer and exporter should have been triggered by now
@ -163,17 +160,8 @@ void TestForeign::cleanup()
m_thread = nullptr;
}
CLEANUP(m_foreignInterface)
//internally there are some deleteLaters on exported interfaces
//we want them processed before we delete the connection
if (m_display) {
QSignalSpy destroyedSpy(m_display, &QObject::destroyed);
m_display->deleteLater();
delete m_display;
m_display = nullptr;
destroyedSpy.wait();
}
QVERIFY(m_compositorInterface.isNull());
#undef CLEANUP
}
@ -189,17 +177,17 @@ void TestForeign::doExport()
m_exportedSurfaceInterface = serverSurfaceCreated.first().first().value<KWaylandServer::SurfaceInterface*>();
//Export a window
m_exported = m_exporter->exportTopLevel(m_exportedSurface, m_connection);
m_exported = m_exporter->exportTopLevel(m_exportedSurface);
QVERIFY(m_exported->handle().isEmpty());
QSignalSpy doneSpy(m_exported.data(), &XdgExported::done);
QVERIFY(doneSpy.wait());
QVERIFY(!m_exported->handle().isEmpty());
QSignalSpy transientSpy(m_foreignInterface, &KWaylandServer::XdgForeignInterface::transientChanged);
QSignalSpy transientSpy(m_foreignInterface, &KWaylandServer::XdgForeignV2Interface::transientChanged);
QVERIFY(transientSpy.isValid());
//Import the just exported window
m_imported = m_importer->importTopLevel(m_exported->handle(), m_connection);
m_imported = m_importer->importTopLevel(m_exported->handle());
QVERIFY(m_imported->isValid());
QSignalSpy childSurfaceInterfaceCreated(m_compositorInterface, SIGNAL(surfaceCreated(KWaylandServer::SurfaceInterface*)));
@ -228,7 +216,7 @@ void TestForeign::testDeleteImported()
{
doExport();
QSignalSpy transientSpy(m_foreignInterface, &KWaylandServer::XdgForeignInterface::transientChanged);
QSignalSpy transientSpy(m_foreignInterface, &KWaylandServer::XdgForeignV2Interface::transientChanged);
QVERIFY(transientSpy.isValid());
m_imported->deleteLater();
@ -245,7 +233,7 @@ void TestForeign::testDeleteChildSurface()
{
doExport();
QSignalSpy transientSpy(m_foreignInterface, &KWaylandServer::XdgForeignInterface::transientChanged);
QSignalSpy transientSpy(m_foreignInterface, &KWaylandServer::XdgForeignV2Interface::transientChanged);
QVERIFY(transientSpy.isValid());
m_childSurface->deleteLater();
@ -260,7 +248,7 @@ void TestForeign::testDeleteParentSurface()
{
doExport();
QSignalSpy transientSpy(m_foreignInterface, &KWaylandServer::XdgForeignInterface::transientChanged);
QSignalSpy transientSpy(m_foreignInterface, &KWaylandServer::XdgForeignV2Interface::transientChanged);
QVERIFY(transientSpy.isValid());
m_exportedSurface->deleteLater();
@ -280,7 +268,7 @@ void TestForeign::testDeleteExported()
{
doExport();
QSignalSpy transientSpy(m_foreignInterface, &KWaylandServer::XdgForeignInterface::transientChanged);
QSignalSpy transientSpy(m_foreignInterface, &KWaylandServer::XdgForeignV2Interface::transientChanged);
QSignalSpy destroyedSpy(m_imported.data(), &KWayland::Client::XdgImported::importedDestroyed);
QVERIFY(transientSpy.isValid());
@ -302,17 +290,17 @@ void TestForeign::testExportTwoTimes()
doExport();
//Export second window
KWayland::Client::XdgExported *exported2 = m_exporter->exportTopLevel(m_exportedSurface, m_connection);
KWayland::Client::XdgExported *exported2 = m_exporter->exportTopLevel(m_exportedSurface);
QVERIFY(exported2->handle().isEmpty());
QSignalSpy doneSpy(exported2, &XdgExported::done);
QVERIFY(doneSpy.wait());
QVERIFY(!exported2->handle().isEmpty());
QSignalSpy transientSpy(m_foreignInterface, &KWaylandServer::XdgForeignInterface::transientChanged);
QSignalSpy transientSpy(m_foreignInterface, &KWaylandServer::XdgForeignV2Interface::transientChanged);
QVERIFY(transientSpy.isValid());
//Import the just exported window
KWayland::Client::XdgImported *imported2 = m_importer->importTopLevel(exported2->handle(), m_connection);
KWayland::Client::XdgImported *imported2 = m_importer->importTopLevel(exported2->handle());
QVERIFY(imported2->isValid());
//create a second child surface
@ -341,11 +329,11 @@ void TestForeign::testImportTwoTimes()
{
doExport();
QSignalSpy transientSpy(m_foreignInterface, &KWaylandServer::XdgForeignInterface::transientChanged);
QSignalSpy transientSpy(m_foreignInterface, &KWaylandServer::XdgForeignV2Interface::transientChanged);
QVERIFY(transientSpy.isValid());
//Import another time the exported window
KWayland::Client::XdgImported *imported2 = m_importer->importTopLevel(m_exported->handle(), m_connection);
KWayland::Client::XdgImported *imported2 = m_importer->importTopLevel(m_exported->handle());
QVERIFY(imported2->isValid());
//create a second child surface

View file

@ -42,7 +42,7 @@
#include "textinput_interface_p.h"
#include "viewporter_interface.h"
#include "xdgdecoration_v1_interface.h"
#include "xdgforeign_interface.h"
#include "xdgforeign_v2_interface.h"
#include "xdgoutput_interface.h"
#include "xdgshell_interface.h"
@ -401,9 +401,9 @@ PointerConstraintsInterface *Display::createPointerConstraints(const PointerCons
return p;
}
XdgForeignInterface *Display::createXdgForeignInterface(QObject *parent)
XdgForeignV2Interface *Display::createXdgForeignV2Interface(QObject *parent)
{
XdgForeignInterface *foreign = new XdgForeignInterface(this, parent);
XdgForeignV2Interface *foreign = new XdgForeignV2Interface(this, parent);
connect(this, &Display::aboutToTerminate, foreign, [foreign] { delete foreign; });
return foreign;
}

View file

@ -65,7 +65,7 @@ enum class PointerGesturesInterfaceVersion;
class PointerGesturesInterface;
enum class PointerConstraintsInterfaceVersion;
class PointerConstraintsInterface;
class XdgForeignInterface;
class XdgForeignV2Interface;
class AppMenuManagerInterface;
class ServerSideDecorationPaletteManagerInterface;
class PlasmaVirtualDesktopManagementInterface;
@ -231,12 +231,12 @@ public:
PointerConstraintsInterface *createPointerConstraints(const PointerConstraintsInterfaceVersion &version, QObject *parent = nullptr);
/**
* Creates the XdgForeignInterface in interface @p version
* Creates the XdgForeignV2Interface in interface @p version
*
* @returns The created manager object
* @since 5.40
**/
XdgForeignInterface *createXdgForeignInterface(QObject *parent = nullptr);
XdgForeignV2Interface *createXdgForeignV2Interface(QObject *parent = nullptr);
/**
* Creates the IdleInhibitManagerInterface in interface @p version.

View file

@ -1,61 +0,0 @@
/*
SPDX-FileCopyrightText: 2017 Marco Martin <notmart@gmail.com>
SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
*/
#include "xdgforeign_interface.h"
#include "xdgforeign_v2_interface_p.h"
#include "display.h"
#include "global_p.h"
#include "resource_p.h"
#include "surface_interface_p.h"
#include "wayland-xdg-foreign-unstable-v2-server-protocol.h"
#include <QUuid>
#include <QDebug>
namespace KWaylandServer
{
XdgForeignInterface::Private::Private(Display *display, XdgForeignInterface *q)
: q(q)
{
exporter = new XdgExporterUnstableV2Interface(display, q);
importer = new XdgImporterUnstableV2Interface(display, q);
connect(importer, &XdgImporterUnstableV2Interface::transientChanged,
q, &XdgForeignInterface::transientChanged);
}
XdgForeignInterface::XdgForeignInterface(Display *display, QObject *parent)
: QObject(parent),
d(new Private(display, this))
{
}
XdgForeignInterface::~XdgForeignInterface()
{
delete d->exporter;
delete d->importer;
delete d;
}
void XdgForeignInterface::create()
{
d->exporter->create();
d->importer->create();
}
bool XdgForeignInterface::isValid()
{
return d->exporter->isValid() && d->importer->isValid();
}
SurfaceInterface *XdgForeignInterface::transientFor(SurfaceInterface *surface)
{
return d->importer->transientFor(surface);
}
}

View file

@ -4,71 +4,71 @@
SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
*/
#include "xdgforeign_interface.h"
#include "xdgforeign_v2_interface_p.h"
#include "display.h"
#include "global_p.h"
#include "resource_p.h"
#include "surface_interface_p.h"
#include "wayland-xdg-foreign-unstable-v2-server-protocol.h"
#include <QUuid>
#include <QDebug>
namespace KWaylandServer
{
class Q_DECL_HIDDEN XdgExporterUnstableV2Interface::Private : public Global::Private
XdgForeignV2InterfacePrivate::XdgForeignV2InterfacePrivate(Display *display, XdgForeignV2Interface *_q)
: QObject(nullptr)
, q(_q)
{
exporter = new XdgExporterV2Interface(display, _q);
importer = new XdgImporterV2Interface(display, _q);
connect(importer, &XdgImporterV2Interface::transientChanged,
q, &XdgForeignV2Interface::transientChanged);
}
XdgForeignV2Interface::XdgForeignV2Interface(Display *display, QObject *parent)
: QObject(parent),
d(new XdgForeignV2InterfacePrivate(display, this))
{
}
XdgForeignV2Interface::~XdgForeignV2Interface()
{
delete d->exporter;
delete d->importer;
}
SurfaceInterface *XdgForeignV2Interface::transientFor(SurfaceInterface *surface)
{
return d->importer->transientFor(surface);
}
class XdgExporterV2InterfacePrivate : public QtWaylandServer::zxdg_exporter_v2
{
public:
Private(XdgExporterUnstableV2Interface *q, Display *d, XdgForeignInterface *foreignInterface);
XdgExporterV2InterfacePrivate(XdgExporterV2Interface *_q, Display *display, XdgForeignV2Interface *foreignInterface);
XdgForeignInterface *foreignInterface;
QHash<QString, XdgExportedUnstableV2Interface *> exportedSurfaces;
private:
void bind(wl_client *client, uint32_t version, uint32_t id) override;
static void unbind(wl_resource *resource);
static Private *cast(wl_resource *r) {
return reinterpret_cast<Private*>(wl_resource_get_user_data(r));
}
static void destroyCallback(wl_client *client, wl_resource *resource);
static void exportCallback(wl_client *client, wl_resource *resource, uint32_t id, wl_resource * surface);
XdgExporterUnstableV2Interface *q;
static const struct zxdg_exporter_v2_interface s_interface;
XdgForeignV2Interface *foreignInterface;
QHash<QString, XdgExportedV2Interface *> exportedSurfaces;
XdgExporterV2Interface *q;
static const quint32 s_version;
protected:
void zxdg_exporter_v2_destroy(Resource *resource) override;
void zxdg_exporter_v2_export_toplevel(Resource *resource, uint32_t id, wl_resource *surface) override;
};
const quint32 XdgExporterUnstableV2Interface::Private::s_version = 1;
const quint32 XdgExporterV2InterfacePrivate::s_version = 1;
#ifndef K_DOXYGEN
const struct zxdg_exporter_v2_interface XdgExporterUnstableV2Interface::Private::s_interface = {
destroyCallback,
exportCallback
};
#endif
XdgExporterUnstableV2Interface::XdgExporterUnstableV2Interface(Display *display, XdgForeignInterface *parent)
: Global(new Private(this, display, parent), parent)
XdgExporterV2Interface::XdgExporterV2Interface(Display *display, XdgForeignV2Interface *parent)
: QObject(parent)
, d(new XdgExporterV2InterfacePrivate(this, display, parent))
{
}
XdgExporterUnstableV2Interface::~XdgExporterUnstableV2Interface()
{}
XdgExporterV2Interface::~XdgExporterV2Interface() = default;
XdgExporterUnstableV2Interface::Private *XdgExporterUnstableV2Interface::d_func() const
XdgExportedV2Interface *XdgExporterV2Interface::exportedSurface(const QString &handle)
{
return reinterpret_cast<Private*>(d.data());
}
XdgExportedUnstableV2Interface *XdgExporterUnstableV2Interface::exportedSurface(const QString &handle)
{
Q_D();
auto it = d->exportedSurfaces.constFind(handle);
if (it != d->exportedSurfaces.constEnd()) {
return it.value();
@ -76,126 +76,90 @@ XdgExportedUnstableV2Interface *XdgExporterUnstableV2Interface::exportedSurface(
return nullptr;
}
void XdgExporterUnstableV2Interface::Private::destroyCallback(wl_client *client, wl_resource *resource)
void XdgExporterV2InterfacePrivate::zxdg_exporter_v2_destroy(Resource *resource)
{
Q_UNUSED(client)
Q_UNUSED(resource)
wl_resource_destroy(resource->handle);
}
void XdgExporterUnstableV2Interface::Private::exportCallback(wl_client *client, wl_resource *resource, uint32_t id, wl_resource * surface)
void XdgExporterV2InterfacePrivate::zxdg_exporter_v2_export_toplevel(Resource *resource, uint32_t id, wl_resource *surface)
{
auto s = cast(resource);
QPointer <XdgExportedUnstableV2Interface> e = new XdgExportedUnstableV2Interface(s->q, surface);
e->create(s->display->getConnection(client), wl_resource_get_version(resource), id);
if (!e->resource()) {
wl_resource_post_no_memory(resource);
delete e;
SurfaceInterface *s = SurfaceInterface::get(surface);
if (!s) {
wl_resource_post_error(resource->handle, 0, "Invalid surface");
return;
}
wl_resource *XdgExported_resource = wl_resource_create(resource->client(), &zxdg_exported_v2_interface, resource->version(), id);
if (!XdgExported_resource) {
wl_client_post_no_memory(resource->client());
return;
}
XdgExportedV2Interface * xdgExported = new XdgExportedV2Interface(s, XdgExported_resource);
const QString handle = QUuid::createUuid().toString();
//a surface not exported anymore
connect(e.data(), &XdgExportedUnstableV2Interface::unbound,
s->q, [s, handle]() {
s->exportedSurfaces.remove(handle);
emit s->q->surfaceUnexported(handle);
QObject::connect(xdgExported, &XdgExportedV2Interface::destroyed,
q, [this, handle]() {
exportedSurfaces.remove(handle);
emit q->surfaceUnexported(handle);
});
//if the surface dies before this, this dies too
connect(SurfaceInterface::get(surface), &QObject::destroyed,
s->q, [s, e, handle]() {
if (e) {
e->deleteLater();
QObject::connect(SurfaceInterface::get(surface), &QObject::destroyed,
q, [this, xdgExported, handle]() {
if (xdgExported) {
xdgExported->deleteLater();
}
s->exportedSurfaces.remove(handle);
emit s->q->surfaceUnexported(handle);
exportedSurfaces.remove(handle);
emit q->surfaceUnexported(handle);
});
s->exportedSurfaces[handle] = e;
zxdg_exported_v2_send_handle(e->resource(), handle.toUtf8().constData());
emit s->q->surfaceExported(handle, e);
exportedSurfaces[handle] = xdgExported;
zxdg_exported_v2_send_handle(XdgExported_resource, handle.toUtf8().constData());
emit q->surfaceExported(handle, xdgExported);
}
XdgExporterUnstableV2Interface::Private::Private(XdgExporterUnstableV2Interface *q, Display *d,XdgForeignInterface *foreignInterface)
: Global::Private(d, &zxdg_exporter_v2_interface, s_version)
XdgExporterV2InterfacePrivate::XdgExporterV2InterfacePrivate(XdgExporterV2Interface *_q, Display *display, XdgForeignV2Interface *foreignInterface)
: QtWaylandServer::zxdg_exporter_v2(*display, s_version)
, foreignInterface(foreignInterface)
, q(q)
, q(_q)
{
}
void XdgExporterUnstableV2Interface::Private::bind(wl_client *client, uint32_t version, uint32_t id)
{
auto c = display->getConnection(client);
wl_resource *resource = c->createResource(&zxdg_exporter_v2_interface, qMin(version, s_version), id);
if (!resource) {
wl_client_post_no_memory(client);
return;
}
wl_resource_set_implementation(resource, &s_interface, this, unbind);
// TODO: should we track?
}
void XdgExporterUnstableV2Interface::Private::unbind(wl_resource *resource)
{
Q_UNUSED(resource)
// TODO: implement?
}
class Q_DECL_HIDDEN XdgImporterUnstableV2Interface::Private : public Global::Private
class XdgImporterV2InterfacePrivate : public QtWaylandServer::zxdg_importer_v2
{
public:
Private(XdgImporterUnstableV2Interface *q, Display *d, XdgForeignInterface *foreignInterface);
XdgImporterV2InterfacePrivate(XdgImporterV2Interface *_q, Display *display, XdgForeignV2Interface *foreignInterface);
XdgForeignInterface *foreignInterface;
QHash<QString, XdgImportedUnstableV2Interface *> importedSurfaces;
XdgForeignV2Interface *foreignInterface;
QHash<QString, XdgImportedV2Interface *> importedSurfaces;
//child->parent hash
QHash<SurfaceInterface *, XdgImportedUnstableV2Interface *> parents;
QHash<SurfaceInterface *, XdgImportedV2Interface *> parents;
//parent->child hash
QHash<XdgImportedUnstableV2Interface *, SurfaceInterface *> children;
private:
void bind(wl_client *client, uint32_t version, uint32_t id) override;
static void unbind(wl_resource *resource);
static Private *cast(wl_resource *r) {
return reinterpret_cast<Private*>(wl_resource_get_user_data(r));
}
static void destroyCallback(wl_client *client, wl_resource *resource);
static void importCallback(wl_client *client, wl_resource *resource, uint32_t id, const char * handle);
XdgImporterUnstableV2Interface *q;
static const struct zxdg_importer_v2_interface s_interface;
QHash<XdgImportedV2Interface *, SurfaceInterface *> children;
XdgImporterV2Interface *q;
static const quint32 s_version;
protected:
void zxdg_importer_v2_destroy(Resource *resource) override;
void zxdg_importer_v2_import_toplevel(Resource *resource, uint32_t id, const QString &handle) override;
};
const quint32 XdgImporterUnstableV2Interface::Private::s_version = 1;
const quint32 XdgImporterV2InterfacePrivate::s_version = 1;
#ifndef K_DOXYGEN
const struct zxdg_importer_v2_interface XdgImporterUnstableV2Interface::Private::s_interface = {
destroyCallback,
importCallback
};
#endif
XdgImporterUnstableV2Interface::XdgImporterUnstableV2Interface(Display *display, XdgForeignInterface *parent)
: Global(new Private(this, display, parent), parent)
XdgImporterV2Interface::XdgImporterV2Interface(Display *display, XdgForeignV2Interface *parent)
: QObject(parent)
, d(new XdgImporterV2InterfacePrivate(this, display, parent))
{
}
XdgImporterUnstableV2Interface::~XdgImporterUnstableV2Interface()
{
}
XdgImporterV2Interface::~XdgImporterV2Interface() = default;
XdgImportedUnstableV2Interface *XdgImporterUnstableV2Interface::importedSurface(const QString &handle)
XdgImportedV2Interface *XdgImporterV2Interface::importedSurface(const QString &handle)
{
Q_D();
auto it = d->importedSurfaces.constFind(handle);
if (it != d->importedSurfaces.constEnd()) {
return it.value();
@ -203,246 +167,175 @@ XdgImportedUnstableV2Interface *XdgImporterUnstableV2Interface::importedSurface(
return nullptr;
}
SurfaceInterface *XdgImporterUnstableV2Interface::transientFor(SurfaceInterface *surface)
SurfaceInterface *XdgImporterV2Interface::transientFor(SurfaceInterface *surface)
{
Q_D();
auto it = d->parents.constFind(surface);
if (it == d->parents.constEnd()) {
return nullptr;
}
return SurfaceInterface::get((*it)->parentResource());
return (*it)->parentResource();
}
XdgImporterUnstableV2Interface::Private *XdgImporterUnstableV2Interface::d_func() const
void XdgImporterV2InterfacePrivate::zxdg_importer_v2_destroy(Resource *resource)
{
return reinterpret_cast<Private*>(d.data());
wl_resource_destroy(resource->handle);
}
void XdgImporterUnstableV2Interface::Private::destroyCallback(wl_client *client, wl_resource *resource)
void XdgImporterV2InterfacePrivate::zxdg_importer_v2_import_toplevel(Resource *resource, uint32_t id, const QString &handle)
{
Q_UNUSED(client)
Q_UNUSED(resource)
}
Q_ASSERT(foreignInterface);
void XdgImporterUnstableV2Interface::Private::importCallback(wl_client *client, wl_resource *resource, uint32_t id, const char *h)
{
auto s = cast(resource);
Q_ASSERT(s->foreignInterface);
const QString handle = QString::fromUtf8(h);
XdgExportedUnstableV2Interface *exp = s->foreignInterface->d->exporter->exportedSurface(handle);
XdgExportedV2Interface *exp = foreignInterface->d->exporter->exportedSurface(handle);
if (!exp) {
zxdg_imported_v2_send_destroyed(resource);
zxdg_imported_v2_send_destroyed(resource->handle);
return;
}
wl_resource *surface = exp->parentResource();
SurfaceInterface *surface = exp->parentResource();
if (!surface) {
zxdg_imported_v2_send_destroyed(resource);
zxdg_imported_v2_send_destroyed(resource->handle);
return;
}
QPointer<XdgImportedUnstableV2Interface> imp = new XdgImportedUnstableV2Interface(s->q, surface);
imp->create(s->display->getConnection(client), wl_resource_get_version(resource), id);
wl_resource *XdgImported_resource = wl_resource_create(resource->client(), &zxdg_imported_v2_interface, resource->version(), id);
if (!XdgImported_resource) {
wl_client_post_no_memory(resource->client());
return;
}
XdgImportedV2Interface * XdgImported = new XdgImportedV2Interface(surface, XdgImported_resource);
//surface no longer exported
connect(exp, &XdgExportedUnstableV2Interface::unbound,
s->q, [s, imp, handle]() {
QObject::connect(exp, &XdgExportedV2Interface::destroyed,
q, [this, XdgImported, handle, XdgImported_resource]() {
//imp valid when the exported is deleted before the imported
if (imp) {
zxdg_imported_v2_send_destroyed(imp->resource());
imp->deleteLater();
if (XdgImported) {
zxdg_imported_v2_send_destroyed(XdgImported_resource);
XdgImported->deleteLater();
}
s->importedSurfaces.remove(handle);
emit s->q->surfaceUnimported(handle);
importedSurfaces.remove(handle);
emit q->surfaceUnimported(handle);
});
connect(imp.data(), &XdgImportedUnstableV2Interface::childChanged,
s->q, [s, imp](SurfaceInterface *child) {
QObject::connect(XdgImported, &XdgImportedV2Interface::childChanged,
q, [this, XdgImported](SurfaceInterface *child) {
//remove any previous association
auto it = s->children.find(imp);
if (it != s->children.end()) {
s->parents.remove(*it);
s->children.erase(it);
auto it = children.find(XdgImported);
if (it != children.end()) {
parents.remove(*it);
children.erase(it);
}
s->parents[child] = imp;
s->children[imp] = child;
SurfaceInterface *parent = SurfaceInterface::get(imp->parentResource());
emit s->q->transientChanged(child, parent);
parents[child] = XdgImported;
children[XdgImported] = child;
SurfaceInterface *parent = XdgImported->parentResource();
emit q->transientChanged(child, parent);
//child surface destroyed
connect(child, &QObject::destroyed,
s->q, [s, child]() {
auto it = s->parents.find(child);
if (it != s->parents.end()) {
KWaylandServer::XdgImportedUnstableV2Interface* parent = *it;
s->children.remove(*it);
s->parents.erase(it);
emit s->q->transientChanged(nullptr, SurfaceInterface::get(parent->parentResource()));
QObject::connect(child, &QObject::destroyed,
q, [this, child]() {
auto it = parents.find(child);
if (it != parents.end()) {
KWaylandServer::XdgImportedV2Interface* parent = *it;
children.remove(*it);
parents.erase(it);
emit q->transientChanged(nullptr, parent->parentResource());
}
});
});
//surface no longer imported
connect(imp.data(), &XdgImportedUnstableV2Interface::unbound,
s->q, [s, handle, imp]() {
s->importedSurfaces.remove(handle);
emit s->q->surfaceUnimported(handle);
QObject::connect(XdgImported, &XdgImportedV2Interface::destroyed,
q, [this, handle, XdgImported]() {
importedSurfaces.remove(handle);
emit q->surfaceUnimported(handle);
auto it = s->children.find(imp);
if (it != s->children.end()) {
auto it = children.find(XdgImported);
if (it != children.end()) {
KWaylandServer::SurfaceInterface* child = *it;
s->parents.remove(*it);
s->children.erase(it);
emit s->q->transientChanged(child, nullptr);
parents.remove(*it);
children.erase(it);
emit q->transientChanged(child, nullptr);
}
});
if (!imp->resource()) {
wl_resource_post_no_memory(resource);
delete imp;
return;
importedSurfaces[handle] = XdgImported;
emit q->surfaceImported(handle, XdgImported);
}
s->importedSurfaces[handle] = imp;
emit s->q->surfaceImported(handle, imp);
}
XdgImporterUnstableV2Interface::Private::Private(XdgImporterUnstableV2Interface *q, Display *d, XdgForeignInterface *foreignInterface)
: Global::Private(d, &zxdg_importer_v2_interface, s_version)
XdgImporterV2InterfacePrivate::XdgImporterV2InterfacePrivate(XdgImporterV2Interface *_q, Display *display, XdgForeignV2Interface *foreignInterface)
: QtWaylandServer::zxdg_importer_v2(*display, s_version)
, foreignInterface(foreignInterface)
, q(q)
, q(_q)
{
}
void XdgImporterUnstableV2Interface::Private::bind(wl_client *client, uint32_t version, uint32_t id)
XdgExportedV2Interface::XdgExportedV2Interface(SurfaceInterface *surface, wl_resource *resource )
: QObject(nullptr)
, QtWaylandServer::zxdg_exported_v2(resource)
, surface(surface)
{
auto c = display->getConnection(client);
wl_resource *resource = c->createResource(&zxdg_importer_v2_interface, qMin(version, s_version), id);
if (!resource) {
wl_client_post_no_memory(client);
return;
}
wl_resource_set_implementation(resource, &s_interface, this, unbind);
// TODO: should we track?
}
void XdgImporterUnstableV2Interface::Private::unbind(wl_resource *resource)
XdgExportedV2Interface::~XdgExportedV2Interface() = default;
SurfaceInterface *XdgExportedV2Interface::parentResource()
{
return surface;
}
void XdgExportedV2Interface::zxdg_exported_v2_destroy(Resource *resource)
{
wl_resource_destroy(resource->handle);
}
void XdgExportedV2Interface::zxdg_exported_v2_destroy_resource(Resource *resource)
{
Q_UNUSED(resource)
// TODO: implement?
delete this;
}
class Q_DECL_HIDDEN XdgExportedUnstableV2Interface::Private : public Resource::Private
{
public:
Private(XdgExportedUnstableV2Interface *q, XdgExporterUnstableV2Interface *c, wl_resource *parentResource);
~Private();
private:
XdgExportedUnstableV2Interface *q_func() {
return reinterpret_cast<XdgExportedUnstableV2Interface *>(q);
}
static const struct zxdg_exported_v2_interface s_interface;
};
#ifndef K_DOXYGEN
const struct zxdg_exported_v2_interface XdgExportedUnstableV2Interface::Private::s_interface = {
resourceDestroyedCallback
};
#endif
XdgExportedUnstableV2Interface::XdgExportedUnstableV2Interface(XdgExporterUnstableV2Interface *parent, wl_resource *parentResource)
: Resource(new Private(this, parent, parentResource))
XdgImportedV2Interface::XdgImportedV2Interface(SurfaceInterface *surface, wl_resource *resource)
: QObject(nullptr)
, QtWaylandServer::zxdg_imported_v2(resource)
, surface(surface)
{
}
XdgExportedUnstableV2Interface::~XdgExportedUnstableV2Interface()
{}
XdgImportedV2Interface::~XdgImportedV2Interface() = default;
XdgExportedUnstableV2Interface::Private *XdgExportedUnstableV2Interface::d_func() const
SurfaceInterface *XdgImportedV2Interface::child() const
{
return reinterpret_cast<Private*>(d.data());
return parentOf.data();
}
XdgExportedUnstableV2Interface::Private::Private(XdgExportedUnstableV2Interface *q, XdgExporterUnstableV2Interface *c, wl_resource *parentResource)
: Resource::Private(q, c, parentResource, &zxdg_exported_v2_interface, &s_interface)
SurfaceInterface *XdgImportedV2Interface::parentResource()
{
return surface;
}
XdgExportedUnstableV2Interface::Private::~Private()
{}
class Q_DECL_HIDDEN XdgImportedUnstableV2Interface::Private : public Resource::Private
void XdgImportedV2Interface::zxdg_imported_v2_set_parent_of(Resource *resource, wl_resource *surface)
{
public:
Private(XdgImportedUnstableV2Interface *q, XdgImporterUnstableV2Interface *c, wl_resource *parentResource);
~Private();
QPointer<SurfaceInterface> parentOf;
private:
static void setParentOfCallback(wl_client *client, wl_resource *resource, wl_resource * surface);
XdgImportedUnstableV2Interface *q_func() {
return reinterpret_cast<XdgImportedUnstableV2Interface *>(q);
}
static const struct zxdg_imported_v2_interface s_interface;
};
#ifndef K_DOXYGEN
const struct zxdg_imported_v2_interface XdgImportedUnstableV2Interface::Private::s_interface = {
resourceDestroyedCallback,
setParentOfCallback
};
#endif
XdgImportedUnstableV2Interface::XdgImportedUnstableV2Interface(XdgImporterUnstableV2Interface *parent, wl_resource *parentResource)
: Resource(new Private(this, parent, parentResource))
{
}
XdgImportedUnstableV2Interface::~XdgImportedUnstableV2Interface()
{}
XdgImportedUnstableV2Interface::Private *XdgImportedUnstableV2Interface::d_func() const
{
return reinterpret_cast<Private*>(d.data());
}
SurfaceInterface *XdgImportedUnstableV2Interface::child() const
{
Q_D();
return d->parentOf.data();
}
void XdgImportedUnstableV2Interface::Private::setParentOfCallback(wl_client *client, wl_resource *resource, wl_resource * surface)
{
Q_UNUSED(client)
auto s = cast<Private>(resource);
Q_UNUSED(resource)
SurfaceInterface *surf = SurfaceInterface::get(surface);
if (!surf) {
return;
}
s->parentOf = surf;
emit s->q_func()->childChanged(surf);
parentOf = surf;
emit childChanged(surf);
}
XdgImportedUnstableV2Interface::Private::Private(XdgImportedUnstableV2Interface *q, XdgImporterUnstableV2Interface *c, wl_resource *parentResource)
: Resource::Private(q, c, parentResource, &zxdg_imported_v2_interface, &s_interface)
void XdgImportedV2Interface::zxdg_imported_v2_destroy(Resource *resource)
{
wl_resource_destroy(resource->handle);
}
XdgImportedUnstableV2Interface::Private::~Private()
{}
void XdgImportedV2Interface::zxdg_imported_v2_destroy_resource(Resource *resource)
{
Q_UNUSED(resource)
delete this;
}
}

View file

@ -6,8 +6,7 @@
#ifndef KWAYLAND_SERVER_XDGFOREIGN_INTERFACE_H
#define KWAYLAND_SERVER_XDGFOREIGN_INTERFACE_H
#include "global.h"
#include "resource.h"
#include <QObject>
#include <KWaylandServer/kwaylandserver_export.h>
@ -16,8 +15,9 @@ namespace KWaylandServer
class Display;
class SurfaceInterface;
class XdgExporterUnstableV2Interface;
class XdgImporterUnstableV2Interface;
class XdgExporterV2Interface;
class XdgImporterV2Interface;
class XdgForeignV2InterfacePrivate;
/**
* This class encapsulates the server side logic of the XdgForeign protocol.
@ -29,23 +29,12 @@ class XdgImporterUnstableV2Interface;
*
* @since 5.40
*/
class KWAYLANDSERVER_EXPORT XdgForeignInterface : public QObject
class KWAYLANDSERVER_EXPORT XdgForeignV2Interface : public QObject
{
Q_OBJECT
public:
XdgForeignInterface(Display *display, QObject *parent = nullptr);
~XdgForeignInterface();
/**
* Creates the native zxdg_exporter_v2 and zxdg_importer_v2 interfaces
* and announces them to the client.
*/
void create();
/**
* @returns true if theimporter and exporter are valid and functional
*/
bool isValid();
XdgForeignV2Interface(Display *display, QObject *parent = nullptr);
~XdgForeignV2Interface() override;
/**
* If a client did import a surface and set one of its own as child of the
@ -69,10 +58,9 @@ Q_SIGNALS:
private:
friend class Display;
friend class XdgExporterUnstableV2Interface;
friend class XdgImporterUnstableV2Interface;
class Private;
Private *d;
friend class XdgExporterV2InterfacePrivate;
friend class XdgImporterV2InterfacePrivate;
QScopedPointer<XdgForeignV2InterfacePrivate> d;
};
}

View file

@ -6,102 +6,110 @@
#ifndef KWAYLAND_SERVER_XDGFOREIGNV2_INTERFACE_P_H
#define KWAYLAND_SERVER_XDGFOREIGNV2_INTERFACE_P_H
#include "global.h"
#include "resource.h"
#include "xdgforeign_v2_interface.h"
#include "surface_interface_p.h"
#include <qwayland-server-xdg-foreign-unstable-v2.h>
namespace KWaylandServer
{
class Display;
class SurfaceInterface;
class XdgExportedUnstableV2Interface;
class XdgImportedUnstableV2Interface;
class XdgExportedV2Interface;
class XdgImportedV2Interface;
class XdgExporterV2InterfacePrivate;
class XdgImporterV2InterfacePrivate;
class XdgExportedV2Interface;
class XdgImportedV2InterfacePrivate;
class Q_DECL_HIDDEN XdgForeignInterface::Private
{
public:
Private(Display *display, XdgForeignInterface *q);
XdgForeignInterface *q;
XdgExporterUnstableV2Interface *exporter;
XdgImporterUnstableV2Interface *importer;
};
class Q_DECL_HIDDEN XdgExporterUnstableV2Interface : public Global
class XdgForeignV2InterfacePrivate : public QObject
{
Q_OBJECT
public:
virtual ~XdgExporterUnstableV2Interface();
XdgForeignV2InterfacePrivate(Display *display, XdgForeignV2Interface *q);
XdgExportedUnstableV2Interface *exportedSurface(const QString &handle);
XdgForeignV2Interface *q;
XdgExporterV2Interface *exporter;
XdgImporterV2Interface *importer;
};
class XdgExporterV2Interface : public QObject
{
Q_OBJECT
public:
explicit XdgExporterV2Interface(Display *display, XdgForeignV2Interface *parent = nullptr);
~XdgExporterV2Interface() override;
XdgExportedV2Interface *exportedSurface(const QString &handle);
Q_SIGNALS:
void surfaceExported(const QString &handle, XdgExportedUnstableV2Interface *exported);
void surfaceExported(const QString &handle, XdgExportedV2Interface *exported);
void surfaceUnexported(const QString &handle);
private:
explicit XdgExporterUnstableV2Interface(Display *display, XdgForeignInterface *parent = nullptr);
friend class Display;
friend class XdgForeignInterface;
class Private;
Private *d_func() const;
QScopedPointer<XdgExporterV2InterfacePrivate> d;
};
class Q_DECL_HIDDEN XdgImporterUnstableV2Interface : public Global
class XdgImporterV2Interface : public QObject
{
Q_OBJECT
public:
virtual ~XdgImporterUnstableV2Interface();
explicit XdgImporterV2Interface(Display *display, XdgForeignV2Interface *parent = nullptr);
~XdgImporterV2Interface() override;
XdgImportedUnstableV2Interface *importedSurface(const QString &handle);
XdgImportedV2Interface *importedSurface(const QString &handle);
SurfaceInterface *transientFor(SurfaceInterface *surface);
Q_SIGNALS:
void surfaceImported(const QString &handle, XdgImportedUnstableV2Interface *imported);
void surfaceImported(const QString &handle, XdgImportedV2Interface *imported);
void surfaceUnimported(const QString &handle);
void transientChanged(KWaylandServer::SurfaceInterface *child, KWaylandServer::SurfaceInterface *parent);
private:
explicit XdgImporterUnstableV2Interface(Display *display, XdgForeignInterface *parent = nullptr);
friend class Display;
friend class XdgForeignInterface;
class Private;
Private *d_func() const;
QScopedPointer<XdgImporterV2InterfacePrivate> d;
};
class Q_DECL_HIDDEN XdgExportedUnstableV2Interface : public Resource
class XdgExportedV2Interface : public QObject, QtWaylandServer::zxdg_exported_v2
{
Q_OBJECT
public:
virtual ~XdgExportedUnstableV2Interface();
explicit XdgExportedV2Interface(SurfaceInterface *surface, wl_resource *resource );
~XdgExportedV2Interface() override;
SurfaceInterface *parentResource();
private:
explicit XdgExportedUnstableV2Interface(XdgExporterUnstableV2Interface *parent, wl_resource *parentResource);
friend class XdgExporterUnstableV2Interface;
SurfaceInterface *surface;
protected:
void zxdg_exported_v2_destroy(Resource *resource) override;
void zxdg_exported_v2_destroy_resource(Resource *resource) override;
class Private;
Private *d_func() const;
};
class Q_DECL_HIDDEN XdgImportedUnstableV2Interface : public Resource
class XdgImportedV2Interface : public QObject, QtWaylandServer::zxdg_imported_v2
{
Q_OBJECT
public:
virtual ~XdgImportedUnstableV2Interface();
explicit XdgImportedV2Interface(SurfaceInterface *surface, wl_resource *resource);
~XdgImportedV2Interface() override;
SurfaceInterface *child() const;
SurfaceInterface *parentResource();
Q_SIGNALS:
void childChanged(KWaylandServer::SurfaceInterface *child);
private:
explicit XdgImportedUnstableV2Interface(XdgImporterUnstableV2Interface *parent, wl_resource *parentResource);
friend class XdgImporterUnstableV2Interface;
SurfaceInterface *surface;
QPointer<SurfaceInterface> parentOf;
protected:
void zxdg_imported_v2_set_parent_of(Resource *resource, wl_resource *surface) override;
void zxdg_imported_v2_destroy(Resource *resource) override;
void zxdg_imported_v2_destroy_resource(Resource *resource) override;
class Private;
Private *d_func() const;
};
}
#endif