Fix screen recording when pipewire is started after kwin (#1)

This fixes screen recording when pipewire is started after kwin.
In my specific case, I use an autostart script.

Reviewed-on: #1
Co-authored-by: Tsaop <leeroy@cock.li>
Co-committed-by: Tsaop <leeroy@cock.li>
This commit is contained in:
Tsaop 2024-04-14 20:07:56 +02:00 committed by Tim Biermann
parent 667821833f
commit 29eeabad69
3 changed files with 135 additions and 7 deletions

View File

@ -1,5 +0,0 @@
untrusted comment: verify with /etc/ports/kde-plasma-6.pub
RWTGxEYrvi0p3snzPSUTg02d675XCVVPO/v9sCXpPVYY87rVPpo+hdbLkN55Bkm4cocOIUNeWw+1v2EHwJAGmafTgAngZES3UQs=
SHA256 (Pkgfile) = 292c15cc9b759b4af2f9c1a1d3ec1cd6ed3e74fbbde4f58d09aac71883176e13
SHA256 (.footprint) = 6e68ef8832d6e6657ed43d2db545437759acef90378a8c94856f4ac0d995d180
SHA256 (kwin-6.0.3.1.tar.xz) = f15108a993206b962a3c5835b988a0b4922c0a9bc9ab80faf6b36a334d321b33

View File

@ -5,10 +5,15 @@
name=kwin
version=6.0.3.1
release=1
source=(https://download.kde.org/stable/plasma/${version::5}/$name-$version.tar.xz)
release=2
source=(https://download.kde.org/stable/plasma/${version::5}/$name-$version.tar.xz
fix-screencast-pipewire.patch)
build() {
# https://bugs.kde.org/show_bug.cgi?id=483137
patch -Np1 -d $name-$version -i $SRC/fix-screencast-pipewire.patch
cmake -S $name-$version -B build -G Ninja \
-D CMAKE_INSTALL_PREFIX=/usr \
-D CMAKE_INSTALL_LIBDIR=lib \

View File

@ -0,0 +1,128 @@
diff --git a/src/plugins/screencast/pipewirecore.cpp b/src/plugins/screencast/pipewirecore.cpp
index 077854c65e..eabf89a852 100644
--- a/src/plugins/screencast/pipewirecore.cpp
+++ b/src/plugins/screencast/pipewirecore.cpp
@@ -94,6 +94,18 @@ bool PipeWireCore::init()
return true;
}
+std::shared_ptr<PipeWireCore> PipeWireCore::self()
+{
+ static std::weak_ptr<PipeWireCore> global;
+ auto ret = global.lock();
+ if (!ret) {
+ ret = std::make_shared<PipeWireCore>();
+ ret->init();
+ global = ret;
+ }
+ return ret;
+}
+
} // namespace KWin
#include "moc_pipewirecore.cpp"
diff --git a/src/plugins/screencast/screencastmanager.cpp b/src/plugins/screencast/screencastmanager.cpp
index 87c84e93f3..d0a2d6552d 100644
--- a/src/plugins/screencast/screencastmanager.cpp
+++ b/src/plugins/screencast/screencastmanager.cpp
@@ -10,7 +10,6 @@
#include "core/output.h"
#include "core/outputbackend.h"
#include "outputscreencastsource.h"
-#include "pipewirecore.h"
#include "regionscreencastsource.h"
#include "screencaststream.h"
#include "wayland/display.h"
@@ -27,9 +26,7 @@ namespace KWin
ScreencastManager::ScreencastManager()
: m_screencast(new ScreencastV1Interface(waylandServer()->display(), this))
- , m_core(new PipeWireCore)
{
- m_core->init();
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 +43,7 @@ void ScreencastManager::streamWindow(ScreencastStreamV1Interface *waylandStream,
return;
}
- auto stream = new ScreenCastStream(new WindowScreenCastSource(window), m_core, this);
+ auto stream = new ScreenCastStream(new WindowScreenCastSource(window), this);
stream->setObjectName(window->desktopFileName());
stream->setCursorMode(mode, 1, window->clientGeometry());
@@ -88,7 +85,7 @@ void ScreencastManager::streamOutput(ScreencastStreamV1Interface *waylandStream,
return;
}
- auto stream = new ScreenCastStream(new OutputScreenCastSource(streamOutput), m_core, this);
+ auto stream = new ScreenCastStream(new OutputScreenCastSource(streamOutput), this);
stream->setObjectName(streamOutput->name());
stream->setCursorMode(mode, streamOutput->scale(), streamOutput->geometry());
@@ -112,7 +109,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, this);
stream->setObjectName(rectToString(geometry));
stream->setCursorMode(mode, scale, geometry);
diff --git a/src/plugins/screencast/screencastmanager.h b/src/plugins/screencast/screencastmanager.h
index 059e64b545..c4829c0bd0 100644
--- a/src/plugins/screencast/screencastmanager.h
+++ b/src/plugins/screencast/screencastmanager.h
@@ -16,7 +16,6 @@ namespace KWin
{
class Output;
class ScreenCastStream;
-class PipeWireCore;
class ScreencastManager : public Plugin
{
@@ -47,7 +46,6 @@ private:
void integrateStreams(ScreencastStreamV1Interface *waylandStream, ScreenCastStream *stream);
ScreencastV1Interface *m_screencast;
- std::shared_ptr<PipeWireCore> m_core;
};
} // namespace KWin
diff --git a/src/plugins/screencast/screencaststream.cpp b/src/plugins/screencast/screencaststream.cpp
index 43d5044c17..183389704b 100644
--- a/src/plugins/screencast/screencaststream.cpp
+++ b/src/plugins/screencast/screencaststream.cpp
@@ -321,9 +321,8 @@ void ScreenCastStream::onStreamRenegotiateFormat(uint64_t)
pw_stream_update_params(m_pwStream, params.data(), params.count());
}
-ScreenCastStream::ScreenCastStream(ScreenCastSource *source, std::shared_ptr<PipeWireCore> pwCore, QObject *parent)
+ScreenCastStream::ScreenCastStream(ScreenCastSource *source, QObject *parent)
: QObject(parent)
- , m_pwCore(pwCore)
, m_source(source)
, m_resolution(source->textureSize())
{
@@ -364,6 +363,7 @@ ScreenCastStream::~ScreenCastStream()
bool ScreenCastStream::init()
{
+ m_pwCore = PipeWireCore::self();
if (!m_pwCore->m_error.isEmpty()) {
m_error = m_pwCore->m_error;
return false;
diff --git a/src/plugins/screencast/screencaststream.h b/src/plugins/screencast/screencaststream.h
index 5abf2dd0bb..9afe32e080 100644
--- a/src/plugins/screencast/screencaststream.h
+++ b/src/plugins/screencast/screencaststream.h
@@ -48,7 +48,7 @@ class KWIN_EXPORT ScreenCastStream : public QObject
{
Q_OBJECT
public:
- explicit ScreenCastStream(ScreenCastSource *source, std::shared_ptr<PipeWireCore> pwCore, QObject *parent);
+ explicit ScreenCastStream(ScreenCastSource *source, QObject *parent);
~ScreenCastStream();
bool init();