From 9975da5ee1c3878850969516336edaa20302496e Mon Sep 17 00:00:00 2001 From: Aleix Pol Date: Thu, 27 May 2021 19:15:09 +0200 Subject: [PATCH 1/2] Add a SNI for active screencasting sessions Allows users to see which are happening and to close them if they feel it should not be happening. --- src/screencast.cpp | 4 ++-- src/screenchooserdialog.cpp | 17 ++++++++++++++--- src/screenchooserdialog.h | 2 +- src/waylandintegration.cpp | 35 +++++++++++++++++++++++++++++------ src/waylandintegration.h | 2 +- src/waylandintegration_p.h | 4 ++-- 6 files changed, 49 insertions(+), 15 deletions(-) diff --git a/src/screencast.cpp b/src/screencast.cpp index ca879e4..81a9b09 100644 --- a/src/screencast.cpp +++ b/src/screencast.cpp @@ -152,8 +152,8 @@ uint ScreenCastPortal::Start(const QDBusObjectPath &handle, } } const auto selectedWindows = screenDialog->selectedWindows(); - for (const QByteArray &winid : selectedWindows) { - if (!WaylandIntegration::startStreamingWindow(winid)) { + for (const auto &win : selectedWindows) { + if (!WaylandIntegration::startStreamingWindow(win)) { return 2; } } diff --git a/src/screenchooserdialog.cpp b/src/screenchooserdialog.cpp index 204b6b1..c6d5fd8 100644 --- a/src/screenchooserdialog.cpp +++ b/src/screenchooserdialog.cpp @@ -38,6 +38,16 @@ public: && !idx.data(PlasmaWindowModel::SkipSwitcher).toBool() // && idx.data(PlasmaWindowModel::Pid) != QCoreApplication::applicationPid(); } + + QMap itemData(const QModelIndex &index) const override + { + using KWayland::Client::PlasmaWindowModel; + auto ret = QSortFilterProxyModel::itemData(index); + for (int i = PlasmaWindowModel::AppId; i <= PlasmaWindowModel::Uuid; ++i) { + ret[i] = index.data(i); + } + return ret; + } }; ScreenChooserDialog::ScreenChooserDialog(const QString &appName, bool multiple, QDialog *parent, Qt::WindowFlags flags) @@ -124,14 +134,15 @@ QList ScreenChooserDialog::selectedScreens() const return m_dialog->screenView->selectedScreens(); } -QList ScreenChooserDialog::selectedWindows() const +QVector> ScreenChooserDialog::selectedWindows() const { const auto idxs = m_dialog->windowsView->selectionModel()->selectedIndexes(); - QList ret; + QVector> ret; ret.reserve(idxs.count()); for (const auto &idx : idxs) { - ret += idx.data(KWayland::Client::PlasmaWindowModel::Uuid).toByteArray(); + auto m = idx.model(); + ret += m->itemData(idx); } return ret; } diff --git a/src/screenchooserdialog.h b/src/screenchooserdialog.h index 3515e6c..d251927 100644 --- a/src/screenchooserdialog.h +++ b/src/screenchooserdialog.h @@ -28,7 +28,7 @@ public: void setSourceTypes(ScreenCastPortal::SourceTypes types); QList selectedScreens() const; - QList selectedWindows() const; + QVector> selectedWindows() const; private: void selectionChanged(const QItemSelection &selected); diff --git a/src/waylandintegration.cpp b/src/waylandintegration.cpp index 5e89faa..ccc1e2b 100644 --- a/src/waylandintegration.cpp +++ b/src/waylandintegration.cpp @@ -28,12 +28,14 @@ #include #include #include +#include #include // system #include #include +#include #include Q_LOGGING_CATEGORY(XdgDesktopPortalKdeWaylandIntegration, "xdp-kde-wayland-integration") @@ -76,9 +78,9 @@ bool WaylandIntegration::startStreamingOutput(quint32 outputName, Screencasting: return globalWaylandIntegration->startStreamingOutput(outputName, mode); } -bool WaylandIntegration::startStreamingWindow(const QByteArray &winid) +bool WaylandIntegration::startStreamingWindow(const QMap &win) { - return globalWaylandIntegration->startStreamingWindow(winid); + return globalWaylandIntegration->startStreamingWindow(win); } void WaylandIntegration::stopAllStreaming() @@ -234,19 +236,22 @@ void WaylandIntegration::WaylandIntegrationPrivate::startStreamingInput() m_streamInput = true; } -bool WaylandIntegration::WaylandIntegrationPrivate::startStreamingWindow(const QByteArray &winid) +bool WaylandIntegration::WaylandIntegrationPrivate::startStreamingWindow(const QMap &win) { - return startStreaming(m_screencasting->createWindowStream(QString::fromUtf8(winid), Screencasting::Hidden), {}); + 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) { auto output = m_outputMap.value(outputName).output(); - return startStreaming(m_screencasting->createOutputStream(output.data(), mode), output); + return startStreaming(m_screencasting->createOutputStream(output.data(), mode), output, {}); } -bool WaylandIntegration::WaylandIntegrationPrivate::startStreaming(ScreencastingStream *stream, QSharedPointer output) +bool WaylandIntegration::WaylandIntegrationPrivate::startStreaming(ScreencastingStream *stream, + QSharedPointer output, + const QMap &win) { QEventLoop loop; bool streamReady = false; @@ -282,6 +287,24 @@ bool WaylandIntegration::WaylandIntegrationPrivate::startStreaming(Screencasting stopStreaming(nodeid); }); streamReady = true; + + auto item = new KStatusNotifierItem(stream); + item->setStandardActionsEnabled(false); + if (output) { + item->setTitle(i18n("Recording screen \"%1\"...", output->model())); + item->setIconByName("video-display"); + } else { + auto name = win[Qt::DecorationRole].value().name(); + item->setIconByName(name.isEmpty() ? "applications-all" : name); + item->setTitle(i18n("Recording window \"%1\"...", win[Qt::DisplayRole].toString())); + } + item->setOverlayIconByName("media-record"); + item->setToolTip(item->iconName(), item->title(), i18n("Press to cancel")); + connect(item, &KStatusNotifierItem::activateRequested, stream, [=] { + stopStreaming(nodeid); + stream->deleteLater(); + }); + loop.quit(); }); QTimer::singleShot(3000, &loop, &QEventLoop::quit); diff --git a/src/waylandintegration.h b/src/waylandintegration.h index 684c54d..87be498 100644 --- a/src/waylandintegration.h +++ b/src/waylandintegration.h @@ -110,7 +110,7 @@ bool isStreamingAvailable(); void startStreamingInput(); bool startStreamingOutput(quint32 outputName, Screencasting::CursorMode mode); -bool startStreamingWindow(const QByteArray &winid); +bool startStreamingWindow(const QMap &win); void stopAllStreaming(); void requestPointerButtonPress(quint32 linuxButton); diff --git a/src/waylandintegration_p.h b/src/waylandintegration_p.h index 8bbc224..4bd4f9f 100644 --- a/src/waylandintegration_p.h +++ b/src/waylandintegration_p.h @@ -75,9 +75,9 @@ public: void startStreamingInput(); - bool startStreaming(ScreencastingStream *stream, QSharedPointer output); + bool startStreaming(ScreencastingStream *stream, QSharedPointer output, const QMap &win); bool startStreamingOutput(quint32 outputName, Screencasting::CursorMode mode); - bool startStreamingWindow(const QByteArray &winid); + bool startStreamingWindow(const QMap &win); void stopStreaming(uint32_t nodeid); void stopAllStreaming(); -- GitLab From abe64105b0586f7125456417d78840984a4c4296 Mon Sep 17 00:00:00 2001 From: Aleix Pol Date: Thu, 27 May 2021 19:22:19 +0200 Subject: [PATCH 2/2] Remove unused method --- src/screencasting.cpp | 7 ------- src/screencasting.h | 1 - 2 files changed, 8 deletions(-) diff --git a/src/screencasting.cpp b/src/screencasting.cpp index 77d0241..621446a 100644 --- a/src/screencasting.cpp +++ b/src/screencasting.cpp @@ -104,13 +104,6 @@ ScreencastingStream *Screencasting::createOutputStream(Output *output, CursorMod return stream; } -ScreencastingStream *Screencasting::createWindowStream(PlasmaWindow *window, CursorMode mode) -{ - auto stream = createWindowStream(QString::fromUtf8(window->uuid()), mode); - stream->setObjectName(window->appId()); - return stream; -} - ScreencastingStream *Screencasting::createWindowStream(const QString &uuid, CursorMode mode) { auto stream = new ScreencastingStream(this); diff --git a/src/screencasting.h b/src/screencasting.h index 62cf9ba..2a073d5 100644 --- a/src/screencasting.h +++ b/src/screencasting.h @@ -61,7 +61,6 @@ public: Q_ENUM(CursorMode); ScreencastingStream *createOutputStream(KWayland::Client::Output *output, CursorMode mode); - ScreencastingStream *createWindowStream(KWayland::Client::PlasmaWindow *window, CursorMode mode); ScreencastingStream *createWindowStream(const QString &uuid, CursorMode mode); void setup(zkde_screencast_unstable_v1 *screencasting); -- GitLab