diff --git a/src/plugins/screencast/screencaststream.cpp b/src/plugins/screencast/screencaststream.cpp index 2932e62a90..18a56ae26a 100644 --- a/src/plugins/screencast/screencaststream.cpp +++ b/src/plugins/screencast/screencaststream.cpp @@ -305,6 +305,8 @@ bool ScreenCastStream::createStream() connect(Cursors::self(), &Cursors::positionChanged, this, [this] { recordFrame(QRegion{m_cursor.lastRect} | cursorGeometry(Cursors::self()->currentCursor())); }); + } else if (m_cursor.mode == KWaylandServer::ScreencastV1Interface::Metadata) { + connect(Cursors::self(), &Cursors::positionChanged, this, &ScreenCastStream::recordCursor); } return true; @@ -458,6 +460,38 @@ void ScreenCastStream::recordFrame(const QRegion &damagedRegion) tryEnqueue(buffer); } +void ScreenCastStream::recordCursor() +{ + Q_ASSERT(!m_stopped); + + if (m_pendingBuffer) { + qCWarning(KWIN_SCREENCAST) << "Dropping a screencast cursor update because the compositor is slow"; + return; + } + + const char *error = ""; + auto state = pw_stream_get_state(pwStream, &error); + if (state != PW_STREAM_STATE_STREAMING) { + if (error) { + qCWarning(KWIN_SCREENCAST) << "Failed to record cursor position: stream is not active" << error; + } + return; + } + + struct pw_buffer *buffer = pw_stream_dequeue_buffer(pwStream); + + if (!buffer) { + return; + } + + struct spa_buffer *spa_buffer = buffer->buffer; + spa_buffer->datas[0].chunk->size = 0; + sendCursorData(Cursors::self()->currentCursor(), + (spa_meta_cursor *) spa_buffer_find_meta_data (spa_buffer, SPA_META_Cursor, sizeof (spa_meta_cursor))); + + tryEnqueue(buffer); +} + void ScreenCastStream::tryEnqueue(pw_buffer *buffer) { m_pendingBuffer = buffer; diff --git a/src/plugins/screencast/screencaststream.h b/src/plugins/screencast/screencaststream.h index 829eb84c4d..b53c5b3ab1 100644 --- a/src/plugins/screencast/screencaststream.h +++ b/src/plugins/screencast/screencaststream.h @@ -55,6 +55,9 @@ public: void setCursorMode(KWaylandServer::ScreencastV1Interface::CursorMode mode, qreal scale, const QRect &viewport); +public Q_SLOTS: + void recordCursor(); + Q_SIGNALS: void streamReady(quint32 nodeId); void startStreaming();