diff --git a/srcpkgs/kwin/patches/screencast-pipewire.patch b/srcpkgs/kwin/patches/screencast-pipewire.patch new file mode 100644 index 00000000000..b303a675602 --- /dev/null +++ b/srcpkgs/kwin/patches/screencast-pipewire.patch @@ -0,0 +1,152 @@ +From 013e69988ffdbed1d3c684a536c0d4b79c7de680 Mon Sep 17 00:00:00 2001 +From: David Edmundson +Date: Fri, 10 May 2024 14:35:11 +0000 +Subject: [PATCH] Reconnect Pipewire on Failure + +Our connection to pipewire can go down if the pipewire service restarts, it's on us to tear down and reconnect. +To ensure Streams can tear down on their own properly, this patch leaves existing streams with a defunct connection +and creates a new connection for new streams, sharing the connection between them. + +This also implicitly fixes the case for distributions without working socket activation. + +BUG: 483137 +--- + src/plugins/screencast/pipewirecore.cpp | 7 ++++++ + src/plugins/screencast/pipewirecore.h | 4 ++++ + src/plugins/screencast/screencastmanager.cpp | 24 ++++++++++++++++---- + src/plugins/screencast/screencastmanager.h | 4 +++- + 4 files changed, 33 insertions(+), 6 deletions(-) + +diff --git a/src/plugins/screencast/pipewirecore.cpp b/src/plugins/screencast/pipewirecore.cpp +index 077854c65ee..085d0595372 100644 +--- a/src/plugins/screencast/pipewirecore.cpp ++++ b/src/plugins/screencast/pipewirecore.cpp +@@ -48,6 +48,7 @@ void PipeWireCore::onCoreError(void *data, uint32_t id, int seq, int res, const + qCWarning(KWIN_SCREENCAST) << "PipeWire remote error: " << message; + if (id == PW_ID_CORE && res == -EPIPE) { + PipeWireCore *pw = static_cast(data); ++ pw->m_valid = false; + Q_EMIT pw->pipewireFailed(QString::fromUtf8(message)); + } + } +@@ -91,9 +92,15 @@ bool PipeWireCore::init() + } + + pw_core_add_listener(pwCore, &coreListener, &pwCoreEvents, this); ++ m_valid = true; + return true; + } + ++bool PipeWireCore::isValid() const ++{ ++ return m_valid; ++} ++ + } // namespace KWin + + #include "moc_pipewirecore.cpp" +diff --git a/src/plugins/screencast/pipewirecore.h b/src/plugins/screencast/pipewirecore.h +index cb20ba8b523..f66dc0edb22 100644 +--- a/src/plugins/screencast/pipewirecore.h ++++ b/src/plugins/screencast/pipewirecore.h +@@ -28,6 +28,7 @@ public: + ~PipeWireCore(); + + bool init(); ++ bool isValid() const; + + static std::shared_ptr self(); + +@@ -41,6 +42,9 @@ public: + + Q_SIGNALS: + void pipewireFailed(const QString &message); ++ ++private: ++ bool m_valid = false; + }; + + } // namespace KWin +diff --git a/src/plugins/screencast/screencastmanager.cpp b/src/plugins/screencast/screencastmanager.cpp +index 87c84e93f39..e0b009c3b70 100644 +--- a/src/plugins/screencast/screencastmanager.cpp ++++ b/src/plugins/screencast/screencastmanager.cpp +@@ -27,9 +27,9 @@ namespace KWin + + ScreencastManager::ScreencastManager() + : m_screencast(new ScreencastV1Interface(waylandServer()->display(), this)) +- , m_core(new PipeWireCore) + { +- m_core->init(); ++ getPipewireConnection(); ++ + connect(m_screencast, &ScreencastV1Interface::windowScreencastRequested, this, &ScreencastManager::streamWindow); + connect(m_screencast, &ScreencastV1Interface::outputScreencastRequested, this, &ScreencastManager::streamWaylandOutput); + connect(m_screencast, &ScreencastV1Interface::virtualOutputScreencastRequested, this, &ScreencastManager::streamVirtualOutput); +@@ -46,7 +46,7 @@ void ScreencastManager::streamWindow(ScreencastStreamV1Interface *waylandStream, + return; + } + +- auto stream = new ScreenCastStream(new WindowScreenCastSource(window), m_core, this); ++ auto stream = new ScreenCastStream(new WindowScreenCastSource(window), getPipewireConnection(), this); + stream->setObjectName(window->desktopFileName()); + stream->setCursorMode(mode, 1, window->clientGeometry()); + +@@ -88,7 +88,7 @@ void ScreencastManager::streamOutput(ScreencastStreamV1Interface *waylandStream, + return; + } + +- auto stream = new ScreenCastStream(new OutputScreenCastSource(streamOutput), m_core, this); ++ auto stream = new ScreenCastStream(new OutputScreenCastSource(streamOutput), getPipewireConnection(), this); + stream->setObjectName(streamOutput->name()); + stream->setCursorMode(mode, streamOutput->scale(), streamOutput->geometry()); + +@@ -112,7 +112,7 @@ void ScreencastManager::streamRegion(ScreencastStreamV1Interface *waylandStream, + } + + auto source = new RegionScreenCastSource(geometry, scale); +- auto stream = new ScreenCastStream(source, m_core, this); ++ auto stream = new ScreenCastStream(source, getPipewireConnection(), this); + stream->setObjectName(rectToString(geometry)); + stream->setCursorMode(mode, scale, geometry); + +@@ -135,6 +135,20 @@ void ScreencastManager::integrateStreams(ScreencastStreamV1Interface *waylandStr + } + } + ++std::shared_ptr ScreencastManager::getPipewireConnection() ++{ ++ if (m_pipewireConnectionCache && m_pipewireConnectionCache->isValid()) { ++ return m_pipewireConnectionCache; ++ } else { ++ std::shared_ptr pipeWireCore = std::make_shared(); ++ if (pipeWireCore->init()) { ++ m_pipewireConnectionCache = pipeWireCore; ++ } ++ // return a valid object even if init fails ++ return pipeWireCore; ++ } ++} ++ + } // namespace KWin + + #include "moc_screencastmanager.cpp" +diff --git a/src/plugins/screencast/screencastmanager.h b/src/plugins/screencast/screencastmanager.h +index 059e64b545a..436040dea9a 100644 +--- a/src/plugins/screencast/screencastmanager.h ++++ b/src/plugins/screencast/screencastmanager.h +@@ -46,8 +46,10 @@ private: + + void integrateStreams(ScreencastStreamV1Interface *waylandStream, ScreenCastStream *stream); + ++ std::shared_ptr getPipewireConnection(); ++ + ScreencastV1Interface *m_screencast; +- std::shared_ptr m_core; ++ std::shared_ptr m_pipewireConnectionCache; + }; + + } // namespace KWin +-- +GitLab + diff --git a/srcpkgs/kwin/template b/srcpkgs/kwin/template index 314bfd89467..934c3735b6f 100644 --- a/srcpkgs/kwin/template +++ b/srcpkgs/kwin/template @@ -1,7 +1,7 @@ # Template file for 'kwin' pkgname=kwin version=6.0.4 -revision=1 +revision=2 build_style=cmake build_helper=qemu configure_args="-DBUILD_TESTING=OFF -DFORCE_CROSSCOMPILED_TOOLS=ON