diff options
Diffstat (limited to 'src/core/api/qwebenginedesktopmediarequest.cpp')
-rw-r--r-- | src/core/api/qwebenginedesktopmediarequest.cpp | 206 |
1 files changed, 206 insertions, 0 deletions
diff --git a/src/core/api/qwebenginedesktopmediarequest.cpp b/src/core/api/qwebenginedesktopmediarequest.cpp new file mode 100644 index 000000000..dae69a68c --- /dev/null +++ b/src/core/api/qwebenginedesktopmediarequest.cpp @@ -0,0 +1,206 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only + +#include "desktop_media_controller.h" +#include "qwebenginedesktopmediarequest.h" +#include "qwebenginedesktopmediarequest_p.h" + +QT_BEGIN_NAMESPACE + +QT_DEFINE_QESDP_SPECIALIZATION_DTOR(QWebEngineDesktopMediaRequestPrivate) + +/*! + \class QWebEngineDesktopMediaRequest + \brief A request for populating a dialog with available sources for screen capturing. + + \since 6.7 + + \inmodule QtWebEngineCore + + To allow web applications to capture contents of a display, applications must connect + to QWebEnginePage::desktopMediaRequested, which takes a QWebEngineDesktopMediaRequest + instance as an argument. + + If a web application requests access to the contents of a display, + QWebEnginePage::desktopMediaRequested will be emitted with a + QWebEngineDesktopMediaRequest instance as an argument which holds references to + QAbstractListModels for available windows and screens that can be captured. + + The data model's \e Qt::DisplayRole specifies the name of the source which is the title of a + window or the number of the display. + The model is dynamically updates if the available list of sources has changed e.g a window is + opened/closed. + + The signal handler needs to then either call QWebEngineDesktopMediaRequest:selectScreen() or + QWebEngineDesktopMediaRequest::selectWindow() to accept the request and start screensharing. + \sa QWebEnginePage::desktopMediaRequested(). +*/ + +class QWebEngineMediaSourceModel : public QAbstractListModel +{ +public: + ~QWebEngineMediaSourceModel() override; + + int rowCount(const QModelIndex &parent = QModelIndex()) const override; + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; + +private: + friend class QWebEngineDesktopMediaRequestPrivate; + explicit QWebEngineMediaSourceModel(QtWebEngineCore::DesktopMediaListQt *mediaList); + QtWebEngineCore::DesktopMediaListQt *m_mediaList; +}; + +QWebEngineMediaSourceModel::QWebEngineMediaSourceModel(QtWebEngineCore::DesktopMediaListQt *mediaList) + : m_mediaList(mediaList) +{ + QObject::connect(m_mediaList, &QtWebEngineCore::DesktopMediaListQt::sourceAdded, this, + [this](int index) { + beginInsertRows(QModelIndex(), index, index); + endInsertRows(); + }); + QObject::connect(m_mediaList, &QtWebEngineCore::DesktopMediaListQt::sourceRemoved, this, + [this](int index) { + beginRemoveRows(QModelIndex(), index, index); + endRemoveRows(); + }); + QObject::connect(m_mediaList, &QtWebEngineCore::DesktopMediaListQt::sourceMoved, this, + [this](int oldIndex, int newIndex) { + beginMoveRows(QModelIndex(), oldIndex, oldIndex, QModelIndex(), newIndex); + endMoveRows(); + }); + QObject::connect(m_mediaList, &QtWebEngineCore::DesktopMediaListQt::sourceNameChanged, this, + [this](int index) { + Q_EMIT dataChanged(QModelIndex(), QModelIndex(), + { Qt::DisplayRole }); + }); +} + +QWebEngineMediaSourceModel::~QWebEngineMediaSourceModel() { } + +int QWebEngineMediaSourceModel::rowCount(const QModelIndex &) const +{ + return m_mediaList->getSourceCount(); +} + +QVariant QWebEngineMediaSourceModel::data(const QModelIndex &index, int role) const +{ + if (!index.isValid()) + return QVariant(); + switch (role) { + case Qt::DisplayRole: + case Qt::EditRole: + return m_mediaList->getSourceName(index.row()); + default: + break; + } + return QVariant(); +} + +QWebEngineDesktopMediaRequestPrivate::QWebEngineDesktopMediaRequestPrivate( + QtWebEngineCore::DesktopMediaController *controller) + : controller(controller) + , m_screensModel(new QWebEngineMediaSourceModel(controller->screens())) + , m_windowsModel(new QWebEngineMediaSourceModel(controller->windows())) +{ +} + +QWebEngineDesktopMediaRequestPrivate::~QWebEngineDesktopMediaRequestPrivate() +{ + // Keep old behavior, if there were no user action select the primary screen. + if (!didSelectOrCancel) + controller->selectScreen(0); +} + +void QWebEngineDesktopMediaRequestPrivate::selectWindow(const QModelIndex &index) +{ + Q_ASSERT(index.model() == m_windowsModel.get()); + if (!index.isValid()) + return; + didSelectOrCancel = true; + controller->selectWindow(index.row()); +} + +void QWebEngineDesktopMediaRequestPrivate::selectScreen(const QModelIndex &index) +{ + Q_ASSERT(index.model() == m_screensModel.get()); + if (!index.isValid()) + return; + didSelectOrCancel = true; + controller->selectScreen(index.row()); +} + +void QWebEngineDesktopMediaRequestPrivate::cancel() +{ + // Notifies webrtc so it can free up it's resources. + didSelectOrCancel = true; + controller->cancel(); +} + +QWebEngineDesktopMediaRequest::QWebEngineDesktopMediaRequest( + QtWebEngineCore::DesktopMediaController *controller) + : d(new QWebEngineDesktopMediaRequestPrivate(controller)) +{ +} + +QWebEngineDesktopMediaRequest::~QWebEngineDesktopMediaRequest() = default; + +QWebEngineDesktopMediaRequest::QWebEngineDesktopMediaRequest( + const QWebEngineDesktopMediaRequest &other) noexcept = default; + +QWebEngineDesktopMediaRequest &QWebEngineDesktopMediaRequest::operator=( + const QWebEngineDesktopMediaRequest &other) noexcept = default; + +QWebEngineDesktopMediaRequest::QWebEngineDesktopMediaRequest( + QWebEngineDesktopMediaRequest &&other) noexcept = default; + +/*! + Returns a QAbstractListModel for the available screens. + + \sa windowsModel() +*/ +QAbstractListModel *QWebEngineDesktopMediaRequest::screensModel() const +{ + return d->m_screensModel.get(); +} + +/*! + Returns a QAbstractListModel for the available windows. + + \sa screensModel() +*/ +QAbstractListModel *QWebEngineDesktopMediaRequest::windowsModel() const +{ + return d->m_windowsModel.get(); +} + +/*! + Selects the window on the \a index to be captured. + + \sa QWebEngineDesktopMediaRequest::selectScreen() +*/ +void QWebEngineDesktopMediaRequest::selectWindow(const QModelIndex &index) const +{ + d->selectWindow(index); +} + +/*! + Selects the screen on the \a index to be captured. + + \sa QWebEngineDesktopMediaRequest::selectWindow() +*/ +void QWebEngineDesktopMediaRequest::selectScreen(const QModelIndex &index) const +{ + d->selectScreen(index); +} + +/*! + Rejects a request. Screen capturing will be aborted. +*/ +void QWebEngineDesktopMediaRequest::cancel() const +{ + d->cancel(); +} + +QT_END_NAMESPACE + +#include "moc_qwebenginedesktopmediarequest.cpp" |