kde-plasma/xdg-desktop-portal-kde: Backport 5.24.6 screencast fixes

See also:
https://invent.kde.org/plasma/xdg-desktop-portal-kde/-/merge_requests/102
https://invent.kde.org/plasma/xdg-desktop-portal-kde/-/merge_requests/103

Package-Manager: Portage-3.0.30, Repoman-3.0.3
Signed-off-by: Andreas Sturmlechner <asturm@gentoo.org>
This commit is contained in:
Andreas Sturmlechner
2022-05-30 17:45:53 +02:00
parent 591b28d3c2
commit 7437df3200
4 changed files with 544 additions and 0 deletions

View File

@@ -0,0 +1,107 @@
From cd8275c722aa25dd22353121131c914d3ab3b438 Mon Sep 17 00:00:00 2001
From: Aleix Pol <aleixpol@kde.org>
Date: Sat, 28 May 2022 03:36:14 +0200
Subject: [PATCH] screencast: When closing a session, only close the streams
from that session
---
src/screencast.cpp | 11 ++++++++---
src/session.h | 12 ++++++++++++
src/waylandintegration.cpp | 5 +++++
src/waylandintegration.h | 1 +
4 files changed, 26 insertions(+), 3 deletions(-)
diff --git a/src/screencast.cpp b/src/screencast.cpp
index 5be6210..84cc4bd 100644
--- a/src/screencast.cpp
+++ b/src/screencast.cpp
@@ -68,8 +68,12 @@ uint ScreenCastPortal::CreateSession(const QDBusObjectPath &handle,
return 2;
}
- connect(session, &Session::closed, []() {
- WaylandIntegration::stopAllStreaming();
+ connect(session, &Session::closed, [session] {
+ auto screencastSession = qobject_cast<ScreenCastSession *>(session);
+ const auto streams = screencastSession->streams();
+ for (const WaylandIntegration::Stream &stream : streams) {
+ WaylandIntegration::stopStreaming(stream.nodeId);
+ }
});
connect(WaylandIntegration::waylandIntegration(), &WaylandIntegration::WaylandIntegration::streamingStopped, session, &Session::close);
@@ -169,7 +173,8 @@ uint ScreenCastPortal::Start(const QDBusObjectPath &handle,
return 2;
}
- results.insert(QStringLiteral("streams"), QVariant::fromValue(streams));
+ session->setStreams(streams);
+ results.insert(QStringLiteral("streams"), QVariant::fromValue<WaylandIntegration::Streams>(streams));
if (inhibitionsEnabled()) {
new NotificationInhibition(app_id, i18nc("Do not disturb mode is enabled because...", "Screen sharing in progress"), session);
diff --git a/src/session.h b/src/session.h
index a42222e..dd05680 100644
--- a/src/session.h
+++ b/src/session.h
@@ -14,6 +14,7 @@
#include "remotedesktop.h"
#include "screencast.h"
+#include "waylandintegration.h"
class Session : public QDBusVirtualObject
{
@@ -62,10 +63,21 @@ public:
return SessionType::ScreenCast;
}
+ WaylandIntegration::Streams streams() const
+ {
+ return m_streams;
+ }
+ void setStreams(const WaylandIntegration::Streams &streams)
+ {
+ m_streams = streams;
+ }
+
private:
bool m_multipleSources;
ScreenCastPortal::CursorModes m_cursorMode;
ScreenCastPortal::SourceType m_types;
+
+ WaylandIntegration::Streams m_streams;
};
class RemoteDesktopSession : public ScreenCastSession
diff --git a/src/waylandintegration.cpp b/src/waylandintegration.cpp
index 9f5a177..e05f73a 100644
--- a/src/waylandintegration.cpp
+++ b/src/waylandintegration.cpp
@@ -89,6 +89,11 @@ void WaylandIntegration::stopAllStreaming()
globalWaylandIntegration->stopAllStreaming();
}
+void WaylandIntegration::stopStreaming(uint node)
+{
+ globalWaylandIntegration->stopStreaming(node);
+}
+
void WaylandIntegration::requestPointerButtonPress(quint32 linuxButton)
{
globalWaylandIntegration->requestPointerButtonPress(linuxButton);
diff --git a/src/waylandintegration.h b/src/waylandintegration.h
index b8e6a00..784ee12 100644
--- a/src/waylandintegration.h
+++ b/src/waylandintegration.h
@@ -131,6 +131,7 @@ void startStreamingInput();
Stream startStreamingOutput(quint32 outputName, Screencasting::CursorMode mode);
Stream startStreamingWindow(const QMap<int, QVariant> &win);
void stopAllStreaming();
+void stopStreaming(uint node);
void requestPointerButtonPress(quint32 linuxButton);
void requestPointerButtonRelease(quint32 linuxButton);
--
GitLab

View File

@@ -0,0 +1,358 @@
From 3dbd366516c38d987025623feea18f79c15d72dd Mon Sep 17 00:00:00 2001
From: Aleix Pol <aleixpol@kde.org>
Date: Mon, 30 May 2022 15:42:02 +0200
Subject: [PATCH] Backport of 5f7fe7482ae3de6e5dabbd2712c283439b0eecac
Since the codebases had diverged over time, I've backported it by hand
using the same concepts as the forementioned fix, trying to minimise the
delta with the latest released Plasma 5.24.
---
src/remotedesktop.cpp | 12 ++------
src/screencast.cpp | 15 ++++++----
src/waylandintegration.cpp | 60 +++++++++++++++-----------------------
src/waylandintegration.h | 26 +++++++++++++++--
src/waylandintegration_p.h | 15 ++--------
5 files changed, 61 insertions(+), 67 deletions(-)
diff --git a/src/remotedesktop.cpp b/src/remotedesktop.cpp
index f36def4..9282ff0 100644
--- a/src/remotedesktop.cpp
+++ b/src/remotedesktop.cpp
@@ -122,20 +122,14 @@ uint RemoteDesktopPortal::Start(const QDBusObjectPath &handle,
if (remoteDesktopDialog->exec()) {
if (session->screenSharingEnabled()) {
- if (!WaylandIntegration::startStreamingOutput(remoteDesktopDialog->selectedScreens().first(), Screencasting::Hidden)) {
+ auto stream = WaylandIntegration::startStreamingOutput(remoteDesktopDialog->selectedScreens().first(), Screencasting::Hidden);
+ if (!stream.isValid()) {
return 2;
}
WaylandIntegration::authenticate();
- QVariant streams = WaylandIntegration::streams();
-
- if (!streams.isValid()) {
- qCWarning(XdgDesktopPortalKdeRemoteDesktop()) << "Pipewire stream is not ready to be streamed";
- return 2;
- }
-
- results.insert(QStringLiteral("streams"), streams);
+ results.insert(QStringLiteral("streams"), QVariant::fromValue<WaylandIntegration::Streams>({stream}));
} else {
qCWarning(XdgDesktopPortalKdeRemoteDesktop()) << "Only stream input";
WaylandIntegration::startStreamingInput();
diff --git a/src/screencast.cpp b/src/screencast.cpp
index 210bbbb..5be6210 100644
--- a/src/screencast.cpp
+++ b/src/screencast.cpp
@@ -147,26 +147,29 @@ uint ScreenCastPortal::Start(const QDBusObjectPath &handle,
if (screenDialog->exec()) {
const auto selectedScreens = screenDialog->selectedScreens();
+ WaylandIntegration::Streams streams;
for (quint32 outputid : selectedScreens) {
- if (!WaylandIntegration::startStreamingOutput(outputid, Screencasting::CursorMode(session->cursorMode()))) {
+ auto stream = WaylandIntegration::startStreamingOutput(outputid, Screencasting::CursorMode(session->cursorMode()));
+ if (!stream.isValid()) {
return 2;
}
+ streams << stream;
}
const auto selectedWindows = screenDialog->selectedWindows();
for (const auto &win : selectedWindows) {
- if (!WaylandIntegration::startStreamingWindow(win)) {
+ auto stream = WaylandIntegration::startStreamingWindow(win);
+ if (!stream.isValid()) {
return 2;
}
+ streams << stream;
}
- QVariant streams = WaylandIntegration::streams();
-
- if (!streams.isValid()) {
+ if (streams.isEmpty()) {
qCWarning(XdgDesktopPortalKdeScreenCast) << "Pipewire stream is not ready to be streamed";
return 2;
}
- results.insert(QStringLiteral("streams"), streams);
+ results.insert(QStringLiteral("streams"), QVariant::fromValue(streams));
if (inhibitionsEnabled()) {
new NotificationInhibition(app_id, i18nc("Do not disturb mode is enabled because...", "Screen sharing in progress"), session);
diff --git a/src/waylandintegration.cpp b/src/waylandintegration.cpp
index 44d862a..9f5a177 100644
--- a/src/waylandintegration.cpp
+++ b/src/waylandintegration.cpp
@@ -43,7 +43,7 @@ Q_LOGGING_CATEGORY(XdgDesktopPortalKdeWaylandIntegration, "xdp-kde-wayland-integ
Q_GLOBAL_STATIC(WaylandIntegration::WaylandIntegrationPrivate, globalWaylandIntegration)
-static QDebug operator<<(QDebug dbg, const WaylandIntegration::WaylandIntegrationPrivate::Stream &c)
+static QDebug operator<<(QDebug dbg, const WaylandIntegration::Stream &c)
{
dbg.nospace() << "Stream(" << c.map << ", " << c.nodeId << ")";
return dbg.space();
@@ -74,12 +74,12 @@ void WaylandIntegration::startStreamingInput()
globalWaylandIntegration->startStreamingInput();
}
-bool WaylandIntegration::startStreamingOutput(quint32 outputName, Screencasting::CursorMode mode)
+WaylandIntegration::Stream WaylandIntegration::startStreamingOutput(quint32 outputName, Screencasting::CursorMode mode)
{
return globalWaylandIntegration->startStreamingOutput(outputName, mode);
}
-bool WaylandIntegration::startStreamingWindow(const QMap<int, QVariant> &win)
+WaylandIntegration::Stream WaylandIntegration::startStreamingWindow(const QMap<int, QVariant> &win)
{
return globalWaylandIntegration->startStreamingWindow(win);
}
@@ -124,11 +124,6 @@ QMap<quint32, WaylandIntegration::WaylandOutput> WaylandIntegration::screens()
return globalWaylandIntegration->screens();
}
-QVariant WaylandIntegration::streams()
-{
- return globalWaylandIntegration->streams();
-}
-
// Thank you kscreen
void WaylandIntegration::WaylandOutput::setOutputType(const QString &type)
{
@@ -157,7 +152,9 @@ void WaylandIntegration::WaylandOutput::setOutputType(const QString &type)
}
}
-const QDBusArgument &operator>>(const QDBusArgument &arg, WaylandIntegration::WaylandIntegrationPrivate::Stream &stream)
+namespace WaylandIntegration
+{
+const QDBusArgument &operator>>(const QDBusArgument &arg, Stream &stream)
{
arg.beginStructure();
arg >> stream.nodeId;
@@ -177,7 +174,7 @@ const QDBusArgument &operator>>(const QDBusArgument &arg, WaylandIntegration::Wa
return arg;
}
-const QDBusArgument &operator<<(QDBusArgument &arg, const WaylandIntegration::WaylandIntegrationPrivate::Stream &stream)
+const QDBusArgument &operator<<(QDBusArgument &arg, const Stream &stream)
{
arg.beginStructure();
arg << stream.nodeId;
@@ -186,9 +183,7 @@ const QDBusArgument &operator<<(QDBusArgument &arg, const WaylandIntegration::Wa
return arg;
}
-
-Q_DECLARE_METATYPE(WaylandIntegration::WaylandIntegrationPrivate::Stream)
-Q_DECLARE_METATYPE(WaylandIntegration::WaylandIntegrationPrivate::Streams)
+}
KWayland::Client::PlasmaWindowManagement *WaylandIntegration::plasmaWindowManagement()
{
@@ -207,8 +202,8 @@ WaylandIntegration::WaylandIntegrationPrivate::WaylandIntegrationPrivate()
, m_fakeInput(nullptr)
, m_screencasting(nullptr)
{
- qDBusRegisterMetaType<WaylandIntegrationPrivate::Stream>();
- qDBusRegisterMetaType<WaylandIntegrationPrivate::Streams>();
+ qDBusRegisterMetaType<Stream>();
+ qDBusRegisterMetaType<Streams>();
}
WaylandIntegration::WaylandIntegrationPrivate::~WaylandIntegrationPrivate() = default;
@@ -228,25 +223,25 @@ void WaylandIntegration::WaylandIntegrationPrivate::startStreamingInput()
m_streamInput = true;
}
-bool WaylandIntegration::WaylandIntegrationPrivate::startStreamingWindow(const QMap<int, QVariant> &win)
+WaylandIntegration::Stream WaylandIntegration::WaylandIntegrationPrivate::startStreamingWindow(const QMap<int, QVariant> &win)
{
auto uuid = win[KWayland::Client::PlasmaWindowModel::Uuid].toString();
return startStreaming(m_screencasting->createWindowStream(uuid, Screencasting::Hidden), {}, win);
}
-bool WaylandIntegration::WaylandIntegrationPrivate::startStreamingOutput(quint32 outputName, Screencasting::CursorMode mode)
+WaylandIntegration::Stream WaylandIntegration::WaylandIntegrationPrivate::startStreamingOutput(quint32 outputName, Screencasting::CursorMode mode)
{
auto output = m_outputMap.value(outputName).output();
return startStreaming(m_screencasting->createOutputStream(output.data(), mode), output, {});
}
-bool WaylandIntegration::WaylandIntegrationPrivate::startStreaming(ScreencastingStream *stream,
- QSharedPointer<KWayland::Client::Output> output,
- const QMap<int, QVariant> &win)
+WaylandIntegration::Stream WaylandIntegration::WaylandIntegrationPrivate::startStreaming(ScreencastingStream *stream,
+ QSharedPointer<KWayland::Client::Output> output,
+ const QMap<int, QVariant> &win)
{
QEventLoop loop;
- bool streamReady = false;
+ Stream ret;
connect(stream, &ScreencastingStream::failed, this, [&](const QString &error) {
qCWarning(XdgDesktopPortalKdeWaylandIntegration) << "failed to start streaming" << stream << error;
@@ -255,30 +250,26 @@ bool WaylandIntegration::WaylandIntegrationPrivate::startStreaming(Screencasting
notification->setText(error);
notification->setIconName(QStringLiteral("dialog-error"));
notification->sendEvent();
-
- streamReady = false;
loop.quit();
});
connect(stream, &ScreencastingStream::created, this, [&](uint32_t nodeid) {
- Stream s;
- s.stream = stream;
- s.nodeId = nodeid;
+ ret.stream = stream;
+ ret.nodeId = nodeid;
if (output) {
m_streamedScreenPosition = output->globalPosition();
- s.map = {
+ ret.map = {
{QLatin1String("size"), output->pixelSize()},
{QLatin1String("source_type"), static_cast<uint>(ScreenCastPortal::Monitor)},
};
} else {
- s.map = {{QLatin1String("source_type"), static_cast<uint>(ScreenCastPortal::Window)}};
+ ret.map = {{QLatin1String("source_type"), static_cast<uint>(ScreenCastPortal::Window)}};
}
- m_streams.append(s);
+ m_streams.append(ret);
startStreamingInput();
connect(stream, &ScreencastingStream::closed, this, [this, nodeid] {
stopStreaming(nodeid);
});
- streamReady = true;
auto item = new KStatusNotifierItem(stream);
item->setStandardActionsEnabled(false);
@@ -303,10 +294,10 @@ bool WaylandIntegration::WaylandIntegrationPrivate::startStreaming(Screencasting
QTimer::singleShot(3000, &loop, &QEventLoop::quit);
loop.exec();
- return streamReady;
+ return ret;
}
-void WaylandIntegration::WaylandIntegrationPrivate::Stream::close()
+void WaylandIntegration::Stream::close()
{
stream->deleteLater();
}
@@ -390,11 +381,6 @@ QMap<quint32, WaylandIntegration::WaylandOutput> WaylandIntegration::WaylandInte
return m_outputMap;
}
-QVariant WaylandIntegration::WaylandIntegrationPrivate::streams()
-{
- return QVariant::fromValue<WaylandIntegrationPrivate::Streams>(m_streams);
-}
-
void WaylandIntegration::WaylandIntegrationPrivate::authenticate()
{
if (!m_waylandAuthenticationRequested) {
diff --git a/src/waylandintegration.h b/src/waylandintegration.h
index 04319c9..b8e6a00 100644
--- a/src/waylandintegration.h
+++ b/src/waylandintegration.h
@@ -9,6 +9,7 @@
#ifndef XDG_DESKTOP_PORTAL_KDE_WAYLAND_INTEGRATION_H
#define XDG_DESKTOP_PORTAL_KDE_WAYLAND_INTEGRATION_H
+#include <QDBusArgument>
#include <QObject>
#include <QPoint>
#include <QSize>
@@ -28,6 +29,23 @@ class ScreencastingSource;
namespace WaylandIntegration
{
+
+struct Stream {
+ ScreencastingStream *stream = nullptr;
+ uint nodeId;
+ QVariantMap map;
+
+ bool isValid() const
+ {
+ return stream != nullptr;
+ }
+
+ void close();
+};
+typedef QVector<Stream> Streams;
+const QDBusArgument &operator<<(QDBusArgument &arg, const Stream &stream);
+const QDBusArgument &operator>>(const QDBusArgument &arg, Stream &stream);
+
class WaylandOutput
{
public:
@@ -110,8 +128,8 @@ bool isStreamingEnabled();
bool isStreamingAvailable();
void startStreamingInput();
-bool startStreamingOutput(quint32 outputName, Screencasting::CursorMode mode);
-bool startStreamingWindow(const QMap<int, QVariant> &win);
+Stream startStreamingOutput(quint32 outputName, Screencasting::CursorMode mode);
+Stream startStreamingWindow(const QMap<int, QVariant> &win);
void stopAllStreaming();
void requestPointerButtonPress(quint32 linuxButton);
@@ -123,7 +141,6 @@ void requestPointerAxisDiscrete(Qt::Orientation axis, qreal delta);
void requestKeyboardKeycode(int keycode, bool state);
QMap<quint32, WaylandOutput> screens();
-QVariant streams();
void init();
@@ -132,4 +149,7 @@ KWayland::Client::PlasmaWindowManagement *plasmaWindowManagement();
WaylandIntegration *waylandIntegration();
}
+Q_DECLARE_METATYPE(WaylandIntegration::Stream)
+Q_DECLARE_METATYPE(WaylandIntegration::Streams)
+
#endif // XDG_DESKTOP_PORTAL_KDE_WAYLAND_INTEGRATION_H
diff --git a/src/waylandintegration_p.h b/src/waylandintegration_p.h
index 220ad3d..e95f6a0 100644
--- a/src/waylandintegration_p.h
+++ b/src/waylandintegration_p.h
@@ -53,15 +53,6 @@ private:
KWayland::Client::PlasmaWindowManagement *m_windowManagement = nullptr;
public:
- struct Stream {
- ScreencastingStream *stream = nullptr;
- uint nodeId;
- QVariantMap map;
-
- void close();
- };
- typedef QVector<Stream> Streams;
-
void authenticate();
bool isStreamingEnabled() const;
@@ -69,9 +60,9 @@ public:
void startStreamingInput();
- bool startStreaming(ScreencastingStream *stream, QSharedPointer<KWayland::Client::Output> output, const QMap<int, QVariant> &win);
- bool startStreamingOutput(quint32 outputName, Screencasting::CursorMode mode);
- bool startStreamingWindow(const QMap<int, QVariant> &win);
+ Stream startStreaming(ScreencastingStream *stream, QSharedPointer<KWayland::Client::Output> output, const QMap<int, QVariant> &win);
+ Stream startStreamingOutput(quint32 outputName, Screencasting::CursorMode mode);
+ Stream startStreamingWindow(const QMap<int, QVariant> &win);
void stopStreaming(uint32_t nodeid);
void stopAllStreaming();
--
GitLab

View File

@@ -0,0 +1,28 @@
From d74e7dce1d333107760a8ae8d2bdd7521d31a09f Mon Sep 17 00:00:00 2001
From: Aleix Pol <aleixpol@kde.org>
Date: Sat, 28 May 2022 03:37:14 +0200
Subject: [PATCH] screencast: When we stop a stream, do it actively
We were just forgetting about it.
(cherry picked from commit aa531bde14a13521f99ae8e44d6e83bc8749d761)
---
src/waylandintegration.cpp | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/waylandintegration.cpp b/src/waylandintegration.cpp
index b1b2d4d..44d862a 100644
--- a/src/waylandintegration.cpp
+++ b/src/waylandintegration.cpp
@@ -328,6 +328,7 @@ void WaylandIntegration::WaylandIntegrationPrivate::stopStreaming(uint32_t nodei
{
for (auto it = m_streams.begin(), itEnd = m_streams.end(); it != itEnd; ++it) {
if (it->nodeId == nodeid) {
+ it->close();
m_streams.erase(it);
break;
}
--
GitLab

View File

@@ -0,0 +1,51 @@
# Copyright 1999-2022 Gentoo Authors
# Distributed under the terms of the GNU General Public License v2
EAPI=8
KFMIN=5.90.0
PVCUT=$(ver_cut 1-3)
QTMIN=5.15.2
inherit ecm kde.org
DESCRIPTION="Backend implementation for xdg-desktop-portal that is using Qt/KDE Frameworks"
LICENSE="LGPL-2+"
SLOT="5"
KEYWORDS="~amd64 ~arm ~arm64 ~ppc64 ~riscv ~x86"
IUSE=""
COMMON_DEPEND="
>=dev-libs/wayland-1.15
>=dev-qt/qtdbus-${QTMIN}:5
>=dev-qt/qtdeclarative-${QTMIN}:5
>=dev-qt/qtgui-${QTMIN}:5
>=dev-qt/qtprintsupport-${QTMIN}:5[cups]
>=dev-qt/qtwidgets-${QTMIN}:5
>=kde-frameworks/kcoreaddons-${KFMIN}:5
>=kde-frameworks/kconfig-${KFMIN}:5
>=kde-frameworks/kdeclarative-${KFMIN}:5
>=kde-frameworks/ki18n-${KFMIN}:5
>=kde-frameworks/kio-${KFMIN}:5
>=kde-frameworks/kirigami-${KFMIN}:5
>=kde-frameworks/knotifications-${KFMIN}:5
>=kde-frameworks/kwidgetsaddons-${KFMIN}:5
>=kde-frameworks/kwindowsystem-${KFMIN}:5
>=kde-frameworks/kwayland-${KFMIN}:5
>=kde-frameworks/plasma-${KFMIN}:5
"
DEPEND="${COMMON_DEPEND}
>=dev-libs/plasma-wayland-protocols-1.1.1
>=dev-qt/qtconcurrent-${QTMIN}:5
"
RDEPEND="${COMMON_DEPEND}
sys-apps/xdg-desktop-portal
"
BDEPEND=">=dev-qt/qtwaylandscanner-${QTMIN}:5"
PATCHES=(
"${FILESDIR}/${P}-show-screenshare-notifier-more-prominently.patch" # KDE-bug 452980
"${FILESDIR}/${P}-screencast-stop-stream-actively.patch"
"${FILESDIR}/${P}-screencast-dont-provide-every-running-stream.patch"
"${FILESDIR}/${P}-screencast-close-only-streams-of-closing-session.patch"
)