summaryrefslogtreecommitdiffstats
path: root/src/core/api/qwebenginedesktopmediarequest.cpp
diff options
context:
space:
mode:
authorMartin Negyokru <negyokru@inf.u-szeged.hu>2022-11-04 10:55:58 +0100
committerMartin Negyokru <negyokru@inf.u-szeged.hu>2023-12-15 09:39:26 +0100
commitde57e1b0b00be63e0647d864ff48b9c75742423d (patch)
tree639eb11f6ae7ab3abe32130fdfa4981402c95aef /src/core/api/qwebenginedesktopmediarequest.cpp
parent39e437f0bc990cf292defff0d77790d27b31df32 (diff)
Add new API for screen capturing
[ChangeLog][WebEngineCore] Add QWebEnginePage::desktopMediaRequested() signal [ChangeLog][WebEngineQuick] Add QQuickWebEngineView::desktopMediaRequested() signal Pick-to: 6.7 Fixes: QTBUG-112142 Task-number: QTBUG-70077 Change-Id: I4bfad88732b45fb68b77f7617440bcb50b248a11 Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
Diffstat (limited to 'src/core/api/qwebenginedesktopmediarequest.cpp')
-rw-r--r--src/core/api/qwebenginedesktopmediarequest.cpp213
1 files changed, 213 insertions, 0 deletions
diff --git a/src/core/api/qwebenginedesktopmediarequest.cpp b/src/core/api/qwebenginedesktopmediarequest.cpp
new file mode 100644
index 000000000..d9ec572c5
--- /dev/null
+++ b/src/core/api/qwebenginedesktopmediarequest.cpp
@@ -0,0 +1,213 @@
+// 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
+/*!
+ \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
+ data models for available windows and screens that can be captured.
+ The signal handler needs to then either call QWebEngineDesktopMediaRequest:selectScreen(),
+ QWebEngineDesktopMediaRequest::selectWindow() to accept the request and start screensharing.
+ \sa QWebEnginePage::desktopMediaRequested().
+*/
+
+/*!
+ \class QWebEngineMediaSourceModel
+ \brief A data model that represents display sources for screen capturing.
+
+ \since 6.7
+
+ \inmodule QtWebEngineCore
+ The QWebEngineMediaSourceModel exposes the \e name Role.
+ The name role 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.
+
+ This type is uncreatable, it can only be accessed from a QWebEngineDesktopMediaRequest.
+ \sa QWebEngineDesktopMediaRequest::windowsModel(),
+ QWebEngineDesktopMediaRequest::screensModel().
+*/
+
+class QWebEngineMediaSourceModelPrivate
+{
+public:
+ QWebEngineMediaSourceModelPrivate(QtWebEngineCore::DesktopMediaListQt *);
+ QtWebEngineCore::DesktopMediaListQt *m_mediaList;
+};
+
+QWebEngineMediaSourceModelPrivate::QWebEngineMediaSourceModelPrivate(
+ QtWebEngineCore::DesktopMediaListQt *mediaList)
+ : m_mediaList(mediaList)
+{
+}
+
+QWebEngineMediaSourceModel::QWebEngineMediaSourceModel(QWebEngineMediaSourceModelPrivate *dd)
+ : d(dd)
+{
+ QObject::connect(d->m_mediaList, &QtWebEngineCore::DesktopMediaListQt::sourceAdded, this,
+ [this](int index) {
+ beginInsertRows(QModelIndex(), index, index);
+ endInsertRows();
+ });
+ QObject::connect(d->m_mediaList, &QtWebEngineCore::DesktopMediaListQt::sourceRemoved, this,
+ [this](int index) {
+ beginRemoveRows(QModelIndex(), index, index);
+ endRemoveRows();
+ });
+ QObject::connect(d->m_mediaList, &QtWebEngineCore::DesktopMediaListQt::sourceMoved, this,
+ [this](int oldIndex, int newIndex) {
+ beginMoveRows(QModelIndex(), oldIndex, oldIndex, QModelIndex(), newIndex);
+ endMoveRows();
+ });
+ QObject::connect(d->m_mediaList, &QtWebEngineCore::DesktopMediaListQt::sourceNameChanged, this,
+ [this](int index) {
+ Q_EMIT dataChanged(QModelIndex(), QModelIndex(),
+ { Qt::DisplayRole, Roles::NameRole });
+ });
+}
+
+QWebEngineMediaSourceModel::~QWebEngineMediaSourceModel() { }
+
+int QWebEngineMediaSourceModel::rowCount(const QModelIndex &) const
+{
+ return d->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:
+ case NameRole:
+ return d->m_mediaList->getSourceName(index.row());
+ default:
+ break;
+ }
+ return QVariant();
+}
+
+QHash<int, QByteArray> QWebEngineMediaSourceModel::roleNames() const
+{
+ QHash<int, QByteArray> roles = QAbstractItemModel::roleNames();
+ roles[NameRole] = "name";
+ return roles;
+}
+
+QWebEngineDesktopMediaRequestPrivate::QWebEngineDesktopMediaRequestPrivate(
+ QtWebEngineCore::DesktopMediaController *controller)
+ : controller(controller)
+ , m_screensModel(new QWebEngineMediaSourceModel(
+ new QWebEngineMediaSourceModelPrivate(controller->screens())))
+ , m_windowsModel(new QWebEngineMediaSourceModel(
+ new QWebEngineMediaSourceModelPrivate(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))
+{
+}
+
+/*!
+ Returns a QWebEngineMediaSourceModel for the available screens.
+
+ \sa windowsModel()
+*/
+QWebEngineMediaSourceModel *QWebEngineDesktopMediaRequest::screensModel() const
+{
+ return d->m_screensModel.get();
+}
+
+/*!
+ Returns a QWebEngineMediaSourceModel for the available windows.
+
+ \sa screensModel()
+*/
+QWebEngineMediaSourceModel *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"