summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPeter Varga <pvarga@inf.u-szeged.hu>2016-04-12 17:35:19 +0200
committerPeter Varga <pvarga@inf.u-szeged.hu>2016-05-04 12:27:20 +0000
commit240efee49a8e4402f2048a05c596605b2feadbd3 (patch)
tree8df93a1a1732bafe78192f70cfdb54bde8b1b3b5 /src
parent0bf8a13a4d0391339bae686e199fb922b64a1dcc (diff)
Combine candidate icons for a page into a single icon
For the Widget API the QIcon returned by QWebEnginePage::icon() function contains all the candidate icons for the current page. For the Quick API the QQuickWebEngineFaviconProvider provides the best quality icon for the requested size from the candidates. Task-number: QTBUG-51179 Change-Id: I42b8427f957e2f2fc745dd0111bedcc71b577216 Reviewed-by: Allan Sandfeld Jensen <allan.jensen@theqtcompany.com>
Diffstat (limited to 'src')
-rw-r--r--src/core/favicon_manager.cpp109
-rw-r--r--src/core/favicon_manager.h9
-rw-r--r--src/core/favicon_manager_p.h2
-rw-r--r--src/webengine/api/qquickwebenginefaviconprovider.cpp7
-rw-r--r--src/webengine/doc/src/webengineview.qdoc7
-rw-r--r--src/webenginewidgets/api/qwebenginepage.cpp8
6 files changed, 104 insertions, 38 deletions
diff --git a/src/core/favicon_manager.cpp b/src/core/favicon_manager.cpp
index 5568e6eb5..be8d17725 100644
--- a/src/core/favicon_manager.cpp
+++ b/src/core/favicon_manager.cpp
@@ -52,9 +52,6 @@
#include "third_party/skia/include/core/SkPixelRef.h"
#include "ui/gfx/geometry/size.h"
-#include <QtCore/QUrl>
-#include <QtGui/QIcon>
-
namespace QtWebEngineCore {
static inline bool isResourceUrl(const QUrl &url)
@@ -139,6 +136,11 @@ void FaviconManagerPrivate::downloadPendingRequests()
void FaviconManagerPrivate::storeIcon(int id, const QIcon &icon)
{
Q_Q(FaviconManager);
+
+ // Icon download has been interrupted
+ if (m_inProgressRequests.isEmpty())
+ return;
+
Q_ASSERT(m_inProgressRequests.contains(id));
QUrl requestUrl = m_inProgressRequests[id];
@@ -169,31 +171,18 @@ void FaviconManagerPrivate::storeIcon(int id, const QIcon &icon)
}
m_inProgressRequests.remove(id);
- if (m_inProgressRequests.isEmpty())
- propagateIcon();
-}
-
-void FaviconManagerPrivate::propagateIcon() const
-{
- Q_Q(const FaviconManager);
+ if (m_inProgressRequests.isEmpty()) {
+ WebEngineSettings *settings = m_viewClient->webEngineSettings();
+ bool touchIconsEnabled = settings->testAttribute(WebEngineSettings::TouchIconsEnabled);
- WebEngineSettings *settings = m_viewClient->webEngineSettings();
- bool touchIconsEnabled = settings->testAttribute(WebEngineSettings::TouchIconsEnabled);
-
- QUrl iconUrl;
- const QList<FaviconInfo> &faviconInfoList = q->getFaviconInfoList(true /* candidates only */);
-
- unsigned bestArea = 0;
- for (auto it = faviconInfoList.cbegin(), end = faviconInfoList.cend(); it != end; ++it) {
- if (!touchIconsEnabled && it->type != FaviconInfo::Favicon)
- continue;
-
- if (it->isValid() && bestArea < area(it->size)) {
- iconUrl = it->url;
- bestArea = area(it->size);
- }
+ q->generateCandidateIcon(touchIconsEnabled);
+ const QUrl &iconUrl = q->candidateIconUrl(touchIconsEnabled);
+ propagateIcon(iconUrl);
}
+}
+void FaviconManagerPrivate::propagateIcon(const QUrl &iconUrl) const
+{
content::NavigationEntry *entry = m_webContents->GetController().GetVisibleEntry();
if (entry) {
content::FaviconStatus &favicon = entry->GetFavicon();
@@ -205,7 +194,7 @@ void FaviconManagerPrivate::propagateIcon() const
}
FaviconManager::FaviconManager(FaviconManagerPrivate *d)
- : m_hasCandidate(false)
+ : m_candidateCount(0)
{
Q_ASSERT(d);
d_ptr.reset(d);
@@ -220,6 +209,10 @@ FaviconManager::~FaviconManager()
QIcon FaviconManager::getIcon(const QUrl &url) const
{
Q_D(const FaviconManager);
+
+ if (url.isEmpty())
+ return m_candidateIcon;
+
if (!d->m_icons.contains(url))
return QIcon();
@@ -281,7 +274,7 @@ void FaviconManager::update(const QList<FaviconInfo> &candidates)
void FaviconManager::updateCandidates(const QList<FaviconInfo> &candidates)
{
- m_hasCandidate = candidates.count();
+ m_candidateCount = candidates.count();
for (FaviconInfo candidateFaviconInfo : candidates) {
const QUrl &candidateUrl = candidateFaviconInfo.url;
@@ -298,14 +291,71 @@ void FaviconManager::updateCandidates(const QList<FaviconInfo> &candidates)
void FaviconManager::resetCandidates()
{
- m_hasCandidate = false;
+ Q_D(FaviconManager);
+
+ // Interrupt in progress icon downloads
+ d->m_pendingRequests.clear();
+ d->m_inProgressRequests.clear();
+
+ m_candidateCount = 0;
+ m_candidateIcon = QIcon();
for (auto it = m_faviconInfoMap.begin(), end = m_faviconInfoMap.end(); it != end; ++it)
it->candidate = false;
}
bool FaviconManager::hasCandidate() const
{
- return m_hasCandidate;
+ return (m_candidateCount > 0);
+}
+
+QUrl FaviconManager::candidateIconUrl(bool touchIconsEnabled) const
+{
+ QUrl iconUrl;
+ const QList<FaviconInfo> &faviconInfoList = getFaviconInfoList(true /* candidates only */);
+
+ unsigned bestArea = 0;
+ for (auto it = faviconInfoList.cbegin(), end = faviconInfoList.cend(); it != end; ++it) {
+ if (!touchIconsEnabled && it->type != FaviconInfo::Favicon)
+ continue;
+
+ if (it->isValid() && bestArea < area(it->size)) {
+ iconUrl = it->url;
+ bestArea = area(it->size);
+ }
+ }
+
+ return iconUrl;
+}
+
+void FaviconManager::generateCandidateIcon(bool touchIconsEnabled)
+{
+ Q_ASSERT(m_candidateCount);
+
+ m_candidateIcon = QIcon();
+ const QList<FaviconInfo> &faviconInfoList = getFaviconInfoList(true /* candidates only */);
+
+ for (auto it = faviconInfoList.cbegin(), end = faviconInfoList.cend(); it != end; ++it) {
+ if (!touchIconsEnabled && it->type != FaviconInfo::Favicon)
+ continue;
+
+ if (!it->isValid() || !it->isDownloaded())
+ continue;
+
+ const QIcon &icon = getIcon(it->url);
+
+ if (!it->multiSize) {
+ if (!m_candidateIcon.availableSizes().contains(it->size))
+ m_candidateIcon.addPixmap(icon.pixmap(it->size));
+
+ continue;
+ }
+
+ const auto sizes = icon.availableSizes();
+ for (const QSize &size : sizes) {
+ if (!m_candidateIcon.availableSizes().contains(size))
+ m_candidateIcon.addPixmap(icon.pixmap(size));
+ }
+ }
}
@@ -323,6 +373,7 @@ FaviconInfo::FaviconInfo(const FaviconInfo &other)
, type(other.type)
, size(other.size)
, candidate(other.candidate)
+ , multiSize(other.multiSize)
{
}
diff --git a/src/core/favicon_manager.h b/src/core/favicon_manager.h
index dc702a0da..e351831c2 100644
--- a/src/core/favicon_manager.h
+++ b/src/core/favicon_manager.h
@@ -46,6 +46,7 @@
#include <QtCore/QObject>
#include <QtCore/QSize>
#include <QtCore/QUrl>
+#include <QtGui/QIcon>
#include "web_engine_settings.h"
@@ -85,7 +86,7 @@ class QWEBENGINE_EXPORT FaviconManager : public QObject {
public:
~FaviconManager();
- QIcon getIcon(const QUrl &) const;
+ QIcon getIcon(const QUrl &url = QUrl()) const;
FaviconInfo getFaviconInfo(const QUrl &) const;
QList<FaviconInfo> getFaviconInfoList(bool) const;
@@ -97,8 +98,12 @@ private:
void resetCandidates();
bool hasCandidate() const;
+ QUrl candidateIconUrl(bool touchIconsEnabled) const;
+ void generateCandidateIcon(bool touchIconsEnabled);
+
QMap<QUrl, FaviconInfo> m_faviconInfoMap;
- bool m_hasCandidate;
+ int m_candidateCount;
+ QIcon m_candidateIcon;
Q_DISABLE_COPY(FaviconManager)
Q_DECLARE_PRIVATE(FaviconManager)
diff --git a/src/core/favicon_manager_p.h b/src/core/favicon_manager_p.h
index 80a012474..e2a49dbc7 100644
--- a/src/core/favicon_manager_p.h
+++ b/src/core/favicon_manager_p.h
@@ -87,7 +87,7 @@ public:
void iconDownloadFinished(int, int, const GURL &, const std::vector<SkBitmap> &, const std::vector<gfx::Size> &);
void storeIcon(int, const QIcon &);
void downloadPendingRequests();
- void propagateIcon() const;
+ void propagateIcon(const QUrl &) const;
content::WebContents *m_webContents;
WebContentsAdapterClient *m_viewClient;
diff --git a/src/webengine/api/qquickwebenginefaviconprovider.cpp b/src/webengine/api/qquickwebenginefaviconprovider.cpp
index c41ec5a07..fe8436d6c 100644
--- a/src/webengine/api/qquickwebenginefaviconprovider.cpp
+++ b/src/webengine/api/qquickwebenginefaviconprovider.cpp
@@ -121,12 +121,13 @@ QPixmap QQuickWebEngineFaviconProvider::requestPixmap(const QString &id, QSize *
return QPixmap();
FaviconManager *faviconManager = view->d_ptr->adapter->faviconManager();
- Q_ASSERT(faviconManager);
- const QIcon &icon = faviconManager->getIcon(iconUrl);
+ 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 = faviconManager->getFaviconInfo(iconUrl).size;
+ const QSize &bestSize = faviconInfo.size;
// If source size is not specified, use the best quality
if (!requestedSize.isValid()) {
diff --git a/src/webengine/doc/src/webengineview.qdoc b/src/webengine/doc/src/webengineview.qdoc
index a070140c7..7c7a2283a 100644
--- a/src/webengine/doc/src/webengineview.qdoc
+++ b/src/webengine/doc/src/webengineview.qdoc
@@ -215,10 +215,17 @@
\qml
Image {
id: appIcon
+ sourceSize: Qt.size(32, 32)
source: webView.icon != "" ? webView.icon : "fallbackFavicon.png";
// ...
}
\endqml
+
+ Specifying the \c{sourceSize} property of the \c{Image} element informs
+ the Qt WebEngine's favicon provider about the requested size. The
+ favicon provider tries to find the best fit among the web page candidate
+ icons. If \c{sourceSize} property is not specified, the provider provides
+ the icon with the largest resolution.
*/
/*!
diff --git a/src/webenginewidgets/api/qwebenginepage.cpp b/src/webenginewidgets/api/qwebenginepage.cpp
index 447c53ba9..e41271471 100644
--- a/src/webenginewidgets/api/qwebenginepage.cpp
+++ b/src/webenginewidgets/api/qwebenginepage.cpp
@@ -151,7 +151,7 @@ void QWebEnginePagePrivate::iconChanged(const QUrl &url)
return;
iconUrl = url;
Q_EMIT q->iconUrlChanged(iconUrl);
- Q_EMIT q->iconChanged(adapter->faviconManager()->getIcon(iconUrl));
+ Q_EMIT q->iconChanged(adapter->faviconManager()->getIcon());
}
void QWebEnginePagePrivate::loadProgressChanged(int progress)
@@ -1506,7 +1506,9 @@ QUrl QWebEnginePage::iconUrl() const
\brief the icon associated with the page currently viewed
\since 5.7
- By default, this property contains a null icon.
+ By default, this property contains a null icon. If the web page specifies more than one icon,
+ the \c{icon} property encapsulates the available candidate icons in a single,
+ scalable \c{QIcon}.
\sa iconChanged(), iconUrl(), iconUrlChanged()
*/
@@ -1517,7 +1519,7 @@ QIcon QWebEnginePage::icon() const
if (d->iconUrl.isEmpty())
return QIcon();
- return d->adapter->faviconManager()->getIcon(d->iconUrl);
+ return d->adapter->faviconManager()->getIcon();
}
qreal QWebEnginePage::zoomFactor() const