diff options
-rw-r--r-- | examples/webenginewidgets/demobrowser/tabwidget.cpp | 59 | ||||
-rw-r--r-- | examples/webenginewidgets/demobrowser/tabwidget.h | 5 | ||||
-rw-r--r-- | src/core/web_contents_adapter.cpp | 18 | ||||
-rw-r--r-- | src/core/web_contents_adapter.h | 3 | ||||
-rw-r--r-- | src/core/web_contents_adapter_client.h | 1 | ||||
-rw-r--r-- | src/core/web_contents_delegate_qt.cpp | 9 | ||||
-rw-r--r-- | src/webengine/api/qquickwebengineview.cpp | 33 | ||||
-rw-r--r-- | src/webengine/api/qquickwebengineview_p.h | 6 | ||||
-rw-r--r-- | src/webengine/api/qquickwebengineview_p_p.h | 1 | ||||
-rw-r--r-- | src/webengine/doc/src/webengineview.qdoc | 34 | ||||
-rw-r--r-- | src/webenginewidgets/api/qwebenginepage.cpp | 36 | ||||
-rw-r--r-- | src/webenginewidgets/api/qwebenginepage.h | 7 | ||||
-rw-r--r-- | src/webenginewidgets/api/qwebenginepage_p.h | 1 | ||||
-rw-r--r-- | src/webenginewidgets/doc/src/qwebenginepage_lgpl.qdoc | 34 |
14 files changed, 246 insertions, 1 deletions
diff --git a/examples/webenginewidgets/demobrowser/tabwidget.cpp b/examples/webenginewidgets/demobrowser/tabwidget.cpp index 95b79aaac..a7e94ee62 100644 --- a/examples/webenginewidgets/demobrowser/tabwidget.cpp +++ b/examples/webenginewidgets/demobrowser/tabwidget.cpp @@ -126,6 +126,15 @@ void TabBar::contextMenuRequested(const QPoint &position) action = menu.addAction(tr("Reload Tab"), this, SLOT(reloadTab()), QKeySequence::Refresh); action->setData(index); + + // Audio mute / unmute. + action = menu.addAction(tr("Mute tab"), + this, SLOT(muteTab())); + action->setData(index); + + action = menu.addAction(tr("Unmute tab"), + this, SLOT(unmuteTab())); + action->setData(index); } else { menu.addSeparator(); } @@ -209,6 +218,22 @@ void TabBar::reloadTab() } } +void TabBar::muteTab() +{ + if (QAction *action = qobject_cast<QAction*>(sender())) { + int index = action->data().toInt(); + emit muteTab(index, true); + } +} + +void TabBar::unmuteTab() +{ + if (QAction *action = qobject_cast<QAction*>(sender())) { + int index = action->data().toInt(); + emit muteTab(index, false); + } +} + TabWidget::TabWidget(QWidget *parent) : QTabWidget(parent) , m_recentlyClosedTabsAction(0) @@ -233,6 +258,7 @@ TabWidget::TabWidget(QWidget *parent) connect(m_tabBar, SIGNAL(reloadTab(int)), this, SLOT(reloadTab(int))); connect(m_tabBar, SIGNAL(reloadAllTabs()), this, SLOT(reloadAllTabs())); connect(m_tabBar, SIGNAL(tabMoved(int,int)), this, SLOT(moveTab(int,int))); + connect(m_tabBar, SIGNAL(muteTab(int,bool)), this, SLOT(setAudioMutedForTab(int,bool))); setTabBar(m_tabBar); setDocumentMode(true); @@ -298,6 +324,18 @@ void TabWidget::moveTab(int fromIndex, int toIndex) m_lineEdits->insertWidget(toIndex, lineEdit); } +void TabWidget::setAudioMutedForTab(int index, bool mute) +{ + if (index < 0) + index = currentIndex(); + if (index < 0 || index >= count()) + return; + + QWidget *widget = this->widget(index); + if (WebView *tab = qobject_cast<WebView*>(widget)) + tab->page()->setAudioMuted(mute); +} + void TabWidget::addWebAction(QAction *action, QWebEnginePage::WebAction webAction) { if (!action) @@ -506,6 +544,10 @@ WebView *TabWidget::newTab(bool makeCurrent) this, SLOT(webViewIconChanged())); connect(webView, SIGNAL(titleChanged(QString)), this, SLOT(webViewTitleChanged(QString))); + connect(webView->page(), SIGNAL(audioMutedChanged(bool)), + this, SLOT(webPageMutedOrAudibleChanged())); + connect(webView->page(), SIGNAL(wasRecentlyAudibleChanged(bool)), + this, SLOT(webPageMutedOrAudibleChanged())); connect(webView, SIGNAL(urlChanged(QUrl)), this, SLOT(webViewUrlChanged(QUrl))); connect(webView->page(), SIGNAL(windowCloseRequested()), @@ -680,6 +722,23 @@ void TabWidget::webViewTitleChanged(const QString &title) BrowserApplication::historyManager()->updateHistoryItem(webView->url(), title); } +void TabWidget::webPageMutedOrAudibleChanged() { + QWebEnginePage* webPage = qobject_cast<QWebEnginePage*>(sender()); + WebView *webView = qobject_cast<WebView*>(webPage->view()); + + int index = webViewIndex(webView); + if (-1 != index) { + QString title = webView->title(); + + bool muted = webPage->isAudioMuted(); + bool audible = webPage->wasRecentlyAudible(); + if (muted) title += tr(" (muted)"); + else if (audible) title += tr(" (audible)"); + + setTabText(index, title); + } +} + void TabWidget::webViewUrlChanged(const QUrl &url) { WebView *webView = qobject_cast<WebView*>(sender()); diff --git a/examples/webenginewidgets/demobrowser/tabwidget.h b/examples/webenginewidgets/demobrowser/tabwidget.h index b00131130..f4ad9c02d 100644 --- a/examples/webenginewidgets/demobrowser/tabwidget.h +++ b/examples/webenginewidgets/demobrowser/tabwidget.h @@ -65,6 +65,7 @@ signals: void closeTab(int index); void closeOtherTabs(int index); void reloadTab(int index); + void muteTab(int index, bool mute); void reloadAllTabs(); void tabMoveRequested(int fromIndex, int toIndex); @@ -81,6 +82,8 @@ private slots: void closeTab(); void closeOtherTabs(); void reloadTab(); + void muteTab(); + void unmuteTab(); void contextMenuRequested(const QPoint &position); private: @@ -204,6 +207,7 @@ public slots: void reloadAllTabs(); void nextTab(); void previousTab(); + void setAudioMutedForTab(int index, bool mute); private slots: void currentChanged(int index); @@ -218,6 +222,7 @@ private slots: void windowCloseRequested(); void moveTab(int fromIndex, int toIndex); void fullScreenRequested(QWebEngineFullScreenRequest request); + void webPageMutedOrAudibleChanged(); private: QAction *m_recentlyClosedTabsAction; diff --git a/src/core/web_contents_adapter.cpp b/src/core/web_contents_adapter.cpp index 543ad24cb..923bb1e2d 100644 --- a/src/core/web_contents_adapter.cpp +++ b/src/core/web_contents_adapter.cpp @@ -795,6 +795,24 @@ void WebContentsAdapter::download(const QUrl &url, const QString &suggestedFileN dlm->DownloadUrl(params.Pass()); } +bool WebContentsAdapter::isAudioMuted() const +{ + const Q_D(WebContentsAdapter); + return d->webContents->IsAudioMuted(); +} + +void WebContentsAdapter::setAudioMuted(bool muted) +{ + Q_D(WebContentsAdapter); + d->webContents->SetAudioMuted(muted); +} + +bool WebContentsAdapter::wasRecentlyAudible() +{ + Q_D(WebContentsAdapter); + return d->webContents->WasRecentlyAudible(); +} + void WebContentsAdapter::copyImageAt(const QPoint &location) { Q_D(WebContentsAdapter); diff --git a/src/core/web_contents_adapter.h b/src/core/web_contents_adapter.h index df9cbb266..01da38894 100644 --- a/src/core/web_contents_adapter.h +++ b/src/core/web_contents_adapter.h @@ -114,6 +114,9 @@ public: void stopFinding(); void updateWebPreferences(const content::WebPreferences &webPreferences); void download(const QUrl &url, const QString &suggestedFileName); + bool isAudioMuted() const; + void setAudioMuted(bool mute); + bool wasRecentlyAudible(); // Must match blink::WebMediaPlayerAction::Type. enum MediaPlayerAction { diff --git a/src/core/web_contents_adapter_client.h b/src/core/web_contents_adapter_client.h index cbe5a687a..92d5aa093 100644 --- a/src/core/web_contents_adapter_client.h +++ b/src/core/web_contents_adapter_client.h @@ -198,6 +198,7 @@ public: virtual void loadProgressChanged(int progress) = 0; virtual void didUpdateTargetURL(const QUrl&) = 0; virtual void selectionChanged() = 0; + virtual void wasRecentlyAudibleChanged(bool wasRecentlyAudible) = 0; virtual QRectF viewportRect() const = 0; virtual qreal dpiScale() const = 0; virtual QColor backgroundColor() const = 0; diff --git a/src/core/web_contents_delegate_qt.cpp b/src/core/web_contents_delegate_qt.cpp index f1c9a7f34..c8e8da713 100644 --- a/src/core/web_contents_delegate_qt.cpp +++ b/src/core/web_contents_delegate_qt.cpp @@ -122,6 +122,15 @@ void WebContentsDelegateQt::NavigationStateChanged(content::WebContents* source, m_viewClient->urlChanged(toQt(source->GetVisibleURL())); if (changed_flags & content::INVALIDATE_TYPE_TITLE) m_viewClient->titleChanged(toQt(source->GetTitle())); + + // NavigationStateChanged gets called with INVALIDATE_TYPE_TAB by AudioStateProvider::Notify, + // whenever an audio sound gets played or stopped, this is the only way to actually figure out + // if there was a recently played audio sound. + // Make sure to only emit the signal when loading isn't in progress, because it causes multiple + // false signals to be emitted. + if ((changed_flags & content::INVALIDATE_TYPE_TAB) && !(changed_flags & content::INVALIDATE_TYPE_LOAD)) { + m_viewClient->wasRecentlyAudibleChanged(source->WasRecentlyAudible()); + } } void WebContentsDelegateQt::AddNewContents(content::WebContents* source, content::WebContents* new_contents, WindowOpenDisposition disposition, const gfx::Rect& initial_pos, bool user_gesture, bool* was_blocked) diff --git a/src/webengine/api/qquickwebengineview.cpp b/src/webengine/api/qquickwebengineview.cpp index b9fa3d605..7b0ed0a33 100644 --- a/src/webengine/api/qquickwebengineview.cpp +++ b/src/webengine/api/qquickwebengineview.cpp @@ -392,6 +392,12 @@ void QQuickWebEngineViewPrivate::didUpdateTargetURL(const QUrl &hoveredUrl) Q_EMIT q->linkHovered(hoveredUrl); } +void QQuickWebEngineViewPrivate::wasRecentlyAudibleChanged(bool wasRecentlyAudible) +{ + Q_Q(QQuickWebEngineView); + Q_EMIT q->wasRecentlyAudibleChanged(wasRecentlyAudible); +} + QRectF QQuickWebEngineViewPrivate::viewportRect() const { Q_Q(const QQuickWebEngineView); @@ -1084,6 +1090,33 @@ void QQuickWebEngineView::setBackgroundColor(const QColor &color) emit backgroundColorChanged(); } +/*! + \property QQuickWebEngineView::audioMuted + \brief the state of whether the current page audio is muted. + \since 5.7 + + The default value is false. +*/ +bool QQuickWebEngineView::isAudioMuted() const { + const Q_D(QQuickWebEngineView); + return d->adapter->isAudioMuted(); + +} +void QQuickWebEngineView::setAudioMuted(bool muted) { + Q_D(QQuickWebEngineView); + bool _isAudioMuted = isAudioMuted(); + d->adapter->setAudioMuted(muted); + if (_isAudioMuted != muted) { + Q_EMIT audioMutedChanged(muted); + } +} + +bool QQuickWebEngineView::wasRecentlyAudible() +{ + Q_D(QQuickWebEngineView); + return d->adapter->wasRecentlyAudible(); +} + bool QQuickWebEngineView::isFullScreen() const { Q_D(const QQuickWebEngineView); diff --git a/src/webengine/api/qquickwebengineview_p.h b/src/webengine/api/qquickwebengineview_p.h index a2f937968..9f7a45156 100644 --- a/src/webengine/api/qquickwebengineview_p.h +++ b/src/webengine/api/qquickwebengineview_p.h @@ -110,6 +110,7 @@ class Q_WEBENGINE_PRIVATE_EXPORT QQuickWebEngineView : public QQuickItem { Q_PROPERTY(QColor backgroundColor READ backgroundColor WRITE setBackgroundColor NOTIFY backgroundColorChanged REVISION 2) Q_PROPERTY(QSizeF contentsSize READ contentsSize NOTIFY contentsSizeChanged FINAL REVISION 3) Q_PROPERTY(QPointF scrollPosition READ scrollPosition NOTIFY scrollPositionChanged FINAL REVISION 3) + Q_PROPERTY(bool audioMuted READ isAudioMuted WRITE setAudioMuted NOTIFY audioMutedChanged REVISION 3) #ifdef ENABLE_QML_TESTSUPPORT_API Q_PROPERTY(QQuickWebEngineTestSupport *testSupport READ testSupport WRITE setTestSupport FINAL) @@ -295,6 +296,9 @@ public Q_SLOTS: Q_REVISION(1) void grantFeaturePermission(const QUrl &securityOrigin, Feature, bool granted); Q_REVISION(2) void setActiveFocusOnPress(bool arg); Q_REVISION(2) void triggerWebAction(WebAction action); + Q_REVISION(3) bool isAudioMuted() const; + Q_REVISION(3) void setAudioMuted(bool muted); + Q_REVISION(3) bool wasRecentlyAudible(); Q_SIGNALS: void titleChanged(); @@ -319,6 +323,8 @@ Q_SIGNALS: Q_REVISION(2) void windowCloseRequested(); Q_REVISION(3) void contentsSizeChanged(const QSizeF& size); Q_REVISION(3) void scrollPositionChanged(const QPointF& position); + Q_REVISION(3) void audioMutedChanged(bool muted); + Q_REVISION(3) void wasRecentlyAudibleChanged(bool wasRecentlyAudible); protected: void geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry); diff --git a/src/webengine/api/qquickwebengineview_p_p.h b/src/webengine/api/qquickwebengineview_p_p.h index 7fca79b7a..69ba60ccd 100644 --- a/src/webengine/api/qquickwebengineview_p_p.h +++ b/src/webengine/api/qquickwebengineview_p_p.h @@ -132,6 +132,7 @@ public: virtual void loadProgressChanged(int progress) Q_DECL_OVERRIDE; virtual void didUpdateTargetURL(const QUrl&) Q_DECL_OVERRIDE; virtual void selectionChanged() Q_DECL_OVERRIDE { } + virtual void wasRecentlyAudibleChanged(bool wasRecentlyAudible) Q_DECL_OVERRIDE; virtual QRectF viewportRect() const Q_DECL_OVERRIDE; virtual qreal dpiScale() const Q_DECL_OVERRIDE; virtual QColor backgroundColor() const Q_DECL_OVERRIDE; diff --git a/src/webengine/doc/src/webengineview.qdoc b/src/webengine/doc/src/webengineview.qdoc index e687d54d9..49717ae50 100644 --- a/src/webengine/doc/src/webengineview.qdoc +++ b/src/webengine/doc/src/webengineview.qdoc @@ -740,3 +740,37 @@ \sa toggleOn */ + +/*! + \qmlproperty bool WebEngineView::audioMuted + \brief The state of whether the current page audio is muted. + \since QtWebEngine 1.3 +*/ + +/*! + \qmlsignal void WebEngineView::audioMutedChanged(bool muted) + \since QtWebEngine 1.3 + + This signal is emitted when the page's audio is (un)muted using setAudioMuted method. + \note Not to be confused with a specific HTML5 audio / video element being muted. +*/ + +/*! + \qmlmethod bool WebEngineView::wasRecentlyAudible() + \since QtWebEngine 1.3 + \sa wasRecentlyAudibleChanged() + + Returns the current page's audible state (audio was recently played, or not). +*/ + +/*! + \qmlsignal void WebEngineView::wasRecentlyAudibleChanged(bool wasRecentlyAudible) + \since QtWebEngine 1.3 + + This signal is emitted when the page's audible state is changed, due to audio + being played or stopped. + + \note The signal is also emitted when calling the setAudioMuted method. + Also if the audio is paused, this signal is emitted with an approximate \b{2 second + delay}, from the moment the audio is paused. +*/ diff --git a/src/webenginewidgets/api/qwebenginepage.cpp b/src/webenginewidgets/api/qwebenginepage.cpp index ee5702309..ec98a8346 100644 --- a/src/webenginewidgets/api/qwebenginepage.cpp +++ b/src/webenginewidgets/api/qwebenginepage.cpp @@ -146,6 +146,12 @@ void QWebEnginePagePrivate::selectionChanged() Q_EMIT q->selectionChanged(); } +void QWebEnginePagePrivate::wasRecentlyAudibleChanged(bool wasRecentlyAudible) +{ + Q_Q(QWebEnginePage); + Q_EMIT q->wasRecentlyAudibleChanged(wasRecentlyAudible); +} + QRectF QWebEnginePagePrivate::viewportRect() const { return view ? view->rect() : QRectF(); @@ -570,6 +576,33 @@ void QWebEnginePage::setBackgroundColor(const QColor &color) d->adapter->backgroundColorChanged(); } +/*! + \property QWebEnginePage::audioMuted + \brief the state of whether the current page audio is muted. + \since 5.7 + + The default value is false. +*/ +bool QWebEnginePage::isAudioMuted() const { + const Q_D(QWebEnginePage); + return d->adapter->isAudioMuted(); +} + +void QWebEnginePage::setAudioMuted(bool muted) { + Q_D(QWebEnginePage); + bool _isAudioMuted = isAudioMuted(); + d->adapter->setAudioMuted(muted); + if (_isAudioMuted != muted) { + Q_EMIT audioMutedChanged(muted); + } +} + +bool QWebEnginePage::wasRecentlyAudible() +{ + Q_D(QWebEnginePage); + return d->adapter->wasRecentlyAudible(); +} + void QWebEnginePage::setView(QWidget *view) { QWebEngineViewPrivate::bind(qobject_cast<QWebEngineView*>(view), this); @@ -873,7 +906,8 @@ void QWebEnginePage::triggerAction(WebAction action, bool) break; case ToggleMediaMute: if (d->m_menuData.mediaUrl.isValid() && d->m_menuData.mediaFlags & WebEngineContextMenuData::MediaHasAudio) { - bool enable = (d->m_menuData.mediaFlags & WebEngineContextMenuData::MediaMuted); + // Make sure to negate the value, so that toggling actually works. + bool enable = !(d->m_menuData.mediaFlags & WebEngineContextMenuData::MediaMuted); d->adapter->executeMediaPlayerActionAt(d->m_menuData.pos, WebContentsAdapter::MediaPlayerMute, enable); } break; diff --git a/src/webenginewidgets/api/qwebenginepage.h b/src/webenginewidgets/api/qwebenginepage.h index b3c592708..7c9495199 100644 --- a/src/webenginewidgets/api/qwebenginepage.h +++ b/src/webenginewidgets/api/qwebenginepage.h @@ -72,6 +72,7 @@ class QWEBENGINEWIDGETS_EXPORT QWebEnginePage : public QObject { Q_PROPERTY(QColor backgroundColor READ backgroundColor WRITE setBackgroundColor) Q_PROPERTY(QSizeF contentsSize READ contentsSize NOTIFY contentsSizeChanged) Q_PROPERTY(QPointF scrollPosition READ scrollPosition NOTIFY scrollPositionChanged) + Q_PROPERTY(bool audioMuted READ isAudioMuted WRITE setAudioMuted NOTIFY audioMutedChanged) public: enum WebAction { @@ -247,6 +248,10 @@ public: QColor backgroundColor() const; void setBackgroundColor(const QColor &color); + bool isAudioMuted() const; + void setAudioMuted(bool muted); + bool wasRecentlyAudible(); + Q_SIGNALS: void loadStarted(); void loadProgress(int progress); @@ -274,6 +279,8 @@ Q_SIGNALS: void scrollPositionChanged(const QPointF &position); void contentsSizeChanged(const QSizeF &size); + void audioMutedChanged(bool muted); + void wasRecentlyAudibleChanged(bool wasRecentlyAudible); protected: virtual QWebEnginePage *createWindow(WebWindowType type); diff --git a/src/webenginewidgets/api/qwebenginepage_p.h b/src/webenginewidgets/api/qwebenginepage_p.h index 6f1341054..2ec5f6288 100644 --- a/src/webenginewidgets/api/qwebenginepage_p.h +++ b/src/webenginewidgets/api/qwebenginepage_p.h @@ -84,6 +84,7 @@ public: virtual void loadProgressChanged(int progress) Q_DECL_OVERRIDE; virtual void didUpdateTargetURL(const QUrl&) Q_DECL_OVERRIDE; virtual void selectionChanged() Q_DECL_OVERRIDE; + virtual void wasRecentlyAudibleChanged(bool wasRecentlyAudible) Q_DECL_OVERRIDE; virtual QRectF viewportRect() const Q_DECL_OVERRIDE; virtual qreal dpiScale() const Q_DECL_OVERRIDE; virtual QColor backgroundColor() const Q_DECL_OVERRIDE; diff --git a/src/webenginewidgets/doc/src/qwebenginepage_lgpl.qdoc b/src/webenginewidgets/doc/src/qwebenginepage_lgpl.qdoc index d3c540016..e09561bef 100644 --- a/src/webenginewidgets/doc/src/qwebenginepage_lgpl.qdoc +++ b/src/webenginewidgets/doc/src/qwebenginepage_lgpl.qdoc @@ -690,3 +690,37 @@ \sa iconUrl() */ + +/*! + \property QWebEnginePage::audioMuted + \brief the state of whether the current page audio is muted. + \since 5.7 +*/ + +/*! + \fn void QWebEnginePage::audioMutedChanged(bool muted) + \since 5.7 + + This signal is emitted when the page's audio is (un)muted using setAudioMuted method. + \note Not to be confused with a specific HTML5 audio / video element being muted. +*/ + +/*! + \fn bool QWebEnginePage::wasRecentlyAudible() + \since 5.7 + \sa wasRecentlyAudibleChanged() + + Returns the current page's audible state (audio was recently played, or not). +*/ + +/*! + \fn void QWebEnginePage::wasRecentlyAudibleChanged(bool wasRecentlyAudible); + \since 5.7 + + This signal is emitted when the page's audible state is changed, due to audio + being played or stopped. + + \note The signal is also emitted when calling the setAudioMuted method. + Also if the audio is paused, this signal is emitted with an approximate \b{2 second + delay}, from the moment the audio is paused. +*/ |