10#include "compositor.h"
26#include <KLocalizedString>
42static QRegion scaleRegion(
const QRegion &_region, qreal scale)
49 for (
auto it = _region.begin(), itEnd = _region.end(); it != itEnd; ++it) {
50 region += QRect(std::floor(it->x() * scale),
51 std::floor(it->y() * scale),
52 std::ceil(it->width() * scale),
53 std::ceil(it->height() * scale));
66 m_timer.setInterval(0);
67 m_timer.setSingleShot(
true);
69 connect(&m_timer, &QTimer::timeout,
this, &WindowStream::bufferToStream);
101void ScreencastManager::streamWindow(ScreencastStreamV1Interface *waylandStream,
102 const QString &winid,
107 waylandStream->sendFailed(i18n(
"Could not find window id %1", winid));
111 auto stream =
new WindowStream(window, m_core,
this);
112 stream->setCursorMode(mode, 1, window->clientGeometry());
115 stream->setCursorMode(mode, 1, window->clientGeometry().toRect());
119 integrateStreams(waylandStream, stream);
122void ScreencastManager::streamVirtualOutput(ScreencastStreamV1Interface *stream,
128 auto output = kwinApp()->outputBackend()->createVirtualOutput(name, size, scale);
129 streamOutput(stream, output, mode);
131 kwinApp()->outputBackend()->removeVirtualOutput(output);
135void ScreencastManager::streamWaylandOutput(ScreencastStreamV1Interface *waylandStream,
136 OutputInterface *output,
139 streamOutput(waylandStream, output->handle(), mode);
142void ScreencastManager::streamOutput(ScreencastStreamV1Interface *waylandStream,
143 Output *streamOutput,
147 waylandStream->sendFailed(i18n(
"Could not find output"));
151 auto stream =
new ScreenCastStream(
new OutputScreenCastSource(streamOutput), m_core,
this);
152 stream->setObjectName(streamOutput->name());
153 stream->setCursorMode(mode, streamOutput->scale(), streamOutput->geometry());
154 auto bufferToStream = [stream, streamOutput](
const QRegion &damagedRegion) {
155 if (!damagedRegion.isEmpty()) {
156 stream->recordFrame(scaleRegion(damagedRegion, streamOutput->scale()));
163 integrateStreams(waylandStream, stream);
166static QString rectToString(
const QRect &rect)
168 return QStringLiteral(
"%1,%2 %3x%4").arg(rect.x()).arg(rect.y()).arg(rect.width()).arg(rect.height());
173 if (!geometry.isValid()) {
174 waylandStream->sendFailed(i18n(
"Invalid region"));
178 auto source =
new RegionScreenCastSource(geometry, scale);
179 auto stream =
new ScreenCastStream(source, m_core,
this);
180 stream->setObjectName(rectToString(geometry));
181 stream->setCursorMode(mode, scale, geometry);
188 for (
auto output : allOutputs) {
189 if (output->geometry().intersects(geometry)) {
190 auto bufferToStream = [output, stream, source](
const QRegion &damagedRegion) {
191 if (damagedRegion.isEmpty()) {
195 const QRect streamRegion = source->region();
196 const QRegion region = output->pixelSize() != output->modeSize() ? output->geometry() : damagedRegion;
197 source->updateOutput(output);
198 stream->recordFrame(scaleRegion(region.translated(-streamRegion.topLeft()).intersected(streamRegion), source->scale()));
205 waylandStream->sendFailed(i18n(
"Region outside the workspace"));
208 integrateStreams(waylandStream, stream);
211void ScreencastManager::integrateStreams(ScreencastStreamV1Interface *waylandStream, ScreenCastStream *stream)
215 waylandStream->sendClosed();
216 stream->deleteLater();
219 waylandStream->sendCreated(nodeid);
221 if (!stream->init()) {
222 waylandStream->sendFailed(stream->error());
229#include "moc_screencastmanager.cpp"
WorkspaceScene * scene() const
static Compositor * self()
void outputChange(const QRegion &damagedRegion)
void addRepaint(const QRegion ®ion)
void streamReady(quint32 nodeId)
void recordFrame(const QRegion &damagedRegion)
void virtualOutputScreencastRequested(ScreencastStreamV1Interface *stream, const QString &name, const QSize &size, double scaling, CursorMode mode)
void outputScreencastRequested(ScreencastStreamV1Interface *stream, OutputInterface *output, CursorMode mode)
void regionScreencastRequested(ScreencastStreamV1Interface *stream, const QRect &geometry, qreal scaling, CursorMode mode)
void windowScreencastRequested(ScreencastStreamV1Interface *stream, const QString &winid, CursorMode mode)
void clientGeometryChanged(const QRectF &oldGeometry)
void damaged(KWin::Window *window)
WindowStream(Window *window, std::shared_ptr< PipeWireCore > pwCore, QObject *parent)
Window * findWindow(const QUuid &internalId) const
static Workspace * self()
QList< Output * > outputs() const
WaylandServer * waylandServer()