Commit 67385809 authored by Aleix Pol Gonzalez's avatar Aleix Pol Gonzalez 🐧 Committed by Aleix Pol Gonzalez
Browse files

screencasting: Drop KWayland dependency, cleanup

Makes it considerably easier to use it and drops a ton of code.

This was adapted from tested code in KPipeWire.

Fixes plasma-mobile#210
parent 1111cc18
Pipeline #229156 passed with stage
in 6 minutes and 33 seconds
......@@ -33,7 +33,7 @@ target_include_directories(taskmanagerplugin PRIVATE ${Libdrm_INCLUDE_DIR})
target_sources(taskmanagerplugin PUBLIC screencasting.cpp screencastingrequest.cpp ${SRCS})
target_link_libraries(taskmanagerplugin Qt::Qml Qt::GuiPrivate
KF5::I18n
KF5::WaylandClient
Qt::WaylandClient
Wayland::Client)
if (${Qt5Gui_OPENGL_IMPLEMENTATION} STREQUAL "GLESv2")
target_link_libraries(taskmanagerplugin Qt5::Gui_GLESv2)
......
......@@ -6,17 +6,13 @@
#include "screencasting.h"
#include "qwayland-zkde-screencast-unstable-v1.h"
#include <KWayland/Client/output.h>
#include <KWayland/Client/plasmawindowmanagement.h>
#include <KWayland/Client/registry.h>
#include <QDebug>
#include <QGuiApplication>
#include <QRect>
#include <QPointer>
#include <QScreen>
#include <QWaylandClientExtensionTemplate>
#include <qpa/qplatformnativeinterface.h>
using namespace KWayland::Client;
class ScreencastingStreamPrivate : public QtWayland::zkde_screencast_stream_unstable_v1
{
public:
......@@ -63,19 +59,24 @@ quint32 ScreencastingStream::nodeId() const
return d->m_nodeId;
}
class ScreencastingPrivate : public QtWayland::zkde_screencast_unstable_v1
class ScreencastingPrivate : public QWaylandClientExtensionTemplate<ScreencastingPrivate>, public QtWayland::zkde_screencast_unstable_v1
{
public:
ScreencastingPrivate(Registry *registry, int id, int version, Screencasting *q)
: QtWayland::zkde_screencast_unstable_v1(*registry, id, version)
, q(q)
{
}
ScreencastingPrivate(::zkde_screencast_unstable_v1 *screencasting, Screencasting *q)
: QtWayland::zkde_screencast_unstable_v1(screencasting)
ScreencastingPrivate(Screencasting *q)
: QWaylandClientExtensionTemplate<ScreencastingPrivate>(ZKDE_SCREENCAST_UNSTABLE_V1_STREAM_REGION_SINCE_VERSION)
, q(q)
{
#if QTWAYLANDCLIENT_VERSION >= QT_VERSION_CHECK(6, 2, 0)
initialize();
#else
// QWaylandClientExtensionTemplate invokes this with a QueuedConnection but we want it called immediately
QMetaObject::invokeMethod(this, "addRegistryListener", Qt::DirectConnection);
#endif
if (!isInitialized()) {
qWarning() << "Remember requesting the interface on your desktop file: X-KDE-Wayland-Interfaces=zkde_screencast_unstable_v1";
}
Q_ASSERT(isInitialized());
}
~ScreencastingPrivate()
......@@ -88,12 +89,7 @@ public:
Screencasting::Screencasting(QObject *parent)
: QObject(parent)
{
}
Screencasting::Screencasting(Registry *registry, int id, int version, QObject *parent)
: QObject(parent)
, d(new ScreencastingPrivate(registry, id, version, this))
, d(new ScreencastingPrivate(this))
{
}
......@@ -118,21 +114,6 @@ ScreencastingStream *Screencasting::createOutputStream(const QString &outputName
return stream;
}
ScreencastingStream *Screencasting::createOutputStream(Output *output, CursorMode mode)
{
auto stream = new ScreencastingStream(this);
stream->setObjectName(output->model());
stream->d->init(d->stream_output(*output, mode));
return stream;
}
ScreencastingStream *Screencasting::createWindowStream(PlasmaWindow *window, CursorMode mode)
{
auto stream = createWindowStream(QString::fromUtf8(window->uuid()), mode);
stream->setObjectName(window->appId());
return stream;
}
ScreencastingStream *Screencasting::createWindowStream(const QString &uuid, CursorMode mode)
{
auto stream = new ScreencastingStream(this);
......@@ -140,11 +121,6 @@ ScreencastingStream *Screencasting::createWindowStream(const QString &uuid, Curs
return stream;
}
void Screencasting::setup(::zkde_screencast_unstable_v1 *screencasting)
{
d.reset(new ScreencastingPrivate(screencasting, this));
}
void Screencasting::destroy()
{
d.reset(nullptr);
......
......@@ -7,24 +7,9 @@
#pragma once
#include <QObject>
#include <QSharedPointer>
#include <QVector>
#include <optional>
struct zkde_screencast_unstable_v1;
namespace KWayland
{
namespace Client
{
class PlasmaWindow;
class Registry;
class Output;
}
}
#include <memory>
class ScreencastingPrivate;
class ScreencastingSourcePrivate;
class ScreencastingStreamPrivate;
class ScreencastingStream : public QObject
{
......@@ -50,7 +35,6 @@ class Screencasting : public QObject
Q_OBJECT
public:
explicit Screencasting(QObject *parent = nullptr);
explicit Screencasting(KWayland::Client::Registry *registry, int id, int version, QObject *parent = nullptr);
~Screencasting() override;
enum CursorMode {
......@@ -61,11 +45,8 @@ public:
Q_ENUM(CursorMode)
ScreencastingStream *createOutputStream(const QString &outputName, CursorMode mode);
ScreencastingStream *createOutputStream(KWayland::Client::Output *output, CursorMode mode);
ScreencastingStream *createWindowStream(KWayland::Client::PlasmaWindow *window, CursorMode mode);
ScreencastingStream *createWindowStream(const QString &uuid, CursorMode mode);
void setup(zkde_screencast_unstable_v1 *screencasting);
void destroy();
Q_SIGNALS:
......
......@@ -7,68 +7,21 @@
#include "screencastingrequest.h"
#include "logging.h"
#include <KWayland/Client/connection_thread.h>
#include <KWayland/Client/registry.h>
#include <QCoreApplication>
#include <QDebug>
#include <QPointer>
#include <functional>
class ScreencastingSingleton : public QObject
{
Q_OBJECT
public:
ScreencastingSingleton(QObject *parent)
: QObject(parent)
{
KWayland::Client::ConnectionThread *connection = KWayland::Client::ConnectionThread::fromApplication(this);
if (!connection) {
return;
}
KWayland::Client::Registry *registry = new KWayland::Client::Registry(this);
connect(registry,
&KWayland::Client::Registry::interfaceAnnounced,
this,
[this, registry](const QByteArray &interfaceName, quint32 name, quint32 version) {
if (interfaceName != "zkde_screencast_unstable_v1")
return;
m_screencasting = new Screencasting(registry, name, version, this);
Q_EMIT created(m_screencasting);
});
registry->create(connection);
registry->setup();
}
static ScreencastingSingleton *self()
{
static QPointer<ScreencastingSingleton> s_self;
if (!s_self && QCoreApplication::instance())
s_self = new ScreencastingSingleton(QCoreApplication::instance());
return s_self;
}
void requestInterface(ScreencastingRequest *item)
{
if (!m_screencasting) {
connect(this, &ScreencastingSingleton::created, item, &ScreencastingRequest::create, Qt::UniqueConnection);
} else {
item->create(m_screencasting);
}
}
Q_SIGNALS:
void created(Screencasting *screencasting);
private:
Screencasting *m_screencasting = nullptr;
struct ScreencastingRequestPrivate {
QPointer<ScreencastingStream> m_stream;
QString m_uuid;
QString m_outputName;
quint32 m_nodeId = 0;
};
ScreencastingRequest::ScreencastingRequest(QObject *parent)
: QObject(parent)
, d(new ScreencastingRequestPrivate)
{
}
......@@ -76,86 +29,75 @@ ScreencastingRequest::~ScreencastingRequest() = default;
quint32 ScreencastingRequest::nodeId() const
{
return m_nodeId;
return d->m_nodeId;
}
void ScreencastingRequest::setUuid(const QString &uuid)
{
if (m_uuid == uuid) {
if (d->m_uuid == uuid) {
return;
}
Q_EMIT closeRunningStreams();
d->m_stream->deleteLater();
setNodeid(0);
m_uuid = uuid;
if (!m_uuid.isEmpty()) {
ScreencastingSingleton::self()->requestInterface(this);
}
d->m_uuid = uuid;
Q_EMIT uuidChanged(uuid);
}
void ScreencastingRequest::setNodeid(uint nodeId)
{
if (nodeId == m_nodeId) {
return;
if (!d->m_uuid.isEmpty()) {
auto screencasting = new Screencasting(this);
auto stream = screencasting->createWindowStream(d->m_uuid, Screencasting::CursorMode::Hidden);
adopt(stream);
}
m_nodeId = nodeId;
Q_EMIT nodeIdChanged(nodeId);
}
QString ScreencastingRequest::outputName() const
{
return m_outputName;
}
void ScreencastingRequest::setOutputName(const QString &outputName)
{
if (m_outputName == outputName) {
if (d->m_outputName == outputName) {
return;
}
setNodeid(0);
m_outputName = outputName;
d->m_outputName = outputName;
Q_EMIT outputNameChanged(outputName);
if (!m_outputName.isEmpty()) {
if (!d->m_outputName.isEmpty()) {
auto screencasting = new Screencasting(this);
auto stream = screencasting->createOutputStream(m_outputName, Screencasting::CursorMode::Hidden);
auto stream = screencasting->createOutputStream(d->m_outputName, Screencasting::CursorMode::Hidden);
adopt(stream);
stream->setObjectName(d->m_outputName);
}
}
void ScreencastingRequest::adopt(ScreencastingStream *stream)
{
connect(stream, &ScreencastingStream::created, this, [stream, this](int nodeId) {
if (stream->objectName() == m_uuid) {
setNodeid(nodeId);
}
});
connect(stream, &ScreencastingStream::created, this, &ScreencastingRequest::setNodeid);
connect(stream, &ScreencastingStream::failed, this, [](const QString &error) {
qCWarning(PIPEWIRE_LOGGING) << "error creating screencast" << error;
qWarning() << "error creating screencast" << error;
});
connect(stream, &ScreencastingStream::closed, this, [this, stream] {
if (stream->nodeId() == m_nodeId) {
if (stream->nodeId() == d->m_nodeId) {
setNodeid(0);
}
});
connect(this, &ScreencastingRequest::closeRunningStreams, stream, &QObject::deleteLater);
}
void ScreencastingRequest::create(Screencasting *screencasting)
void ScreencastingRequest::setNodeid(uint nodeId)
{
auto stream = screencasting->createWindowStream(m_uuid, Screencasting::CursorMode::Hidden);
stream->setObjectName(m_uuid);
adopt(stream);
if (nodeId == d->m_nodeId) {
return;
}
d->m_nodeId = nodeId;
Q_EMIT nodeIdChanged(nodeId);
}
QString ScreencastingRequest::uuid() const
{
return m_uuid;
return d->m_uuid;
}
#include "screencastingrequest.moc"
QString ScreencastingRequest::outputName() const
{
return d->m_outputName;
}
......@@ -10,6 +10,7 @@
#include <QObject>
class ScreencastingStream;
struct ScreencastingRequestPrivate;
/**
* Allows us to request a stream for a window identified by its universally
......@@ -48,22 +49,14 @@ public:
QString outputName() const;
quint32 nodeId() const;
void create(Screencasting *screencasting);
Q_SIGNALS:
void nodeIdChanged(quint32 nodeId);
void outputNameChanged(const QString &outputNames);
void uuidChanged(const QString &uuid);
void closeRunningStreams();
void cursorModeChanged(Screencasting::CursorMode cursorMode);
void outputNameChanged(const QString &outputNames);
private:
void adopt(ScreencastingStream *stream);
void setNodeid(uint nodeId);
ScreencastingStream *m_stream = nullptr;
QString m_uuid;
QString m_outputName;
KWayland::Client::Output *m_output = nullptr;
quint32 m_nodeId = 0;
QScopedPointer<ScreencastingRequestPrivate> d;
};
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment