From 755f7e414583c5458c2d421d047a1c7890c8d8d2 Mon Sep 17 00:00:00 2001 From: Kirill Burtsev Date: Mon, 11 Feb 2019 19:13:01 +0100 Subject: Set download state to finished when cancelling or destroying the download item MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Task-number: QTBUG-73839 Change-Id: Ieebaa802bdfe0c410618e4213a9bedbbae9d0f61 Reviewed-by: Michael Brüning Reviewed-by: Jüri Valdmann --- src/webenginewidgets/api/qwebenginedownloaditem.cpp | 19 ++++++++++++++----- src/webenginewidgets/api/qwebenginedownloaditem_p.h | 4 +++- 2 files changed, 17 insertions(+), 6 deletions(-) (limited to 'src/webenginewidgets') diff --git a/src/webenginewidgets/api/qwebenginedownloaditem.cpp b/src/webenginewidgets/api/qwebenginedownloaditem.cpp index 55d4fcca8..f0f0958a5 100644 --- a/src/webenginewidgets/api/qwebenginedownloaditem.cpp +++ b/src/webenginewidgets/api/qwebenginedownloaditem.cpp @@ -197,11 +197,8 @@ void QWebEngineDownloadItemPrivate::update(const ProfileAdapterClient::DownloadI Q_EMIT q->downloadProgress(receivedBytes, totalBytes); } - if (info.done != downloadFinished) { - downloadFinished = info.done; - if (downloadFinished) - Q_EMIT q->finished(); - } + if (info.done) + setFinished(); if (downloadPaused != info.paused) { downloadPaused = info.paused; @@ -209,6 +206,15 @@ void QWebEngineDownloadItemPrivate::update(const ProfileAdapterClient::DownloadI } } +void QWebEngineDownloadItemPrivate::setFinished() +{ + if (downloadFinished) + return; + + downloadFinished = true; + Q_EMIT q_ptr->finished(); +} + /*! Accepts the current download request, which will start the download. @@ -262,6 +268,7 @@ void QWebEngineDownloadItem::cancel() } else { d->downloadState = QWebEngineDownloadItem::DownloadCancelled; Q_EMIT stateChanged(d->downloadState); + d->setFinished(); } } @@ -653,6 +660,8 @@ QWebEngineDownloadItem::QWebEngineDownloadItem(QWebEngineDownloadItemPrivate *p, */ QWebEngineDownloadItem::~QWebEngineDownloadItem() { + if (!isFinished()) + cancel(); if (auto profileAdapter = d_ptr->profile->profileAdapter()) profileAdapter->removeDownload(d_ptr->downloadId); } diff --git a/src/webenginewidgets/api/qwebenginedownloaditem_p.h b/src/webenginewidgets/api/qwebenginedownloaditem_p.h index bdcda5be6..b3bc8a3fe 100644 --- a/src/webenginewidgets/api/qwebenginedownloaditem_p.h +++ b/src/webenginewidgets/api/qwebenginedownloaditem_p.h @@ -53,7 +53,7 @@ #include "qtwebenginewidgetsglobal.h" -#include "qwebenginedownloaditem_p.h" +#include "qwebenginedownloaditem.h" #include "qwebengineprofile_p.h" #include @@ -84,6 +84,8 @@ public: QWebEnginePage *page; void update(const QtWebEngineCore::ProfileAdapterClient::DownloadItemInfo &info); + + void setFinished(); }; QT_END_NAMESPACE -- cgit v1.2.3 From 7537526093c92e89672d1e952a9baceecaa91730 Mon Sep 17 00:00:00 2001 From: Kirill Burtsev Date: Mon, 11 Feb 2019 19:21:03 +0100 Subject: Remove download properly on profile destruction to avoid use after free MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In the Widgets API, download items are children of the profile and are destroyed when the parent profile destroys its children. The download item's destructor can therefore not access the profile, as it would cause a heap-use-after-free crashes. On quick side turn ongoing downloads cleanup to match widgets one. Fixes: QTBUG-73839 Change-Id: Iabb379e91187e3e68ebcd4693fec35883b72b1f2 Reviewed-by: Michael Brüning Reviewed-by: Jüri Valdmann --- .../api/qwebenginedownloaditem.cpp | 4 +-- src/webenginewidgets/api/qwebengineprofile.cpp | 30 ++++++++++++++-------- src/webenginewidgets/api/qwebengineprofile_p.h | 2 ++ 3 files changed, 23 insertions(+), 13 deletions(-) (limited to 'src/webenginewidgets') diff --git a/src/webenginewidgets/api/qwebenginedownloaditem.cpp b/src/webenginewidgets/api/qwebenginedownloaditem.cpp index f0f0958a5..deb92bfd3 100644 --- a/src/webenginewidgets/api/qwebenginedownloaditem.cpp +++ b/src/webenginewidgets/api/qwebenginedownloaditem.cpp @@ -660,10 +660,10 @@ QWebEngineDownloadItem::QWebEngineDownloadItem(QWebEngineDownloadItemPrivate *p, */ QWebEngineDownloadItem::~QWebEngineDownloadItem() { + // MEMO Items are owned by profile by default and will be destroyed on profile's destruction + // It's not safe to access profile in that case, so we rely on profile to clean up items if (!isFinished()) cancel(); - if (auto profileAdapter = d_ptr->profile->profileAdapter()) - profileAdapter->removeDownload(d_ptr->downloadId); } QT_END_NAMESPACE diff --git a/src/webenginewidgets/api/qwebengineprofile.cpp b/src/webenginewidgets/api/qwebengineprofile.cpp index 03ce5e0bc..0d12fdae1 100644 --- a/src/webenginewidgets/api/qwebengineprofile.cpp +++ b/src/webenginewidgets/api/qwebengineprofile.cpp @@ -175,13 +175,6 @@ QWebEngineProfilePrivate::~QWebEngineProfilePrivate() m_profileAdapter->removeClient(this); } - for (QWebEngineDownloadItem *download : qAsConst(m_ongoingDownloads)) { - if (download) - download->cancel(); - } - - m_ongoingDownloads.clear(); - if (m_profileAdapter != QtWebEngineCore::ProfileAdapter::defaultProfileAdapter()) delete m_profileAdapter; @@ -196,6 +189,23 @@ ProfileAdapter* QWebEngineProfilePrivate::profileAdapter() const void QWebEngineProfilePrivate::downloadDestroyed(quint32 downloadId) { m_ongoingDownloads.remove(downloadId); + if (m_profileAdapter) + m_profileAdapter->removeDownload(downloadId); +} + +void QWebEngineProfilePrivate::cleanDownloads() +{ + for (auto download : m_ongoingDownloads.values()) { + if (!download) + continue; + + if (!download->isFinished()) + download->cancel(); + + if (m_profileAdapter) + m_profileAdapter->removeDownload(download->id()); + } + m_ongoingDownloads.clear(); } void QWebEngineProfilePrivate::downloadRequested(DownloadItemInfo &info) @@ -219,6 +229,7 @@ void QWebEngineProfilePrivate::downloadRequested(DownloadItemInfo &info) QWebEngineDownloadItem *download = new QWebEngineDownloadItem(itemPrivate, q); m_ongoingDownloads.insert(info.id, download); + QObject::connect(download, &QWebEngineDownloadItem::destroyed, q, [id = info.id, this] () { downloadDestroyed(id); }); Q_EMIT q->downloadRequested(download); @@ -232,7 +243,6 @@ void QWebEngineProfilePrivate::downloadRequested(DownloadItemInfo &info) if (state == QWebEngineDownloadItem::DownloadRequested) { // Delete unaccepted downloads. info.accepted = false; - m_ongoingDownloads.remove(info.id); delete download; } } @@ -250,9 +260,6 @@ void QWebEngineProfilePrivate::downloadUpdated(const DownloadItemInfo &info) } download->d_func()->update(info); - - if (download->isFinished()) - m_ongoingDownloads.remove(info.id); } /*! @@ -301,6 +308,7 @@ QWebEngineProfile::QWebEngineProfile(QWebEngineProfilePrivate *privatePtr, QObje */ QWebEngineProfile::~QWebEngineProfile() { + d_ptr->cleanDownloads(); } /*! diff --git a/src/webenginewidgets/api/qwebengineprofile_p.h b/src/webenginewidgets/api/qwebengineprofile_p.h index 9ff8df849..4a76f457f 100644 --- a/src/webenginewidgets/api/qwebengineprofile_p.h +++ b/src/webenginewidgets/api/qwebengineprofile_p.h @@ -81,6 +81,8 @@ public: void downloadDestroyed(quint32 downloadId); + void cleanDownloads(); + void downloadRequested(DownloadItemInfo &info) override; void downloadUpdated(const DownloadItemInfo &info) override; -- cgit v1.2.3 From fd2acd57df7d62490a9a7c1f7b5b60ae50c51ce6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=BCri=20Valdmann?= Date: Thu, 21 Feb 2019 13:23:41 +0100 Subject: Clarify documentation of QWebEnginePage::title() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Explain what happens when the HTML has no proper defined and clarify the meaning of 'by default': it refers to the state before load()/setUrl()/etc. Fixes: QTBUG-71799 Change-Id: Ib2669007573b3ea53e205d9228237bae392f6f78 Reviewed-by: Michael Brüning <michael.bruning@qt.io> Reviewed-by: Leena Miettinen <riitta-leena.miettinen@qt.io> --- src/webenginewidgets/doc/src/qwebenginepage_lgpl.qdoc | 6 ++++++ src/webenginewidgets/doc/src/qwebengineview_lgpl.qdoc | 4 ++-- 2 files changed, 8 insertions(+), 2 deletions(-) (limited to 'src/webenginewidgets') diff --git a/src/webenginewidgets/doc/src/qwebenginepage_lgpl.qdoc b/src/webenginewidgets/doc/src/qwebenginepage_lgpl.qdoc index 035b45a6d..ef1166601 100644 --- a/src/webenginewidgets/doc/src/qwebenginepage_lgpl.qdoc +++ b/src/webenginewidgets/doc/src/qwebenginepage_lgpl.qdoc @@ -643,6 +643,12 @@ \property QWebEnginePage::title \brief the title of the page as defined by the HTML \c <title> element + If the page has no \c <title> element, then the URL is used instead. For \c + file:// URLs only the filename is used and not the full path. + + By default, before any content has been loaded, this property contains an + empty string. + \sa titleChanged() */ diff --git a/src/webenginewidgets/doc/src/qwebengineview_lgpl.qdoc b/src/webenginewidgets/doc/src/qwebengineview_lgpl.qdoc index 501959ab9..1c51a2a52 100644 --- a/src/webenginewidgets/doc/src/qwebengineview_lgpl.qdoc +++ b/src/webenginewidgets/doc/src/qwebengineview_lgpl.qdoc @@ -173,9 +173,9 @@ /*! \property QWebEngineView::title - \brief the title of the web page currently viewed + \brief the title of the page as defined by the HTML \c <title> element - By default, this property contains an empty string. + Equivalent to \l {QWebEnginePage::title()}. \sa titleChanged() */ -- cgit v1.2.3 From 598bfc652edffb047948e01c3c76eb9e0cb7db4e Mon Sep 17 00:00:00 2001 From: Kai Koehne <kai.koehne@qt.io> Date: Thu, 21 Feb 2019 17:01:03 +0100 Subject: Doc: Always treat \brief as full sentence Make sure all \brief descriptions start with an upper-case letter and end with a . Also start descriptions of \class with the name of the class or struct. Change-Id: Ifd2656201f9c1dff092085508a5423ce516e2d3f Reviewed-by: Leena Miettinen <riitta-leena.miettinen@qt.io> --- src/webenginewidgets/api/qwebenginepage.cpp | 12 ++++++------ src/webenginewidgets/api/qwebengineview.cpp | 2 +- .../doc/src/qtwebenginewidgets-examples.qdoc | 2 +- src/webenginewidgets/doc/src/qwebenginepage_lgpl.qdoc | 14 +++++++------- src/webenginewidgets/doc/src/qwebengineview_lgpl.qdoc | 12 ++++++------ 5 files changed, 21 insertions(+), 21 deletions(-) (limited to 'src/webenginewidgets') diff --git a/src/webenginewidgets/api/qwebenginepage.cpp b/src/webenginewidgets/api/qwebenginepage.cpp index 67f3d7a76..aa1f7be7c 100644 --- a/src/webenginewidgets/api/qwebenginepage.cpp +++ b/src/webenginewidgets/api/qwebenginepage.cpp @@ -905,7 +905,7 @@ QWebEnginePage::QWebEnginePage(QObject* parent) \property QWebEnginePage::contentsSize \since 5.7 - The size of the page contents. + \brief The size of the page contents. */ /*! @@ -1054,7 +1054,7 @@ void QWebEnginePage::setWebChannel(QWebChannel *channel, uint worldId) /*! \property QWebEnginePage::backgroundColor - \brief the page's background color behind the document's body. + \brief The page's background color behind the document's body. \since 5.6 You can set the background color to Qt::transparent or to a translucent @@ -1105,7 +1105,7 @@ void QWebEnginePage::save(const QString &filePath, /*! \property QWebEnginePage::audioMuted - \brief whether the current page audio is muted. + \brief Whether the current page audio is muted. \since 5.7 The default value is \c false. @@ -1127,7 +1127,7 @@ void QWebEnginePage::setAudioMuted(bool muted) { /*! \property QWebEnginePage::recentlyAudible - \brief the current page's \e {audible state}, that is, whether audio was recently played + \brief The current page's \e {audible state}, that is, whether audio was recently played or not. \since 5.7 @@ -2046,7 +2046,7 @@ QUrl QWebEnginePage::requestedUrl() const /*! \property QWebEnginePage::iconUrl - \brief the URL of the icon associated with the page currently viewed + \brief The URL of the icon associated with the page currently viewed. By default, this property contains an empty URL. @@ -2060,7 +2060,7 @@ QUrl QWebEnginePage::iconUrl() const /*! \property QWebEnginePage::icon - \brief the icon associated with the page currently viewed + \brief The icon associated with the page currently viewed. \since 5.7 By default, this property contains a null icon. If the web page specifies more than one icon, diff --git a/src/webenginewidgets/api/qwebengineview.cpp b/src/webenginewidgets/api/qwebengineview.cpp index 576baad17..966b30100 100644 --- a/src/webenginewidgets/api/qwebengineview.cpp +++ b/src/webenginewidgets/api/qwebengineview.cpp @@ -238,7 +238,7 @@ QUrl QWebEngineView::iconUrl() const /*! \property QWebEngineView::icon - \brief the icon associated with the page currently viewed + \brief The icon associated with the page currently viewed. \since 5.7 By default, this property contains a null icon. diff --git a/src/webenginewidgets/doc/src/qtwebenginewidgets-examples.qdoc b/src/webenginewidgets/doc/src/qtwebenginewidgets-examples.qdoc index 8accdf062..b6c5cb497 100644 --- a/src/webenginewidgets/doc/src/qtwebenginewidgets-examples.qdoc +++ b/src/webenginewidgets/doc/src/qtwebenginewidgets-examples.qdoc @@ -28,7 +28,7 @@ /*! \group webengine-widgetexamples \title Qt WebEngine Widgets Examples - \brief Examples demonstrating the Qt WebEngine Widgets usage + \brief Examples demonstrating the Qt WebEngine Widgets usage. \ingroup all-examples Qt provides an integrated Web browser component based on Chromium, the popular diff --git a/src/webenginewidgets/doc/src/qwebenginepage_lgpl.qdoc b/src/webenginewidgets/doc/src/qwebenginepage_lgpl.qdoc index ef1166601..517fdc7d9 100644 --- a/src/webenginewidgets/doc/src/qwebenginepage_lgpl.qdoc +++ b/src/webenginewidgets/doc/src/qwebenginepage_lgpl.qdoc @@ -449,14 +449,14 @@ /*! \property QWebEnginePage::hasSelection - \brief whether this page contains selected content or not. + \brief Whether this page contains selected content or not. \sa selectionChanged() */ /*! \property QWebEnginePage::selectedText - \brief the text currently selected + \brief The text currently selected. By default, this property contains an empty string. @@ -641,7 +641,7 @@ /*! \property QWebEnginePage::title - \brief the title of the page as defined by the HTML \c <title> element + \brief The title of the page as defined by the HTML \c <title> element. If the page has no \c <title> element, then the URL is used instead. For \c file:// URLs only the filename is used and not the full path. @@ -654,7 +654,7 @@ /*! \property QWebEnginePage::url - \brief the URL of the page currently viewed + \brief The URL of the page currently viewed. Setting this property clears the view and loads the URL. @@ -665,8 +665,8 @@ /*! \property QWebEnginePage::requestedUrl - \brief the URL that was originally requested to be loaded by the page - that is currently viewed + \brief The URL that was originally requested to be loaded by the page + that is currently viewed. \note The URL may differ from the one returned by url(), which is the actual URL that results from DNS resolution or redirection. @@ -733,7 +733,7 @@ /*! \property QWebEnginePage::zoomFactor - \brief the zoom factor for the page content + \brief The zoom factor for the page content. Valid values are within the range from \c{0.25} to \c{5.0}. The default factor is \c{1.0}. */ diff --git a/src/webenginewidgets/doc/src/qwebengineview_lgpl.qdoc b/src/webenginewidgets/doc/src/qwebengineview_lgpl.qdoc index 1c51a2a52..568e7a63a 100644 --- a/src/webenginewidgets/doc/src/qwebengineview_lgpl.qdoc +++ b/src/webenginewidgets/doc/src/qwebengineview_lgpl.qdoc @@ -173,7 +173,7 @@ /*! \property QWebEngineView::title - \brief the title of the page as defined by the HTML \c <title> element + \brief The title of the page as defined by the HTML \c <title> element. Equivalent to \l {QWebEnginePage::title()}. @@ -182,7 +182,7 @@ /*! \property QWebEngineView::url - \brief the URL of the web page currently viewed + \brief The URL of the web page currently viewed. Setting this property clears the view and loads the URL. @@ -193,7 +193,7 @@ /*! \property QWebEngineView::iconUrl - \brief the URL of the icon associated with the page currently viewed + \brief The URL of the icon associated with the page currently viewed. By default, this property contains an empty URL. @@ -202,7 +202,7 @@ /*! \property QWebEngineView::hasSelection - \brief whether this page contains selected content or not. + \brief Whether this page contains selected content or not. By default, this property is \c false. @@ -211,7 +211,7 @@ /*! \property QWebEngineView::selectedText - \brief the text currently selected + \brief The text currently selected. By default, this property contains an empty string. @@ -238,7 +238,7 @@ /*! \property QWebEngineView::zoomFactor - \brief the zoom factor for the view + \brief The zoom factor for the view. Valid values are within the range from \c{0.25} to \c{5.0}. The default factor is \c{1.0}. */ -- cgit v1.2.3 From 56fadb571f32b721d8b99554e6e38692009ec37f Mon Sep 17 00:00:00 2001 From: Michal Klocek <michal.klocek@qt.io> Date: Thu, 28 Feb 2019 10:49:22 +0100 Subject: Force destruction of webcontent client before profile adapter Currently users might forget to delete webcontent client before profile adapter. This might be nasty if users are not aware of default profile. Instead of asserting badly in chromium, clean up and release chromium resources. This avoids the crash, but might leak memory if users never deletes page. Task-number: QTBUG-74021 Change-Id: I66f466f169d12f7ee08866d505260dca47800bb0 Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io> --- src/webenginewidgets/api/qwebenginepage.cpp | 22 +++++++++++++++++----- src/webenginewidgets/api/qwebenginepage_p.h | 1 + src/webenginewidgets/api/qwebengineprofile.cpp | 12 ++++++++++++ src/webenginewidgets/api/qwebengineprofile_p.h | 3 +++ 4 files changed, 33 insertions(+), 5 deletions(-) (limited to 'src/webenginewidgets') diff --git a/src/webenginewidgets/api/qwebenginepage.cpp b/src/webenginewidgets/api/qwebenginepage.cpp index aa1f7be7c..fae34ae8d 100644 --- a/src/webenginewidgets/api/qwebenginepage.cpp +++ b/src/webenginewidgets/api/qwebenginepage.cpp @@ -256,12 +256,15 @@ QWebEnginePagePrivate::QWebEnginePagePrivate(QWebEngineProfile *_profile) ensureInitialized(); wasShown(); }); + + profile->d_ptr->addWebContentsAdapterClient(this); } QWebEnginePagePrivate::~QWebEnginePagePrivate() { delete history; delete settings; + profile->d_ptr->removeWebContentsAdapterClient(this); } RenderWidgetHostViewQtDelegate *QWebEnginePagePrivate::CreateRenderWidgetHostViewQtDelegate(RenderWidgetHostViewQtDelegateClient *client) @@ -545,6 +548,13 @@ void QWebEnginePagePrivate::authenticationRequired(QSharedPointer<Authentication controller->accept(networkAuth.user(), networkAuth.password()); } +void QWebEnginePagePrivate::releaseProfile() +{ + qDebug("Release of profile requested but WebEnginePage still not deleted. Expect troubles !"); + // this is not the way to go, but might avoid the crash if user code does not make any calls to page. + delete q_ptr->d_ptr.take(); +} + void QWebEnginePagePrivate::showColorDialog(QSharedPointer<ColorChooserController> controller) { #if QT_CONFIG(colordialog) @@ -967,11 +977,13 @@ QWebEnginePage::QWebEnginePage(QWebEngineProfile *profile, QObject* parent) QWebEnginePage::~QWebEnginePage() { - Q_D(QWebEnginePage); - setDevToolsPage(nullptr); - d->adapter->stopFinding(); - QWebEnginePagePrivate::bindPageAndView(this, nullptr); - QWebEnginePagePrivate::bindPageAndWidget(this, nullptr); + if (d_ptr) { + // d_ptr might be exceptionally null if profile adapter got deleted first + setDevToolsPage(nullptr); + d_ptr->adapter->stopFinding(); + QWebEnginePagePrivate::bindPageAndView(this, nullptr); + QWebEnginePagePrivate::bindPageAndWidget(this, nullptr); + } } QWebEngineHistory *QWebEnginePage::history() const diff --git a/src/webenginewidgets/api/qwebenginepage_p.h b/src/webenginewidgets/api/qwebenginepage_p.h index eecbf0b65..a50a1972a 100644 --- a/src/webenginewidgets/api/qwebenginepage_p.h +++ b/src/webenginewidgets/api/qwebenginepage_p.h @@ -129,6 +129,7 @@ public: void passOnFocus(bool reverse) override; void javaScriptConsoleMessage(JavaScriptConsoleMessageLevel level, const QString& message, int lineNumber, const QString& sourceID) override; void authenticationRequired(QSharedPointer<QtWebEngineCore::AuthenticationDialogController>) override; + void releaseProfile() override; void runMediaAccessPermissionRequest(const QUrl &securityOrigin, MediaRequestFlags requestFlags) override; void runGeolocationPermissionRequest(const QUrl &securityOrigin) override; void runMouseLockPermissionRequest(const QUrl &securityOrigin) override; diff --git a/src/webenginewidgets/api/qwebengineprofile.cpp b/src/webenginewidgets/api/qwebengineprofile.cpp index 0d12fdae1..929c2aaa1 100644 --- a/src/webenginewidgets/api/qwebengineprofile.cpp +++ b/src/webenginewidgets/api/qwebengineprofile.cpp @@ -262,6 +262,18 @@ void QWebEngineProfilePrivate::downloadUpdated(const DownloadItemInfo &info) download->d_func()->update(info); } +void QWebEngineProfilePrivate::addWebContentsAdapterClient(QtWebEngineCore::WebContentsAdapterClient *adapter) +{ + Q_ASSERT(m_profileAdapter); + m_profileAdapter->addWebContentsAdapterClient(adapter); +} + +void QWebEngineProfilePrivate::removeWebContentsAdapterClient(QtWebEngineCore::WebContentsAdapterClient *adapter) +{ + Q_ASSERT(m_profileAdapter); + m_profileAdapter->removeWebContentsAdapterClient(adapter); +} + /*! Constructs a new off-the-record profile with the parent \a parent. diff --git a/src/webenginewidgets/api/qwebengineprofile_p.h b/src/webenginewidgets/api/qwebengineprofile_p.h index 4a76f457f..cb43dace5 100644 --- a/src/webenginewidgets/api/qwebengineprofile_p.h +++ b/src/webenginewidgets/api/qwebengineprofile_p.h @@ -86,6 +86,9 @@ public: void downloadRequested(DownloadItemInfo &info) override; void downloadUpdated(const DownloadItemInfo &info) override; + void addWebContentsAdapterClient(QtWebEngineCore::WebContentsAdapterClient *adapter) override; + void removeWebContentsAdapterClient(QtWebEngineCore::WebContentsAdapterClient *adapter) override; + private: QWebEngineProfile *q_ptr; QWebEngineSettings *m_settings; -- cgit v1.2.3