[arch-commits] Commit in qt5-webengine/repos/kde-unstable-x86_64 (8 files)
Antonio Rojas
arojas at archlinux.org
Wed Mar 21 22:28:30 UTC 2018
Date: Wednesday, March 21, 2018 @ 22:28:29
Author: arojas
Revision: 319785
archrelease: copy kde-unstable to kde-unstable-x86_64
Added:
qt5-webengine/repos/kde-unstable-x86_64/PKGBUILD
(from rev 319784, qt5-webengine/kde-unstable/PKGBUILD)
qt5-webengine/repos/kde-unstable-x86_64/qtbug-66333.patch
(from rev 319784, qt5-webengine/kde-unstable/qtbug-66333.patch)
qt5-webengine/repos/kde-unstable-x86_64/qtbug-66338.patch
(from rev 319784, qt5-webengine/kde-unstable/qtbug-66338.patch)
qt5-webengine/repos/kde-unstable-x86_64/qtwebengine-harmony.patch
(from rev 319784, qt5-webengine/kde-unstable/qtwebengine-harmony.patch)
qt5-webengine/repos/kde-unstable-x86_64/qtwebengine-no-gpu.patch
(from rev 319784, qt5-webengine/kde-unstable/qtwebengine-no-gpu.patch)
Deleted:
qt5-webengine/repos/kde-unstable-x86_64/PKGBUILD
qt5-webengine/repos/kde-unstable-x86_64/qtwebengine-harmony.patch
qt5-webengine/repos/kde-unstable-x86_64/qtwebengine-no-gpu.patch
---------------------------+
PKGBUILD | 130 +++---
qtbug-66333.patch | 870 ++++++++++++++++++++++++++++++++++++++++++++
qtbug-66338.patch | 196 +++++++++
qtwebengine-harmony.patch | 154 +++----
qtwebengine-no-gpu.patch | 198 +++++-----
5 files changed, 1310 insertions(+), 238 deletions(-)
Deleted: PKGBUILD
===================================================================
--- PKGBUILD 2018-03-21 22:28:03 UTC (rev 319784)
+++ PKGBUILD 2018-03-21 22:28:29 UTC (rev 319785)
@@ -1,62 +0,0 @@
-# $Id$
-# Maintainer: Felix Yan <felixonmars at archlinux.org>
-# Contributor: Andrea Scarpino <andrea at archlinux.org>
-
-pkgname=qt5-webengine
-_qtver=5.11.0-beta2
-pkgver=${_qtver/-/}
-pkgrel=1
-arch=('x86_64')
-url='http://qt-project.org/'
-license=('LGPL3' 'LGPL2.1' 'BSD')
-pkgdesc='Provides support for web applications using the Chromium browser project'
-depends=('qt5-webchannel' 'qt5-location' 'libxcomposite' 'libxrandr' 'pciutils' 'libxss'
- 'libevent' 'snappy' 'nss' 'protobuf' 'libxslt' 'minizip' 'ffmpeg' 're2' 'libvpx')
-makedepends=('python2' 'git' 'gperf' 'jsoncpp' 'ninja' 'qt5-tools')
-groups=('qt' 'qt5')
-_pkgfqn="${pkgname/5-/}-everywhere-src-${_qtver}"
-source=("http://download.qt.io/development_releases/qt/${pkgver%.*}/${_qtver}/submodules/${_pkgfqn}.tar.xz"
- qtwebengine-harmony.patch
- qtwebengine-no-gpu.patch)
-sha256sums=('fb5b2daffd55f0f4398e2cce9f022191543e6486b39f4a53ba67a23b5175f4fd'
- 'feca54ab09ac0fc9d0626770a6b899a6ac5a12173c7d0c1005bc3964ec83e7b3'
- '6cd70c37f3b3aea926f1ee20c1f59354f2a02d240dbf344c6dc0a75f8aa8e07b')
-
-prepare() {
- mkdir -p build
-
- # Hack to force using python2
- mkdir -p bin
- ln -s /usr/bin/python2 bin/python
-
- cd ${_pkgfqn}
-
- # FreeType 2.8.1
- patch -Np1 -i ../qtwebengine-harmony.patch
- # Disable GPU rendering on nouveau and wayland (openSUSE) https://bugreports.qt.io/browse/QTBUG-65682
- # patch -p1 -i ../qtwebengine-no-gpu.patch
-}
-
-build() {
- cd build
-
- export PATH="$srcdir/bin:$PATH"
- qmake ../${_pkgfqn} -- \
- -proprietary-codecs \
- -system-ffmpeg \
- -webp \
- -spellchecker
-# -webengine-icu
- make
-}
-
-package() {
- cd build
- make INSTALL_ROOT="$pkgdir" install
-
- # Drop QMAKE_PRL_BUILD_DIR because reference the build dir
- find "$pkgdir/usr/lib" -type f -name '*.prl' \
- -exec sed -i -e '/^QMAKE_PRL_BUILD_DIR/d' {} \;
-
- install -Dm644 "$srcdir"/${_pkgfqn}/src/3rdparty/chromium/LICENSE "$pkgdir"/usr/share/licenses/${pkgname}/LICENSE.chromium
-}
Copied: qt5-webengine/repos/kde-unstable-x86_64/PKGBUILD (from rev 319784, qt5-webengine/kde-unstable/PKGBUILD)
===================================================================
--- PKGBUILD (rev 0)
+++ PKGBUILD 2018-03-21 22:28:29 UTC (rev 319785)
@@ -0,0 +1,68 @@
+# $Id$
+# Maintainer: Felix Yan <felixonmars at archlinux.org>
+# Contributor: Andrea Scarpino <andrea at archlinux.org>
+
+pkgname=qt5-webengine
+_qtver=5.11.0-beta2
+pkgver=${_qtver/-/}
+pkgrel=2
+arch=('x86_64')
+url='http://qt-project.org/'
+license=('LGPL3' 'LGPL2.1' 'BSD')
+pkgdesc='Provides support for web applications using the Chromium browser project'
+depends=('qt5-webchannel' 'qt5-location' 'libxcomposite' 'libxrandr' 'pciutils' 'libxss'
+ 'libevent' 'snappy' 'nss' 'protobuf' 'libxslt' 'minizip' 'ffmpeg' 're2' 'libvpx')
+makedepends=('python2' 'git' 'gperf' 'jsoncpp' 'ninja' 'qt5-tools')
+groups=('qt' 'qt5')
+_pkgfqn="${pkgname/5-/}-everywhere-src-${_qtver}"
+source=("http://download.qt.io/development_releases/qt/${pkgver%.*}/${_qtver}/submodules/${_pkgfqn}.tar.xz"
+ qtwebengine-harmony.patch
+ qtwebengine-no-gpu.patch
+ qtbug-66333.patch qtbug-66338.patch)
+sha256sums=('fb5b2daffd55f0f4398e2cce9f022191543e6486b39f4a53ba67a23b5175f4fd'
+ 'feca54ab09ac0fc9d0626770a6b899a6ac5a12173c7d0c1005bc3964ec83e7b3'
+ '6cd70c37f3b3aea926f1ee20c1f59354f2a02d240dbf344c6dc0a75f8aa8e07b'
+ '276370082dedec73c0c7016724406225d40fb1926dd0347b3f242fe3a4c3e365'
+ '95ee51ea7e73443a6be315dacebfa49eee313b9cb9fcf30a4969847df332aa7d')
+
+prepare() {
+ mkdir -p build
+
+ # Hack to force using python2
+ mkdir -p bin
+ ln -s /usr/bin/python2 bin/python
+
+ cd ${_pkgfqn}
+
+ # FreeType 2.8.1
+ patch -Np1 -i ../qtwebengine-harmony.patch
+ # Disable GPU rendering on nouveau and wayland (openSUSE) https://bugreports.qt.io/browse/QTBUG-65682
+ # patch -p1 -i ../qtwebengine-no-gpu.patch
+ # Fix falkon crashes
+ patch -p1 -i ../qtbug-66333.patch
+ patch -p1 -i ../qtbug-66338.patch
+}
+
+build() {
+ cd build
+
+ export PATH="$srcdir/bin:$PATH"
+ qmake ../${_pkgfqn} -- \
+ -proprietary-codecs \
+ -system-ffmpeg \
+ -webp \
+ -spellchecker
+# -webengine-icu
+ make
+}
+
+package() {
+ cd build
+ make INSTALL_ROOT="$pkgdir" install
+
+ # Drop QMAKE_PRL_BUILD_DIR because reference the build dir
+ find "$pkgdir/usr/lib" -type f -name '*.prl' \
+ -exec sed -i -e '/^QMAKE_PRL_BUILD_DIR/d' {} \;
+
+ install -Dm644 "$srcdir"/${_pkgfqn}/src/3rdparty/chromium/LICENSE "$pkgdir"/usr/share/licenses/${pkgname}/LICENSE.chromium
+}
Copied: qt5-webengine/repos/kde-unstable-x86_64/qtbug-66333.patch (from rev 319784, qt5-webengine/kde-unstable/qtbug-66333.patch)
===================================================================
--- qtbug-66333.patch (rev 0)
+++ qtbug-66333.patch 2018-03-21 22:28:29 UTC (rev 319785)
@@ -0,0 +1,870 @@
+From 235def8f2af6b858f5c8eafd8bc9a411a53dc7e9 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?J=C3=BCri=20Valdmann?= <juri.valdmann at qt.io>
+Date: Mon, 19 Feb 2018 11:25:24 +0100
+Subject: [PATCH] Make WebChannelIPCTransport into a RenderFrameObserver
+
+As of version 63, Chromium creates proxy frames also for the main frame in the
+frame tree during cross-process navigations. This leads to a segmentation fault
+in WebChannelIPCTransport because we assume that all main frames are local.
+
+See https://crrev.com/27caae83cb530daaf49f9a38793e427cdf493a65 for details.
+
+This patch refactors the renderer-side WebChannelIPCTransport from a
+RenderViewObserver into a RenderFrameObserver, which prevents the segmentation
+fault since the RenderFrameObserver is not created for proxy frames. Most likely
+this would have to be done eventually anyway since the RenderView and
+RenderViewObserver classes are deprecated and will likely be removed as part of
+the Site Isolation project.
+
+Installation is changed to follow Chromium's RenderFrameImpl in the sense of
+performing the installation from RenderFrameObserver::DidClearWindowObject
+instead of ContentRendererClient::RunScriptsAtDocumentStart. This has the
+benefit of avoiding the ScriptForbiddenScope DCHECK.
+
+Additionally there are the following minor changes:
+
+ - The deprecated parameterless version of v8::Value::ToObject() method is
+ replaced with v8::Value::IsObject() check and v8::Local::Cast.
+
+ - The deprecated v8::Handle typedef is replaced with v8::Local.
+
+ - The deprecated single-parameter WebContentsObserver::OnMessageReceived is
+ replaced with the new two-parameter version.
+
+ - blink::MainThreadIsolate() is used instead of v8::Isolate::GetCurrent() for
+ Install/Uninstall since we know we are executing on the main thread.
+
+ - WebChannelIPCTransportHost is changed to ignore messages from unexpected
+ renderers in case something goes wrong with the renderers.
+
+ - Logging is added to WebChannelIPCTransportHost for debugging purposes.
+
+Some new unit tests are added, all of which fail with the old version.
+
+Task-number: QTBUG-66333
+Change-Id: I936d142fb042d9f936a3f9d08d4328ecba595f1f
+---
+ src/core/common/qt_messages.h | 3 +-
+ src/core/renderer/content_renderer_client_qt.cpp | 5 +-
+ src/core/renderer/web_channel_ipc_transport.cpp | 237 ++++++++++-----------
+ src/core/renderer/web_channel_ipc_transport.h | 36 ++--
+ .../web_channel_ipc_transport_host.cpp | 89 ++++----
+ .../renderer_host/web_channel_ipc_transport_host.h | 32 +--
+ .../qwebenginescript/tst_qwebenginescript.cpp | 121 ++++++++++-
+ 7 files changed, 312 insertions(+), 211 deletions(-)
+
+diff --git a/src/core/common/qt_messages.h b/src/core/common/qt_messages.h
+index 3bedb10d217..864c3ea454d 100644
+--- a/src/core/common/qt_messages.h
++++ b/src/core/common/qt_messages.h
+@@ -39,8 +39,7 @@ IPC_MESSAGE_ROUTED1(RenderViewObserverQt_FetchDocumentInnerText,
+ IPC_MESSAGE_ROUTED1(RenderViewObserverQt_SetBackgroundColor,
+ uint32_t /* color */)
+
+-IPC_MESSAGE_ROUTED1(WebChannelIPCTransport_Install, uint /* worldId */)
+-IPC_MESSAGE_ROUTED1(WebChannelIPCTransport_Uninstall, uint /* worldId */)
++IPC_MESSAGE_ROUTED1(WebChannelIPCTransport_SetWorldId, base::Optional<uint> /* worldId */)
+ IPC_MESSAGE_ROUTED2(WebChannelIPCTransport_Message, std::vector<char> /*binaryJSON*/, uint /* worldId */)
+
+ // User scripts messages
+diff --git a/src/core/renderer/content_renderer_client_qt.cpp b/src/core/renderer/content_renderer_client_qt.cpp
+index a77bcf7854f..4f7c5cff4ad 100644
+--- a/src/core/renderer/content_renderer_client_qt.cpp
++++ b/src/core/renderer/content_renderer_client_qt.cpp
+@@ -124,13 +124,14 @@ void ContentRendererClientQt::RenderViewCreated(content::RenderView* render_view
+ {
+ // RenderViewObservers destroy themselves with their RenderView.
+ new RenderViewObserverQt(render_view, m_webCacheImpl.data());
+- new WebChannelIPCTransport(render_view);
+ UserResourceController::instance()->renderViewCreated(render_view);
+ }
+
+ void ContentRendererClientQt::RenderFrameCreated(content::RenderFrame* render_frame)
+ {
+ new QtWebEngineCore::RenderFrameObserverQt(render_frame);
++ if (render_frame->IsMainFrame())
++ new WebChannelIPCTransport(render_frame);
+ UserResourceController::instance()->renderFrameCreated(render_frame);
+
+ #if BUILDFLAG(ENABLE_SPELLCHECK)
+@@ -151,8 +152,6 @@ void ContentRendererClientQt::RunScriptsAtDocumentStart(content::RenderFrame* re
+ if (!render_frame_observer || render_frame_observer->isFrameDetached())
+ return; // The frame is invisible to scripts.
+
+- if (WebChannelIPCTransport *transport = WebChannelIPCTransport::Get(render_frame->GetRenderView()))
+- transport->RunScriptsAtDocumentStart(render_frame);
+ UserResourceController::instance()->RunScriptsAtDocumentStart(render_frame);
+ }
+
+diff --git a/src/core/renderer/web_channel_ipc_transport.cpp b/src/core/renderer/web_channel_ipc_transport.cpp
+index 534ee302dcb..bb544168f7b 100644
+--- a/src/core/renderer/web_channel_ipc_transport.cpp
++++ b/src/core/renderer/web_channel_ipc_transport.cpp
+@@ -45,13 +45,12 @@
+ #include "common/qt_messages.h"
+
+ #include "content/public/renderer/render_frame.h"
+-#include "content/public/renderer/render_view.h"
+ #include "gin/arguments.h"
+ #include "gin/handle.h"
+ #include "gin/object_template_builder.h"
+ #include "gin/wrappable.h"
++#include "third_party/WebKit/public/web/WebKit.h"
+ #include "third_party/WebKit/public/web/WebLocalFrame.h"
+-#include "third_party/WebKit/public/web/WebView.h"
+ #include "v8/include/v8.h"
+
+ #include <QJsonDocument>
+@@ -61,193 +60,189 @@ namespace QtWebEngineCore {
+ class WebChannelTransport : public gin::Wrappable<WebChannelTransport> {
+ public:
+ static gin::WrapperInfo kWrapperInfo;
+- static void Install(blink::WebFrame *frame, uint worldId);
+- static void Uninstall(blink::WebFrame *frame, uint worldId);
++ static void Install(blink::WebLocalFrame *frame, uint worldId);
++ static void Uninstall(blink::WebLocalFrame *frame, uint worldId);
+ private:
+- content::RenderView *GetRenderView(v8::Isolate *isolate);
+- WebChannelTransport() { }
+- gin::ObjectTemplateBuilder GetObjectTemplateBuilder(v8::Isolate *isolate) override;
++ WebChannelTransport() {}
++ bool NativeQtSendMessage(gin::Arguments *args);
+
+- bool NativeQtSendMessage(gin::Arguments *args)
+- {
+- content::RenderView *renderView = GetRenderView(args->isolate());
+- if (!renderView || args->Length() != 1)
+- return false;
+- v8::Handle<v8::Value> val;
+- args->GetNext(&val);
+- if (!val->IsString() && !val->IsStringObject())
+- return false;
+- v8::String::Utf8Value utf8(val->ToString());
+-
+- QByteArray valueData(*utf8, utf8.length());
+- QJsonParseError error;
+- QJsonDocument doc = QJsonDocument::fromJson(valueData, &error);
+- if (error.error != QJsonParseError::NoError) {
+- qWarning("%s %d: Parsing error: %s",__FILE__, __LINE__, qPrintable(error.errorString()));
+- return false;
+- }
+- int size = 0;
+- const char *rawData = doc.rawData(&size);
+- if (size == 0)
+- return false;
+- renderView->Send(new WebChannelIPCTransportHost_SendMessage(renderView->GetRoutingID(), std::vector<char>(rawData, rawData + size)));
+- return true;
+- }
++ // gin::WrappableBase
++ gin::ObjectTemplateBuilder GetObjectTemplateBuilder(v8::Isolate *isolate) override;
+
+ DISALLOW_COPY_AND_ASSIGN(WebChannelTransport);
+ };
+
+ gin::WrapperInfo WebChannelTransport::kWrapperInfo = { gin::kEmbedderNativeGin };
+
+-void WebChannelTransport::Install(blink::WebFrame *frame, uint worldId)
++void WebChannelTransport::Install(blink::WebLocalFrame *frame, uint worldId)
+ {
+- v8::Isolate *isolate = v8::Isolate::GetCurrent();
++ v8::Isolate *isolate = blink::MainThreadIsolate();
+ v8::HandleScope handleScope(isolate);
+- v8::Handle<v8::Context> context;
++ v8::Local<v8::Context> context;
+ if (worldId == 0)
+- context = frame->ToWebLocalFrame()->MainWorldScriptContext();
++ context = frame->MainWorldScriptContext();
+ else
+- context = frame->ToWebLocalFrame()->IsolatedWorldScriptContext(worldId);
++ context = frame->IsolatedWorldScriptContext(worldId);
+ v8::Context::Scope contextScope(context);
+
+ gin::Handle<WebChannelTransport> transport = gin::CreateHandle(isolate, new WebChannelTransport);
+- v8::Handle<v8::Object> global = context->Global();
+- v8::Handle<v8::Object> qt = global->Get(gin::StringToV8(isolate, "qt"))->ToObject();
+- if (qt.IsEmpty()) {
+- qt = v8::Object::New(isolate);
+- global->Set(gin::StringToV8(isolate, "qt"), qt);
++
++ v8::Local<v8::Object> global = context->Global();
++ v8::Local<v8::Value> qtObjectValue = global->Get(gin::StringToV8(isolate, "qt"));
++ v8::Local<v8::Object> qtObject;
++ if (qtObjectValue.IsEmpty() || !qtObjectValue->IsObject()) {
++ qtObject = v8::Object::New(isolate);
++ global->Set(gin::StringToV8(isolate, "qt"), qtObject);
++ } else {
++ qtObject = v8::Local<v8::Object>::Cast(qtObjectValue);
+ }
+- qt->Set(gin::StringToV8(isolate, "webChannelTransport"), transport.ToV8());
++ qtObject->Set(gin::StringToV8(isolate, "webChannelTransport"), transport.ToV8());
+ }
+
+-void WebChannelTransport::Uninstall(blink::WebFrame *frame, uint worldId)
++void WebChannelTransport::Uninstall(blink::WebLocalFrame *frame, uint worldId)
+ {
+- v8::Isolate *isolate = v8::Isolate::GetCurrent();
++ v8::Isolate *isolate = blink::MainThreadIsolate();
+ v8::HandleScope handleScope(isolate);
+- v8::Handle<v8::Context> context;
++ v8::Local<v8::Context> context;
+ if (worldId == 0)
+- context = frame->ToWebLocalFrame()->MainWorldScriptContext();
++ context = frame->MainWorldScriptContext();
+ else
+- context = frame->ToWebLocalFrame()->IsolatedWorldScriptContext(worldId);
++ context = frame->IsolatedWorldScriptContext(worldId);
+ v8::Context::Scope contextScope(context);
+
+- v8::Handle<v8::Object> global(context->Global());
+- v8::Handle<v8::Object> qt = global->Get(gin::StringToV8(isolate, "qt"))->ToObject();
+- if (qt.IsEmpty())
++ v8::Local<v8::Object> global(context->Global());
++ v8::Local<v8::Value> qtObjectValue = global->Get(gin::StringToV8(isolate, "qt"));
++ if (qtObjectValue.IsEmpty() || !qtObjectValue->IsObject())
+ return;
+- qt->Delete(gin::StringToV8(isolate, "webChannelTransport"));
+-}
+-
+-gin::ObjectTemplateBuilder WebChannelTransport::GetObjectTemplateBuilder(v8::Isolate *isolate)
+-{
+- return gin::Wrappable<WebChannelTransport>::GetObjectTemplateBuilder(isolate).SetMethod("send", &WebChannelTransport::NativeQtSendMessage);
++ v8::Local<v8::Object> qtObject = v8::Local<v8::Object>::Cast(qtObjectValue);
++ qtObject->Delete(gin::StringToV8(isolate, "webChannelTransport"));
+ }
+
+-content::RenderView *WebChannelTransport::GetRenderView(v8::Isolate *isolate)
++bool WebChannelTransport::NativeQtSendMessage(gin::Arguments *args)
+ {
+- blink::WebLocalFrame *webframe = blink::WebLocalFrame::FrameForContext(isolate->GetCurrentContext());
+- DCHECK(webframe) << "There should be an active frame since we just got a native function called.";
+- if (!webframe)
+- return 0;
++ blink::WebLocalFrame *frame = blink::WebLocalFrame::FrameForCurrentContext();
++ if (!frame || !frame->View())
++ return false;
++
++ content::RenderFrame *renderFrame = content::RenderFrame::FromWebFrame(frame);
++ if (!renderFrame)
++ return false;
++
++ std::string message;
++ if (!args->GetNext(&message))
++ return false;
++
++ QByteArray valueData(message.data(), message.size());
++ QJsonParseError error;
++ QJsonDocument doc = QJsonDocument::fromJson(valueData, &error);
++ if (error.error != QJsonParseError::NoError) {
++ LOG(WARNING) << "Parsing error: " << qPrintable(error.errorString());
++ return false;
++ }
+
+- blink::WebView *webview = webframe->View();
+- if (!webview)
+- return 0; // can happen during closing
++ int size = 0;
++ const char *rawData = doc.rawData(&size);
++ if (size == 0)
++ return false;
+
+- return content::RenderView::FromWebView(webview);
++ renderFrame->Send(new WebChannelIPCTransportHost_SendMessage(
++ renderFrame->GetRoutingID(),
++ std::vector<char>(rawData, rawData + size)));
++ return true;
+ }
+
+-WebChannelIPCTransport::WebChannelIPCTransport(content::RenderView *renderView)
+- : content::RenderViewObserver(renderView)
+- , content::RenderViewObserverTracker<WebChannelIPCTransport>(renderView)
+- , m_installed(false)
+- , m_installedWorldId(0)
++gin::ObjectTemplateBuilder WebChannelTransport::GetObjectTemplateBuilder(v8::Isolate *isolate)
+ {
++ return gin::Wrappable<WebChannelTransport>::GetObjectTemplateBuilder(isolate)
++ .SetMethod("send", &WebChannelTransport::NativeQtSendMessage);
+ }
+
+-void WebChannelIPCTransport::RunScriptsAtDocumentStart(content::RenderFrame *render_frame)
++WebChannelIPCTransport::WebChannelIPCTransport(content::RenderFrame *renderFrame)
++ : content::RenderFrameObserver(renderFrame)
+ {
+- // JavaScript run before this point doesn't stick, and needs to be redone.
+- // ### FIXME: we should try no even installing before
+- if (m_installed && render_frame->IsMainFrame())
+- WebChannelTransport::Install(render_frame->GetWebFrame(), m_installedWorldId);
+ }
+
+-
+-void WebChannelIPCTransport::installWebChannel(uint worldId)
++void WebChannelIPCTransport::setWorldId(base::Optional<uint> worldId)
+ {
+- blink::WebView *webView = render_view()->GetWebView();
+- if (!webView)
++ if (m_worldId == worldId)
+ return;
+- WebChannelTransport::Install(webView->MainFrame(), worldId);
+- m_installed = true;
+- m_installedWorldId = worldId;
+-}
+
+-void WebChannelIPCTransport::uninstallWebChannel(uint worldId)
+-{
+- Q_ASSERT(worldId == m_installedWorldId);
+- blink::WebView *webView = render_view()->GetWebView();
+- if (!webView)
+- return;
+- WebChannelTransport::Uninstall(webView->MainFrame(), worldId);
+- m_installed = false;
++ if (m_worldId && m_canUseContext)
++ WebChannelTransport::Uninstall(render_frame()->GetWebFrame(), *m_worldId);
++
++ m_worldId = worldId;
++
++ if (m_worldId && m_canUseContext)
++ WebChannelTransport::Install(render_frame()->GetWebFrame(), *m_worldId);
+ }
+
+-void WebChannelIPCTransport::dispatchWebChannelMessage(const std::vector<char> &binaryJSON, uint worldId)
++void WebChannelIPCTransport::dispatchWebChannelMessage(const std::vector<char> &binaryJson, uint worldId)
+ {
+- blink::WebView *webView = render_view()->GetWebView();
+- if (!webView)
+- return;
++ DCHECK(m_canUseContext);
++ DCHECK(m_worldId == worldId);
+
+- QJsonDocument doc = QJsonDocument::fromRawData(binaryJSON.data(), binaryJSON.size(), QJsonDocument::BypassValidation);
+- Q_ASSERT(doc.isObject());
++ QJsonDocument doc = QJsonDocument::fromRawData(binaryJson.data(), binaryJson.size(), QJsonDocument::BypassValidation);
++ DCHECK(doc.isObject());
+ QByteArray json = doc.toJson(QJsonDocument::Compact);
+
+- v8::Isolate *isolate = v8::Isolate::GetCurrent();
++ blink::WebLocalFrame *frame = render_frame()->GetWebFrame();
++ v8::Isolate *isolate = blink::MainThreadIsolate();
+ v8::HandleScope handleScope(isolate);
+- blink::WebFrame *frame = webView->MainFrame();
+- v8::Handle<v8::Context> context;
++ v8::Local<v8::Context> context;
+ if (worldId == 0)
+- context = frame->ToWebLocalFrame()->MainWorldScriptContext();
++ context = frame->MainWorldScriptContext();
+ else
+- context = frame->ToWebLocalFrame()->IsolatedWorldScriptContext(worldId);
++ context = frame->IsolatedWorldScriptContext(worldId);
+ v8::Context::Scope contextScope(context);
+
+- v8::Handle<v8::Object> global(context->Global());
+- v8::Handle<v8::Value> qtObjectValue(global->Get(gin::StringToV8(isolate, "qt")));
+- if (!qtObjectValue->IsObject())
++ v8::Local<v8::Object> global(context->Global());
++ v8::Local<v8::Value> qtObjectValue(global->Get(gin::StringToV8(isolate, "qt")));
++ if (qtObjectValue.IsEmpty() || !qtObjectValue->IsObject())
+ return;
+- v8::Handle<v8::Value> webChannelObjectValue(qtObjectValue->ToObject()->Get(gin::StringToV8(isolate, "webChannelTransport")));
+- if (!webChannelObjectValue->IsObject())
++ v8::Local<v8::Object> qtObject = v8::Local<v8::Object>::Cast(qtObjectValue);
++ v8::Local<v8::Value> webChannelObjectValue(qtObject->Get(gin::StringToV8(isolate, "webChannelTransport")));
++ if (webChannelObjectValue.IsEmpty() || !webChannelObjectValue->IsObject())
+ return;
+- v8::Handle<v8::Value> onmessageCallbackValue(webChannelObjectValue->ToObject()->Get(gin::StringToV8(isolate, "onmessage")));
+- if (!onmessageCallbackValue->IsFunction()) {
+- qWarning("onmessage is not a callable property of qt.webChannelTransport. Some things might not work as expected.");
++ v8::Local<v8::Object> webChannelObject = v8::Local<v8::Object>::Cast(webChannelObjectValue);
++ v8::Local<v8::Value> callbackValue(webChannelObject->Get(gin::StringToV8(isolate, "onmessage")));
++ if (callbackValue.IsEmpty() || !callbackValue->IsFunction()) {
++ LOG(WARNING) << "onmessage is not a callable property of qt.webChannelTransport. Some things might not work as expected.";
+ return;
+ }
+
+- v8::Handle<v8::Object> messageObject(v8::Object::New(isolate));
++ v8::Local<v8::Object> messageObject(v8::Object::New(isolate));
+ v8::Maybe<bool> wasSet = messageObject->DefineOwnProperty(
+ context,
+ v8::String::NewFromUtf8(isolate, "data"),
+ v8::String::NewFromUtf8(isolate, json.constData(), v8::String::kNormalString, json.size()),
+ v8::PropertyAttribute(v8::ReadOnly | v8::DontDelete));
+- Q_ASSERT(!wasSet.IsNothing() && wasSet.FromJust());
++ DCHECK(!wasSet.IsNothing() && wasSet.FromJust());
++
++ v8::Local<v8::Function> callback = v8::Local<v8::Function>::Cast(callbackValue);
++ v8::Local<v8::Value> argv[] = { messageObject };
++ frame->CallFunctionEvenIfScriptDisabled(callback, webChannelObject, 1, argv);
++}
++
++void WebChannelIPCTransport::WillReleaseScriptContext(v8::Local<v8::Context> context, int worldId)
++{
++ if (static_cast<uint>(worldId) == m_worldId)
++ m_canUseContext = false;
++}
+
+- v8::Handle<v8::Function> callback = v8::Handle<v8::Function>::Cast(onmessageCallbackValue);
+- const int argc = 1;
+- v8::Handle<v8::Value> argv[argc];
+- argv[0] = messageObject;
+- frame->ToWebLocalFrame()->CallFunctionEvenIfScriptDisabled(callback, webChannelObjectValue->ToObject(), argc, argv);
++void WebChannelIPCTransport::DidClearWindowObject()
++{
++ if (!m_canUseContext) {
++ m_canUseContext = true;
++ if (m_worldId)
++ WebChannelTransport::Install(render_frame()->GetWebFrame(), *m_worldId);
++ }
+ }
+
+ bool WebChannelIPCTransport::OnMessageReceived(const IPC::Message &message)
+ {
+ bool handled = true;
+ IPC_BEGIN_MESSAGE_MAP(WebChannelIPCTransport, message)
+- IPC_MESSAGE_HANDLER(WebChannelIPCTransport_Install, installWebChannel)
+- IPC_MESSAGE_HANDLER(WebChannelIPCTransport_Uninstall, uninstallWebChannel)
++ IPC_MESSAGE_HANDLER(WebChannelIPCTransport_SetWorldId, setWorldId)
+ IPC_MESSAGE_HANDLER(WebChannelIPCTransport_Message, dispatchWebChannelMessage)
+ IPC_MESSAGE_UNHANDLED(handled = false)
+ IPC_END_MESSAGE_MAP()
+@@ -259,4 +254,4 @@ void WebChannelIPCTransport::OnDestruct()
+ delete this;
+ }
+
+-} // namespace
++} // namespace QtWebEngineCore
+diff --git a/src/core/renderer/web_channel_ipc_transport.h b/src/core/renderer/web_channel_ipc_transport.h
+index 04041c6c7d0..19494360a5a 100644
+--- a/src/core/renderer/web_channel_ipc_transport.h
++++ b/src/core/renderer/web_channel_ipc_transport.h
+@@ -40,41 +40,31 @@
+ #ifndef WEB_CHANNEL_IPC_TRANSPORT_H
+ #define WEB_CHANNEL_IPC_TRANSPORT_H
+
+-#include "base/values.h"
+-#include "content/public/renderer/render_view_observer.h"
+-#include "content/public/renderer/render_view_observer_tracker.h"
++#include "content/public/renderer/render_frame_observer.h"
+
+ #include <QtCore/qglobal.h>
+
+-namespace content {
+-class RenderFrame;
+-}
+-
+-namespace v8 {
+-class Extension;
+-}
+-
+ namespace QtWebEngineCore {
+
+-class WebChannelIPCTransport : public content::RenderViewObserver
+- , public content::RenderViewObserverTracker<WebChannelIPCTransport>
+-{
++class WebChannelIPCTransport : private content::RenderFrameObserver {
+ public:
+- WebChannelIPCTransport(content::RenderView *);
+-
+- void RunScriptsAtDocumentStart(content::RenderFrame *render_frame);
++ WebChannelIPCTransport(content::RenderFrame *);
+
+ private:
+- void dispatchWebChannelMessage(const std::vector<char> &binaryJSON, uint worldId);
+- void installWebChannel(uint worldId);
+- void uninstallWebChannel(uint worldId);
++ void setWorldId(base::Optional<uint> worldId);
++ void dispatchWebChannelMessage(const std::vector<char> &binaryJson, uint worldId);
+
+- // content::RenderViewObserver overrides:
++ // RenderFrameObserver
++ void WillReleaseScriptContext(v8::Local<v8::Context> context, int worldId) override;
++ void DidClearWindowObject() override;
+ bool OnMessageReceived(const IPC::Message &message) override;
+ void OnDestruct() override;
+
+- bool m_installed;
+- uint m_installedWorldId;
++ // The worldId from our WebChannelIPCTransportHost or empty when there is no
++ // WebChannelIPCTransportHost.
++ base::Optional<uint> m_worldId;
++ // True means it's currently OK to manipulate the frame's script context.
++ bool m_canUseContext = false;
+ };
+
+ } // namespace
+diff --git a/src/core/renderer_host/web_channel_ipc_transport_host.cpp b/src/core/renderer_host/web_channel_ipc_transport_host.cpp
+index b624d7e454d..6b32093a6c3 100644
+--- a/src/core/renderer_host/web_channel_ipc_transport_host.cpp
++++ b/src/core/renderer_host/web_channel_ipc_transport_host.cpp
+@@ -1,6 +1,6 @@
+ /****************************************************************************
+ **
+-** Copyright (C) 2016 The Qt Company Ltd.
++** Copyright (C) 2018 The Qt Company Ltd.
+ ** Contact: https://www.qt.io/licensing/
+ **
+ ** This file is part of the QtWebEngine module of the Qt Toolkit.
+@@ -39,70 +39,71 @@
+
+ #include "web_channel_ipc_transport_host.h"
+
+-#include "base/strings/string16.h"
+-#include "content/public/browser/render_view_host.h"
++#include "content/public/browser/render_frame_host.h"
++#include "content/public/browser/render_process_host.h"
+ #include "content/public/browser/web_contents.h"
+
+ #include "common/qt_messages.h"
+-#include "type_conversion.h"
+
+ #include <QJsonDocument>
+ #include <QJsonObject>
++#include <QLoggingCategory>
+
+ namespace QtWebEngineCore {
+
++Q_LOGGING_CATEGORY(log, "qt.webengine.webchanneltransport");
++
++inline QDebug operator<<(QDebug stream, content::RenderFrameHost *frame)
++{
++ return stream << "frame " << frame->GetRoutingID() << " in process " << frame->GetProcess()->GetID();
++}
++
++template <class T>
++inline QDebug operator<<(QDebug stream, const base::Optional<T> &opt)
++{
++ if (opt)
++ return stream << *opt;
++ else
++ return stream << "nullopt";
++}
++
+ WebChannelIPCTransportHost::WebChannelIPCTransportHost(content::WebContents *contents, uint worldId, QObject *parent)
+ : QWebChannelAbstractTransport(parent)
+ , content::WebContentsObserver(contents)
+- , m_worldId(worldId)
+ {
+- contents->GetRenderViewHost()->Send(
+- new WebChannelIPCTransport_Install(
+- contents->GetRenderViewHost()->GetRoutingID(),
+- m_worldId));
++ setWorldId(worldId);
+ }
+
+ WebChannelIPCTransportHost::~WebChannelIPCTransportHost()
+ {
++ setWorldId(base::nullopt);
+ }
+
+-void WebChannelIPCTransportHost::RenderViewHostChanged(content::RenderViewHost *oldHost, content::RenderViewHost *)
+-{
+- if (oldHost)
+- oldHost->Send(new WebChannelIPCTransport_Uninstall(oldHost->GetRoutingID(), m_worldId));
+-}
+-
+-void WebChannelIPCTransportHost::RenderViewCreated(content::RenderViewHost *view_host)
++void WebChannelIPCTransportHost::sendMessage(const QJsonObject &message)
+ {
+- // Make sure the new view knows a webchannel is installed and in which world.
+- view_host->Send(new WebChannelIPCTransport_Install(view_host->GetRoutingID(), m_worldId));
++ QJsonDocument doc(message);
++ int size = 0;
++ const char *rawData = doc.rawData(&size);
++ content::RenderFrameHost *frame = web_contents()->GetMainFrame();
++ qCDebug(log).nospace() << "sending webchannel message to " << frame << ": " << doc;
++ frame->Send(new WebChannelIPCTransport_Message(frame->GetRoutingID(), std::vector<char>(rawData, rawData + size), *m_worldId));
+ }
+
+-void WebChannelIPCTransportHost::setWorldId(uint worldId)
++void WebChannelIPCTransportHost::setWorldId(base::Optional<uint> worldId)
+ {
+- if (worldId == m_worldId)
++ if (m_worldId == worldId)
+ return;
+- web_contents()->GetRenderViewHost()->Send(
+- new WebChannelIPCTransport_Uninstall(
+- web_contents()->GetRenderViewHost()->GetRoutingID(),
+- m_worldId));
++ for (content::RenderFrameHost *frame : web_contents()->GetAllFrames())
++ setWorldId(frame, worldId);
+ m_worldId = worldId;
+- web_contents()->GetRenderViewHost()->Send(
+- new WebChannelIPCTransport_Install(
+- web_contents()->GetRenderViewHost()->GetRoutingID(),
+- m_worldId));
+ }
+
+-void WebChannelIPCTransportHost::sendMessage(const QJsonObject &message)
++void WebChannelIPCTransportHost::setWorldId(content::RenderFrameHost *frame, base::Optional<uint> worldId)
+ {
+- QJsonDocument doc(message);
+- int size = 0;
+- const char *rawData = doc.rawData(&size);
+- web_contents()->GetRenderViewHost()->Send(
+- new WebChannelIPCTransport_Message(
+- web_contents()->GetRenderViewHost()->GetRoutingID(),
+- std::vector<char>(rawData, rawData + size),
+- m_worldId));
++ if (!frame->IsRenderFrameLive())
++ return;
++ qCDebug(log).nospace() << "sending setWorldId(" << worldId << ") message to " << frame;
++ frame->Send(new WebChannelIPCTransport_SetWorldId(frame->GetRoutingID(), worldId));
+ }
+
+ void WebChannelIPCTransportHost::onWebChannelMessage(const std::vector<char> &message)
+@@ -110,11 +111,21 @@ void WebChannelIPCTransportHost::onWebChannelMessage(const std::vector<char> &me
+ Q_ASSERT(!message.empty());
+ QJsonDocument doc = QJsonDocument::fromRawData(message.data(), message.size(), QJsonDocument::BypassValidation);
+ Q_ASSERT(doc.isObject());
++ content::RenderFrameHost *frame = web_contents()->GetMainFrame();
++ qCDebug(log).nospace() << "received webchannel message from " << frame << ": " << doc;
+ Q_EMIT messageReceived(doc.object(), this);
+ }
+
+-bool WebChannelIPCTransportHost::OnMessageReceived(const IPC::Message &message)
++void WebChannelIPCTransportHost::RenderFrameCreated(content::RenderFrameHost *frame)
+ {
++ setWorldId(frame, m_worldId);
++}
++
++bool WebChannelIPCTransportHost::OnMessageReceived(const IPC::Message& message, content::RenderFrameHost *receiver)
++{
++ if (receiver != web_contents()->GetMainFrame())
++ return false;
++
+ bool handled = true;
+ IPC_BEGIN_MESSAGE_MAP(WebChannelIPCTransportHost, message)
+ IPC_MESSAGE_HANDLER(WebChannelIPCTransportHost_SendMessage, onWebChannelMessage)
+@@ -123,4 +134,4 @@ bool WebChannelIPCTransportHost::OnMessageReceived(const IPC::Message &message)
+ return handled;
+ }
+
+-} // namespace
++} // namespace QtWebEngineCore
+diff --git a/src/core/renderer_host/web_channel_ipc_transport_host.h b/src/core/renderer_host/web_channel_ipc_transport_host.h
+index a1e697a910a..3a814a79419 100644
+--- a/src/core/renderer_host/web_channel_ipc_transport_host.h
++++ b/src/core/renderer_host/web_channel_ipc_transport_host.h
+@@ -1,6 +1,6 @@
+ /****************************************************************************
+ **
+-** Copyright (C) 2016 The Qt Company Ltd.
++** Copyright (C) 2018 The Qt Company Ltd.
+ ** Contact: https://www.qt.io/licensing/
+ **
+ ** This file is part of the QtWebEngine module of the Qt Toolkit.
+@@ -40,38 +40,40 @@
+ #ifndef WEB_CHANNEL_IPC_TRANSPORT_H
+ #define WEB_CHANNEL_IPC_TRANSPORT_H
+
++#include "qtwebenginecoreglobal.h"
+
+-#include <QtWebChannel/QWebChannelAbstractTransport>
+ #include "content/public/browser/web_contents_observer.h"
+
+-#include "qtwebenginecoreglobal.h"
+-#include <QtCore/QObject>
++#include <QWebChannelAbstractTransport>
+
+ QT_FORWARD_DECLARE_CLASS(QString)
+
+ namespace QtWebEngineCore {
+
+ class WebChannelIPCTransportHost : public QWebChannelAbstractTransport
+- , public content::WebContentsObserver
+-{
++ , private content::WebContentsObserver {
+ public:
+- WebChannelIPCTransportHost(content::WebContents *, uint worldId = 0, QObject *parent = 0);
++ WebChannelIPCTransportHost(content::WebContents *webContents, uint worldId = 0, QObject *parent = nullptr);
+ virtual ~WebChannelIPCTransportHost();
+
+- // WebContentsObserver
+- void RenderViewHostChanged(content::RenderViewHost* old_host, content::RenderViewHost* new_host) override;
+- void RenderViewCreated(content::RenderViewHost* render_view_host) override;
++ void setWorldId(uint worldId) { setWorldId(base::Optional<uint>(worldId)); }
++ uint worldId() const { return *m_worldId; }
+
+ // QWebChannelAbstractTransport
+ void sendMessage(const QJsonObject &message) override;
+
+- void setWorldId(uint worldId);
+- uint worldId() const { return m_worldId; }
+-
+ private:
+- bool OnMessageReceived(const IPC::Message& message) override;
++ void setWorldId(base::Optional<uint> worldId);
++ void setWorldId(content::RenderFrameHost *frame, base::Optional<uint> worldId);
+ void onWebChannelMessage(const std::vector<char> &message);
+- uint m_worldId;
++
++ // WebContentsObserver
++ void RenderFrameCreated(content::RenderFrameHost *frame) override;
++ bool OnMessageReceived(const IPC::Message& message, content::RenderFrameHost *receiver) override;
++
++ // Empty only during construction/destruction. Synchronized to all the
++ // WebChannelIPCTransports/RenderFrames in the observed WebContents.
++ base::Optional<uint> m_worldId;
+ };
+
+ } // namespace
+diff --git a/tests/auto/widgets/qwebenginescript/tst_qwebenginescript.cpp b/tests/auto/widgets/qwebenginescript/tst_qwebenginescript.cpp
+index d852ca90200..e342632e75f 100644
+--- a/tests/auto/widgets/qwebenginescript/tst_qwebenginescript.cpp
++++ b/tests/auto/widgets/qwebenginescript/tst_qwebenginescript.cpp
+@@ -20,6 +20,7 @@
+ #include <QtTest/QtTest>
+
+ #include <qwebenginepage.h>
++#include <qwebengineprofile.h>
+ #include <qwebenginescript.h>
+ #include <qwebenginescriptcollection.h>
+ #include <qwebengineview.h>
+@@ -39,6 +40,9 @@ private Q_SLOTS:
+ void webChannel();
+ void noTransportWithoutWebChannel();
+ void scriptsInNestedIframes();
++ void webChannelResettingAndUnsetting();
++ void webChannelWithExistingQtObject();
++ void navigation();
+ };
+
+ void tst_QWebEngineScript::domEditing()
+@@ -183,6 +187,27 @@ private:
+ QString m_text;
+ };
+
++static QString readFile(const QString &path)
++{
++ QFile file(path);
++ file.open(QFile::ReadOnly);
++ QByteArray contents = file.readAll();
++ file.close();
++ return contents;
++}
++
++static QWebEngineScript webChannelScript()
++{
++ QString sourceCode = readFile(QStringLiteral(":/qwebchannel.js"));
++ if (sourceCode.isEmpty())
++ return {};
++
++ QWebEngineScript script;
++ script.setSourceCode(sourceCode);
++ script.setInjectionPoint(QWebEngineScript::DocumentCreation);
++ script.setWorldId(QWebEngineScript::MainWorld);
++ return script;
++}
+
+ void tst_QWebEngineScript::webChannel_data()
+ {
+@@ -204,15 +229,8 @@ void tst_QWebEngineScript::webChannel()
+ channel->registerObject(QStringLiteral("object"), &testObject);
+ page.setWebChannel(channel.data(), worldId);
+
+- QFile qwebchanneljs(":/qwebchannel.js");
+- QVERIFY(qwebchanneljs.exists());
+- qwebchanneljs.open(QFile::ReadOnly);
+- QByteArray scriptSrc = qwebchanneljs.readAll();
+- qwebchanneljs.close();
+- QWebEngineScript script;
+- script.setInjectionPoint(QWebEngineScript::DocumentCreation);
++ QWebEngineScript script = webChannelScript();
+ script.setWorldId(worldId);
+- script.setSourceCode(QString::fromLatin1(scriptSrc));
+ page.scripts().insert(script);
+ page.setHtml(QStringLiteral("<html><body></body></html>"));
+ QSignalSpy spyFinished(&page, &QWebEnginePage::loadFinished);
+@@ -300,6 +318,93 @@ void tst_QWebEngineScript::scriptsInNestedIframes()
+ QVariant::fromValue(QStringLiteral("Modified Inner text")));
+ }
+
++void tst_QWebEngineScript::webChannelResettingAndUnsetting()
++{
++ QWebEnginePage page;
++
++ // There should be no webChannelTransport yet.
++ QCOMPARE(evaluateJavaScriptSyncInWorld(&page, "qt.webChannelTransport", QWebEngineScript::MainWorld),
++ QVariant(QVariant::Invalid));
++ QCOMPARE(evaluateJavaScriptSyncInWorld(&page, "qt.webChannelTransport", QWebEngineScript::ApplicationWorld),
++ QVariant(QVariant::Invalid));
++
++ QWebChannel channel;
++ page.setWebChannel(&channel, QWebEngineScript::MainWorld);
++
++ // There should be one in MainWorld now.
++ QCOMPARE(evaluateJavaScriptSyncInWorld(&page, "qt.webChannelTransport", QWebEngineScript::MainWorld),
++ QVariant(QVariantMap()));
++ QCOMPARE(evaluateJavaScriptSyncInWorld(&page, "qt.webChannelTransport", QWebEngineScript::ApplicationWorld),
++ QVariant(QVariant::Invalid));
++
++ page.setWebChannel(&channel, QWebEngineScript::ApplicationWorld);
++
++ // Now it should have moved to ApplicationWorld.
++ QCOMPARE(evaluateJavaScriptSyncInWorld(&page, "qt.webChannelTransport", QWebEngineScript::MainWorld),
++ QVariant(QVariant::Invalid));
++ QCOMPARE(evaluateJavaScriptSyncInWorld(&page, "qt.webChannelTransport", QWebEngineScript::ApplicationWorld),
++ QVariant(QVariantMap()));
++
++ page.setWebChannel(nullptr);
++
++ // And now it should be gone again.
++ QCOMPARE(evaluateJavaScriptSyncInWorld(&page, "qt.webChannelTransport", QWebEngineScript::MainWorld),
++ QVariant(QVariant::Invalid));
++ QCOMPARE(evaluateJavaScriptSyncInWorld(&page, "qt.webChannelTransport", QWebEngineScript::ApplicationWorld),
++ QVariant(QVariant::Invalid));
++}
++
++void tst_QWebEngineScript::webChannelWithExistingQtObject()
++{
++ QWebEnginePage page;
++
++ evaluateJavaScriptSync(&page, "qt = 42");
++ QCOMPARE(evaluateJavaScriptSync(&page, "qt.webChannelTransport"), QVariant(QVariant::Invalid));
++
++ QWebChannel channel;
++ page.setWebChannel(&channel);
++
++ // setWebChannel should have overwritten the qt variable
++ QCOMPARE(evaluateJavaScriptSync(&page, "qt.webChannelTransport"), QVariant(QVariantMap()));
++}
++
++static QWebEngineScript locationMonitorScript()
++{
++ QWebEngineScript script = webChannelScript();
++ script.setSourceCode(script.sourceCode() + QStringLiteral(R"(
++ new QWebChannel(qt.webChannelTransport, channel => {
++ channel.objects.object.text = window.location.href;
++ })
++ )"));
++ return script;
++}
++
++void tst_QWebEngineScript::navigation()
++{
++ QWebEnginePage page;
++ TestObject testObject;
++ QSignalSpy spyTextChanged(&testObject, &TestObject::textChanged);
++ QWebChannel channel;
++ channel.registerObject(QStringLiteral("object"), &testObject);
++ page.setWebChannel(&channel);
++ page.scripts().insert(locationMonitorScript());
++
++ QString url1 = QStringLiteral("about:blank");
++ page.setUrl(url1);
++ QTRY_COMPARE(spyTextChanged.count(), 1);
++ QCOMPARE(testObject.text(), url1);
++
++ QString url2 = QStringLiteral("chrome://gpu/");
++ page.setUrl(url2);
++ QTRY_COMPARE(spyTextChanged.count(), 2);
++ QCOMPARE(testObject.text(), url2);
++
++ QString url3 = QStringLiteral("qrc:/resources/test_iframe_main.html");
++ page.setUrl(url3);
++ QTRY_COMPARE(spyTextChanged.count(), 3);
++ QCOMPARE(testObject.text(), url3);
++}
++
+ QTEST_MAIN(tst_QWebEngineScript)
+
+ #include "tst_qwebenginescript.moc"
+--
+2.16.2
+
Copied: qt5-webengine/repos/kde-unstable-x86_64/qtbug-66338.patch (from rev 319784, qt5-webengine/kde-unstable/qtbug-66338.patch)
===================================================================
--- qtbug-66338.patch (rev 0)
+++ qtbug-66338.patch 2018-03-21 22:28:29 UTC (rev 319785)
@@ -0,0 +1,196 @@
+From 0ab2905aeb3de6f3bcff10730be5b77a78022567 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?J=C3=BCri=20Valdmann?= <juri.valdmann at qt.io>
+Date: Mon, 5 Mar 2018 11:12:41 +0100
+Subject: [PATCH] Execute scripts asynchronously in UserResourceController
+
+Needed to avoid ScriptForbiddenScope DCHECK when executing isolated world
+scripts in subframes on document creation. The main frame does not trigger the
+DCHECK because the HTML parser is suspended and resumed before trying to execute
+the scripts, which bypasses the DCHECK. The subframe HTML parser seems to work
+in one go however, so some extra asynchronicity is needed.
+
+Also ExecuteScriptInIsolatedWorld is marked as deprecated in blink.
+
+Task-number: QTBUG-66338
+Change-Id: Ica4acb8ada4acc38aa5e1ca00e7512a2e69b785f
+---
+ src/core/renderer/user_resource_controller.cpp | 10 +++-
+ .../qwebenginescript/tst_qwebenginescript.cpp | 67 +++++++++++++++++-----
+ 2 files changed, 61 insertions(+), 16 deletions(-)
+
+diff --git a/src/core/renderer/user_resource_controller.cpp b/src/core/renderer/user_resource_controller.cpp
+index eed5208766f..129123577e4 100644
+--- a/src/core/renderer/user_resource_controller.cpp
++++ b/src/core/renderer/user_resource_controller.cpp
+@@ -191,9 +191,13 @@ void UserResourceController::runScripts(UserScriptData::InjectionPoint p, blink:
+ if (!scriptMatchesURL(script, frame->GetDocument().Url()))
+ continue;
+ blink::WebScriptSource source(blink::WebString::FromUTF8(script.source), script.url);
+- if (script.worldId)
+- frame->ExecuteScriptInIsolatedWorld(script.worldId, &source, /*numSources = */1, /*contentScriptExtentsionGroup = */ 0);
+- else
++ if (script.worldId) {
++ unsigned numSources = 1;
++ bool userGesture = false;
++ blink::WebLocalFrame::ScriptExecutionType executionType = blink::WebLocalFrame::kAsynchronous;
++ blink::WebScriptExecutionCallback *callback = nullptr;
++ frame->RequestExecuteScriptInIsolatedWorld(script.worldId, &source, numSources, userGesture, executionType, callback);
++ } else
+ frame->ExecuteScript(source);
+ }
+ }
+diff --git a/tests/auto/widgets/qwebenginescript/tst_qwebenginescript.cpp b/tests/auto/widgets/qwebenginescript/tst_qwebenginescript.cpp
+index 43e9d313565..3a7591a6981 100644
+--- a/tests/auto/widgets/qwebenginescript/tst_qwebenginescript.cpp
++++ b/tests/auto/widgets/qwebenginescript/tst_qwebenginescript.cpp
+@@ -27,6 +27,9 @@
+ #include "../util.h"
+ #include <QWebChannel>
+
++Q_DECLARE_METATYPE(QWebEngineScript::InjectionPoint);
++Q_DECLARE_METATYPE(QWebEngineScript::ScriptWorldId);
++
+ class tst_QWebEngineScript: public QObject {
+ Q_OBJECT
+
+@@ -39,7 +42,10 @@ private Q_SLOTS:
+ void webChannel_data();
+ void webChannel();
+ void noTransportWithoutWebChannel();
++ void scriptsInNestedIframes_data();
+ void scriptsInNestedIframes();
++ void scriptsInNestedIframesNoDom_data();
++ void scriptsInNestedIframesNoDom();
+ void webChannelResettingAndUnsetting();
+ void webChannelWithExistingQtObject();
+ void navigation();
+@@ -77,12 +83,12 @@ void tst_QWebEngineScript::domEditing()
+
+ void tst_QWebEngineScript::injectionPoint()
+ {
+- QFETCH(int, injectionPoint);
++ QFETCH(QWebEngineScript::InjectionPoint, injectionPoint);
+ QFETCH(QString, testScript);
+
+ QWebEngineScript s;
+ s.setSourceCode("var foo = \"foobar\";");
+- s.setInjectionPoint(static_cast<QWebEngineScript::InjectionPoint>(injectionPoint));
++ s.setInjectionPoint(injectionPoint);
+ s.setWorldId(QWebEngineScript::MainWorld);
+ QWebEnginePage page;
+ QSignalSpy spyFinished(&page, &QWebEnginePage::loadFinished);
+@@ -95,17 +101,17 @@ void tst_QWebEngineScript::injectionPoint()
+
+ void tst_QWebEngineScript::injectionPoint_data()
+ {
+- QTest::addColumn<int>("injectionPoint");
++ QTest::addColumn<QWebEngineScript::InjectionPoint>("injectionPoint");
+ QTest::addColumn<QString>("testScript");
+- QTest::newRow("DocumentCreation") << static_cast<int>(QWebEngineScript::DocumentCreation)
++ QTest::newRow("DocumentCreation") << QWebEngineScript::DocumentCreation
+ << QStringLiteral("document.myContents = (typeof(foo) == \"undefined\")? \"FAILURE\" : \"SUCCESS\";");
+- QTest::newRow("DocumentReady") << static_cast<int>(QWebEngineScript::DocumentReady)
++ QTest::newRow("DocumentReady") << QWebEngineScript::DocumentReady
+ // use a zero timeout to make sure the user script got a chance to run as the order is undefined.
+ << QStringLiteral("document.addEventListener(\"DOMContentLoaded\", function() {\
+ setTimeout(function() {\
+ document.myContents = (typeof(foo) == \"undefined\")? \"FAILURE\" : \"SUCCESS\";\
+ }, 0)});");
+- QTest::newRow("Deferred") << static_cast<int>(QWebEngineScript::DocumentReady)
++ QTest::newRow("Deferred") << QWebEngineScript::DocumentReady
+ << QStringLiteral("document.onreadystatechange = function() { \
+ if (document.readyState == \"complete\") { \
+ setTimeout(function() {\
+@@ -266,14 +272,21 @@ void tst_QWebEngineScript::noTransportWithoutWebChannel()
+ QCOMPARE(evaluateJavaScriptSync(&page, "qt.webChannelTransport"), QVariant(QVariant::Invalid));
+ }
+
++void tst_QWebEngineScript::scriptsInNestedIframes_data()
++{
++ QTest::addColumn<QWebEngineScript::ScriptWorldId>("worldId");
++ QTest::newRow("MainWorld") << QWebEngineScript::MainWorld;
++ QTest::newRow("ApplicationWorld") << QWebEngineScript::ApplicationWorld;
++}
++
+ void tst_QWebEngineScript::scriptsInNestedIframes()
+ {
++ QFETCH(QWebEngineScript::ScriptWorldId, worldId);
++
+ QWebEnginePage page;
+- QWebEngineView view;
+- view.setPage(&page);
+ QWebEngineScript s;
+ s.setInjectionPoint(QWebEngineScript::DocumentReady);
+- s.setWorldId(QWebEngineScript::ApplicationWorld);
++ s.setWorldId(worldId);
+
+ // Prepend a "Modified prefix" to every frame's div content.
+ s.setSourceCode("var elements = document.getElementsByTagName(\"div\");\
+@@ -290,13 +303,12 @@ void tst_QWebEngineScript::scriptsInNestedIframes()
+
+ QSignalSpy spyFinished(&page, &QWebEnginePage::loadFinished);
+ page.load(QUrl("qrc:/resources/test_iframe_main.html"));
+- view.show();
+ QVERIFY(spyFinished.wait());
+
+ // Check that main frame has modified content.
+ QCOMPARE(
+ evaluateJavaScriptSyncInWorld(&page, "document.getElementsByTagName(\"div\")[0].innerHTML",
+- QWebEngineScript::ApplicationWorld),
++ worldId),
+ QVariant::fromValue(QStringLiteral("Modified Main text")));
+
+ // Check that outer frame has modified content.
+@@ -304,7 +316,7 @@ void tst_QWebEngineScript::scriptsInNestedIframes()
+ evaluateJavaScriptSyncInWorld(&page,
+ "var i = document.getElementById(\"outer\").contentDocument;\
+ i.getElementsByTagName(\"div\")[0].innerHTML",
+- QWebEngineScript::ApplicationWorld),
++ worldId),
+ QVariant::fromValue(QStringLiteral("Modified Outer text")));
+
+
+@@ -314,10 +326,39 @@ void tst_QWebEngineScript::scriptsInNestedIframes()
+ "var i = document.getElementById(\"outer\").contentDocument;\
+ var i2 = i.getElementById(\"inner\").contentDocument;\
+ i2.getElementsByTagName(\"div\")[0].innerHTML",
+- QWebEngineScript::ApplicationWorld),
++ worldId),
+ QVariant::fromValue(QStringLiteral("Modified Inner text")));
+ }
+
++void tst_QWebEngineScript::scriptsInNestedIframesNoDom_data()
++{
++ QTest::addColumn<QWebEngineScript::InjectionPoint>("injectionPoint");
++ QTest::addColumn<QWebEngineScript::ScriptWorldId>("worldId");
++ QTest::newRow("DocumentCreation/MainWorld") << QWebEngineScript::DocumentCreation << QWebEngineScript::MainWorld;
++ QTest::newRow("DocumentCreation/ApplicationWorld") << QWebEngineScript::DocumentCreation << QWebEngineScript::ApplicationWorld;
++ QTest::newRow("DocumentReady/MainWorld") << QWebEngineScript::DocumentReady << QWebEngineScript::MainWorld;
++ QTest::newRow("DocumentReady/ApplicationWorld") << QWebEngineScript::DocumentReady << QWebEngineScript::ApplicationWorld;
++}
++
++void tst_QWebEngineScript::scriptsInNestedIframesNoDom()
++{
++ QFETCH(QWebEngineScript::InjectionPoint, injectionPoint);
++ QFETCH(QWebEngineScript::ScriptWorldId, worldId);
++ QWebEnginePage page;
++ QWebEngineScript s;
++ s.setInjectionPoint(injectionPoint);
++ s.setWorldId(worldId);
++ s.setSourceCode("window.scriptOk = true");
++ s.setRunsOnSubFrames(true);
++ page.scripts().insert(s);
++ QSignalSpy spyFinished(&page, &QWebEnginePage::loadFinished);
++ page.load(QUrl("qrc:/resources/test_iframe_main.html"));
++ QVERIFY(spyFinished.wait());
++ QCOMPARE(evaluateJavaScriptSyncInWorld(&page, "window.scriptOk", worldId), QVariant::fromValue(true));
++ QCOMPARE(evaluateJavaScriptSyncInWorld(&page, "window[0].scriptOk", worldId), QVariant::fromValue(true));
++ QCOMPARE(evaluateJavaScriptSyncInWorld(&page, "window[0][0].scriptOk", worldId), QVariant::fromValue(true));
++}
++
+ void tst_QWebEngineScript::webChannelResettingAndUnsetting()
+ {
+ QWebEnginePage page;
+--
+2.16.2
+
Deleted: qtwebengine-harmony.patch
===================================================================
--- qtwebengine-harmony.patch 2018-03-21 22:28:03 UTC (rev 319784)
+++ qtwebengine-harmony.patch 2018-03-21 22:28:29 UTC (rev 319785)
@@ -1,77 +0,0 @@
---- qtwebengine-opensource-src-5.9.1/src/3rdparty/chromium/third_party/skia/src/ports/SkFontHost_FreeType.cpp.orig 2017-10-10 17:42:06.956950985 +0200
-+++ qtwebengine-opensource-src-5.9.1/src/3rdparty/chromium/third_party/skia/src/ports/SkFontHost_FreeType.cpp 2017-10-10 17:46:05.824187787 +0200
-@@ -99,8 +99,6 @@
- FreeTypeLibrary()
- : fGetVarDesignCoordinates(nullptr)
- , fLibrary(nullptr)
-- , fIsLCDSupported(false)
-- , fLCDExtra(0)
- {
- if (FT_New_Library(&gFTMemory, &fLibrary)) {
- return;
-@@ -147,12 +145,7 @@
- }
- #endif
-
-- // Setup LCD filtering. This reduces color fringes for LCD smoothed glyphs.
-- // The default has changed over time, so this doesn't mean the same thing to all users.
-- if (FT_Library_SetLcdFilter(fLibrary, FT_LCD_FILTER_DEFAULT) == 0) {
-- fIsLCDSupported = true;
-- fLCDExtra = 2; //Using a filter adds one full pixel to each side.
-- }
-+ FT_Library_SetLcdFilter(fLibrary, FT_LCD_FILTER_DEFAULT);
- }
- ~FreeTypeLibrary() {
- if (fLibrary) {
-@@ -161,8 +153,6 @@
- }
-
- FT_Library library() { return fLibrary; }
-- bool isLCDSupported() { return fIsLCDSupported; }
-- int lcdExtra() { return fLCDExtra; }
-
- // FT_Get_{MM,Var}_{Blend,Design}_Coordinates were added in FreeType 2.7.1.
- // Prior to this there was no way to get the coordinates out of the FT_Face.
-@@ -173,8 +163,6 @@
-
- private:
- FT_Library fLibrary;
-- bool fIsLCDSupported;
-- int fLCDExtra;
-
- // FT_Library_SetLcdFilterWeights was introduced in FreeType 2.4.0.
- // The following platforms provide FreeType of at least 2.4.0.
-@@ -704,17 +692,6 @@
- rec->fTextSize = SkIntToScalar(1 << 14);
- }
-
-- if (isLCD(*rec)) {
-- // TODO: re-work so that FreeType is set-up and selected by the SkFontMgr.
-- SkAutoMutexAcquire ama(gFTMutex);
-- ref_ft_library();
-- if (!gFTLibrary->isLCDSupported()) {
-- // If the runtime Freetype library doesn't support LCD, disable it here.
-- rec->fMaskFormat = SkMask::kA8_Format;
-- }
-- unref_ft_library();
-- }
--
- SkPaint::Hinting h = rec->getHinting();
- if (SkPaint::kFull_Hinting == h && !isLCD(*rec)) {
- // collapse full->normal hinting if we're not doing LCD
-@@ -1115,11 +1092,11 @@
- void SkScalerContext_FreeType::updateGlyphIfLCD(SkGlyph* glyph) {
- if (isLCD(fRec)) {
- if (fLCDIsVert) {
-- glyph->fHeight += gFTLibrary->lcdExtra();
-- glyph->fTop -= gFTLibrary->lcdExtra() >> 1;
-+ glyph->fHeight += 2;
-+ glyph->fTop -= 1;
- } else {
-- glyph->fWidth += gFTLibrary->lcdExtra();
-- glyph->fLeft -= gFTLibrary->lcdExtra() >> 1;
-+ glyph->fWidth += 2;
-+ glyph->fLeft -= 1;
- }
- }
- }
Copied: qt5-webengine/repos/kde-unstable-x86_64/qtwebengine-harmony.patch (from rev 319784, qt5-webengine/kde-unstable/qtwebengine-harmony.patch)
===================================================================
--- qtwebengine-harmony.patch (rev 0)
+++ qtwebengine-harmony.patch 2018-03-21 22:28:29 UTC (rev 319785)
@@ -0,0 +1,77 @@
+--- qtwebengine-opensource-src-5.9.1/src/3rdparty/chromium/third_party/skia/src/ports/SkFontHost_FreeType.cpp.orig 2017-10-10 17:42:06.956950985 +0200
++++ qtwebengine-opensource-src-5.9.1/src/3rdparty/chromium/third_party/skia/src/ports/SkFontHost_FreeType.cpp 2017-10-10 17:46:05.824187787 +0200
+@@ -99,8 +99,6 @@
+ FreeTypeLibrary()
+ : fGetVarDesignCoordinates(nullptr)
+ , fLibrary(nullptr)
+- , fIsLCDSupported(false)
+- , fLCDExtra(0)
+ {
+ if (FT_New_Library(&gFTMemory, &fLibrary)) {
+ return;
+@@ -147,12 +145,7 @@
+ }
+ #endif
+
+- // Setup LCD filtering. This reduces color fringes for LCD smoothed glyphs.
+- // The default has changed over time, so this doesn't mean the same thing to all users.
+- if (FT_Library_SetLcdFilter(fLibrary, FT_LCD_FILTER_DEFAULT) == 0) {
+- fIsLCDSupported = true;
+- fLCDExtra = 2; //Using a filter adds one full pixel to each side.
+- }
++ FT_Library_SetLcdFilter(fLibrary, FT_LCD_FILTER_DEFAULT);
+ }
+ ~FreeTypeLibrary() {
+ if (fLibrary) {
+@@ -161,8 +153,6 @@
+ }
+
+ FT_Library library() { return fLibrary; }
+- bool isLCDSupported() { return fIsLCDSupported; }
+- int lcdExtra() { return fLCDExtra; }
+
+ // FT_Get_{MM,Var}_{Blend,Design}_Coordinates were added in FreeType 2.7.1.
+ // Prior to this there was no way to get the coordinates out of the FT_Face.
+@@ -173,8 +163,6 @@
+
+ private:
+ FT_Library fLibrary;
+- bool fIsLCDSupported;
+- int fLCDExtra;
+
+ // FT_Library_SetLcdFilterWeights was introduced in FreeType 2.4.0.
+ // The following platforms provide FreeType of at least 2.4.0.
+@@ -704,17 +692,6 @@
+ rec->fTextSize = SkIntToScalar(1 << 14);
+ }
+
+- if (isLCD(*rec)) {
+- // TODO: re-work so that FreeType is set-up and selected by the SkFontMgr.
+- SkAutoMutexAcquire ama(gFTMutex);
+- ref_ft_library();
+- if (!gFTLibrary->isLCDSupported()) {
+- // If the runtime Freetype library doesn't support LCD, disable it here.
+- rec->fMaskFormat = SkMask::kA8_Format;
+- }
+- unref_ft_library();
+- }
+-
+ SkPaint::Hinting h = rec->getHinting();
+ if (SkPaint::kFull_Hinting == h && !isLCD(*rec)) {
+ // collapse full->normal hinting if we're not doing LCD
+@@ -1115,11 +1092,11 @@
+ void SkScalerContext_FreeType::updateGlyphIfLCD(SkGlyph* glyph) {
+ if (isLCD(fRec)) {
+ if (fLCDIsVert) {
+- glyph->fHeight += gFTLibrary->lcdExtra();
+- glyph->fTop -= gFTLibrary->lcdExtra() >> 1;
++ glyph->fHeight += 2;
++ glyph->fTop -= 1;
+ } else {
+- glyph->fWidth += gFTLibrary->lcdExtra();
+- glyph->fLeft -= gFTLibrary->lcdExtra() >> 1;
++ glyph->fWidth += 2;
++ glyph->fLeft -= 1;
+ }
+ }
+ }
Deleted: qtwebengine-no-gpu.patch
===================================================================
--- qtwebengine-no-gpu.patch 2018-03-21 22:28:03 UTC (rev 319784)
+++ qtwebengine-no-gpu.patch 2018-03-21 22:28:29 UTC (rev 319785)
@@ -1,99 +0,0 @@
-From: Antonio Larrosa <alarrosa at suse.com>
-Subject: Disable GPU when using nouveau or running on wayland
-References: boo#1005323, boo#1060990
-
-Qt WebEngine uses multi-threaded OpenGL, which nouveau does not support.
-It also crashes when running on wayland, the cause is not yet known.
-Work around these issues by not doing GPU-accelerated rendering in such
-cases.
-
-Index: qtwebengine-everywhere-src-5.10.0/src/core/web_engine_context.cpp
-===================================================================
---- qtwebengine-everywhere-src-5.10.0.orig/src/core/web_engine_context.cpp
-+++ qtwebengine-everywhere-src-5.10.0/src/core/web_engine_context.cpp
-@@ -93,6 +93,7 @@
- #include <QOffscreenSurface>
- #ifndef QT_NO_OPENGL
- # include <QOpenGLContext>
-+# include <QOpenGLFunctions>
- #endif
- #include <QQuickWindow>
- #include <QStringList>
-@@ -167,6 +168,39 @@ void dummyGetPluginCallback(const std::v
- }
- #endif
-
-+#ifndef QT_NO_OPENGL
-+QString openGLVendor()
-+{
-+ QString vendor;
-+
-+ QOpenGLContext *oldContext = QOpenGLContext::currentContext();
-+ QSurface *oldSurface = 0;
-+ if (oldContext)
-+ oldSurface = oldContext->surface();
-+
-+ QScopedPointer<QOffscreenSurface> surface( new QOffscreenSurface );
-+ surface->create();
-+ QOpenGLContext context;
-+ if (!context.create()) {
-+ qDebug() << "Error creating openGL context";
-+ }
-+ else if (!context.makeCurrent(surface.data())) {
-+ qDebug() << "Error making openGL context current context";
-+ } else {
-+ const GLubyte *p;
-+ QOpenGLFunctions *f = context.functions();
-+ if ((p = f->glGetString(GL_VENDOR)))
-+ vendor = QString::fromLatin1(reinterpret_cast<const char *>(p));
-+ }
-+
-+ context.doneCurrent();
-+ if (oldContext && oldSurface)
-+ oldContext->makeCurrent(oldSurface);
-+
-+ return vendor;
-+}
-+#endif
-+
- } // namespace
-
- namespace QtWebEngineCore {
-@@ -379,6 +413,27 @@ WebEngineContext::WebEngineContext()
- const char *glType = 0;
- #ifndef QT_NO_OPENGL
-
-+ bool disableGpu = qEnvironmentVariableIsSet("QT_WEBENGINE_DISABLE_GPU");
-+
-+ if (!qEnvironmentVariableIsSet("QT_WEBENGINE_DISABLE_WAYLAND_WORKAROUND") && platform.startsWith("wayland", Qt::CaseInsensitive))
-+ {
-+ qWarning() << "Running on wayland. Qt WebEngine will disable usage of the GPU.\n"
-+ "Note: you can set the QT_WEBENGINE_DISABLE_WAYLAND_WORKAROUND\n"
-+ "environment variable before running this application, but this is \n"
-+ "not recommended since this usually causes applications to crash.";
-+ disableGpu = true;
-+ }
-+
-+ if (!qEnvironmentVariableIsSet("QT_WEBENGINE_DISABLE_NOUVEAU_WORKAROUND") && openGLVendor() == QStringLiteral("nouveau"))
-+ {
-+ qWarning() << "Nouveau openGL driver detected. Qt WebEngine will disable usage of the GPU.\n"
-+ "Note: you can set the QT_WEBENGINE_DISABLE_NOUVEAU_WORKAROUND\n"
-+ "environment variable before running this application, but this is \n"
-+ "not recommended since this usually causes applications to crash as\n"
-+ "Nouveau openGL drivers don't support multithreaded rendering";
-+ disableGpu = true;
-+ }
-+
- bool tryGL =
- !usingANGLE()
- && (!usingSoftwareDynamicGL()
-@@ -389,7 +444,7 @@ WebEngineContext::WebEngineContext()
- || enableWebGLSoftwareRendering
- #endif
- )
-- && !usingQtQuick2DRenderer();
-+ && !usingQtQuick2DRenderer() && !disableGpu;
-
- if (tryGL) {
- if (qt_gl_global_share_context() && qt_gl_global_share_context()->isValid()) {
-
Copied: qt5-webengine/repos/kde-unstable-x86_64/qtwebengine-no-gpu.patch (from rev 319784, qt5-webengine/kde-unstable/qtwebengine-no-gpu.patch)
===================================================================
--- qtwebengine-no-gpu.patch (rev 0)
+++ qtwebengine-no-gpu.patch 2018-03-21 22:28:29 UTC (rev 319785)
@@ -0,0 +1,99 @@
+From: Antonio Larrosa <alarrosa at suse.com>
+Subject: Disable GPU when using nouveau or running on wayland
+References: boo#1005323, boo#1060990
+
+Qt WebEngine uses multi-threaded OpenGL, which nouveau does not support.
+It also crashes when running on wayland, the cause is not yet known.
+Work around these issues by not doing GPU-accelerated rendering in such
+cases.
+
+Index: qtwebengine-everywhere-src-5.10.0/src/core/web_engine_context.cpp
+===================================================================
+--- qtwebengine-everywhere-src-5.10.0.orig/src/core/web_engine_context.cpp
++++ qtwebengine-everywhere-src-5.10.0/src/core/web_engine_context.cpp
+@@ -93,6 +93,7 @@
+ #include <QOffscreenSurface>
+ #ifndef QT_NO_OPENGL
+ # include <QOpenGLContext>
++# include <QOpenGLFunctions>
+ #endif
+ #include <QQuickWindow>
+ #include <QStringList>
+@@ -167,6 +168,39 @@ void dummyGetPluginCallback(const std::v
+ }
+ #endif
+
++#ifndef QT_NO_OPENGL
++QString openGLVendor()
++{
++ QString vendor;
++
++ QOpenGLContext *oldContext = QOpenGLContext::currentContext();
++ QSurface *oldSurface = 0;
++ if (oldContext)
++ oldSurface = oldContext->surface();
++
++ QScopedPointer<QOffscreenSurface> surface( new QOffscreenSurface );
++ surface->create();
++ QOpenGLContext context;
++ if (!context.create()) {
++ qDebug() << "Error creating openGL context";
++ }
++ else if (!context.makeCurrent(surface.data())) {
++ qDebug() << "Error making openGL context current context";
++ } else {
++ const GLubyte *p;
++ QOpenGLFunctions *f = context.functions();
++ if ((p = f->glGetString(GL_VENDOR)))
++ vendor = QString::fromLatin1(reinterpret_cast<const char *>(p));
++ }
++
++ context.doneCurrent();
++ if (oldContext && oldSurface)
++ oldContext->makeCurrent(oldSurface);
++
++ return vendor;
++}
++#endif
++
+ } // namespace
+
+ namespace QtWebEngineCore {
+@@ -379,6 +413,27 @@ WebEngineContext::WebEngineContext()
+ const char *glType = 0;
+ #ifndef QT_NO_OPENGL
+
++ bool disableGpu = qEnvironmentVariableIsSet("QT_WEBENGINE_DISABLE_GPU");
++
++ if (!qEnvironmentVariableIsSet("QT_WEBENGINE_DISABLE_WAYLAND_WORKAROUND") && platform.startsWith("wayland", Qt::CaseInsensitive))
++ {
++ qWarning() << "Running on wayland. Qt WebEngine will disable usage of the GPU.\n"
++ "Note: you can set the QT_WEBENGINE_DISABLE_WAYLAND_WORKAROUND\n"
++ "environment variable before running this application, but this is \n"
++ "not recommended since this usually causes applications to crash.";
++ disableGpu = true;
++ }
++
++ if (!qEnvironmentVariableIsSet("QT_WEBENGINE_DISABLE_NOUVEAU_WORKAROUND") && openGLVendor() == QStringLiteral("nouveau"))
++ {
++ qWarning() << "Nouveau openGL driver detected. Qt WebEngine will disable usage of the GPU.\n"
++ "Note: you can set the QT_WEBENGINE_DISABLE_NOUVEAU_WORKAROUND\n"
++ "environment variable before running this application, but this is \n"
++ "not recommended since this usually causes applications to crash as\n"
++ "Nouveau openGL drivers don't support multithreaded rendering";
++ disableGpu = true;
++ }
++
+ bool tryGL =
+ !usingANGLE()
+ && (!usingSoftwareDynamicGL()
+@@ -389,7 +444,7 @@ WebEngineContext::WebEngineContext()
+ || enableWebGLSoftwareRendering
+ #endif
+ )
+- && !usingQtQuick2DRenderer();
++ && !usingQtQuick2DRenderer() && !disableGpu;
+
+ if (tryGL) {
+ if (qt_gl_global_share_context() && qt_gl_global_share_context()->isValid()) {
+
More information about the arch-commits
mailing list