summaryrefslogtreecommitdiff
blob: dba877ebf5f3fecb6aca546efe45c3b435bb5926 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
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 REVISION 1)
+    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