2020-03-15 15:19:28 +00:00
|
|
|
/*
|
|
|
|
SPDX-FileCopyrightText: 2016 Martin Gräßlin <mgraesslin@kde.org>
|
|
|
|
SPDX-FileCopyrightText: 2017 Marco Martin <mart@kde.org>
|
|
|
|
|
|
|
|
SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
|
|
|
|
*/
|
2021-08-29 05:11:06 +00:00
|
|
|
#include "KWayland/Client/xdgforeign.h"
|
2020-04-29 13:59:23 +00:00
|
|
|
#include "KWayland/Client/compositor.h"
|
|
|
|
#include "KWayland/Client/connection_thread.h"
|
|
|
|
#include "KWayland/Client/event_queue.h"
|
|
|
|
#include "KWayland/Client/registry.h"
|
|
|
|
#include "KWayland/Client/shell.h"
|
|
|
|
#include "KWayland/Client/shm_pool.h"
|
|
|
|
#include "KWayland/Client/xdgshell.h"
|
Wayland foreign protocol
Summary:
Implement the "foreign" wayland protocol.
A client can export a surface with an unique string as handle,
then another client can refer to that surface and set an own surface as
child of that surface.
Potential use cases are out-of-process dialogs, such as file dialogs,
meant to be used by sandboxed processes that may not have the access
it needs to implement such dialogs.
The handle needs to be shared between the processes with other means,
such as dbus or command line paramenters.
The public api of the server side only tracks parent/child relationships as this is the only data kwin would need it for, the rest of the api is not exported so should be safer from eventual protocol changes
Test Plan:
the autotest works, but has a lot of random crashes when deleting surfaces,
unfortunately backtraces don't tell much and the crashes never occur when running into valgrind
behavior may still be wrong, depending on how the protocol is supposed
to work if more clients try to set the same exported surface as parent
Reviewers: #plasma, #kwin, davidedmundson, graesslin
Reviewed By: #plasma, #kwin, graesslin
Subscribers: davidedmundson, graesslin, plasma-devel, #frameworks
Tags: #frameworks, #plasma_on_wayland
Differential Revision: https://phabricator.kde.org/D7369
2017-10-13 09:29:17 +00:00
|
|
|
// Qt
|
|
|
|
#include <QCommandLineParser>
|
2021-08-29 05:11:06 +00:00
|
|
|
#include <QDebug>
|
Wayland foreign protocol
Summary:
Implement the "foreign" wayland protocol.
A client can export a surface with an unique string as handle,
then another client can refer to that surface and set an own surface as
child of that surface.
Potential use cases are out-of-process dialogs, such as file dialogs,
meant to be used by sandboxed processes that may not have the access
it needs to implement such dialogs.
The handle needs to be shared between the processes with other means,
such as dbus or command line paramenters.
The public api of the server side only tracks parent/child relationships as this is the only data kwin would need it for, the rest of the api is not exported so should be safer from eventual protocol changes
Test Plan:
the autotest works, but has a lot of random crashes when deleting surfaces,
unfortunately backtraces don't tell much and the crashes never occur when running into valgrind
behavior may still be wrong, depending on how the protocol is supposed
to work if more clients try to set the same exported surface as parent
Reviewers: #plasma, #kwin, davidedmundson, graesslin
Reviewed By: #plasma, #kwin, graesslin
Subscribers: davidedmundson, graesslin, plasma-devel, #frameworks
Tags: #frameworks, #plasma_on_wayland
Differential Revision: https://phabricator.kde.org/D7369
2017-10-13 09:29:17 +00:00
|
|
|
#include <QGuiApplication>
|
|
|
|
#include <QImage>
|
|
|
|
#include <QThread>
|
|
|
|
using namespace KWayland::Client;
|
|
|
|
|
|
|
|
class XdgForeignTest : public QObject
|
|
|
|
{
|
|
|
|
Q_OBJECT
|
|
|
|
public:
|
|
|
|
explicit XdgForeignTest(QObject *parent = nullptr);
|
|
|
|
virtual ~XdgForeignTest();
|
|
|
|
|
|
|
|
void init();
|
|
|
|
|
|
|
|
private:
|
|
|
|
void setupRegistry(Registry *registry);
|
|
|
|
void render();
|
|
|
|
QThread *m_connectionThread;
|
|
|
|
ConnectionThread *m_connectionThreadObject;
|
|
|
|
EventQueue *m_eventQueue = nullptr;
|
|
|
|
Compositor *m_compositor = nullptr;
|
|
|
|
XdgShell *m_shell = nullptr;
|
|
|
|
XdgShellSurface *m_shellSurface = nullptr;
|
|
|
|
ShmPool *m_shm = nullptr;
|
|
|
|
Surface *m_surface = nullptr;
|
|
|
|
|
|
|
|
XdgShellSurface *m_childShellSurface = nullptr;
|
|
|
|
Surface *m_childSurface = nullptr;
|
|
|
|
|
|
|
|
KWayland::Client::XdgExporter *m_exporter = nullptr;
|
|
|
|
KWayland::Client::XdgImporter *m_importer = nullptr;
|
|
|
|
KWayland::Client::XdgExported *m_exported = nullptr;
|
|
|
|
KWayland::Client::XdgImported *m_imported = nullptr;
|
|
|
|
};
|
|
|
|
|
|
|
|
XdgForeignTest::XdgForeignTest(QObject *parent)
|
|
|
|
: QObject(parent)
|
|
|
|
, m_connectionThread(new QThread(this))
|
|
|
|
, m_connectionThreadObject(new ConnectionThread())
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
XdgForeignTest::~XdgForeignTest()
|
|
|
|
{
|
|
|
|
m_connectionThread->quit();
|
|
|
|
m_connectionThread->wait();
|
|
|
|
m_connectionThreadObject->deleteLater();
|
|
|
|
}
|
|
|
|
|
|
|
|
void XdgForeignTest::init()
|
|
|
|
{
|
2021-08-29 05:11:06 +00:00
|
|
|
connect(
|
|
|
|
m_connectionThreadObject,
|
|
|
|
&ConnectionThread::connected,
|
|
|
|
this,
|
Wayland foreign protocol
Summary:
Implement the "foreign" wayland protocol.
A client can export a surface with an unique string as handle,
then another client can refer to that surface and set an own surface as
child of that surface.
Potential use cases are out-of-process dialogs, such as file dialogs,
meant to be used by sandboxed processes that may not have the access
it needs to implement such dialogs.
The handle needs to be shared between the processes with other means,
such as dbus or command line paramenters.
The public api of the server side only tracks parent/child relationships as this is the only data kwin would need it for, the rest of the api is not exported so should be safer from eventual protocol changes
Test Plan:
the autotest works, but has a lot of random crashes when deleting surfaces,
unfortunately backtraces don't tell much and the crashes never occur when running into valgrind
behavior may still be wrong, depending on how the protocol is supposed
to work if more clients try to set the same exported surface as parent
Reviewers: #plasma, #kwin, davidedmundson, graesslin
Reviewed By: #plasma, #kwin, graesslin
Subscribers: davidedmundson, graesslin, plasma-devel, #frameworks
Tags: #frameworks, #plasma_on_wayland
Differential Revision: https://phabricator.kde.org/D7369
2017-10-13 09:29:17 +00:00
|
|
|
[this] {
|
|
|
|
m_eventQueue = new EventQueue(this);
|
|
|
|
m_eventQueue->setup(m_connectionThreadObject);
|
|
|
|
|
|
|
|
Registry *registry = new Registry(this);
|
|
|
|
setupRegistry(registry);
|
|
|
|
},
|
2021-08-29 05:11:06 +00:00
|
|
|
Qt::QueuedConnection);
|
Wayland foreign protocol
Summary:
Implement the "foreign" wayland protocol.
A client can export a surface with an unique string as handle,
then another client can refer to that surface and set an own surface as
child of that surface.
Potential use cases are out-of-process dialogs, such as file dialogs,
meant to be used by sandboxed processes that may not have the access
it needs to implement such dialogs.
The handle needs to be shared between the processes with other means,
such as dbus or command line paramenters.
The public api of the server side only tracks parent/child relationships as this is the only data kwin would need it for, the rest of the api is not exported so should be safer from eventual protocol changes
Test Plan:
the autotest works, but has a lot of random crashes when deleting surfaces,
unfortunately backtraces don't tell much and the crashes never occur when running into valgrind
behavior may still be wrong, depending on how the protocol is supposed
to work if more clients try to set the same exported surface as parent
Reviewers: #plasma, #kwin, davidedmundson, graesslin
Reviewed By: #plasma, #kwin, graesslin
Subscribers: davidedmundson, graesslin, plasma-devel, #frameworks
Tags: #frameworks, #plasma_on_wayland
Differential Revision: https://phabricator.kde.org/D7369
2017-10-13 09:29:17 +00:00
|
|
|
m_connectionThreadObject->moveToThread(m_connectionThread);
|
|
|
|
m_connectionThread->start();
|
|
|
|
|
|
|
|
m_connectionThreadObject->initConnection();
|
|
|
|
}
|
|
|
|
|
|
|
|
void XdgForeignTest::setupRegistry(Registry *registry)
|
|
|
|
{
|
2021-08-29 05:11:06 +00:00
|
|
|
connect(registry, &Registry::compositorAnnounced, this, [this, registry](quint32 name, quint32 version) {
|
|
|
|
m_compositor = registry->createCompositor(name, version, this);
|
|
|
|
});
|
|
|
|
connect(registry, &Registry::xdgShellUnstableV5Announced, this, [this, registry](quint32 name, quint32 version) {
|
|
|
|
m_shell = registry->createXdgShell(name, version, this);
|
|
|
|
});
|
|
|
|
connect(registry, &Registry::shmAnnounced, this, [this, registry](quint32 name, quint32 version) {
|
|
|
|
m_shm = registry->createShmPool(name, version, this);
|
|
|
|
});
|
|
|
|
connect(registry, &Registry::exporterUnstableV2Announced, this, [this, registry](quint32 name, quint32 version) {
|
|
|
|
m_exporter = registry->createXdgExporter(name, version, this);
|
|
|
|
m_exporter->setEventQueue(m_eventQueue);
|
|
|
|
});
|
|
|
|
connect(registry, &Registry::importerUnstableV2Announced, this, [this, registry](quint32 name, quint32 version) {
|
|
|
|
m_importer = registry->createXdgImporter(name, version, this);
|
|
|
|
m_importer->setEventQueue(m_eventQueue);
|
|
|
|
});
|
|
|
|
connect(registry, &Registry::interfacesAnnounced, this, [this] {
|
|
|
|
Q_ASSERT(m_compositor);
|
|
|
|
Q_ASSERT(m_shell);
|
|
|
|
Q_ASSERT(m_shm);
|
|
|
|
Q_ASSERT(m_exporter);
|
|
|
|
Q_ASSERT(m_importer);
|
|
|
|
m_surface = m_compositor->createSurface(this);
|
|
|
|
Q_ASSERT(m_surface);
|
|
|
|
m_shellSurface = m_shell->createSurface(m_surface, this);
|
|
|
|
Q_ASSERT(m_shellSurface);
|
|
|
|
connect(m_shellSurface, &XdgShellSurface::sizeChanged, this, &XdgForeignTest::render);
|
|
|
|
|
|
|
|
m_childSurface = m_compositor->createSurface(this);
|
|
|
|
Q_ASSERT(m_childSurface);
|
|
|
|
m_childShellSurface = m_shell->createSurface(m_childSurface, this);
|
|
|
|
Q_ASSERT(m_childShellSurface);
|
|
|
|
connect(m_childShellSurface, &XdgShellSurface::sizeChanged, this, &XdgForeignTest::render);
|
|
|
|
|
|
|
|
m_exported = m_exporter->exportTopLevel(m_surface, this);
|
|
|
|
connect(m_exported, &XdgExported::done, this, [this]() {
|
|
|
|
m_imported = m_importer->importTopLevel(m_exported->handle(), this);
|
|
|
|
m_imported->setParentOf(m_childSurface);
|
|
|
|
});
|
|
|
|
render();
|
|
|
|
});
|
Wayland foreign protocol
Summary:
Implement the "foreign" wayland protocol.
A client can export a surface with an unique string as handle,
then another client can refer to that surface and set an own surface as
child of that surface.
Potential use cases are out-of-process dialogs, such as file dialogs,
meant to be used by sandboxed processes that may not have the access
it needs to implement such dialogs.
The handle needs to be shared between the processes with other means,
such as dbus or command line paramenters.
The public api of the server side only tracks parent/child relationships as this is the only data kwin would need it for, the rest of the api is not exported so should be safer from eventual protocol changes
Test Plan:
the autotest works, but has a lot of random crashes when deleting surfaces,
unfortunately backtraces don't tell much and the crashes never occur when running into valgrind
behavior may still be wrong, depending on how the protocol is supposed
to work if more clients try to set the same exported surface as parent
Reviewers: #plasma, #kwin, davidedmundson, graesslin
Reviewed By: #plasma, #kwin, graesslin
Subscribers: davidedmundson, graesslin, plasma-devel, #frameworks
Tags: #frameworks, #plasma_on_wayland
Differential Revision: https://phabricator.kde.org/D7369
2017-10-13 09:29:17 +00:00
|
|
|
registry->setEventQueue(m_eventQueue);
|
|
|
|
registry->create(m_connectionThreadObject);
|
|
|
|
registry->setup();
|
|
|
|
}
|
|
|
|
|
|
|
|
void XdgForeignTest::render()
|
|
|
|
{
|
|
|
|
QSize size = m_shellSurface->size().isValid() ? m_shellSurface->size() : QSize(500, 500);
|
|
|
|
auto buffer = m_shm->getBuffer(size, size.width() * 4).toStrongRef();
|
|
|
|
buffer->setUsed(true);
|
|
|
|
QImage image(buffer->address(), size.width(), size.height(), QImage::Format_ARGB32_Premultiplied);
|
|
|
|
image.fill(QColor(255, 255, 255, 255));
|
|
|
|
|
|
|
|
m_surface->attachBuffer(*buffer);
|
|
|
|
m_surface->damage(QRect(QPoint(0, 0), size));
|
|
|
|
m_surface->commit(Surface::CommitFlag::None);
|
|
|
|
buffer->setUsed(false);
|
2020-03-15 15:19:28 +00:00
|
|
|
|
Wayland foreign protocol
Summary:
Implement the "foreign" wayland protocol.
A client can export a surface with an unique string as handle,
then another client can refer to that surface and set an own surface as
child of that surface.
Potential use cases are out-of-process dialogs, such as file dialogs,
meant to be used by sandboxed processes that may not have the access
it needs to implement such dialogs.
The handle needs to be shared between the processes with other means,
such as dbus or command line paramenters.
The public api of the server side only tracks parent/child relationships as this is the only data kwin would need it for, the rest of the api is not exported so should be safer from eventual protocol changes
Test Plan:
the autotest works, but has a lot of random crashes when deleting surfaces,
unfortunately backtraces don't tell much and the crashes never occur when running into valgrind
behavior may still be wrong, depending on how the protocol is supposed
to work if more clients try to set the same exported surface as parent
Reviewers: #plasma, #kwin, davidedmundson, graesslin
Reviewed By: #plasma, #kwin, graesslin
Subscribers: davidedmundson, graesslin, plasma-devel, #frameworks
Tags: #frameworks, #plasma_on_wayland
Differential Revision: https://phabricator.kde.org/D7369
2017-10-13 09:29:17 +00:00
|
|
|
size = m_childShellSurface->size().isValid() ? m_childShellSurface->size() : QSize(200, 200);
|
|
|
|
buffer = m_shm->getBuffer(size, size.width() * 4).toStrongRef();
|
|
|
|
buffer->setUsed(true);
|
|
|
|
image = QImage(buffer->address(), size.width(), size.height(), QImage::Format_ARGB32_Premultiplied);
|
|
|
|
image.fill(QColor(255, 0, 0, 255));
|
|
|
|
|
|
|
|
m_childSurface->attachBuffer(*buffer);
|
|
|
|
m_childSurface->damage(QRect(QPoint(0, 0), size));
|
|
|
|
m_childSurface->commit(Surface::CommitFlag::None);
|
|
|
|
buffer->setUsed(false);
|
|
|
|
}
|
|
|
|
|
|
|
|
int main(int argc, char **argv)
|
|
|
|
{
|
|
|
|
QCoreApplication app(argc, argv);
|
|
|
|
|
|
|
|
XdgForeignTest client;
|
|
|
|
|
|
|
|
client.init();
|
|
|
|
|
|
|
|
return app.exec();
|
|
|
|
}
|
|
|
|
|
|
|
|
#include "xdgforeigntest.moc"
|