diff --git a/.qmake.conf b/.qmake.conf
index a988f0face6e1d7a181f8a7d1b08fdea22d77d12..71d8c7d74d129b58e793bf69ac78495b1148ad80 100644
--- a/.qmake.conf
+++ b/.qmake.conf
@@ -1,5 +1,3 @@
-QMAKEPATH += $$PWD/tools/qmake
-
 # Resolve root directories for sources
 QTWEBENGINE_ROOT = $$PWD
 QTWEBENGINE_OUT_ROOT = $$shadowed($$PWD)
diff --git a/tools/qmake/config.tests/alsa/alsa.pro b/config.tests/alsa/alsa.pro
similarity index 100%
rename from tools/qmake/config.tests/alsa/alsa.pro
rename to config.tests/alsa/alsa.pro
diff --git a/tools/qmake/config.tests/alsa/alsatest.cpp b/config.tests/alsa/alsatest.cpp
similarity index 100%
rename from tools/qmake/config.tests/alsa/alsatest.cpp
rename to config.tests/alsa/alsatest.cpp
diff --git a/tools/qmake/config.tests/khr/khr.cpp b/config.tests/khr/khr.cpp
similarity index 100%
rename from tools/qmake/config.tests/khr/khr.cpp
rename to config.tests/khr/khr.cpp
diff --git a/tools/qmake/config.tests/khr/khr.pro b/config.tests/khr/khr.pro
similarity index 100%
rename from tools/qmake/config.tests/khr/khr.pro
rename to config.tests/khr/khr.pro
diff --git a/tools/qmake/config.tests/libvpx/libvpx.cpp b/config.tests/libvpx/libvpx.cpp
similarity index 100%
rename from tools/qmake/config.tests/libvpx/libvpx.cpp
rename to config.tests/libvpx/libvpx.cpp
diff --git a/tools/qmake/config.tests/libvpx/libvpx.pro b/config.tests/libvpx/libvpx.pro
similarity index 100%
rename from tools/qmake/config.tests/libvpx/libvpx.pro
rename to config.tests/libvpx/libvpx.pro
diff --git a/tools/qmake/config.tests/snappy/snappy.cpp b/config.tests/snappy/snappy.cpp
similarity index 100%
rename from tools/qmake/config.tests/snappy/snappy.cpp
rename to config.tests/snappy/snappy.cpp
diff --git a/tools/qmake/config.tests/snappy/snappy.pro b/config.tests/snappy/snappy.pro
similarity index 100%
rename from tools/qmake/config.tests/snappy/snappy.pro
rename to config.tests/snappy/snappy.pro
diff --git a/tools/qmake/config.tests/srtp/srtp.cpp b/config.tests/srtp/srtp.cpp
similarity index 100%
rename from tools/qmake/config.tests/srtp/srtp.cpp
rename to config.tests/srtp/srtp.cpp
diff --git a/tools/qmake/config.tests/srtp/srtp.pro b/config.tests/srtp/srtp.pro
similarity index 100%
rename from tools/qmake/config.tests/srtp/srtp.pro
rename to config.tests/srtp/srtp.pro
diff --git a/tools/qmake/config.tests/winversion/winversion.cpp b/config.tests/winversion/winversion.cpp
similarity index 100%
rename from tools/qmake/config.tests/winversion/winversion.cpp
rename to config.tests/winversion/winversion.cpp
diff --git a/tools/qmake/config.tests/winversion/winversion.pro b/config.tests/winversion/winversion.pro
similarity index 100%
rename from tools/qmake/config.tests/winversion/winversion.pro
rename to config.tests/winversion/winversion.pro
diff --git a/configure.json b/configure.json
index 62b56bbb1ab5a63087a6271c3960a5453fcaf900..805ed400124dd4c9c86706db68245c02d0010ab3 100644
--- a/configure.json
+++ b/configure.json
@@ -4,13 +4,10 @@
         "printsupport"
     ],
 
-    "testDir": "tools/qmake/config.tests",
-
     "commandline": {
         "options": {
             "alsa": "boolean",
             "embedded": "boolean",
-            "optimize-for-size": { "type": "boolean", "name": "optimize_size" },
             "ffmpeg": { "type": "enum", "name": "system-ffmpeg", "values": { "system": "yes", "qt": "no" } },
             "opus": { "type": "enum", "name": "system-opus", "values": { "system": "yes", "qt": "no" } },
             "webp": { "type": "enum", "name": "system-webp", "values": { "system": "yes", "qt": "no" } },
@@ -58,6 +55,11 @@
     },
 
     "tests" : {
+        "python2": {
+            "label": "Python 2",
+            "type": "detectPython2",
+            "log": "location"
+        },
         "ninja": {
             "label": "system ninja",
             "type": "detectNinja"
@@ -73,6 +75,13 @@
     },
 
     "features": {
+        "python2": {
+            "label": "Python 2",
+            "condition": "tests.python2",
+            "output": [
+                { "type": "varAssign", "name": "QMAKE_PYTHON2", "value": "tests.python2.location" }
+            ]
+        },
         "embedded": {
             "label": "Embedded build",
             "condition": "config.unix",
@@ -80,11 +89,6 @@
             "purpose": "Enables the embedded build configuration",
             "output": [ "privateFeature" ]
         },
-        "optimize_size": {
-            "label": "Optimize for size",
-            "autoDetect": "tests.embedded",
-            "output": [ "privateFeature" ]
-        },
         "alsa": {
             "label": "ALSA",
             "condition": "config.unix && libs.alsa",
@@ -157,12 +161,19 @@
         }
     },
 
+    "report": [
+        {
+            "type": "warning",
+            "condition": "!features.python2",
+            "message": "Python version 2 (2.7.5 or later) is required to build QtWebEngine."
+        }
+    ],
+
     "summary": [
         {
             "section": "Qt WebEngine",
             "entries": [
                 "embedded",
-                "optimize_size",
                 "pepper-plugins",
                 "printing-and-pdf",
                 "proprietary-codecs",
diff --git a/configure.pri b/configure.pri
index 23f31686e8e88f61a2bf55acc4ac40707f5cf873..ce36642bbbf939c73e9e37e3a7e33079eb1431b6 100644
--- a/configure.pri
+++ b/configure.pri
@@ -1,5 +1,46 @@
 equals(QMAKE_HOST.os, Windows): EXE_SUFFIX = .exe
 
+defineTest(isPythonVersionSupported) {
+    python = $$system_quote($$system_path($$1))
+    python_version = $$system('$$python -c "import sys; print(sys.version_info[0:3])"')
+    python_version ~= s/[()]//g
+    python_version = $$split(python_version, ',')
+    python_major_version = $$first(python_version)
+    greaterThan(python_major_version, 2) {
+        qtLog("Python version 3 is not supported by Chromium.")
+        return(false)
+    }
+    python_minor_version = $$member(python_version, 1)
+    python_patch_version = $$member(python_version, 2)
+    greaterThan(python_major_version, 1): greaterThan(python_minor_version, 6): greaterThan(python_patch_version, 4): return(true)
+    qtLog("Unsupported python version: $${python_major_version}.$${python_minor_version}.$${python_patch_version}.")
+    return(false)
+}
+
+defineTest(qtConfTest_detectPython2) {
+    python = $$qtConfFindInPath("python2")
+    isEmpty(python) {
+        qtLog("'python2' not found in PATH. Checking for 'python'.")
+        python = $$qtConfFindInPath("python$$EXE_SUFFIX")
+    }
+    isEmpty(python) {
+        qtLog("'python$$EXE_SUFFIX' not found in PATH. Giving up.")
+        return(false)
+    }
+    !isPythonVersionSupported($$python) {
+        qtLog("A suitable Python 2 executable could not be located.")
+        return(false)
+    }
+
+    # Make tests.python2.location available in configure.json.
+    $${1}.location = $$clean_path($$python)
+    export($${1}.location)
+    $${1}.cache += location
+    export($${1}.cache)
+
+    return(true)
+}
+
 defineTest(qtConfTest_detectNinja) {
     ninja = $$qtConfFindInPath("ninja$$EXE_SUFFIX")
     !isEmpty(ninja) {
diff --git a/examples/webengine/quicknanobrowser/ApplicationRoot.qml b/examples/webengine/quicknanobrowser/ApplicationRoot.qml
index 6735be932f30e2ebd7ff7ddc645b5614e5dc8f85..78defab802384daadccc347b32d9575c98b9da4b 100644
--- a/examples/webengine/quicknanobrowser/ApplicationRoot.qml
+++ b/examples/webengine/quicknanobrowser/ApplicationRoot.qml
@@ -70,18 +70,18 @@ QtObject {
         onClosing: destroy()
     }
     function createWindow(profile) {
-        var newWindow = browserWindowComponent.createObject(root)
-        newWindow.currentWebView.profile = profile
-        profile.downloadRequested.connect(newWindow.onDownloadRequested)
-        return newWindow
+        var newWindow = browserWindowComponent.createObject(root);
+        newWindow.currentWebView.profile = profile;
+        profile.downloadRequested.connect(newWindow.onDownloadRequested);
+        return newWindow;
     }
     function createDialog(profile) {
-        var newDialog = browserDialogComponent.createObject(root)
-        newDialog.currentWebView.profile = profile
-        return newDialog
+        var newDialog = browserDialogComponent.createObject(root);
+        newDialog.currentWebView.profile = profile;
+        return newDialog;
     }
     function load(url) {
-        var browserWindow = createWindow(defaultProfile)
-        browserWindow.currentWebView.url = url
+        var browserWindow = createWindow(defaultProfile);
+        browserWindow.currentWebView.url = url;
     }
 }
diff --git a/examples/webengine/quicknanobrowser/BrowserWindow.qml b/examples/webengine/quicknanobrowser/BrowserWindow.qml
index c008425d98896be94d2ae29704e8c4bff20a3aa8..596e4a76ed532bfd635955d685058293011e47d0 100644
--- a/examples/webengine/quicknanobrowser/BrowserWindow.qml
+++ b/examples/webengine/quicknanobrowser/BrowserWindow.qml
@@ -48,15 +48,16 @@
 **
 ****************************************************************************/
 
+import Qt.labs.settings 1.0
+import QtQml 2.2
 import QtQuick 2.2
-import QtWebEngine 1.2
 import QtQuick.Controls 1.0
+import QtQuick.Controls.Private 1.0
 import QtQuick.Controls.Styles 1.0
+import QtQuick.Dialogs 1.2
 import QtQuick.Layouts 1.0
 import QtQuick.Window 2.1
-import QtQuick.Controls.Private 1.0
-import QtQuick.Dialogs 1.2
-import Qt.labs.settings 1.0
+import QtWebEngine 1.3
 
 ApplicationWindow {
     id: browserWindow
@@ -79,19 +80,19 @@ ApplicationWindow {
 
     Settings {
         id : appSettings
-        property alias autoLoadImages: loadImages.checked;
-        property alias javaScriptEnabled: javaScriptEnabled.checked;
-        property alias errorPageEnabled: errorPageEnabled.checked;
-        property alias pluginsEnabled: pluginsEnabled.checked;
-        property alias fullScreenSupportEnabled: fullScreenSupportEnabled.checked;
-        property alias autoLoadIconsForPage: autoLoadIconsForPage.checked;
-        property alias touchIconsEnabled: touchIconsEnabled.checked;
+        property alias autoLoadImages: loadImages.checked
+        property alias javaScriptEnabled: javaScriptEnabled.checked
+        property alias errorPageEnabled: errorPageEnabled.checked
+        property alias pluginsEnabled: pluginsEnabled.checked
+        property alias fullScreenSupportEnabled: fullScreenSupportEnabled.checked
+        property alias autoLoadIconsForPage: autoLoadIconsForPage.checked
+        property alias touchIconsEnabled: touchIconsEnabled.checked
     }
 
     Action {
         shortcut: "Ctrl+D"
         onTriggered: {
-            downloadView.visible = !downloadView.visible
+            downloadView.visible = !downloadView.visible;
         }
     }
     Action {
@@ -106,14 +107,14 @@ ApplicationWindow {
         shortcut: StandardKey.Refresh
         onTriggered: {
             if (currentWebView)
-                currentWebView.reload()
+                currentWebView.reload();
         }
     }
     Action {
         shortcut: StandardKey.AddTab
         onTriggered: {
-            tabs.createEmptyTab(currentWebView.profile)
-            tabs.currentIndex = tabs.count - 1
+            tabs.createEmptyTab(currentWebView.profile);
+            tabs.currentIndex = tabs.count - 1;
             addressBar.forceActiveFocus();
             addressBar.selectAll();
         }
@@ -128,23 +129,23 @@ ApplicationWindow {
         shortcut: "Escape"
         onTriggered: {
             if (currentWebView.state == "FullScreen") {
-                browserWindow.visibility = browserWindow.previousVisibility
-                fullScreenNotification.hide()
+                browserWindow.visibility = browserWindow.previousVisibility;
+                fullScreenNotification.hide();
                 currentWebView.triggerWebAction(WebEngineView.ExitFullScreen);
             }
         }
     }
     Action {
         shortcut: "Ctrl+0"
-        onTriggered: currentWebView.zoomFactor = 1.0;
+        onTriggered: currentWebView.zoomFactor = 1.0
     }
     Action {
         shortcut: StandardKey.ZoomOut
-        onTriggered: currentWebView.zoomFactor -= 0.1;
+        onTriggered: currentWebView.zoomFactor -= 0.1
     }
     Action {
         shortcut: StandardKey.ZoomIn
-        onTriggered: currentWebView.zoomFactor += 0.1;
+        onTriggered: currentWebView.zoomFactor += 0.1
     }
 
     Action {
@@ -187,7 +188,7 @@ ApplicationWindow {
     toolBar: ToolBar {
         id: navigationBar
             RowLayout {
-                anchors.fill: parent;
+                anchors.fill: parent
                 ToolButton {
                     enabled: currentWebView && (currentWebView.canGoBack || currentWebView.canGoForward)
                     menu:Menu {
@@ -294,7 +295,7 @@ ApplicationWindow {
                             id: httpDiskCacheEnabled
                             text: "HTTP Disk Cache"
                             checkable: !currentWebView.profile.offTheRecord
-                            checked: (currentWebView.profile.httpCacheType == WebEngineProfile.DiskHttpCache)
+                            checked: (currentWebView.profile.httpCacheType === WebEngineProfile.DiskHttpCache)
                             onToggled: currentWebView.profile.httpCacheType = checked ? WebEngineProfile.DiskHttpCache : WebEngineProfile.MemoryHttpCache
                         }
                         MenuItem {
@@ -336,12 +337,12 @@ ApplicationWindow {
     TabView {
         id: tabs
         function createEmptyTab(profile) {
-            var tab = addTab("", tabComponent)
+            var tab = addTab("", tabComponent);
             // We must do this first to make sure that tab.active gets set so that tab.item gets instantiated immediately.
-            tab.active = true
-            tab.title = Qt.binding(function() { return tab.item.title })
-            tab.item.profile = profile
-            return tab
+            tab.active = true;
+            tab.title = Qt.binding(function() { return tab.item.title });
+            tab.item.profile = profile;
+            return tab;
         }
 
         anchors.fill: parent
@@ -355,10 +356,10 @@ ApplicationWindow {
 
                 onLinkHovered: {
                     if (hoveredUrl == "")
-                        resetStatusText.start()
+                        resetStatusText.start();
                     else {
-                        resetStatusText.stop()
-                        statusText.text = hoveredUrl
+                        resetStatusText.stop();
+                        statusText.text = hoveredUrl;
                     }
                 }
 
@@ -385,69 +386,69 @@ ApplicationWindow {
                 settings.touchIconsEnabled: appSettings.touchIconsEnabled
 
                 onCertificateError: {
-                    error.defer()
-                    sslDialog.enqueue(error)
+                    error.defer();
+                    sslDialog.enqueue(error);
                 }
 
                 onNewViewRequested: {
                     if (!request.userInitiated)
-                        print("Warning: Blocked a popup window.")
+                        print("Warning: Blocked a popup window.");
                     else if (request.destination == WebEngineView.NewViewInTab) {
-                        var tab = tabs.createEmptyTab(currentWebView.profile)
-                        tabs.currentIndex = tabs.count - 1
-                        request.openIn(tab.item)
+                        var tab = tabs.createEmptyTab(currentWebView.profile);
+                        tabs.currentIndex = tabs.count - 1;
+                        request.openIn(tab.item);
                     } else if (request.destination == WebEngineView.NewViewInBackgroundTab) {
-                        var tab = tabs.createEmptyTab(currentWebView.profile)
-                        request.openIn(tab.item)
+                        var backgroundTab = tabs.createEmptyTab(currentWebView.profile);
+                        request.openIn(backgroundTab.item);
                     } else if (request.destination == WebEngineView.NewViewInDialog) {
-                        var dialog = applicationRoot.createDialog(currentWebView.profile)
-                        request.openIn(dialog.currentWebView)
+                        var dialog = applicationRoot.createDialog(currentWebView.profile);
+                        request.openIn(dialog.currentWebView);
                     } else {
-                        var window = applicationRoot.createWindow(currentWebView.profile)
-                        request.openIn(window.currentWebView)
+                        var window = applicationRoot.createWindow(currentWebView.profile);
+                        request.openIn(window.currentWebView);
                     }
                 }
 
                 onFullScreenRequested: {
                     if (request.toggleOn) {
-                        webEngineView.state = "FullScreen"
-                        browserWindow.previousVisibility = browserWindow.visibility
-                        browserWindow.showFullScreen()
-                        fullScreenNotification.show()
+                        webEngineView.state = "FullScreen";
+                        browserWindow.previousVisibility = browserWindow.visibility;
+                        browserWindow.showFullScreen();
+                        fullScreenNotification.show();
                     } else {
-                        webEngineView.state = ""
-                        browserWindow.visibility = browserWindow.previousVisibility
-                        fullScreenNotification.hide()
+                        webEngineView.state = "";
+                        browserWindow.visibility = browserWindow.previousVisibility;
+                        fullScreenNotification.hide();
                     }
-                    request.accept()
+                    request.accept();
                 }
 
                 onRenderProcessTerminated: {
-                    var status = ""
+                    var status = "";
                     switch (terminationStatus) {
                     case WebEngineView.NormalTerminationStatus:
-                        status = "(normal exit)"
+                        status = "(normal exit)";
                         break;
                     case WebEngineView.AbnormalTerminationStatus:
-                        status = "(abnormal exit)"
+                        status = "(abnormal exit)";
                         break;
                     case WebEngineView.CrashedTerminationStatus:
-                        status = "(crashed)"
+                        status = "(crashed)";
                         break;
                     case WebEngineView.KilledTerminationStatus:
-                        status = "(killed)"
+                        status = "(killed)";
                         break;
                     }
 
-                    print("Render process exited with code " + exitCode + " " + status)
-                    reloadTimer.running = true
+                    print("Render process exited with code " + exitCode + " " + status);
+                    reloadTimer.running = true;
                 }
 
                 onWindowCloseRequested: {
                     if (tabs.count == 1)
-                        browserWindow.close()
+                        browserWindow.close();
                     else
-                        tabs.removeTab(tabs.currentIndex)
+                        tabs.removeTab(tabs.currentIndex);
                 }
 
                 Timer {
@@ -473,19 +474,19 @@ ApplicationWindow {
                       "you may not be connected with the host you tried to connect to.\n" +
                       "Do you wish to override the security check and continue?"
         onYes: {
-            certErrors.shift().ignoreCertificateError()
-            presentError()
+            certErrors.shift().ignoreCertificateError();
+            presentError();
         }
         onNo: reject()
         onRejected: reject()
 
         function reject(){
-            certErrors.shift().rejectCertificate()
-            presentError()
+            certErrors.shift().rejectCertificate();
+            presentError();
         }
         function enqueue(error){
-            certErrors.push(error)
-            presentError()
+            certErrors.push(error);
+            presentError();
         }
         function presentError(){
             visible = certErrors.length > 0
@@ -503,9 +504,9 @@ ApplicationWindow {
     }
 
     function onDownloadRequested(download) {
-        downloadView.visible = true
-        downloadView.append(download)
-        download.accept()
+        downloadView.visible = true;
+        downloadView.append(download);
+        download.accept();
     }
 
     Rectangle {
diff --git a/examples/webengine/quicknanobrowser/DownloadView.qml b/examples/webengine/quicknanobrowser/DownloadView.qml
index 13be4bd780b3b7aadeb560bf070f71beb79e27b1..ed28c761c9cb5fa42c1f955705de72365a900f55 100644
--- a/examples/webengine/quicknanobrowser/DownloadView.qml
+++ b/examples/webengine/quicknanobrowser/DownloadView.qml
@@ -64,8 +64,8 @@ Rectangle {
     }
 
     function append(download) {
-        downloadModel.append(download)
-        downloadModel.downloads.push(download)
+        downloadModel.append(download);
+        downloadModel.downloads.push(download);
     }
 
     Component {
@@ -113,14 +113,14 @@ Rectangle {
                     anchors.right: parent.right
                     iconSource: "icons/process-stop.png"
                     onClicked: {
-                        var download = downloadModel.downloads[index]
+                        var download = downloadModel.downloads[index];
 
-                        download.cancel()
+                        download.cancel();
 
                         downloadModel.downloads = downloadModel.downloads.filter(function (el) {
                             return el.id !== download.id;
                         });
-                        downloadModel.remove(index)
+                        downloadModel.remove(index);
                     }
                 }
             }
@@ -167,7 +167,7 @@ Rectangle {
                 text: "OK"
                 anchors.centerIn: parent
                 onClicked: {
-                    downloadView.visible = false
+                    downloadView.visible = false;
                 }
             }
         }
diff --git a/examples/webengine/quicknanobrowser/FullScreenNotification.qml b/examples/webengine/quicknanobrowser/FullScreenNotification.qml
index 80a63d4791f8c2fa54fd05cde04803ccff673823..f0487e868d437d77fff2ef24c93c0155db3e7176 100644
--- a/examples/webengine/quicknanobrowser/FullScreenNotification.qml
+++ b/examples/webengine/quicknanobrowser/FullScreenNotification.qml
@@ -51,14 +51,14 @@ Rectangle {
     opacity: 0
 
     function show() {
-        visible = true
-        opacity = 1
-        reset.start()
+        visible = true;
+        opacity = 1;
+        reset.start();
     }
 
     function hide() {
-        reset.stop()
-        opacity = 0
+        reset.stop();
+        opacity = 0;
     }
 
     Behavior on opacity {
@@ -66,7 +66,7 @@ Rectangle {
             duration: 750
             onStopped: {
                 if (opacity == 0)
-                    visible = false
+                    visible = false;
             }
         }
     }
diff --git a/examples/webenginewidgets/markdowneditor/document.h b/examples/webenginewidgets/markdowneditor/document.h
index 3c16c251d4d0a47cd8c75f5de34f7d9387129d9a..bc65527314b8bf4d9966e0f1efa98989f40b91e2 100644
--- a/examples/webenginewidgets/markdowneditor/document.h
+++ b/examples/webenginewidgets/markdowneditor/document.h
@@ -57,7 +57,7 @@
 class Document : public QObject
 {
     Q_OBJECT
-    Q_PROPERTY(QString text MEMBER m_text NOTIFY textChanged)
+    Q_PROPERTY(QString text MEMBER m_text NOTIFY textChanged FINAL)
 public:
     explicit Document(QObject *parent = nullptr) : QObject(parent) {}
 
diff --git a/examples/webenginewidgets/markdowneditor/mainwindow.h b/examples/webenginewidgets/markdowneditor/mainwindow.h
index ad032037367b9c0d54e29e986c246e78a91481d1..817f626d80ffb8b168bf168a91400a66bb7dc5fe 100644
--- a/examples/webenginewidgets/markdowneditor/mainwindow.h
+++ b/examples/webenginewidgets/markdowneditor/mainwindow.h
@@ -67,7 +67,7 @@ class MainWindow : public QMainWindow
     Q_OBJECT
 
 public:
-    explicit MainWindow(QWidget *parent = 0);
+    explicit MainWindow(QWidget *parent = nullptr);
     ~MainWindow();
 
     void openFile(const QString &path);
diff --git a/examples/webenginewidgets/simplebrowser/browserwindow.cpp b/examples/webenginewidgets/simplebrowser/browserwindow.cpp
index c01f912d3ef9506f6b857368c84f1823e932b180..762d56c85766332d0ab7febf20bb787d03f35973 100644
--- a/examples/webenginewidgets/simplebrowser/browserwindow.cpp
+++ b/examples/webenginewidgets/simplebrowser/browserwindow.cpp
@@ -105,6 +105,13 @@ BrowserWindow::BrowserWindow(QWidget *parent, Qt::WindowFlags flags)
 
     m_urlLineEdit->setFavIcon(QIcon(QStringLiteral(":defaulticon.png")));
 
+    QAction *focusUrlLineEditAction = new QAction(this);
+    addAction(focusUrlLineEditAction);
+    focusUrlLineEditAction->setShortcut(QKeySequence(Qt::CTRL | Qt::Key_L));
+    connect(focusUrlLineEditAction, &QAction::triggered, this, [this] () {
+        m_urlLineEdit->setFocus(Qt::ShortcutFocusReason);
+    });
+
     handleWebViewTitleChanged(tr("Qt Simple Browser"));
     m_tabWidget->createTab();
 }
diff --git a/examples/webenginewidgets/videoplayer/data/index.html b/examples/webenginewidgets/videoplayer/data/index.html
new file mode 100644
index 0000000000000000000000000000000000000000..4a1bdc33e36c609cc6f93d456a129afb4d70f365
--- /dev/null
+++ b/examples/webenginewidgets/videoplayer/data/index.html
@@ -0,0 +1,23 @@
+<!doctype html>
+<html lang="en">
+    <head>
+        <meta charset="utf-8">
+        <style type="text/css">
+            #ytplayer {
+                position: absolute;
+                top: 0;
+                left: 0;
+                width: 100%;
+                height: 100%;
+            }
+        </style>
+    </head>
+    <body>
+        <iframe
+            id="ytplayer"
+            src="https://www.youtube.com/embed/CjyjEUFn_FI"
+            frameborder="0"
+            allowfullscreen>
+        </iframe>
+    </body>
+</html>
diff --git a/examples/webenginewidgets/videoplayer/data/videoplayer.qrc b/examples/webenginewidgets/videoplayer/data/videoplayer.qrc
new file mode 100644
index 0000000000000000000000000000000000000000..c3322b45413f5f7085ea562d67ea20f93ad3849e
--- /dev/null
+++ b/examples/webenginewidgets/videoplayer/data/videoplayer.qrc
@@ -0,0 +1,5 @@
+<RCC>
+    <qresource prefix="/">
+        <file>index.html</file>
+    </qresource>
+</RCC>
diff --git a/examples/webenginewidgets/videoplayer/doc/images/videoplayer-example.png b/examples/webenginewidgets/videoplayer/doc/images/videoplayer-example.png
new file mode 100644
index 0000000000000000000000000000000000000000..9cf51d84aaa00f8136df365c5edf3c514780c6e9
Binary files /dev/null and b/examples/webenginewidgets/videoplayer/doc/images/videoplayer-example.png differ
diff --git a/examples/webenginewidgets/videoplayer/doc/src/videoplayer.qdoc b/examples/webenginewidgets/videoplayer/doc/src/videoplayer.qdoc
new file mode 100644
index 0000000000000000000000000000000000000000..599e13e6c14105a5a3f025da6d41833bbac879bf
--- /dev/null
+++ b/examples/webenginewidgets/videoplayer/doc/src/videoplayer.qdoc
@@ -0,0 +1,186 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the documentation of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:FDL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Free Documentation License Usage
+** Alternatively, this file may be used under the terms of the GNU Free
+** Documentation License version 1.3 as published by the Free Software
+** Foundation and appearing in the file included in the packaging of
+** this file. Please review the following information to ensure
+** the GNU Free Documentation License version 1.3 requirements
+** will be met: http://www.gnu.org/copyleft/fdl.html.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*!
+    \example webenginewidgets/videoplayer
+    \title WebEngine Widgets Video Player Example
+    \ingroup webengine-widgetexamples
+    \brief Displays full screen video using \l QWebEngineView
+
+    \image videoplayer-example.png
+
+    \e {Video Player} demonstrates how to support full screen playback of HTML5
+    video using \l QWebEngineView.
+
+    \l {https://fullscreen.spec.whatwg.org/}{The Fullscreen API} is a
+    cross-browser Javascript API that enables a web page to request that one of
+    its HTML elements be made to occupy the user's entire screen. It is
+    commonly used for full screen video playback via the \c <video> element, but
+    can in principle be used to display any HTML content in full screen mode. Qt
+    WebEngine supports this API, however it is disabled by default. This example
+    shows the steps needed to switch it on, including:
+
+    \list
+        \li Enabling it in \l QWebEngineSettings.
+        \li Handling the \l QWebEnginePage::fullScreenRequested signal by creating
+            a new full screen window.
+        \li Displaying a notification popup to ensure that the user is aware
+            that something is being displayed full screen.
+    \endlist
+
+    \include examples-run.qdocinc
+
+    \section1 Overview
+
+    Once started, the example program will create a normal (non-fullscreen)
+    window with a \l QWebEngineView showing an embedded YouTube video player.
+    You can then click on the full screen toggle button (bottom-right corner) to
+    enter full screen mode. This should also display a centered notification
+    overlay informing you that you can exit full screen mode by pressing the
+    escape key.
+
+    Implementation-wise entering full screen mode entails creating a new full
+    screen window with a separate \l QWebEngineView instance and migrating the
+    \l QWebEnginePage from the normal window's \l QWebEngineView to this new \l
+    QWebEngineView. Exiting full screen mode reverses this migration.
+
+    The example code is divided between three classes, \c MainWindow, \c
+    FullScreenWindow, and \c FullScreenNotification. The classes \c MainWindow
+    and \c FullScreenWindow are each responsible for managing one top-level
+    window, while \c FullScreenNotification is responsible for styling and
+    animating the notification box. A \c MainWindow is created on startup and
+    lives for the entire program runtime, while a new \c FullScreenWindow is
+    created every time full screen mode is entered.
+
+    \section1 MainWindow Class Declaration
+
+    A \c MainWindow is a \l QMainWindow with a \l QWebEngineView as the central
+    widget:
+
+    \quotefromfile webenginewidgets/videoplayer/mainwindow.h
+    \skipto #include
+    \printuntil /^\}/
+
+    \section1 MainWindow Class Definition
+
+    In the constructor we start by setting up the \l QWebEngineView as the
+    central widget:
+
+    \quotefromfile webenginewidgets/videoplayer/mainwindow.cpp
+    \skipto MainWindow::MainWindow
+    \printuntil setCentralWidget
+
+    We then configure Qt WebEngine to advertise support for the Fullscreen API:
+
+    \printline QWebEngineSettings
+
+    Without this line the full screen toggle button would be disabled (grayed
+    out) as the Javascript running on the page can detect that our browser
+    does not support full screen mode.
+
+    Next we connect the \c fullScreenRequested signal to our slot:
+
+    \printuntil &MainWindow::fullScreenRequested
+
+    This signal is emitted whenever the Javascript on the page wants to enter or
+    exit full screen mode. Without handling this signal (but still keeping the
+    \c FullScreenSupportEnabled attribute as \c true) the toggle button will be
+    enabled but clicking on it will have no effect as Javascript's full screen
+    request will be denied.
+
+    Finally, we load some HTML (see
+    \l{webenginewidgets/videoplayer/data/index.html}{index.html} included with
+    the example) into our \l QWebEngineView:
+
+    \printline load
+
+    The second part of \c MainWindow is handling the full screen requests:
+
+    \skipto MainWindow::fullScreenRequested
+    \printuntil /^\}/
+
+    We create a new \c FullScreenWindow when entering full screen mode, and
+    delete it when exiting.
+
+    \section1 FullScreenWindow Class Declaration
+
+    A \c FullScreenWindow is a \l QWidget containing a \l QWebEngineView and a
+    \c FullScreenNotification.
+
+    \quotefromfile webenginewidgets/videoplayer/fullscreenwindow.h
+    \skipto #include
+    \printuntil /^\}/
+
+    \section1 FullScreenWindow Class Definition
+
+    The constructor is responsible for hiding the normal window (while saving
+    its geometry) and showing the new \c FullScreenWindow instead:
+
+    \quotefromfile webenginewidgets/videoplayer/fullscreenwindow.cpp
+    \skipto FullScreenWindow::FullScreenWindow
+    \printuntil /^\}/
+
+    The call to \l QWebEngineView::setPage will move the web page from the \c
+    MainWindow's view to \c FullScreenWindow's view.
+
+    In the destructor we use the same method to move the page back, after which
+    we restore the main window's geometry and visibility:
+
+    \skipto FullScreenWindow::~FullScreenWindow
+    \printuntil /^\}/
+
+    We override \l QWidget::resizeEvent to do manual layout, keeping the \l
+    QWebEngineView maximized, and the \c FullScreenNotification centered within
+    the window:
+
+    \skipto FullScreenWindow::resizeEvent
+    \printuntil /^\}/
+
+    \section1 FullScreenNotification Class Declaration
+
+    A \c FullScreenNotification is just a \l QLabel with some styling and
+    animation:
+
+    \quotefromfile webenginewidgets/videoplayer/fullscreennotification.h
+    \skipto #include
+    \printuntil /^\}/
+
+    \section1 FullScreenWindow Class Definition
+
+    In the constructor we configure the QLabel and set up a delayed fade-out
+    animation using \l {The Animation Framework}:
+
+    \quotefromfile webenginewidgets/videoplayer/fullscreennotification.cpp
+    \skipto FullScreenNotification::FullScreenNotification
+    \printuntil /^\}/
+
+    The custom signal \c shown, which we use to trigger the animation, is
+    emitted from the \c showEvent method:
+
+    \skipto FullScreenNotification::showEvent
+    \printuntil /^\}/
+*/
diff --git a/examples/webenginewidgets/videoplayer/fullscreennotification.cpp b/examples/webenginewidgets/videoplayer/fullscreennotification.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..e65e2cbad30b120d6f55f6aba7c44ee78859740a
--- /dev/null
+++ b/examples/webenginewidgets/videoplayer/fullscreennotification.cpp
@@ -0,0 +1,87 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+**   * Redistributions of source code must retain the above copyright
+**     notice, this list of conditions and the following disclaimer.
+**   * Redistributions in binary form must reproduce the above copyright
+**     notice, this list of conditions and the following disclaimer in
+**     the documentation and/or other materials provided with the
+**     distribution.
+**   * Neither the name of The Qt Company Ltd nor the names of its
+**     contributors may be used to endorse or promote products derived
+**     from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include "fullscreennotification.h"
+
+#include <QGraphicsOpacityEffect>
+#include <QPropertyAnimation>
+#include <QSequentialAnimationGroup>
+
+FullScreenNotification::FullScreenNotification(QWidget *parent)
+    : QLabel(parent)
+    , m_previouslyVisible(false)
+{
+    setText(tr("You are now in full screen mode. Press ESC to quit!"));
+    setStyleSheet(
+        "font-size: 24px;"
+        "color: white;"
+        "background-color: black;"
+        "border-color: white;"
+        "border-width: 2px;"
+        "border-style: solid;"
+        "padding: 100px");
+    setAttribute(Qt::WA_TransparentForMouseEvents);
+
+    auto effect = new QGraphicsOpacityEffect;
+    effect->setOpacity(1);
+    setGraphicsEffect(effect);
+
+    auto animations = new QSequentialAnimationGroup(this);
+    animations->addPause(3000);
+    auto opacityAnimation = new QPropertyAnimation(effect, "opacity", animations);
+    opacityAnimation->setDuration(2000);
+    opacityAnimation->setStartValue(1.0);
+    opacityAnimation->setEndValue(0.0);
+    opacityAnimation->setEasingCurve(QEasingCurve::OutQuad);
+    animations->addAnimation(opacityAnimation);
+
+    connect(this, &FullScreenNotification::shown,
+            [animations](){ animations->start(); });
+
+    connect(animations, &QAbstractAnimation::finished,
+            [this](){ this->hide(); });
+}
+
+void FullScreenNotification::showEvent(QShowEvent *event)
+{
+    QLabel::showEvent(event);
+    if (!m_previouslyVisible && isVisible())
+        emit shown();
+    m_previouslyVisible = isVisible();
+}
diff --git a/examples/webenginewidgets/videoplayer/fullscreennotification.h b/examples/webenginewidgets/videoplayer/fullscreennotification.h
new file mode 100644
index 0000000000000000000000000000000000000000..9f1befb9f9eaabf7f8d4de6f68590fea60d1196c
--- /dev/null
+++ b/examples/webenginewidgets/videoplayer/fullscreennotification.h
@@ -0,0 +1,61 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+**   * Redistributions of source code must retain the above copyright
+**     notice, this list of conditions and the following disclaimer.
+**   * Redistributions in binary form must reproduce the above copyright
+**     notice, this list of conditions and the following disclaimer in
+**     the documentation and/or other materials provided with the
+**     distribution.
+**   * Neither the name of The Qt Company Ltd nor the names of its
+**     contributors may be used to endorse or promote products derived
+**     from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#ifndef FULLSCREENNOTIFICATION_H
+#define FULLSCREENNOTIFICATION_H
+
+#include <QLabel>
+
+class FullScreenNotification : public QLabel
+{
+    Q_OBJECT
+public:
+    FullScreenNotification(QWidget *parent = nullptr);
+
+protected:
+    void showEvent(QShowEvent *event) override;
+
+signals:
+    void shown();
+
+private:
+    bool m_previouslyVisible;
+};
+
+#endif // FULLSCREENNOTIFICATION_H
diff --git a/examples/webenginewidgets/videoplayer/fullscreenwindow.cpp b/examples/webenginewidgets/videoplayer/fullscreenwindow.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..df28839a2e2f438a279ff62781e42caec36a7d2b
--- /dev/null
+++ b/examples/webenginewidgets/videoplayer/fullscreenwindow.cpp
@@ -0,0 +1,88 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+**   * Redistributions of source code must retain the above copyright
+**     notice, this list of conditions and the following disclaimer.
+**   * Redistributions in binary form must reproduce the above copyright
+**     notice, this list of conditions and the following disclaimer in
+**     the documentation and/or other materials provided with the
+**     distribution.
+**   * Neither the name of The Qt Company Ltd nor the names of its
+**     contributors may be used to endorse or promote products derived
+**     from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include "fullscreenwindow.h"
+
+#include "fullscreennotification.h"
+
+#include <QAction>
+#include <QLabel>
+#include <QWebEngineView>
+
+FullScreenWindow::FullScreenWindow(QWebEngineView *oldView, QWidget *parent)
+    : QWidget(parent)
+    , m_view(new QWebEngineView(this))
+    , m_notification(new FullScreenNotification(this))
+    , m_oldView(oldView)
+    , m_oldGeometry(oldView->window()->geometry())
+{
+    m_view->stackUnder(m_notification);
+
+    auto exitAction = new QAction(this);
+    exitAction->setShortcut(Qt::Key_Escape);
+    connect(exitAction, &QAction::triggered, [this]() {
+        m_view->triggerPageAction(QWebEnginePage::ExitFullScreen);
+    });
+    addAction(exitAction);
+
+    m_view->setPage(m_oldView->page());
+    setGeometry(m_oldGeometry);
+    showFullScreen();
+    m_oldView->window()->hide();
+}
+
+FullScreenWindow::~FullScreenWindow()
+{
+    m_oldView->setPage(m_view->page());
+    m_oldView->window()->setGeometry(m_oldGeometry);
+    m_oldView->window()->show();
+    hide();
+}
+
+void FullScreenWindow::resizeEvent(QResizeEvent *event)
+{
+    QRect viewGeometry(QPoint(0, 0), size());
+    m_view->setGeometry(viewGeometry);
+
+    QRect notificationGeometry(QPoint(0, 0), m_notification->sizeHint());
+    notificationGeometry.moveCenter(viewGeometry.center());
+    m_notification->setGeometry(notificationGeometry);
+
+    QWidget::resizeEvent(event);
+}
diff --git a/examples/webenginewidgets/videoplayer/fullscreenwindow.h b/examples/webenginewidgets/videoplayer/fullscreenwindow.h
new file mode 100644
index 0000000000000000000000000000000000000000..dda0a9885aaac6c6f23859e6a1fa0408e326d1d6
--- /dev/null
+++ b/examples/webenginewidgets/videoplayer/fullscreenwindow.h
@@ -0,0 +1,68 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+**   * Redistributions of source code must retain the above copyright
+**     notice, this list of conditions and the following disclaimer.
+**   * Redistributions in binary form must reproduce the above copyright
+**     notice, this list of conditions and the following disclaimer in
+**     the documentation and/or other materials provided with the
+**     distribution.
+**   * Neither the name of The Qt Company Ltd nor the names of its
+**     contributors may be used to endorse or promote products derived
+**     from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#ifndef FULLSCREENWINDOW_H
+#define FULLSCREENWINDOW_H
+
+#include <QWidget>
+
+QT_BEGIN_NAMESPACE
+class QWebEngineView;
+QT_END_NAMESPACE
+
+class FullScreenNotification;
+
+class FullScreenWindow : public QWidget
+{
+    Q_OBJECT
+public:
+    explicit FullScreenWindow(QWebEngineView *oldView, QWidget *parent = nullptr);
+    ~FullScreenWindow();
+
+protected:
+    void resizeEvent(QResizeEvent *event) override;
+
+private:
+    QWebEngineView *m_view;
+    FullScreenNotification *m_notification;
+    QWebEngineView *m_oldView;
+    QRect m_oldGeometry;
+};
+
+#endif // FULLSCREENWINDOW_H
diff --git a/examples/webenginewidgets/videoplayer/main.cpp b/examples/webenginewidgets/videoplayer/main.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..fcddd988e9520223fa6b6d57bc10de104c376f7c
--- /dev/null
+++ b/examples/webenginewidgets/videoplayer/main.cpp
@@ -0,0 +1,53 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+**   * Redistributions of source code must retain the above copyright
+**     notice, this list of conditions and the following disclaimer.
+**   * Redistributions in binary form must reproduce the above copyright
+**     notice, this list of conditions and the following disclaimer in
+**     the documentation and/or other materials provided with the
+**     distribution.
+**   * Neither the name of The Qt Company Ltd nor the names of its
+**     contributors may be used to endorse or promote products derived
+**     from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "mainwindow.h"
+#include <QApplication>
+
+int main(int argc, char *argv[])
+{
+    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
+    QApplication app(argc, argv);
+
+    MainWindow mainWindow;
+    mainWindow.show();
+
+    return app.exec();
+}
diff --git a/examples/webenginewidgets/videoplayer/mainwindow.cpp b/examples/webenginewidgets/videoplayer/mainwindow.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..55885e0c5ba72dd8d32a30b7ff4923ea4acfcb32
--- /dev/null
+++ b/examples/webenginewidgets/videoplayer/mainwindow.cpp
@@ -0,0 +1,72 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+**   * Redistributions of source code must retain the above copyright
+**     notice, this list of conditions and the following disclaimer.
+**   * Redistributions in binary form must reproduce the above copyright
+**     notice, this list of conditions and the following disclaimer in
+**     the documentation and/or other materials provided with the
+**     distribution.
+**   * Neither the name of The Qt Company Ltd nor the names of its
+**     contributors may be used to endorse or promote products derived
+**     from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include "mainwindow.h"
+
+#include <QWebEngineView>
+#include <QWebEngineSettings>
+#include <QWebEngineFullScreenRequest>
+
+MainWindow::MainWindow(QWidget *parent)
+    : QMainWindow(parent)
+    , m_view(new QWebEngineView(this))
+{
+    setCentralWidget(m_view);
+    m_view->settings()->setAttribute(QWebEngineSettings::FullScreenSupportEnabled, true);
+    connect(m_view->page(),
+            &QWebEnginePage::fullScreenRequested,
+            this,
+            &MainWindow::fullScreenRequested);
+    m_view->load(QUrl(QStringLiteral("qrc:/index.html")));
+}
+
+void MainWindow::fullScreenRequested(QWebEngineFullScreenRequest request)
+{
+    if (request.toggleOn()) {
+        if (m_fullScreenWindow)
+            return;
+        request.accept();
+        m_fullScreenWindow.reset(new FullScreenWindow(m_view));
+    } else {
+        if (!m_fullScreenWindow)
+            return;
+        request.accept();
+        m_fullScreenWindow.reset();
+    }
+}
diff --git a/examples/webenginewidgets/videoplayer/mainwindow.h b/examples/webenginewidgets/videoplayer/mainwindow.h
new file mode 100644
index 0000000000000000000000000000000000000000..a270c6295e65a522c7f5f1a2d0a98b058ab5504f
--- /dev/null
+++ b/examples/webenginewidgets/videoplayer/mainwindow.h
@@ -0,0 +1,64 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+**   * Redistributions of source code must retain the above copyright
+**     notice, this list of conditions and the following disclaimer.
+**   * Redistributions in binary form must reproduce the above copyright
+**     notice, this list of conditions and the following disclaimer in
+**     the documentation and/or other materials provided with the
+**     distribution.
+**   * Neither the name of The Qt Company Ltd nor the names of its
+**     contributors may be used to endorse or promote products derived
+**     from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#ifndef MAINWINDOW_H
+#define MAINWINDOW_H
+
+#include "fullscreenwindow.h"
+
+#include <QMainWindow>
+#include <QWebEngineView>
+#include <QWebEngineFullScreenRequest>
+
+class MainWindow : public QMainWindow
+{
+    Q_OBJECT
+
+public:
+    explicit MainWindow(QWidget *parent = nullptr);
+
+private slots:
+    void fullScreenRequested(QWebEngineFullScreenRequest request);
+
+private:
+    QWebEngineView *m_view;
+    QScopedPointer<FullScreenWindow> m_fullScreenWindow;
+};
+
+#endif // MAINWINDOW_H
diff --git a/examples/webenginewidgets/videoplayer/videoplayer.pro b/examples/webenginewidgets/videoplayer/videoplayer.pro
new file mode 100644
index 0000000000000000000000000000000000000000..ab55992e0fe94d198588aaf329158c676ee2eb22
--- /dev/null
+++ b/examples/webenginewidgets/videoplayer/videoplayer.pro
@@ -0,0 +1,19 @@
+TEMPLATE = app
+
+QT += webenginewidgets
+
+HEADERS += \
+    mainwindow.h \
+    fullscreenwindow.h \
+    fullscreennotification.h
+
+SOURCES += main.cpp \
+    mainwindow.cpp \
+    fullscreenwindow.cpp \
+    fullscreennotification.cpp
+
+RESOURCES += \
+    data/videoplayer.qrc
+
+target.path = $$[QT_INSTALL_EXAMPLES]/webenginewidgets/videoplayer
+INSTALLS += target
diff --git a/examples/webenginewidgets/webenginewidgets.pro b/examples/webenginewidgets/webenginewidgets.pro
index 353104d6ac7025bf268bc78d99fce2f401989849..41582bbf7a1642752a3a475750a59f6a686817dd 100644
--- a/examples/webenginewidgets/webenginewidgets.pro
+++ b/examples/webenginewidgets/webenginewidgets.pro
@@ -6,7 +6,8 @@ SUBDIRS += \
     cookiebrowser \
     demobrowser \
     markdowneditor \
-    simplebrowser
+    simplebrowser \
+    videoplayer
 
 contains(WEBENGINE_CONFIG, use_spellchecker):!cross_compile {
     !contains(WEBENGINE_CONFIG, use_native_spellchecker) {
diff --git a/tools/qmake/mkspecs/features/configure.prf b/mkspecs/features/configure.prf
similarity index 97%
rename from tools/qmake/mkspecs/features/configure.prf
rename to mkspecs/features/configure.prf
index 55a7c45a412c637b30356bb2556ed8dda1ac89b5..9b0be0140097fd08855a465d7061238c906150e8 100644
--- a/tools/qmake/mkspecs/features/configure.prf
+++ b/mkspecs/features/configure.prf
@@ -11,7 +11,7 @@ defineTest(runConfigure) {
     # Ignore the cached config tests results in case they were not successful
     CONFIG += recheck
     #Override the config.tests path
-    QMAKE_CONFIG_TESTS_DIR = $$QTWEBENGINE_ROOT/tools/qmake/config.tests
+    QMAKE_CONFIG_TESTS_DIR = $$QTWEBENGINE_ROOT/config.tests
     CONFIG_TESTS = $$files($$QMAKE_CONFIG_TESTS_DIR/*.pro, true)
     log("Running configure tests$${EOL}")
     for(test, CONFIG_TESTS) {
@@ -30,7 +30,6 @@ defineTest(runConfigure) {
         qtConfig(spellchecker): WEBENGINE_CONFIG += use_spellchecker
         qtConfig(webrtc): WEBENGINE_CONFIG += use_webrtc
         qtConfig(embedded): WEBENGINE_CONFIG += embedded_build
-        qtConfig(optimize_size): WEBENGINE_CONFIG += reduce_binary_size
         qtConfig(system-webp): WEBENGINE_CONFIG += use_system_libwebp
         else: WEBENGINE_CONFIG += use_bundled_libwebp
         qtConfig(system-opus): WEBENGINE_CONFIG += use_system_opus
@@ -42,6 +41,9 @@ defineTest(runConfigure) {
     }
     isQtMinimum(5, 9) {
         qtConfig(appstore-compliant): WEBENGINE_CONFIG += use_appstore_compliant_code
+        optimize_size: WEBENGINE_CONFIG += reduce_binary_size
+    } else {
+        qtConfig(embedded): WEBENGINE_CONFIG += reduce_binary_size
     }
 
     linux {
diff --git a/tools/qmake/mkspecs/features/default_pre.prf b/mkspecs/features/default_pre.prf
similarity index 82%
rename from tools/qmake/mkspecs/features/default_pre.prf
rename to mkspecs/features/default_pre.prf
index 77e437bc9693065f055a04d9d6fa2bad7ade13a5..c7440fa7a2b3846d72c1a19efd62d7712cd46acf 100644
--- a/tools/qmake/mkspecs/features/default_pre.prf
+++ b/mkspecs/features/default_pre.prf
@@ -1,6 +1,3 @@
-# We depend on libc++ to build chromium so our macosx-version-min has to be 10.7
-QMAKE_MACOSX_DEPLOYMENT_TARGET = 10.7
-
 QTWEBENGINEPROCESS_NAME_RELEASE = QtWebEngineProcess
 debug_and_release {
     QTWEBENGINEPROCESS_NAME_DEBUG = $$join(QTWEBENGINEPROCESS_NAME_RELEASE,,,d)
diff --git a/tools/qmake/mkspecs/features/functions.prf b/mkspecs/features/functions.prf
similarity index 93%
rename from tools/qmake/mkspecs/features/functions.prf
rename to mkspecs/features/functions.prf
index ed113303783c386ce558b85b6f7988233be38993..eb421f8b5f92b426cc4b5f0caac9e999c2b8a6e9 100644
--- a/tools/qmake/mkspecs/features/functions.prf
+++ b/mkspecs/features/functions.prf
@@ -86,7 +86,6 @@ defineTest(isPlatformSupported) {
     skipBuild("Static builds of QtWebEngine aren't supported.")
     return(false)
   }
-  !isPythonVersionSupported(): return(false)
   !isArchSupported(): return(false)
   isSanitizerEnabled():!isSanitizerSupported():!forceSanitizerBuild(): return(false)
   return(true)
@@ -101,25 +100,6 @@ defineTest(isArchSupported) {
     return(false)
 }
 
-defineTest(isPythonVersionSupported) {
-    python_error_msg = "Python version 2 (2.7.5 or later) is required to build Qt WebEngine."
-    python_version = $$system('python -c "import sys; print(sys.version_info[0:3])"')
-    python_version ~= s/[()]//g
-    python_version = $$split(python_version, ',')
-    python_major_version = $$first(python_version)
-    greaterThan(python_major_version, 2) {
-        skipBuild("Python version 3 is not supported by Chromium.")
-        skipBuild($$python_error_msg)
-        return(false)
-    }
-    python_minor_version = $$member(python_version, 1)
-    python_patch_version = $$member(python_version, 2)
-    greaterThan(python_major_version, 1): greaterThan(python_minor_version, 6): greaterThan(python_patch_version, 4): return(true)
-    skipBuild("Using Python version $${python_major_version}.$${python_minor_version}.$${python_patch_version}.")
-    skipBuild($$python_error_msg)
-    return(false)
-}
-
 defineTest(isSanitizerEnabled) {
   sanitize_address|sanitize_memory|sanitize_undefined|sanitize_thread: return(true)
   return(false)
@@ -358,6 +338,25 @@ defineTest(use?) {
     return(false)
 }
 
+# Returns the unquoted path to the python executable.
+defineReplace(pythonPath) {
+    isEmpty(QMAKE_PYTHON2) {
+        # Fallback for building QtWebEngine with Qt < 5.8
+        QMAKE_PYTHON2 = python
+    }
+    return($$QMAKE_PYTHON2)
+}
+
+# Returns the python executable for use with shell / make targets.
+defineReplace(pythonPathForShell) {
+    return($$shell_quote($$shell_path($$pythonPath())))
+}
+
+# Returns the python executable for use with $$system()
+defineReplace(pythonPathForSystem) {
+    return($$system_quote($$system_path($$pythonPath())))
+}
+
 defineReplace(ninjaPath) {
     src_3rd_party_dir = $$absolute_path("$${getChromiumSrcDir()}/../", "$$QTWEBENGINE_ROOT")
     out = $$shadowed($$absolute_path(ninja/ninja, $$src_3rd_party_dir))
diff --git a/tools/qmake/mkspecs/features/gn_generator.prf b/mkspecs/features/gn_generator.prf
similarity index 100%
rename from tools/qmake/mkspecs/features/gn_generator.prf
rename to mkspecs/features/gn_generator.prf
diff --git a/qtwebengine.pro b/qtwebengine.pro
index b6e7358763c9089a97dfe2982c0f85a0fcb72774..c8f3555e33e7370b7044cbb0dd49c6696ce0b60f 100644
--- a/qtwebengine.pro
+++ b/qtwebengine.pro
@@ -16,9 +16,9 @@ isPlatformSupported() {
 OTHER_FILES = \
     tools/buildscripts/* \
     tools/scripts/* \
-    tools/qmake/config.tests/khr/* \
-    tools/qmake/config.tests/libcap/* \
-    tools/qmake/config.tests/libvpx/* \
-    tools/qmake/config.tests/snappy/* \
-    tools/qmake/config.tests/srtp/* \
-    tools/qmake/mkspecs/features/*
+    config.tests/khr/* \
+    config.tests/libcap/* \
+    config.tests/libvpx/* \
+    config.tests/snappy/* \
+    config.tests/srtp/* \
+    mkspecs/features/*
diff --git a/src/3rdparty b/src/3rdparty
index 853d4069e45b06106f33611c458f5480f71e7c57..898afbbf79637101bbd5e6ab12695ced6a759ae7 160000
--- a/src/3rdparty
+++ b/src/3rdparty
@@ -1 +1 @@
-Subproject commit 853d4069e45b06106f33611c458f5480f71e7c57
+Subproject commit 898afbbf79637101bbd5e6ab12695ced6a759ae7
diff --git a/src/buildtools/gn.pro b/src/buildtools/gn.pro
index 092888e0e59f59d5e0a6479ab484848b431ce9ea..829e7a31af3ac2891df8b205f6d62033e7899ec3 100644
--- a/src/buildtools/gn.pro
+++ b/src/buildtools/gn.pro
@@ -1,36 +1,30 @@
 TEMPLATE = aux
-CONFIG += release
-
 option(host_build)
 
-defineReplace(buildGn) {
-    gn_args = $$1
-    out = $$gnPath()
-    !qtConfig(system-ninja): ninja_path = "--path $$ninjaPath()"
-    # check if it is not already build
-    !exists($$out) {
-        mkpath($$dirname(out))
-        src_3rd_party_dir = $$absolute_path("$${getChromiumSrcDir()}/../", "$$QTWEBENGINE_ROOT")
-        gn_bootstrap = $$system_path($$absolute_path(chromium/tools/gn/bootstrap/bootstrap.py, $$src_3rd_party_dir))
-        gn_args = $$system_quote($$gn_args)
-        gn_configure = $$system_quote($$gn_bootstrap) --shadow --gn-gen-args=$$gn_args $$ninja_path
-        !system("cd $$system_quote($$system_path($$dirname(out))) && python $$gn_configure") {
-            error("GN build error!")
-        }
-    }
-}
+!debug_and_release: CONFIG += release
 
 isQtMinimum(5, 8) {
     include($$QTWEBENGINE_OUT_ROOT/qtwebengine-config.pri)
     QT_FOR_CONFIG += webengine-private
 }
 
-!qtConfig(system-gn) {
-    buildgn.target = build_gn
-    buildgn.commands = $$buildGn($$gnArgs())
-    QMAKE_EXTRA_TARGETS += buildgn
-
-    default_target.target = first
-    default_target.depends = buildgn
-    QMAKE_EXTRA_TARGETS += default_target
+build_pass|!debug_and_release {
+    !qtConfig(system-gn): CONFIG(release, debug|release) {
+        buildgn.target = build_gn
+        gn_args = $$gnArgs()
+        out = $$gnPath()
+        !qtConfig(system-ninja): ninja_path = "--path $$ninjaPath()"
+        # check if it is not already build
+        !exists($$out) {
+            mkpath($$dirname(out))
+            src_3rd_party_dir = $$absolute_path("$${getChromiumSrcDir()}/../", "$$QTWEBENGINE_ROOT")
+            gn_bootstrap = $$system_path($$absolute_path(chromium/tools/gn/bootstrap/bootstrap.py, $$src_3rd_party_dir))
+            gn_args = $$system_quote($$gn_args)
+            gn_configure = $$system_quote($$gn_bootstrap) --shadow --gn-gen-args=$$gn_args $$ninja_path
+            !system("cd $$system_quote($$system_path($$dirname(out))) && $$pythonPathForSystem() $$gn_configure") {
+                error("GN build error!")
+            }
+        }
+        QMAKE_DISTCLEAN += $$out
+    }
 }
diff --git a/src/buildtools/ninja.pro b/src/buildtools/ninja.pro
index c391d6e84f3c7697a2dbcf2da4bc7dbf21a8b805..1b17c6dfa8f417e31fe78bc4e44942adef77999a 100644
--- a/src/buildtools/ninja.pro
+++ b/src/buildtools/ninja.pro
@@ -1,31 +1,25 @@
 TEMPLATE = aux
-CONFIG += release
 
-defineReplace(buildNinja) {
-   out = $$ninjaPath()
-   # check if it is not already build
-   !exists($$out) {
-       mkpath($$dirname(out))
-       src_3rd_party_dir = $$absolute_path("$${getChromiumSrcDir()}/../", "$$QTWEBENGINE_ROOT")
-       ninja_configure =  $$system_quote($$system_path($$absolute_path(ninja/configure.py, $$src_3rd_party_dir)))
-       !system("cd $$system_quote($$system_path($$dirname(out))) && python $$ninja_configure --bootstrap") {
-            error("NINJA build error!")
-       }
-   }
-}
+!debug_and_release: CONFIG += release
 
 isQtMinimum(5, 8) {
     include($$QTWEBENGINE_OUT_ROOT/qtwebengine-config.pri)
     QT_FOR_CONFIG += webengine-private
 }
 
-!qtConfig(system-ninja) {
-    buildninja.target = build_ninja
-    buildninja.commands = $$buildNinja()
-    QMAKE_EXTRA_TARGETS += buildninja
-
-    default_target.target = first
-    default_target.depends = buildninja
-    QMAKE_EXTRA_TARGETS += default_target
+build_pass|!debug_and_release {
+    !qtConfig(system-ninja): CONFIG(release, debug|release) {
+        out = $$ninjaPath()
+        # check if it is not already build
+        !exists($$out) {
+            mkpath($$dirname(out))
+            src_3rd_party_dir = $$absolute_path("$${getChromiumSrcDir()}/../", "$$QTWEBENGINE_ROOT")
+            ninja_configure =  $$system_quote($$system_path($$absolute_path(ninja/configure.py, $$src_3rd_party_dir)))
+            !system("cd $$system_quote($$system_path($$dirname(out))) && $$pythonPathForSystem() $$ninja_configure --bootstrap") {
+                error("NINJA build error!")
+            }
+        }
+    QMAKE_DISTCLEAN += $$out
+    }
 }
 
diff --git a/src/core/core.pro b/src/core/core.pro
index 91c5044b6eb369fc73467f88b3bc4db237516577..6cc8080e0c6b268c3d886de243ddc610d37bf66a 100644
--- a/src/core/core.pro
+++ b/src/core/core.pro
@@ -41,7 +41,7 @@ core_api.depends = gn_run
 
 # A fake project for qt creator
 core_project.file = core_project.pro
-core_project.depends = core_headers
+core_project.depends = gn_run
 
 SUBDIRS += \
             core_headers \
diff --git a/src/core/core_common.pri b/src/core/core_common.pri
index 9c29aea718dffe4158a2625d3db091b8e303a461..370fe4d2a03dc15263e3df9c83ba867630af3614 100644
--- a/src/core/core_common.pri
+++ b/src/core/core_common.pri
@@ -5,8 +5,4 @@ TARGET = QtWebEngineCore
 QT += qml quick webchannel
 QT_PRIVATE += quick-private gui-private core-private webenginecoreheaders-private
 
-# Make QtCreator happy.
-CHROMIUM_SRC_DIR = $$QTWEBENGINE_ROOT/$$getChromiumSrcDir()
-INCLUDEPATH += $$CHROMIUM_SRC_DIR
-
 qtHaveModule(positioning):QT += positioning
diff --git a/src/core/core_module.pro b/src/core/core_module.pro
index f4f3fb736240a3ed399bc37ffc4a8d8e529c57a4..44e8ac61354bb816bb00e0711e248e03b22d4386 100644
--- a/src/core/core_module.pro
+++ b/src/core/core_module.pro
@@ -130,9 +130,6 @@ icu.files = $$OUT_PWD/$$getConfigDir()/icudtl.dat
 }
 
 OTHER_FILES = \
-    $$files(../3rdparty/chromium/*.h, true) \
-    $$files(../3rdparty/chromium/*.cc, true) \
-    $$files(../3rdparty/chromium/*.mm, true) \
     $$files(../3rdparty/chromium/*.py, true) \
     $$files(../3rdparty/chromium/*.gyp, true) \
     $$files(../3rdparty/chromium/*.gypi, true) \
diff --git a/src/core/core_project.pro b/src/core/core_project.pro
index 8418ab22b1e8be032db15dbffe2eeaca50e0e394..c046ce1ff5886893e25be39dffbc8bb83fb53fdd 100644
--- a/src/core/core_project.pro
+++ b/src/core/core_project.pro
@@ -1,3 +1,18 @@
 TEMPLATE = lib
+# Fake project to make QtCreator happy.
 
-include(core_chromium.pri)
+include(core_common.pri)
+
+linking_pri = $$OUT_PWD/$$getConfigDir()/$${TARGET}.pri
+
+!include($$linking_pri) {
+    error("Could not find the linking information that gn should have generated.")
+}
+
+CHROMIUM_SRC_DIR = $$QTWEBENGINE_ROOT/$$getChromiumSrcDir()
+INCLUDEPATH += $$CHROMIUM_SRC_DIR \
+               $$OUT_PWD/$$getConfigDir()/gen
+
+SOURCES += $$NINJA_SOURCES
+HEADERS += $$NINJA_HEADERS
+DEFINES += $$NINJA_DEFINES
diff --git a/src/core/gn_run.pro b/src/core/gn_run.pro
index 07635d04c6d0c0749511c45a3d3054e7fab0fce9..ee4e7892e6efa81fb67706aa4d3a4a54c47850b4 100644
--- a/src/core/gn_run.pro
+++ b/src/core/gn_run.pro
@@ -5,13 +5,6 @@ isQtMinimum(5, 8) {
 
 TEMPLATE = aux
 
-defineReplace(runGn) {
-    message("Running: $$1")
-    !system($$1) {
-        error("GN run error!")
-    }
-}
-
 qtConfig(debug_and_release): CONFIG += debug_and_release build_all
 
 qtConfig(system-ninja) {
@@ -42,16 +35,22 @@ build_pass|!debug_and_release {
         gn_args += is_debug=false
     }
 
-    gn_args += "qtwebengine_target=\"$$shell_path($$OUT_PWD/$$getConfigDir()):QtWebEngineCore\""
+    gn_args += "qtwebengine_target=\"$$system_path($$OUT_PWD/$$getConfigDir()):QtWebEngineCore\""
 
     !qtConfig(system-gn) {
-        gn_binary = $$shell_quote($$shell_path($$gnPath()))
+        gn_binary = $$system_quote($$system_path($$gnPath()))
     }
 
-    gn_args = $$shell_quote($$gn_args)
-    gn_src_root = $$shell_quote($$shell_path($$QTWEBENGINE_ROOT/$$getChromiumSrcDir()))
-    gn_build_root = $$shell_quote($$shell_path($$OUT_PWD/$$getConfigDir()))
-    $$runGn($$gn_binary gen $$gn_build_root --args=$$gn_args --root=$$gn_src_root)
+    gn_args = $$system_quote($$gn_args)
+    gn_src_root = $$system_quote($$system_path($$QTWEBENGINE_ROOT/$$getChromiumSrcDir()))
+    gn_build_root = $$system_quote($$system_path($$OUT_PWD/$$getConfigDir()))
+    gn_python = "--script-executable=$$pythonPathForSystem()"
+    gn_run = $$gn_binary gen $$gn_build_root $$gn_python --args=$$gn_args --root=$$gn_src_root
+
+    message("Running: $$gn_run ")
+    !system($$gn_run) {
+        error("GN run error!")
+    }
 
     runninja.commands = $$NINJA \$\(NINJAFLAGS\) -C $$gn_build_root QtWebEngineCore
     QMAKE_EXTRA_TARGETS += runninja
diff --git a/src/core/web_engine_context.cpp b/src/core/web_engine_context.cpp
index 81f968d115388cd6266fd8a0536df12d1f2abc2e..60622b4ae6fd25368202366dc59df96ca75d7a02 100644
--- a/src/core/web_engine_context.cpp
+++ b/src/core/web_engine_context.cpp
@@ -91,6 +91,7 @@
 #ifndef QT_NO_OPENGL
 # include <QOpenGLContext>
 #endif
+#include <QQuickWindow>
 #include <QStringList>
 #include <QSurfaceFormat>
 #include <QVector>
@@ -157,6 +158,8 @@ bool usingQtQuick2DRenderer()
         }
     }
 
+    if (device.isEmpty())
+        device = QQuickWindow::sceneGraphBackend();
     if (device.isEmpty())
         device = QString::fromLocal8Bit(qgetenv("QT_QUICK_BACKEND"));
     if (device.isEmpty())
diff --git a/src/webengine/doc/qtwebengine.qdocconf b/src/webengine/doc/qtwebengine.qdocconf
index fe83b082f076111a4e50806e4dfe758b3e4f2237..bc63addbe56243c6234dec4afe22e099b09b231d 100644
--- a/src/webengine/doc/qtwebengine.qdocconf
+++ b/src/webengine/doc/qtwebengine.qdocconf
@@ -67,7 +67,7 @@ exampledirs +=  . \
                 ../../core/doc/snippets \
                 ../../webenginewidgets/doc/snippets
 
-examples.fileextensions += *.aff *.dic
+examples.fileextensions += *.aff *.dic *.html
 
 imagedirs += images
 
diff --git a/src/webengine/webengine.pro b/src/webengine/webengine.pro
index 27239225b6af709e713e403c6cc5e200e5e057bc..5ac93c9a7ee4e491c2d90922ad933954926b6172 100644
--- a/src/webengine/webengine.pro
+++ b/src/webengine/webengine.pro
@@ -71,9 +71,10 @@ use?(pdf) {
 }
 
 !build_pass {
+    python = $$pythonPathForShell()
     chromium_attributions.commands = \
         cd $$shell_quote($$shell_path($$PWD/../3rdparty)) && \
-        python chromium/tools/licenses.py \
+        $$python chromium/tools/licenses.py \
         --file-template ../../tools/about_credits.tmpl \
         --entry-template ../../tools/about_credits_entry.tmpl credits \
         > $$shell_quote($$shell_path($$OUT_PWD/chromium_attributions.qdoc))
diff --git a/tests/auto/quick/qmltests/data/tst_keyboardEvents.qml b/tests/auto/quick/qmltests/data/tst_keyboardEvents.qml
index 677727632f6c18eb97a18c8d84c2efff6f175191..2536f319b983bce46bb7234fd50ba50e847bb8da 100644
--- a/tests/auto/quick/qmltests/data/tst_keyboardEvents.qml
+++ b/tests/auto/quick/qmltests/data/tst_keyboardEvents.qml
@@ -143,7 +143,7 @@ TestWebEngineView {
             keyPress(Qt.Key_B);
             compareElementValue("combobox", "b");
             // Must wait with the second key press to simulate selection of another element
-            wait(1000);
+            wait(1100); // blink::typeAheadTimeout + 0.1s
             keyPress(Qt.Key_C);
             compareElementValue("combobox", "c");
 
diff --git a/tests/auto/quick/qmltests/data/tst_newViewRequest.qml b/tests/auto/quick/qmltests/data/tst_newViewRequest.qml
index 754a9e018c71e47068904dcf1e19b6cdd89874ab..7a04d5f5b999542f31223774ea2b30a11d37101b 100644
--- a/tests/auto/quick/qmltests/data/tst_newViewRequest.qml
+++ b/tests/auto/quick/qmltests/data/tst_newViewRequest.qml
@@ -93,7 +93,7 @@ TestWebEngineView {
             compare(newViewRequest.destination, WebEngineView.NewViewInTab);
             verify(!newViewRequest.userInitiated);
 
-            verify(dialog.webEngineView.waitForLoadSucceeded);
+            verify(dialog.webEngineView.waitForLoadSucceeded());
             compare(dialog.webEngineView.url, "");
             newViewRequestedSpy.clear();
             dialog.destroy();
@@ -109,7 +109,7 @@ TestWebEngineView {
 
             compare(newViewRequest.destination, WebEngineView.NewViewInDialog);
             verify(!newViewRequest.userInitiated);
-            verify(dialog.webEngineView.waitForLoadSucceeded);
+            verify(dialog.webEngineView.waitForLoadSucceeded());
             newViewRequestedSpy.clear();
             dialog.destroy();
 
@@ -128,7 +128,7 @@ TestWebEngineView {
 
             compare(newViewRequest.destination, WebEngineView.NewViewInDialog);
             verify(newViewRequest.userInitiated);
-            verify(dialog.webEngineView.waitForLoadSucceeded);
+            verify(dialog.webEngineView.waitForLoadSucceeded());
             newViewRequestedSpy.clear();
             dialog.destroy();
         }
diff --git a/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp b/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp
index ce88ace16747f51e07de39d199d31c282b3771ea..32a518ad8e80da99fb122a8ff01f6e3ab7dddcc3 100644
--- a/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp
+++ b/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp
@@ -1109,7 +1109,7 @@ void tst_QWebEngineView::keyboardEvents()
     QTest::keyPress(view.focusProxy(), Qt::Key_B);
     QTRY_COMPARE(evaluateJavaScriptSync(view.page(), "document.getElementById('combobox').value").toString(), QStringLiteral("b"));
     // Must wait with the second key press to simulate selection of another element
-    QTest::keyPress(view.focusProxy(), Qt::Key_C, Qt::NoModifier, 1000);
+    QTest::keyPress(view.focusProxy(), Qt::Key_C, Qt::NoModifier, 1100 /* blink::typeAheadTimeout + 0.1s */);
     QTRY_COMPARE(evaluateJavaScriptSync(view.page(), "document.getElementById('combobox').value").toString(), QStringLiteral("c"));
 
     // Test the Enter key by loading a page with a hyperlink