diff options
author | Peter Varga <pvarga@inf.u-szeged.hu> | 2020-06-19 11:17:50 +0200 |
---|---|---|
committer | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2021-06-04 18:41:41 +0200 |
commit | 881339e9d9054c46f2621119246de7a13c83761a (patch) | |
tree | 77db7d7188c4ac61cab939c2ccd7a9610d4a01f4 /src/webenginequick | |
parent | 4d67b9f639114ddec0521980495ba27921800e39 (diff) |
Replace FaviconManager with Chromium's Favicon Component
Task-number: QTBUG-51184
Change-Id: Ie050cb23f2c86841a66ec384bfbcdf0713cffa7c
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
Diffstat (limited to 'src/webenginequick')
5 files changed, 88 insertions, 149 deletions
diff --git a/src/webenginequick/api/qquickwebenginefaviconprovider.cpp b/src/webenginequick/api/qquickwebenginefaviconprovider.cpp index f817e4016..23397003e 100644 --- a/src/webenginequick/api/qquickwebenginefaviconprovider.cpp +++ b/src/webenginequick/api/qquickwebenginefaviconprovider.cpp @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2016 The Qt Company Ltd. +** Copyright (C) 2021 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QtWebEngine module of the Qt Toolkit. @@ -39,7 +39,6 @@ #include "qquickwebenginefaviconprovider_p_p.h" -#include "favicon_manager.h" #include "qquickwebengineview_p.h" #include "qquickwebengineview_p_p.h" #include "web_contents_adapter.h" @@ -47,21 +46,65 @@ #include <QtGui/QIcon> #include <QtGui/QPixmap> -#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) -#include <QtGui/qiconengine.h> -#include <QtGui/private/qicon_p.h> -#endif - QT_BEGIN_NAMESPACE -using QtWebEngineCore::FaviconInfo; -using QtWebEngineCore::FaviconManager; - static inline unsigned area(const QSize &size) { return size.width() * size.height(); } +static QSize largestSize(const QList<QSize> &availableSizes) +{ + QSize result; + for (const QSize &size : availableSizes) { + if (area(size) > area(result)) + result = size; + } + + return result; +} + +static QSize fitSize(const QList<QSize> &availableSizes, const QSize &requestedSize) +{ + Q_ASSERT(availableSizes.count()); + QSize result = largestSize(availableSizes); + if (availableSizes.count() == 1 || area(requestedSize) >= area(result)) + return result; + + for (const QSize &size : availableSizes) { + if (area(size) == area(requestedSize)) + return size; + + if (area(requestedSize) < area(size) && area(size) < area(result)) + result = size; + } + + return result; +} + +static QPixmap extractPixmap(const QIcon &icon, const QSize &requestedSize) +{ + Q_ASSERT(!icon.isNull()); + + // If source size is not specified, use the largest icon + if (!requestedSize.isValid()) + return icon.pixmap(largestSize(icon.availableSizes()), 1.0).copy(); + + const QSize &size = fitSize(icon.availableSizes(), requestedSize); + const QPixmap &iconPixmap = icon.pixmap(size, 1.0); + return iconPixmap.scaled(requestedSize, Qt::KeepAspectRatio, Qt::SmoothTransformation).copy(); +} + +static QQuickWebEngineView *findViewById(const QString &id, QList<QQuickWebEngineView *> *views) +{ + for (QQuickWebEngineView *view : *views) { + if (view->icon() == QQuickWebEngineFaviconProvider::faviconProviderUrl(QUrl(id))) + return view; + } + + return nullptr; +} + QString QQuickWebEngineFaviconProvider::identifier() { return QStringLiteral("favicon"); @@ -75,7 +118,8 @@ QUrl QQuickWebEngineFaviconProvider::faviconProviderUrl(const QUrl &url) QUrl providerUrl; providerUrl.setScheme(QStringLiteral("image")); providerUrl.setHost(identifier()); - providerUrl.setPath(QStringLiteral("/%1").arg(url.toString(QUrl::RemoveQuery | QUrl::RemoveFragment))); + providerUrl.setPath( + QStringLiteral("/%1").arg(url.toString(QUrl::RemoveQuery | QUrl::RemoveFragment))); if (url.hasQuery()) providerUrl.setQuery(url.query(QUrl::FullyDecoded)); if (url.hasFragment()) @@ -86,125 +130,29 @@ QUrl QQuickWebEngineFaviconProvider::faviconProviderUrl(const QUrl &url) QQuickWebEngineFaviconProvider::QQuickWebEngineFaviconProvider() : QQuickImageProvider(QQuickImageProvider::Pixmap) - , m_latestView(0) { } -QQuickWebEngineFaviconProvider::~QQuickWebEngineFaviconProvider() -{ - qDeleteAll(m_iconUrlMap); -} +QQuickWebEngineFaviconProvider::~QQuickWebEngineFaviconProvider() { } -QUrl QQuickWebEngineFaviconProvider::attach(QQuickWebEngineView *view, const QUrl &iconUrl) -{ - if (iconUrl.isEmpty()) - return QUrl(); - - m_latestView = view; - - if (!m_iconUrlMap.contains(view)) - m_iconUrlMap.insert(view, new QList<QUrl>()); - - QList<QUrl> *iconUrls = m_iconUrlMap[view]; - if (!iconUrls->contains(iconUrl)) - iconUrls->append(iconUrl); - - return faviconProviderUrl(iconUrl); -} - -void QQuickWebEngineFaviconProvider::detach(QQuickWebEngineView *view) -{ - QList<QUrl> *iconUrls = m_iconUrlMap.take(view); - delete iconUrls; -} - -#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) -static QPixmap getUnscaledPixmap(QIcon icon, const QSize &size) -{ - QPixmap pixmap = icon.data_ptr()->engine->pixmap(size, QIcon::Normal, QIcon::Off); - pixmap.setDevicePixelRatio(1.0); - return pixmap; -} -#else -static QPixmap getUnscaledPixmap(const QIcon &icon, const QSize &size) -{ - return icon.pixmap(size, 1.0); -} -#endif - -QPixmap QQuickWebEngineFaviconProvider::requestPixmap(const QString &id, QSize *size, const QSize &requestedSize) +QPixmap QQuickWebEngineFaviconProvider::requestPixmap(const QString &id, QSize *size, + const QSize &requestedSize) { Q_UNUSED(size); Q_UNUSED(requestedSize); - QUrl iconUrl(id); - QQuickWebEngineView *view = viewForIconUrl(iconUrl); - - if (!view || iconUrl.isEmpty()) + if (m_views.isEmpty()) return QPixmap(); - FaviconManager *faviconManager = view->d_ptr->adapter->faviconManager(); - - Q_ASSERT(faviconManager); - const FaviconInfo &faviconInfo = faviconManager->getFaviconInfo(iconUrl); - const QIcon &icon = faviconManager->getIcon(faviconInfo.candidate ? QUrl() : iconUrl); - - Q_ASSERT(!icon.isNull()); - const QSize &bestSize = faviconInfo.size; - - // If source size is not specified, use the best quality - if (!requestedSize.isValid()) { - if (size) - *size = bestSize; - - return getUnscaledPixmap(icon, bestSize).copy(); - } - - const QSize &fitSize = findFitSize(icon.availableSizes(), requestedSize, bestSize); - const QPixmap &iconPixmap = getUnscaledPixmap(icon, fitSize); - - if (size) - *size = iconPixmap.size(); - - return iconPixmap.scaled(requestedSize, Qt::KeepAspectRatio, Qt::SmoothTransformation).copy(); -} - -QQuickWebEngineView *QQuickWebEngineFaviconProvider::viewForIconUrl(const QUrl &iconUrl) const -{ - // The most common use case is that the requested iconUrl belongs to the - // latest WebEngineView which was raised an iconChanged signal. - if (m_latestView) { - QList<QUrl> *iconUrls = m_iconUrlMap[m_latestView]; - if (iconUrls && iconUrls->contains(iconUrl)) - return m_latestView; - } - - for (auto it = m_iconUrlMap.cbegin(), end = m_iconUrlMap.cend(); it != end; ++it) { - if (it.value()->contains(iconUrl)) - return it.key(); - } - - return 0; -} - -QSize QQuickWebEngineFaviconProvider::findFitSize(const QList<QSize> &availableSizes, - const QSize &requestedSize, - const QSize &bestSize) const -{ - Q_ASSERT(availableSizes.count()); - if (availableSizes.count() == 1 || area(requestedSize) >= area(bestSize)) - return bestSize; - - QSize fitSize = bestSize; - for (const QSize &size : availableSizes) { - if (area(size) == area(requestedSize)) - return size; + QQuickWebEngineView *view = findViewById(id, &m_views); + if (!view) + return QPixmap(); - if (area(requestedSize) < area(size) && area(size) < area(fitSize)) - fitSize = size; - } + QIcon icon = view->d_ptr->adapter->icon(); + if (icon.isNull()) + return QPixmap(); - return fitSize; + return extractPixmap(icon, requestedSize).copy(); } QT_END_NAMESPACE diff --git a/src/webenginequick/api/qquickwebenginefaviconprovider_p_p.h b/src/webenginequick/api/qquickwebenginefaviconprovider_p_p.h index 80d2f65f2..d284a73d5 100644 --- a/src/webenginequick/api/qquickwebenginefaviconprovider_p_p.h +++ b/src/webenginequick/api/qquickwebenginefaviconprovider_p_p.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2016 The Qt Company Ltd. +** Copyright (C) 2021 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QtWebEngine module of the Qt Toolkit. @@ -52,15 +52,15 @@ // #include <QtWebEngineQuick/private/qtwebengineglobal_p.h> +#include <QtCore/QList> #include <QtQuick/QQuickImageProvider> -#include <QtCore/QMap> - QT_BEGIN_NAMESPACE class QQuickWebEngineView; -class Q_WEBENGINE_PRIVATE_EXPORT QQuickWebEngineFaviconProvider : public QQuickImageProvider { +class Q_WEBENGINE_PRIVATE_EXPORT QQuickWebEngineFaviconProvider : public QQuickImageProvider +{ public: static QString identifier(); static QUrl faviconProviderUrl(const QUrl &); @@ -68,18 +68,13 @@ public: QQuickWebEngineFaviconProvider(); ~QQuickWebEngineFaviconProvider(); - QUrl attach(QQuickWebEngineView *, const QUrl &); - void detach(QQuickWebEngineView *); - + void attach(QQuickWebEngineView *view) { m_views.append(view); } + void detach(QQuickWebEngineView *view) { m_views.removeAll(view); } QPixmap requestPixmap(const QString &, QSize *, const QSize &) override; private: - QQuickWebEngineView *viewForIconUrl(const QUrl &) const; - QSize findFitSize(const QList<QSize> &, const QSize &, const QSize &) const; - - QMap<QQuickWebEngineView *, QList<QUrl> *> m_iconUrlMap; - QQuickWebEngineView *m_latestView; + QList<QQuickWebEngineView *> m_views; }; QT_END_NAMESPACE diff --git a/src/webenginequick/api/qquickwebengineview.cpp b/src/webenginequick/api/qquickwebengineview.cpp index 5524b8954..2e6a2f428 100644 --- a/src/webenginequick/api/qquickwebengineview.cpp +++ b/src/webenginequick/api/qquickwebengineview.cpp @@ -132,7 +132,6 @@ QQuickWebEngineViewPrivate::QQuickWebEngineViewPrivate() , m_testSupport(0) #endif , contextMenuExtraItems(0) - , faviconProvider(0) , loadProgress(0) , m_fullscreenMode(false) , isLoading(false) @@ -179,8 +178,8 @@ QQuickWebEngineViewPrivate::~QQuickWebEngineViewPrivate() { Q_ASSERT(m_profileInitialized); m_profile->d_ptr->removeWebContentsAdapterClient(this); - if (faviconProvider) - faviconProvider->detach(q_ptr); + if (m_faviconProvider) + m_faviconProvider->detach(q_ptr); // q_ptr->d_ptr might be null due to destroy() if (q_ptr->d_ptr) bindViewAndWidget(q_ptr, nullptr); @@ -408,20 +407,7 @@ void QQuickWebEngineViewPrivate::iconChanged(const QUrl &url) if (iconUrl == QQuickWebEngineFaviconProvider::faviconProviderUrl(url)) return; - if (!faviconProvider) { - QQmlEngine *engine = qmlEngine(q); - - // TODO: this is a workaround for QTBUG-65044 - if (!engine) - return; - - Q_ASSERT(engine); - faviconProvider = static_cast<QQuickWebEngineFaviconProvider *>( - engine->imageProvider(QQuickWebEngineFaviconProvider::identifier())); - Q_ASSERT(faviconProvider); - } - - iconUrl = faviconProvider->attach(q, url); + iconUrl = QQuickWebEngineFaviconProvider::faviconProviderUrl(url); m_history->reset(); QTimer::singleShot(0, q, &QQuickWebEngineView::iconChanged); } @@ -904,6 +890,17 @@ void QQuickWebEngineViewPrivate::ensureContentsAdapter() else adapter->loadDefault(); } + + if (!m_faviconProvider) { + QQmlEngine *engine = qmlEngine(q_ptr); + // TODO: this is a workaround for QTBUG-65044 + if (!engine) + return; + m_faviconProvider = static_cast<QQuickWebEngineFaviconProvider *>( + engine->imageProvider(QQuickWebEngineFaviconProvider::identifier())); + m_faviconProvider->attach(q_ptr); + Q_ASSERT(m_faviconProvider); + } } void QQuickWebEngineViewPrivate::initializationFinished() diff --git a/src/webenginequick/api/qquickwebengineview_p.h b/src/webenginequick/api/qquickwebengineview_p.h index ca3b5349e..5b8231cbf 100644 --- a/src/webenginequick/api/qquickwebengineview_p.h +++ b/src/webenginequick/api/qquickwebengineview_p.h @@ -70,7 +70,6 @@ class QQuickWebEngineAction; class QQuickWebEngineAuthenticationDialogRequest; class QQuickWebEngineClientCertificateSelection; class QQuickWebEngineColorDialogRequest; -class QQuickWebEngineFaviconProvider; class QQuickWebEngineFileDialogRequest; class QQuickWebEngineHistory; class QQuickWebEngineJavaScriptDialogRequest; diff --git a/src/webenginequick/api/qquickwebengineview_p_p.h b/src/webenginequick/api/qquickwebengineview_p_p.h index 115c13e06..1b50de26a 100644 --- a/src/webenginequick/api/qquickwebengineview_p_p.h +++ b/src/webenginequick/api/qquickwebengineview_p_p.h @@ -196,7 +196,6 @@ public: QUrl m_url; QString m_html; QUrl iconUrl; - QQuickWebEngineFaviconProvider *faviconProvider; int loadProgress; bool m_fullscreenMode; bool isLoading; @@ -230,6 +229,7 @@ private: QWebEngineContextMenuRequest *m_contextMenuRequest; LoadVisuallyCommittedState m_loadVisuallyCommittedState = NotCommitted; QScopedPointer<QQuickWebEngineScriptCollection> m_scriptCollection; + QQuickWebEngineFaviconProvider *m_faviconProvider = nullptr; }; #ifndef QT_NO_ACCESSIBILITY |