From ef6cb53a1d49de616067126c8f49d2406c9a7f43 Mon Sep 17 00:00:00 2001 From: Arvid Nilsson <anilsson@blackberry.com> Date: Thu, 3 Oct 2013 12:33:54 +0200 Subject: [PATCH] Quick: Add Favicon API Adds a favicon API modelled after the WebKit2 QQuickWebView API, but using an http(s) URL instead of a custom protocol, because there's no icondatabase yet. The icon URL lingers even when a new load is committed, until the load finishes. It might be more prudent to clear the icon when committing a new load, but I opted to let the app take care of that detail if desired. Many browsers show a spinner instead of the favicon while loading, for example. There's no widget API implementation for favicons yet, because that API only makes sense if we have a full-fledged icon database (case in point: QWebEngineSettings::iconForUrl()). Change-Id: I1e7b85104c80de2ae46a5fe9a273104d43a5c71f Reviewed-by: Andras Becsi <andras.becsi@digia.com> --- examples/quick/quicknanobrowser/quickwindow.qml | 5 +++++ lib/quick/qquickwebengineview.cpp | 13 +++++++++++++ lib/quick/qquickwebengineview_p.h | 3 +++ lib/quick/qquickwebengineview_p_p.h | 2 ++ lib/web_contents_adapter_client.h | 1 + lib/web_contents_delegate_qt.cpp | 12 ++++++++++++ lib/web_contents_delegate_qt.h | 1 + lib/widgets/Api/qwebenginepage.cpp | 5 +++++ lib/widgets/Api/qwebenginepage_p.h | 1 + 9 files changed, 43 insertions(+) diff --git a/examples/quick/quicknanobrowser/quickwindow.qml b/examples/quick/quicknanobrowser/quickwindow.qml index bec301e6d..7ec4fc021 100644 --- a/examples/quick/quicknanobrowser/quickwindow.qml +++ b/examples/quick/quicknanobrowser/quickwindow.qml @@ -82,6 +82,10 @@ ApplicationWindow { iconSource: webEngineView.loading ? "icons/process-stop.png" : "icons/view-refresh.png" onClicked: webEngineView.reload() } + Image { + id: faviconImage + width: 16; height: 16 + } TextField { id: addressBar focus: true @@ -99,5 +103,6 @@ ApplicationWindow { url: utils.initialUrl() onUrlChanged: addressBar.text = url + onIconChanged: faviconImage.source = url } } diff --git a/lib/quick/qquickwebengineview.cpp b/lib/quick/qquickwebengineview.cpp index 708a7ecb6..aa942c017 100644 --- a/lib/quick/qquickwebengineview.cpp +++ b/lib/quick/qquickwebengineview.cpp @@ -74,6 +74,13 @@ void QQuickWebEngineViewPrivate::urlChanged(const QUrl &url) Q_EMIT q->urlChanged(); } +void QQuickWebEngineViewPrivate::iconChanged(const QUrl &url) +{ + Q_Q(QQuickWebEngineView); + icon = url; + Q_EMIT q->iconChanged(); +} + void QQuickWebEngineViewPrivate::loadingStateChanged() { Q_Q(QQuickWebEngineView); @@ -127,6 +134,12 @@ void QQuickWebEngineView::setUrl(const QUrl& url) d->adapter->load(url); } +QUrl QQuickWebEngineView::icon() const +{ + Q_D(const QQuickWebEngineView); + return d->icon; +} + void QQuickWebEngineView::goBack() { Q_D(QQuickWebEngineView); diff --git a/lib/quick/qquickwebengineview_p.h b/lib/quick/qquickwebengineview_p.h index faeb234a1..1c3e27732 100644 --- a/lib/quick/qquickwebengineview_p.h +++ b/lib/quick/qquickwebengineview_p.h @@ -51,6 +51,7 @@ class QQuickWebEngineViewPrivate; class QQuickWebEngineView : public QQuickItem { Q_OBJECT Q_PROPERTY(QUrl url READ url WRITE setUrl NOTIFY urlChanged) + Q_PROPERTY(QUrl icon READ icon NOTIFY iconChanged) Q_PROPERTY(bool loading READ isLoading NOTIFY loadingStateChanged) Q_PROPERTY(QString title READ title NOTIFY titleChanged) Q_PROPERTY(bool canGoBack READ canGoBack NOTIFY loadingStateChanged) @@ -62,6 +63,7 @@ public: QUrl url() const; void setUrl(const QUrl&); + QUrl icon() const; bool isLoading() const; QString title() const; bool canGoBack() const; @@ -76,6 +78,7 @@ public Q_SLOTS: Q_SIGNALS: void titleChanged(); void urlChanged(); + void iconChanged(); void loadingStateChanged(); protected: diff --git a/lib/quick/qquickwebengineview_p_p.h b/lib/quick/qquickwebengineview_p_p.h index 9831fa0f3..38621b44d 100644 --- a/lib/quick/qquickwebengineview_p_p.h +++ b/lib/quick/qquickwebengineview_p_p.h @@ -61,6 +61,7 @@ public: virtual RenderWidgetHostViewQtDelegate* CreateRenderWidgetHostViewQtDelegate(CompositingMode mode) Q_DECL_OVERRIDE; virtual void titleChanged(const QString&) Q_DECL_OVERRIDE; virtual void urlChanged(const QUrl&) Q_DECL_OVERRIDE; + virtual void iconChanged(const QUrl&) Q_DECL_OVERRIDE; virtual void loadingStateChanged() Q_DECL_OVERRIDE; virtual QRectF viewportRect() const Q_DECL_OVERRIDE; virtual void loadFinished(bool success) Q_DECL_OVERRIDE; @@ -68,6 +69,7 @@ public: virtual void adoptNewWindow(WebContentsAdapter *newWebContents, WindowOpenDisposition disposition) Q_DECL_OVERRIDE; QExplicitlySharedDataPointer<WebContentsAdapter> adapter; + QUrl icon; }; QT_END_NAMESPACE diff --git a/lib/web_contents_adapter_client.h b/lib/web_contents_adapter_client.h index b0ab502c8..ea6e5a666 100644 --- a/lib/web_contents_adapter_client.h +++ b/lib/web_contents_adapter_client.h @@ -80,6 +80,7 @@ public: virtual RenderWidgetHostViewQtDelegate* CreateRenderWidgetHostViewQtDelegate(CompositingMode mode) = 0; virtual void titleChanged(const QString&) = 0; virtual void urlChanged(const QUrl&) = 0; + virtual void iconChanged(const QUrl&) = 0; virtual void loadingStateChanged() = 0; virtual QRectF viewportRect() const = 0; virtual void loadFinished(bool success) = 0; diff --git a/lib/web_contents_delegate_qt.cpp b/lib/web_contents_delegate_qt.cpp index e64649aea..12a00481c 100644 --- a/lib/web_contents_delegate_qt.cpp +++ b/lib/web_contents_delegate_qt.cpp @@ -48,6 +48,7 @@ #include "content/public/browser/render_view_host.h" #include "content/public/browser/web_contents.h" #include "content/public/browser/invalidate_type.h" +#include "content/public/common/favicon_url.h" WebContentsDelegateQt::WebContentsDelegateQt(content::WebContents *webContents, WebContentsAdapterClient *adapterClient) : m_viewClient(adapterClient) @@ -96,3 +97,14 @@ void WebContentsDelegateQt::DidFinishLoad(int64 frame_id, const GURL &validated_ if (is_main_frame) m_viewClient->loadFinished(true); } + +void WebContentsDelegateQt::DidUpdateFaviconURL(int32 page_id, const std::vector<content::FaviconURL>& candidates) +{ + Q_UNUSED(page_id) + Q_FOREACH (content::FaviconURL candidate, candidates) { + if (candidate.icon_type == content::FaviconURL::FAVICON && !candidate.icon_url.is_empty()) { + m_viewClient->iconChanged(toQt(candidate.icon_url)); + break; + } + } +} diff --git a/lib/web_contents_delegate_qt.h b/lib/web_contents_delegate_qt.h index e56800571..629fd5c6c 100644 --- a/lib/web_contents_delegate_qt.h +++ b/lib/web_contents_delegate_qt.h @@ -64,6 +64,7 @@ public: virtual void LoadingStateChanged(content::WebContents* source); virtual void DidFailLoad(int64 frame_id, const GURL &validated_url, bool is_main_frame, int error_code, const string16 &error_description, content::RenderViewHost *render_view_host); virtual void DidFinishLoad(int64 frame_id, const GURL &validated_url, bool is_main_frame, content::RenderViewHost *render_view_host); + virtual void DidUpdateFaviconURL(int32 page_id, const std::vector<content::FaviconURL>& candidates); private: WebContentsAdapterClient *m_viewClient; diff --git a/lib/widgets/Api/qwebenginepage.cpp b/lib/widgets/Api/qwebenginepage.cpp index ee0238368..ab3b1e675 100644 --- a/lib/widgets/Api/qwebenginepage.cpp +++ b/lib/widgets/Api/qwebenginepage.cpp @@ -69,6 +69,11 @@ void QWebEnginePagePrivate::urlChanged(const QUrl &url) Q_EMIT q->urlChanged(url); } +void QWebEnginePagePrivate::iconChanged(const QUrl &url) +{ + Q_UNUSED(url) +} + void QWebEnginePagePrivate::loadingStateChanged() { Q_Q(QWebEnginePage); diff --git a/lib/widgets/Api/qwebenginepage_p.h b/lib/widgets/Api/qwebenginepage_p.h index 22066b5bc..ad1de0047 100644 --- a/lib/widgets/Api/qwebenginepage_p.h +++ b/lib/widgets/Api/qwebenginepage_p.h @@ -67,6 +67,7 @@ public: virtual RenderWidgetHostViewQtDelegate* CreateRenderWidgetHostViewQtDelegate(CompositingMode mode) Q_DECL_OVERRIDE; virtual void titleChanged(const QString&) Q_DECL_OVERRIDE; virtual void urlChanged(const QUrl&) Q_DECL_OVERRIDE; + virtual void iconChanged(const QUrl&) Q_DECL_OVERRIDE; virtual void loadingStateChanged() Q_DECL_OVERRIDE; virtual QRectF viewportRect() const Q_DECL_OVERRIDE; virtual void loadFinished(bool success) Q_DECL_OVERRIDE; -- GitLab