From 3adadda878f63fcca6892c49c4ddc82143d59b66 Mon Sep 17 00:00:00 2001
From: Jocelyn Turcotte <jturcotte@woboq.com>
Date: Thu, 9 Jul 2015 21:52:43 +0200
Subject: [PATCH] Add a backgroundColor property

This also allows setting a transparent color to see through
the web view's body if its background color isn't specified.

The color is initially held by the top API view and is pulled
by the WebContentsAdapter in order to set it on the RenderView.
Since both blink and our local compositors (in the QOpenGLWidget
case) need to know about this color, RWHVQt takes care of pushing
it to both. The former through an IPC message and the latter
directly on the RWHVQtDelegate.

Task-number: QTBUG-41960
Change-Id: Ie13317b2d087f5612ad9c5fb0e05ca3e91aec9af
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@theqtcompany.com>
Reviewed-by: Andras Becsi <andras.becsi@theqtcompany.com>
---
 qtwebengine/src/core/common/qt_messages.h                      |  3 ++
 qtwebengine/src/core/render_widget_host_view_qt.cpp            |  9 ++++++
 qtwebengine/src/core/render_widget_host_view_qt.h              |  1 +
 qtwebengine/src/core/render_widget_host_view_qt_delegate.h     |  1 +
 qtwebengine/src/core/renderer/qt_render_view_observer.cpp      |  6 ++++
 qtwebengine/src/core/renderer/qt_render_view_observer.h        |  1 +
 qtwebengine/src/core/type_conversion.h                         |  5 ++++
 qtwebengine/src/core/web_contents_adapter.cpp                  |  7 +++++
 qtwebengine/src/core/web_contents_adapter.h                    |  1 +
 qtwebengine/src/core/web_contents_adapter_client.h             |  1 +
 qtwebengine/src/core/web_contents_view_qt.cpp                  |  7 +++++
 qtwebengine/src/core/web_contents_view_qt.h                    |  2 +-
 qtwebengine/src/webengine/api/qquickwebengineview.cpp          | 34 ++++++++++++++++++++++
 qtwebengine/src/webengine/api/qquickwebengineview_p.h          |  5 +++-
 qtwebengine/src/webengine/api/qquickwebengineview_p_p.h        |  2 ++
 .../render_widget_host_view_qt_delegate_quick.h    |  2 ++
 ...nder_widget_host_view_qt_delegate_quickwindow.h |  1 +
 qtwebengine/src/webenginewidgets/api/qwebenginepage.cpp        | 33 +++++++++++++++++++++
 qtwebengine/src/webenginewidgets/api/qwebenginepage.h          |  3 ++
 qtwebengine/src/webenginewidgets/api/qwebenginepage_p.h        |  2 ++
 .../render_widget_host_view_qt_delegate_widget.cpp | 16 +++++++++-
 .../render_widget_host_view_qt_delegate_widget.h   |  2 ++
 22 files changed, 141 insertions(+), 3 deletions(-)

diff --git a/qtwebengine/src/core/common/qt_messages.h b/src/core/common/qt_messages.h
index c692ee5..25a995b 100644
--- a/qtwebengine/src/core/common/qt_messages.h
+++ b/qtwebengine/src/core/common/qt_messages.h
@@ -31,6 +31,9 @@ IPC_MESSAGE_ROUTED1(QtRenderViewObserver_FetchDocumentMarkup,
 IPC_MESSAGE_ROUTED1(QtRenderViewObserver_FetchDocumentInnerText,
                     uint64 /* requestId */)
 
+IPC_MESSAGE_ROUTED1(QtRenderViewObserver_SetBackgroundColor,
+                    uint32 /* color */)
+
 IPC_MESSAGE_ROUTED1(WebChannelIPCTransport_Message, std::vector<char> /*binaryJSON*/)
 
 // User scripts messages
diff --git a/qtwebengine/src/core/render_widget_host_view_qt.cpp b/src/core/render_widget_host_view_qt.cpp
index 572bc34..20b41bc 100644
--- a/qtwebengine/src/core/render_widget_host_view_qt.cpp
+++ b/qtwebengine/src/core/render_widget_host_view_qt.cpp
@@ -36,6 +36,7 @@
 
 #include "render_widget_host_view_qt.h"
 
+#include "common/qt_messages.h"
 #include "browser_accessibility_manager_qt.h"
 #include "browser_accessibility_qt.h"
 #include "chromium_overrides.h"
@@ -408,6 +409,14 @@ gfx::Rect RenderWidgetHostViewQt::GetViewBounds() const
     return gfx::BoundingRect(p1, p2);
 }
 
+void RenderWidgetHostViewQt::SetBackgroundColor(SkColor color) {
+    RenderWidgetHostViewBase::SetBackgroundColor(color);
+    // Set the background of the compositor if necessary
+    m_delegate->setClearColor(toQt(color));
+    // Set the background of the blink::FrameView
+    m_host->Send(new QtRenderViewObserver_SetBackgroundColor(m_host->GetRoutingID(), color));
+}
+
 // Return value indicates whether the mouse is locked successfully or not.
 bool RenderWidgetHostViewQt::LockMouse()
 {
diff --git a/qtwebengine/src/core/render_widget_host_view_qt.h b/src/core/render_widget_host_view_qt.h
index 248c52f..2724292 100644
--- a/qtwebengine/src/core/render_widget_host_view_qt.h
+++ b/qtwebengine/src/core/render_widget_host_view_qt.h
@@ -125,6 +125,7 @@ public:
     virtual void Hide() Q_DECL_OVERRIDE;
     virtual bool IsShowing() Q_DECL_OVERRIDE;
     virtual gfx::Rect GetViewBounds() const Q_DECL_OVERRIDE;
+    virtual void SetBackgroundColor(SkColor color) Q_DECL_OVERRIDE;
     virtual bool LockMouse() Q_DECL_OVERRIDE;
     virtual void UnlockMouse() Q_DECL_OVERRIDE;
     virtual void WasShown() Q_DECL_OVERRIDE;
diff --git a/qtwebengine/src/core/render_widget_host_view_qt_delegate.h b/src/core/render_widget_host_view_qt_delegate.h
index da595b9..f4aa9b2 100644
--- a/qtwebengine/src/core/render_widget_host_view_qt_delegate.h
+++ b/qtwebengine/src/core/render_widget_host_view_qt_delegate.h
@@ -96,6 +96,7 @@ public:
     virtual void move(const QPoint &) = 0;
     virtual void inputMethodStateChanged(bool editorVisible) = 0;
     virtual void setTooltip(const QString &) = 0;
+    virtual void setClearColor(const QColor &color) = 0;
 };
 
 } // namespace QtWebEngineCore
diff --git a/qtwebengine/src/core/renderer/qt_render_view_observer.cpp b/src/core/renderer/qt_render_view_observer.cpp
index 83534da..ba91e54 100644
--- a/qtwebengine/src/core/renderer/qt_render_view_observer.cpp
+++ b/qtwebengine/src/core/renderer/qt_render_view_observer.cpp
@@ -65,6 +65,11 @@ void QtRenderViewObserver::onFetchDocumentInnerText(quint64 requestId)
         render_view()->GetWebView()->mainFrame()->contentAsText(std::numeric_limits<std::size_t>::max())));
 }
 
+void QtRenderViewObserver::onSetBackgroundColor(quint32 color)
+{
+    render_view()->GetWebView()->setBaseBackgroundColor(color);
+}
+
 void QtRenderViewObserver::OnFirstVisuallyNonEmptyLayout()
 {
     Send(new QtRenderViewObserverHost_DidFirstVisuallyNonEmptyLayout(routing_id()));
@@ -76,6 +81,7 @@ bool QtRenderViewObserver::OnMessageReceived(const IPC::Message& message)
     IPC_BEGIN_MESSAGE_MAP(QtRenderViewObserver, message)
         IPC_MESSAGE_HANDLER(QtRenderViewObserver_FetchDocumentMarkup, onFetchDocumentMarkup)
         IPC_MESSAGE_HANDLER(QtRenderViewObserver_FetchDocumentInnerText, onFetchDocumentInnerText)
+        IPC_MESSAGE_HANDLER(QtRenderViewObserver_SetBackgroundColor, onSetBackgroundColor)
         IPC_MESSAGE_UNHANDLED(handled = false)
     IPC_END_MESSAGE_MAP()
     return handled;
diff --git a/qtwebengine/src/core/renderer/qt_render_view_observer.h b/src/core/renderer/qt_render_view_observer.h
index cb77cd0..3f7829a 100644
--- a/qtwebengine/src/core/renderer/qt_render_view_observer.h
+++ b/qtwebengine/src/core/renderer/qt_render_view_observer.h
@@ -47,6 +47,7 @@ public:
 private:
     void onFetchDocumentMarkup(quint64 requestId);
     void onFetchDocumentInnerText(quint64 requestId);
+    void onSetBackgroundColor(quint32 color);
 
     void OnFirstVisuallyNonEmptyLayout() Q_DECL_OVERRIDE;
 
diff --git a/qtwebengine/src/core/type_conversion.h b/src/core/type_conversion.h
index 66fcd4d..f1bf54b 100644
--- a/qtwebengine/src/core/type_conversion.h
+++ b/qtwebengine/src/core/type_conversion.h
@@ -122,6 +122,11 @@ inline QColor toQt(const SkColor &c)
     return QColor(SkColorGetR(c), SkColorGetG(c), SkColorGetB(c), SkColorGetA(c));
 }
 
+inline SkColor toSk(const QColor &c)
+{
+    return c.rgba();
+}
+
 inline QMatrix4x4 toQt(const SkMatrix44 &m)
 {
     QMatrix4x4 qtMatrix(
diff --git a/qtwebengine/src/core/web_contents_adapter.cpp b/src/core/web_contents_adapter.cpp
index 8c13035..0c5b6ca 100644
--- a/qtwebengine/src/core/web_contents_adapter.cpp
+++ b/qtwebengine/src/core/web_contents_adapter.cpp
@@ -837,6 +837,13 @@ void WebContentsAdapter::filesSelectedInChooser(const QStringList &fileList, Web
     rvh->FilesSelectedInChooser(toVector<content::FileChooserFileInfo>(files), static_cast<content::FileChooserParams::Mode>(mode));
 }
 
+void WebContentsAdapter::backgroundColorChanged()
+{
+    Q_D(WebContentsAdapter);
+    if (content::RenderWidgetHostView *rwhv = d->webContents->GetRenderWidgetHostView())
+        rwhv->SetBackgroundColor(toSk(d->adapterClient->backgroundColor()));
+}
+
 content::WebContents *WebContentsAdapter::webContents() const
 {
     Q_D(const WebContentsAdapter);
diff --git a/qtwebengine/src/core/web_contents_adapter.h b/src/core/web_contents_adapter.h
index 5ea55c1..929967a 100644
--- a/qtwebengine/src/core/web_contents_adapter.h
+++ b/qtwebengine/src/core/web_contents_adapter.h
@@ -120,6 +120,7 @@ public:
     void grantMouseLockPermission(bool granted);
 
     void dpiScaleChanged();
+    void backgroundColorChanged();
     QAccessibleInterface *browserAccessible();
     BrowserContextQt* browserContext();
     BrowserContextAdapter* browserContextAdapter();
diff --git a/qtwebengine/src/core/web_contents_adapter_client.h b/src/core/web_contents_adapter_client.h
index 3ed3ab9..acf3095 100644
--- a/qtwebengine/src/core/web_contents_adapter_client.h
+++ b/qtwebengine/src/core/web_contents_adapter_client.h
@@ -152,6 +152,7 @@ public:
     virtual void selectionChanged() = 0;
     virtual QRectF viewportRect() const = 0;
     virtual qreal dpiScale() const = 0;
+    virtual QColor backgroundColor() const = 0;
     virtual void loadStarted(const QUrl &provisionalUrl, bool isErrorPage = false) = 0;
     virtual void loadCommitted() = 0;
     virtual void loadVisuallyCommitted() = 0;
diff --git a/qtwebengine/src/core/web_contents_view_qt.cpp b/src/core/web_contents_view_qt.cpp
index 9321706..f40bf8f 100644
--- a/qtwebengine/src/core/web_contents_view_qt.cpp
+++ b/qtwebengine/src/core/web_contents_view_qt.cpp
@@ -81,6 +81,13 @@ content::RenderWidgetHostViewBase* WebContentsViewQt::CreateViewForPopupWidget(c
     return view;
 }
 
+void WebContentsViewQt::RenderViewCreated(content::RenderViewHost* host)
+{
+    // The render process is done creating the RenderView and it's ready to be routed
+    // messages at this point.
+    host->GetView()->SetBackgroundColor(toSk(m_client->backgroundColor()));
+}
+
 void WebContentsViewQt::CreateView(const gfx::Size& initial_size, gfx::NativeView context)
 {
     // This is passed through content::WebContents::CreateParams::context either as the native view's client
diff --git a/qtwebengine/src/core/web_contents_view_qt.h b/src/core/web_contents_view_qt.h
index 896955f..3ede530 100644
--- a/qtwebengine/src/core/web_contents_view_qt.h
+++ b/qtwebengine/src/core/web_contents_view_qt.h
@@ -75,7 +75,7 @@ public:
 
     virtual void SetPageTitle(const base::string16& title) Q_DECL_OVERRIDE { }
 
-    virtual void RenderViewCreated(content::RenderViewHost* host) Q_DECL_OVERRIDE { QT_NOT_YET_IMPLEMENTED }
+    virtual void RenderViewCreated(content::RenderViewHost* host) Q_DECL_OVERRIDE;
 
     virtual void RenderViewSwappedIn(content::RenderViewHost* host) Q_DECL_OVERRIDE { QT_NOT_YET_IMPLEMENTED }
 
diff --git a/qtwebengine/src/webengine/api/qquickwebengineview.cpp b/src/webengine/api/qquickwebengineview.cpp
index 7405cae..c57d8d1 100644
--- a/qtwebengine/src/webengine/api/qquickwebengineview.cpp
+++ b/qtwebengine/src/webengine/api/qquickwebengineview.cpp
@@ -104,6 +104,7 @@ QQuickWebEngineViewPrivate::QQuickWebEngineViewPrivate()
     , isLoading(false)
     , devicePixelRatio(QGuiApplication::primaryScreen()->devicePixelRatio())
     , m_dpiScale(1.0)
+    , m_backgroundColor(Qt::white)
 {
     // The gold standard for mobile web content is 160 dpi, and the devicePixelRatio expected
     // is the (possibly quantized) ratio of device dpi to 160 dpi.
@@ -310,6 +311,11 @@ qreal QQuickWebEngineViewPrivate::dpiScale() const
     return m_dpiScale;
 }
 
+QColor QQuickWebEngineViewPrivate::backgroundColor() const
+{
+    return m_backgroundColor;
+}
+
 void QQuickWebEngineViewPrivate::loadStarted(const QUrl &provisionalUrl, bool isErrorPage)
 {
     Q_Q(QQuickWebEngineView);
@@ -858,6 +864,34 @@ qreal QQuickWebEngineView::zoomFactor() const
     return d->adapter->currentZoomFactor();
 }
 
+/*!
+    \qmlproperty bool WebEngineView::backgroundColor
+    \since QtWebEngine 1.3
+
+    Sets this property to change the color of the WebEngineView's background,
+    behing the document's body. You can set it to "transparent" or to a translucent
+    color to see through the document, or you can set this color to match your
+    web content in an hybrid app to prevent the white flashes that may appear
+    during loading.
+
+    The default value is white.
+*/
+QColor QQuickWebEngineView::backgroundColor() const
+{
+    Q_D(const QQuickWebEngineView);
+    return d->m_backgroundColor;
+}
+
+void QQuickWebEngineView::setBackgroundColor(const QColor &color)
+{
+    Q_D(QQuickWebEngineView);
+    if (color == d->m_backgroundColor)
+        return;
+    d->m_backgroundColor = color;
+    d->ensureContentsAdapter();
+    d->adapter->backgroundColorChanged();
+    emit backgroundColorChanged();
+}
 
 bool QQuickWebEngineView::isFullScreen() const
 {
diff --git a/qtwebengine/src/webengine/api/qquickwebengineview_p.h b/src/webengine/api/qquickwebengineview_p.h
index 40299c1..362c3a2 100644
--- a/qtwebengine/src/webengine/api/qquickwebengineview_p.h
+++ b/qtwebengine/src/webengine/api/qquickwebengineview_p.h
@@ -89,6 +89,7 @@ class Q_WEBENGINE_PRIVATE_EXPORT QQuickWebEngineView : public QQuickItem {
     Q_PROPERTY(QQuickWebEngineHistory *navigationHistory READ navigationHistory CONSTANT FINAL REVISION 1)
     Q_PROPERTY(QQmlWebChannel *webChannel READ webChannel WRITE setWebChannel NOTIFY webChannelChanged REVISION 1)
     Q_PROPERTY(QQmlListProperty<QQuickWebEngineScript> userScripts READ userScripts FINAL)
+    Q_PROPERTY(QColor backgroundColor READ backgroundColor WRITE setBackgroundColor NOTIFY backgroundColorChanged REVISION 1)
 
 #ifdef ENABLE_QML_TESTSUPPORT_API
     Q_PROPERTY(QQuickWebEngineTestSupport *testSupport READ testSupport WRITE setTestSupport FINAL)
@@ -118,6 +119,8 @@ public:
     bool isFullScreen() const;
     qreal zoomFactor() const;
     void setZoomFactor(qreal arg);
+    QColor backgroundColor() const;
+    void setBackgroundColor(const QColor &color);
 
     QQuickWebEngineViewExperimental *experimental() const;
 
@@ -230,7 +233,7 @@ Q_SIGNALS:
     Q_REVISION(1) void zoomFactorChanged(qreal arg);
     Q_REVISION(1) void profileChanged();
     Q_REVISION(1) void webChannelChanged();
-
+    Q_REVISION(1) void backgroundColorChanged();
 
 protected:
     void geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry);
diff --git a/qtwebengine/src/webengine/api/qquickwebengineview_p_p.h b/src/webengine/api/qquickwebengineview_p_p.h
index edc8c1a..3bfed2f 100644
--- a/qtwebengine/src/webengine/api/qquickwebengineview_p_p.h
+++ b/qtwebengine/src/webengine/api/qquickwebengineview_p_p.h
@@ -123,6 +123,7 @@ public:
     virtual void selectionChanged() Q_DECL_OVERRIDE { }
     virtual QRectF viewportRect() const Q_DECL_OVERRIDE;
     virtual qreal dpiScale() const Q_DECL_OVERRIDE;
+    virtual QColor backgroundColor() const Q_DECL_OVERRIDE;
     virtual void loadStarted(const QUrl &provisionalUrl, bool isErrorPage = false) Q_DECL_OVERRIDE;
     virtual void loadCommitted() Q_DECL_OVERRIDE;
     virtual void loadVisuallyCommitted() Q_DECL_OVERRIDE;
@@ -192,6 +193,7 @@ private:
     QScopedPointer<QtWebEngineCore::UIDelegatesManager> m_uIDelegatesManager;
     QList<QQuickWebEngineScript *> m_userScripts;
     qreal m_dpiScale;
+    QColor m_backgroundColor;
 };
 
 #ifndef QT_NO_ACCESSIBILITY
diff --git a/qtwebengine/src/webengine/render_widget_host_view_qt_delegate_quick.h b/src/webengine/render_widget_host_view_qt_delegate_quick.h
index ddd0e4d..eb2860b 100644
--- a/qtwebengine/src/webengine/render_widget_host_view_qt_delegate_quick.h
+++ b/qtwebengine/src/webengine/render_widget_host_view_qt_delegate_quick.h
@@ -70,6 +70,8 @@ public:
     virtual void move(const QPoint&) Q_DECL_OVERRIDE { }
     virtual void inputMethodStateChanged(bool editorVisible) Q_DECL_OVERRIDE;
     virtual void setTooltip(const QString&) Q_DECL_OVERRIDE { }
+    // The QtQuick view doesn't have a backbuffer of its own and doesn't need this
+    virtual void setClearColor(const QColor &) Q_DECL_OVERRIDE { }
 
 protected:
     virtual void focusInEvent(QFocusEvent *event) Q_DECL_OVERRIDE;
diff --git a/qtwebengine/src/webengine/render_widget_host_view_qt_delegate_quickwindow.h b/src/webengine/render_widget_host_view_qt_delegate_quickwindow.h
index cda51a1..a4b0848 100644
--- a/qtwebengine/src/webengine/render_widget_host_view_qt_delegate_quickwindow.h
+++ b/qtwebengine/src/webengine/render_widget_host_view_qt_delegate_quickwindow.h
@@ -73,6 +73,7 @@ public:
     virtual void move(const QPoint &screenPos) Q_DECL_OVERRIDE;
     virtual void inputMethodStateChanged(bool) Q_DECL_OVERRIDE {}
     virtual void setTooltip(const QString &tooltip) Q_DECL_OVERRIDE;
+    virtual void setClearColor(const QColor &) Q_DECL_OVERRIDE { }
 
 private:
     QScopedPointer<RenderWidgetHostViewQtDelegate> m_realDelegate;
diff --git a/qtwebengine/src/webenginewidgets/api/qwebenginepage.cpp b/src/webenginewidgets/api/qwebenginepage.cpp
index 1b5a243..1cd7d6a 100644
--- a/qtwebengine/src/webenginewidgets/api/qwebenginepage.cpp
+++ b/qtwebengine/src/webenginewidgets/api/qwebenginepage.cpp
@@ -185,6 +185,7 @@ QWebEnginePagePrivate::QWebEnginePagePrivate(QWebEngineProfile *_profile)
     , view(0)
     , isLoading(false)
     , scriptCollection(new QWebEngineScriptCollectionPrivate(browserContextAdapter()->userScriptController(), adapter.data()))
+    , m_backgroundColor(Qt::white)
 {
     memset(actions, 0, sizeof(actions));
 }
@@ -247,6 +248,11 @@ qreal QWebEnginePagePrivate::dpiScale() const
     return 1.0;
 }
 
+QColor QWebEnginePagePrivate::backgroundColor() const
+{
+    return m_backgroundColor;
+}
+
 void QWebEnginePagePrivate::loadStarted(const QUrl &provisionalUrl, bool isErrorPage)
 {
     Q_UNUSED(provisionalUrl);
@@ -531,6 +537,33 @@ void QWebEnginePage::setWebChannel(QWebChannel *channel)
     d->adapter->setWebChannel(channel);
 }
 
+/*!
+    \property QWebEnginePage::backgroundColor
+    \brief the page's background color, behing the document's body.
+    \since 5.6
+
+    You can set it to Qt::transparent or to a translucent
+    color to see through the document, or you can set this color to match your
+    web content in an hybrid app to prevent the white flashes that may appear
+    during loading.
+
+    The default value is white.
+*/
+QColor QWebEnginePage::backgroundColor() const
+{
+    Q_D(const QWebEnginePage);
+    return d->m_backgroundColor;
+}
+
+void QWebEnginePage::setBackgroundColor(const QColor &color)
+{
+    Q_D(QWebEnginePage);
+    if (d->m_backgroundColor == color)
+        return;
+    d->m_backgroundColor = color;
+    d->adapter->backgroundColorChanged();
+}
+
 void QWebEnginePage::setView(QWidget *view)
 {
     QWebEngineViewPrivate::bind(qobject_cast<QWebEngineView*>(view), this);
diff --git a/qtwebengine/src/webenginewidgets/api/qwebenginepage.h b/src/webenginewidgets/api/qwebenginepage.h
index b4cf522..57ed071 100644
--- a/qtwebengine/src/webenginewidgets/api/qwebenginepage.h
+++ b/qtwebengine/src/webenginewidgets/api/qwebenginepage.h
@@ -98,6 +98,7 @@ class QWEBENGINEWIDGETS_EXPORT QWebEnginePage : public QObject {
     Q_PROPERTY(QString title READ title)
     Q_PROPERTY(QUrl url READ url WRITE setUrl)
     Q_PROPERTY(QUrl iconUrl READ iconUrl)
+    Q_PROPERTY(QColor backgroundColor READ backgroundColor WRITE setBackgroundColor)
 
 public:
     enum WebAction {
@@ -236,6 +237,8 @@ public:
 
     QWebChannel *webChannel() const;
     void setWebChannel(QWebChannel *);
+    QColor backgroundColor() const;
+    void setBackgroundColor(const QColor &color);
 
 Q_SIGNALS:
     void loadStarted();
diff --git a/qtwebengine/src/webenginewidgets/api/qwebenginepage_p.h b/src/webenginewidgets/api/qwebenginepage_p.h
index 8f45ecd..7d74d3f 100644
--- a/qtwebengine/src/webenginewidgets/api/qwebenginepage_p.h
+++ b/qtwebengine/src/webenginewidgets/api/qwebenginepage_p.h
@@ -118,6 +118,7 @@ public:
     virtual void selectionChanged() Q_DECL_OVERRIDE;
     virtual QRectF viewportRect() const Q_DECL_OVERRIDE;
     virtual qreal dpiScale() const Q_DECL_OVERRIDE;
+    virtual QColor backgroundColor() const Q_DECL_OVERRIDE;
     virtual void loadStarted(const QUrl &provisionalUrl, bool isErrorPage = false) Q_DECL_OVERRIDE;
     virtual void loadCommitted() Q_DECL_OVERRIDE;
     virtual void loadVisuallyCommitted() Q_DECL_OVERRIDE { }
@@ -170,6 +171,7 @@ public:
     QtWebEngineCore::WebEngineContextMenuData m_menuData;
     bool isLoading;
     QWebEngineScriptCollection scriptCollection;
+    QColor m_backgroundColor;
 
     mutable CallbackDirectory m_callbacks;
     mutable QAction *actions[QWebEnginePage::WebActionCount];
diff --git a/qtwebengine/src/webenginewidgets/render_widget_host_view_qt_delegate_widget.cpp b/src/webenginewidgets/render_widget_host_view_qt_delegate_widget.cpp
index dba37ce..76ca8d3 100644
--- a/qtwebengine/src/webenginewidgets/render_widget_host_view_qt_delegate_widget.cpp
+++ b/qtwebengine/src/webenginewidgets/render_widget_host_view_qt_delegate_widget.cpp
@@ -59,6 +59,7 @@ RenderWidgetHostViewQtDelegateWidget::RenderWidgetHostViewQtDelegateWidget(Rende
     , m_rootNode(new QSGRootNode)
     , m_sgEngine(new QSGEngine)
     , m_isPopup(false)
+    , m_clearColor(Qt::white)
 {
     setFocusPolicy(Qt::StrongFocus);
 
@@ -218,6 +219,19 @@ void RenderWidgetHostViewQtDelegateWidget::setTooltip(const QString &tooltip)
     setToolTip(wrappedTip);
 }
 
+void RenderWidgetHostViewQtDelegateWidget::setClearColor(const QColor &color)
+{
+    m_clearColor = color;
+    // QOpenGLWidget is usually blended by punching holes into widgets
+    // above it to simulate the visual stacking order. If we want it to be
+    // transparent we have to throw away the proper stacking order and always
+    // blend the complete normal widgets backing store under it.
+    bool isTranslucent = color.alpha() < 255;
+    setAttribute(Qt::WA_AlwaysStackOnTop, isTranslucent);
+    setAttribute(Qt::WA_OpaquePaintEvent, !isTranslucent);
+    update();
+}
+
 QVariant RenderWidgetHostViewQtDelegateWidget::inputMethodQuery(Qt::InputMethodQuery query) const
 {
     return m_client->inputMethodQuery(query);
@@ -270,7 +284,7 @@ void RenderWidgetHostViewQtDelegateWidget::initializeGL()
     m_sgEngine->initialize(QOpenGLContext::currentContext());
     m_sgRenderer.reset(m_sgEngine->createRenderer());
     m_sgRenderer->setRootNode(m_rootNode.data());
-    m_sgRenderer->setClearColor(Qt::white);
+    m_sgRenderer->setClearColor(m_clearColor);
 }
 
 void RenderWidgetHostViewQtDelegateWidget::paintGL()
diff --git a/qtwebengine/src/webenginewidgets/render_widget_host_view_qt_delegate_widget.h b/src/webenginewidgets/render_widget_host_view_qt_delegate_widget.h
index d0dfdc6..d228bd4 100644
--- a/qtwebengine/src/webenginewidgets/render_widget_host_view_qt_delegate_widget.h
+++ b/qtwebengine/src/webenginewidgets/render_widget_host_view_qt_delegate_widget.h
@@ -78,6 +78,7 @@ public:
     virtual void move(const QPoint &screenPos) Q_DECL_OVERRIDE;
     virtual void inputMethodStateChanged(bool editorVisible) Q_DECL_OVERRIDE;
     virtual void setTooltip(const QString &tooltip) Q_DECL_OVERRIDE;
+    virtual void setClearColor(const QColor &color) Q_DECL_OVERRIDE;
 
 protected:
     bool event(QEvent *event) Q_DECL_OVERRIDE;
@@ -98,6 +99,7 @@ private:
     QScopedPointer<QSGEngine> m_sgEngine;
     QScopedPointer<QSGAbstractRenderer> m_sgRenderer;
     bool m_isPopup;
+    QColor m_clearColor;
     QList<QMetaObject::Connection> m_windowConnections;
 };
 
-- 
2.3.3


