diff --git a/configure.json b/configure.json
index f9719b3c6d2631fe548a20a28da27352b9665878..e82247ec56cc3ca9248b8d414163f3e0e8bba327 100644
--- a/configure.json
+++ b/configure.json
@@ -8,6 +8,7 @@
         "options": {
             "alsa": "boolean",
             "embedded": "boolean",
+            "webengine-icu": { "type": "enum", "name": "system-icu", "values": { "system": "yes", "qt": "no" } },
             "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" } },
@@ -34,6 +35,12 @@
                 { "type": "pkgConfig", "args": "libpulse >= 0.9.10 libpulse-mainloop-glib" }
             ]
         },
+        "icu": {
+            "label": "icu >= 53",
+            "sources": [
+                { "type": "pkgConfig", "args": "icu-uc >= 53 icu-i18n >= 53" }
+            ]
+        },
         "ffmpeg": {
             "label": "libavcodec libavformat libavutil",
             "sources": [
@@ -154,6 +161,12 @@
             "condition": "libs.ffmpeg && features.system-opus && features.system-webp",
             "output": [ "privateFeature" ]
         },
+        "system-icu": {
+            "label": "ICU",
+            "autoDetect": false,
+            "condition": "libs.icu",
+            "output": [ "privateFeature" ]
+        },
         "system-ninja": {
             "label": "Using system ninja",
             "condition": "tests.ninja",
@@ -200,6 +213,7 @@
                    "section": "System libraries",
                    "condition": "config.unix",
                    "entries": [
+                        "system-icu",
                         "system-webp",
                         "system-opus",
                         "system-ffmpeg"
diff --git a/dist/changes-5.9.0 b/dist/changes-5.9.0
new file mode 100644
index 0000000000000000000000000000000000000000..00c79fb9224cb1244471bfa0c36c319351c6f379
--- /dev/null
+++ b/dist/changes-5.9.0
@@ -0,0 +1,119 @@
+Qt 5.9 introduces many new features and improvements as well as bugfixes
+over the 5.8.x series. For more details, refer to the online documentation
+included in this distribution. The documentation is also available online:
+
+http://doc.qt.io/qt-5/index.html
+
+The Qt version 5.9 series is binary compatible with the 5.8.x series.
+Applications compiled for 5.8 will continue to run with 5.9.
+
+Some of the changes listed in this file include issue tracking numbers
+corresponding to tasks in the Qt Bug Tracker:
+
+https://bugreports.qt.io/
+
+Each of these identifiers can be entered in the bug tracker to obtain more
+information about a particular change.
+
+
+****************************************************************************
+*                             General                                      *
+****************************************************************************
+
+Important Changes
+-----------------
+
+ - Configure options are now handled by the global configure script. This
+   means options previously controlled by WEBENGINE_CONFIG options should
+   now use configure flags. For instance the configure command-line option
+   -proprietary-codecs replaces WEBENGINE_CONFIG+=use_proprietary_codecs.
+ - [QTBUG-54650, QTBUG-59922] Accessibility is now disabled by default on
+   Linux, like it is in Chrome, due to poor options for enabling it
+   conditionally and its heavy performance impact. Set the environment
+   variable QTWEBENGINE_ENABLE_LINUX_ACCESSIBILITY to enable it again.
+
+
+Chromium Snapshot
+-----------------
+
+ - Updated the Chromium version to 56.0.2924.122.
+ - Security fixes from Chromium up to version 58.0.3029.96
+    Including fixes for: CVE-2017-5029, CVE-2017-5032, CVE-2017-5033,
+    CVE-2017-5034, CVE-2017-5036, CVE-2017-5039, CVE-2017-5040, CVE-2017-5044,
+    CVE-2017-5045, CVE-2017-5046, CVE-2017-5052, CVE-2017-5053, CVE-2017-5055,
+    CVE-2017-5057, CVE-2017-5058, CVE-2017-5059, CVE-2017-5060, CVE-2017-5061,
+    CVE-2017-5062, CVE-2017-5065, CVE-2017-5066, CVE-2017-5067, CVE-2017-5068,
+    CVE-2017-5069
+ - Changed the Chromium build-system to GN.
+
+
+Qt WebengineCore
+----------------
+
+ - [QTBUG-56531] Enabled filesystem: protocol handler.
+ - [QTBUG-57720] Optimized incremental scene-graph rendering in particular
+   for software rendering.
+ - [QTBUG-58362, QTBUG-60031] Fixed IME issues on Chinese and Japanese.
+ - [QTBUG-55766, QTBUG-58362, QTBUG-55766] Fixed selection and IME issues.
+ - [QTBUG-58982] Fixed crash on exit on macOS.
+ - [QTBUG-59127] Fixed movementX and movementY properties of mouse events.
+ - [QTBUG-59168] Fixed 5.8 regression in handling <input type="file">.
+ - [QTBUG-59407] Fixed black bar on some youtube videos with OpenGL disabled.
+ - [QTBUG-60049] Enabled brotli support.
+
+
+****************************************************************************
+*                                APIs                                      *
+****************************************************************************
+
+General
+-------
+
+ - Took Q_ENUM to use on QtWebEngineWidgets interfaces.
+ - Added a setting to again allow insecure origins to request geolocation.
+ - [QTBUG-54053] Fixed support for macOS Airplay.
+ - [QTBUG-56677] Made printing to a PDF file emit the signal.
+   pdfPrintingFinished() in both QQuickWebEngineView and QWebEnginePage.
+ - [QTBUG-57354] Fixed font loading issue on macOS.
+ - [QTBUG-57924] Fixed assert on right-clicking Flash apps.
+ - [QTBUG-58037] Fixed drag and drop issues.
+ - [QTBUG-58488] Fixed window type of popups on X11.
+ - [QTBUG-58561] Stopped firing too many mousemove events.
+ - [QTBUG-58650] Fixed segfault when changing cookie policy.
+ - [QTBUG-58920] Fixed crash while dragging on Windows.
+ - [QTBUG-59053] Fixed a conflict with single letter short-cuts and
+   editable input fields.
+ - [QTBUG-59273] Now handles Qt::AA_UseSoftwareOpenGL.
+
+
+DownloadItem
+------------
+
+ - [QTBUG-58155] Fixed that (QWebEngine)DownloadItem::path() incorrectly
+   returned percentage-encoded filenames when the suggested path was based
+   on a URL. Percentage-decoding the path is generally not only incorrect
+   when the path is not based on URL, but also dangerous as it can lead to
+   downloads that escape the download folder.
+ - [QTBUG-56839] Added a downloadInterruptReason property for interrupted
+   downloads to download items.
+
+
+Qt WebEngine
+------------
+
+ - [QTBUG-51034] Added profile-wide user scripts like the widgets API has.
+
+
+Qt WebEngineWidgets
+-------------------
+
+ - [QTBUG-53314, QTBUG-53372] Added the QWebEngineHttpRequest class for
+   sending HTTP requests over the network using HTTP POST or with custom
+   HTTP headers.
+ - [QTBUG-58381] Fixed active tab bug (5.8 regression).
+ - [QTBUG-58515] Fixed issue with QWebEngineView::setFocus().
+ - [QTBUG-58563] Fixed segfault when closing tab with active search.
+ - [QTBUG-58673] QWebEnginePage: Started calling the javaScriptConfirm
+   method also for unload dialogs (onbeforeunload handlers).
+ - [QTBUG-59599] Fixed QWebEngineHistory::currentItem() segfault.
+ - [QTBUG-60236] Fixed crash on exit with url-request interceptors.
diff --git a/examples/webengine/quicknanobrowser/BrowserWindow.qml b/examples/webengine/quicknanobrowser/BrowserWindow.qml
index 596e4a76ed532bfd635955d685058293011e47d0..16efc9e372be4e5911793b237a38e76aaa701b19 100644
--- a/examples/webengine/quicknanobrowser/BrowserWindow.qml
+++ b/examples/webengine/quicknanobrowser/BrowserWindow.qml
@@ -52,7 +52,7 @@ import Qt.labs.settings 1.0
 import QtQml 2.2
 import QtQuick 2.2
 import QtQuick.Controls 1.0
-import QtQuick.Controls.Private 1.0
+import QtQuick.Controls.Private 1.0 as QQCPrivate
 import QtQuick.Controls.Styles 1.0
 import QtQuick.Dialogs 1.2
 import QtQuick.Layouts 1.0
@@ -75,7 +75,7 @@ ApplicationWindow {
 
     // Create a styleItem to determine the platform.
     // When using style "mac", ToolButtons are not supposed to accept focus.
-    StyleItem { id: styleItem }
+    QQCPrivate.StyleItem { id: styleItem }
     property bool platformIsMac: styleItem.style == "mac"
 
     Settings {
diff --git a/examples/webenginewidgets/spellchecker/webview.cpp b/examples/webenginewidgets/spellchecker/webview.cpp
index 0e52e7628dd6defffa2c52543f3af64b541c12bf..80158f7e524100c46f60ae6ae18d690a1385084f 100644
--- a/examples/webenginewidgets/spellchecker/webview.cpp
+++ b/examples/webenginewidgets/spellchecker/webview.cpp
@@ -69,7 +69,7 @@ void WebView::contextMenuEvent(QContextMenuEvent *event)
     QMenu *menu = page()->createStandardContextMenu();
     menu->addSeparator();
 
-    QAction *spellcheckAction = new QAction(tr("Check Spelling"));
+    QAction *spellcheckAction = new QAction(tr("Check Spelling"), nullptr);
     spellcheckAction->setCheckable(true);
     spellcheckAction->setChecked(profile->isSpellCheckEnabled());
     connect(spellcheckAction, &QAction::toggled, this, [profile](bool toogled) {
diff --git a/mkspecs/features/configure.prf b/mkspecs/features/configure.prf
index 9b0be0140097fd08855a465d7061238c906150e8..c1e919603b0d114733108c4ed50ecc0f4cd44977 100644
--- a/mkspecs/features/configure.prf
+++ b/mkspecs/features/configure.prf
@@ -31,13 +31,20 @@ defineTest(runConfigure) {
         qtConfig(webrtc): WEBENGINE_CONFIG += use_webrtc
         qtConfig(embedded): WEBENGINE_CONFIG += embedded_build
         qtConfig(system-webp): WEBENGINE_CONFIG += use_system_libwebp
-        else: WEBENGINE_CONFIG += use_bundled_libwebp
         qtConfig(system-opus): WEBENGINE_CONFIG += use_system_opus
-        else: WEBENGINE_CONFIG += use_bundled_opus
         qtConfig(system-ffmpeg): WEBENGINE_CONFIG += use_system_ffmpeg
-        else: WEBENGINE_CONFIG += use_bundled_ffmpeg
+        qtConfig(system-icu): WEBENGINE_CONFIG += use_system_icu
+        !contains(WEBENGINE_CONFIG, use_system_libwebp): WEBENGINE_CONFIG += use_bundled_libwebp
+        !contains(WEBENGINE_CONFIG, use_system_opus): WEBENGINE_CONFIG += use_bundled_opus
+        !contains(WEBENGINE_CONFIG, use_system_ffmpeg): WEBENGINE_CONFIG += use_bundled_ffmpeg
+        !contains(WEBENGINE_CONFIG, use_system_icu): WEBENGINE_CONFIG += use_bundled_icu
     } else {
-        cross_compile: WEBENGINE_CONFIG += embedded_build reduce_binary_size
+        # Feature defaults when building with Qt 5.6 LTS:
+        cross_compile {
+            WEBENGINE_CONFIG += embedded_build reduce_binary_size
+        } else {
+            WEBENGINE_CONFIG += use_spellchecker use_webrtc use_pepper_plugins use_printing use_pdf
+        }
     }
     isQtMinimum(5, 9) {
         qtConfig(appstore-compliant): WEBENGINE_CONFIG += use_appstore_compliant_code
@@ -112,10 +119,8 @@ defineTest(runConfigure) {
             WEBENGINE_CONFIG += use_bundled_snappy
         }
 
-        !contains(WEBENGINE_CONFIG, embedded_build) {
-            packagesExist(nss): WEBENGINE_CONFIG += use_nss
-            else: log("System NSS not found, BoringSSL will be used.$${EOL}")
-        }
+        packagesExist(nss): WEBENGINE_CONFIG += use_nss
+        else: log("System NSS not found, BoringSSL will be used.$${EOL}")
     }
 
     win32 {
@@ -136,18 +141,18 @@ defineTest(runConfigure) {
 
     unix:!darwin {
         log("System library dependencies:$${EOL}")
-        use?(system_icu) {
-            packagesExist("icu-uc icu-i18n") {
-                log("  ICU ................................ Using system version$${EOL}")
+        !isQtMinimum(5, 8) {
+            use?(system_icu) {
+                packagesExist("\'icu-uc >= 53\', \'icu-i18n >= 53\'") {
+                    log("  ICU ................................ Using system version$${EOL}")
+                } else {
+                    log("  ICU ................................ System ICU not found$${EOL}")
+                    skipBuild("Unmet dependencies: icu-uc, icu-i18n")
+                }
             } else {
-                log("  ICU ................................ System ICU not found$${EOL}")
-                skipBuild("Unmet dependencies: icu-uc, icu-i18n")
+                log("  ICU ................................ Using internal copy (Default, force system ICU with WEBENGINE_CONFIG+=use_system_icu)$${EOL}")
+                WEBENGINE_CONFIG += use_bundled_icu
             }
-        } else {
-            log("  ICU ................................ Using internal copy (Default, force system ICU with WEBENGINE_CONFIG+=use_system_icu)$${EOL}")
-            WEBENGINE_CONFIG += use_bundled_icu
-        }
-        !isQtMinimum(5, 8) {
             use?(system_ffmpeg) {
                 packagesExist("libavcodec libavformat libavutil") {
                     packagesExist("libwebp, libwebpdemux, opus, \'vpx >= 1.4\'"){
@@ -182,7 +187,7 @@ defineTest(runConfigure) {
     use?(proprietary_codecs) {
         log("  Proprietary codecs (H264, MP3) ..... Enabled$${EOL}")
     } else {
-        log("  Proprietary codecs (H264, MP3) ..... Not enabled         (Default, enable with WEBENGINE_CONFIG+=use_proprietary_codecs)$${EOL}")
+        log("  Proprietary codecs (H264, MP3) ..... Not enabled         (Default, enable with -proprietary-codecs)$${EOL}")
     }
     qtHaveModule(positioning): {
         log("  Geolocation ........................ Enabled$${EOL}")
@@ -197,11 +202,6 @@ defineTest(runConfigure) {
         }
     }
     osx {
-        use?(appstore_compliant_code) {
-            log("  Mac App Store Compliant ............ Enabled$${EOL}")
-        } else {
-            log("  Mac App Store Compliant ............ Not enabled         (Default, enable with WEBENGINE_CONFIG+=use_appstore_compliant_code)$${EOL}")
-        }
         use?(native_spellchecker) {
             log("Native Spellchecker .............. Enabled$${EOL}")
         } else {
diff --git a/src/3rdparty b/src/3rdparty
index 898afbbf79637101bbd5e6ab12695ced6a759ae7..aa2fdd6be3d465280d2a0c3aacdc738bb4ffec05 160000
--- a/src/3rdparty
+++ b/src/3rdparty
@@ -1 +1 @@
-Subproject commit 898afbbf79637101bbd5e6ab12695ced6a759ae7
+Subproject commit aa2fdd6be3d465280d2a0c3aacdc738bb4ffec05
diff --git a/src/core/api/core_api.pro b/src/core/api/core_api.pro
index cda01db40d041ffe92f1b73101eac12313c64171..22c165e2a04c196b5c9fad21633114aa14d99d39 100644
--- a/src/core/api/core_api.pro
+++ b/src/core/api/core_api.pro
@@ -50,6 +50,10 @@ SOURCES = \
     qwebengineurlrequestjob.cpp \
     qwebengineurlschemehandler.cpp
 
+unix:!isEmpty(QMAKE_LFLAGS_VERSION_SCRIPT):!static {
+    SOURCES += qtbug-60565.cpp
+}
+
 msvc {
     # Create a list of object files that can be used as response file for the linker.
     # This is done to simulate -whole-archive on MSVC.
diff --git a/src/core/api/qtbug-60565.cpp b/src/core/api/qtbug-60565.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..21b545ccaf600feecbccd0f7adb7c82e7579f5e1
--- /dev/null
+++ b/src/core/api/qtbug-60565.cpp
@@ -0,0 +1,121 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtWebEngine module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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 https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <new>
+#include <unistd.h>
+
+#if defined(__LP64__)
+#  define SIZE_T_MANGLING  "m"
+#else
+#  define SIZE_T_MANGLING  "j"
+#endif
+
+#define SHIM_ALIAS_SYMBOL(fn) __attribute__((weak, alias(#fn)))
+
+extern "C" {
+
+__asm__(".symver __ShimCppNew, _Znw" SIZE_T_MANGLING "@Qt_5");
+void* __ShimCppNew(size_t size)
+    SHIM_ALIAS_SYMBOL(ShimCppNew);
+
+__asm__(".symver __ShimCppDelete, _ZdlPv@Qt_5");
+void __ShimCppDelete(void* address)
+    SHIM_ALIAS_SYMBOL(ShimCppDelete);
+
+__asm__(".symver __ShimCppNewArray, _Zna" SIZE_T_MANGLING "@Qt_5");
+void* __ShimCppNewArray(size_t size)
+    SHIM_ALIAS_SYMBOL(ShimCppNewArray);
+
+__asm__(".symver __ShimCppDeleteArray, _ZdaPv@Qt_5");
+void __ShimCppDeleteArray(void* address)
+    SHIM_ALIAS_SYMBOL(ShimCppDeleteArray);
+
+__asm__(".symver __ShimCppNewNoThrow, _Znw" SIZE_T_MANGLING "RKSt9nothrow_t@Qt_5");
+void __ShimCppNewNoThrow(size_t size, const std::nothrow_t&) noexcept
+    SHIM_ALIAS_SYMBOL(ShimCppNew);
+
+__asm__(".symver __ShimCppNewArrayNoThrow, _Zna" SIZE_T_MANGLING "RKSt9nothrow_t@Qt_5");
+void __ShimCppNewArrayNoThrow(size_t size, const std::nothrow_t&) noexcept
+    SHIM_ALIAS_SYMBOL(ShimCppNewArray);
+
+__asm__(".symver __ShimCppDeleteNoThrow, _ZdlPvRKSt9nothrow_t@Qt_5");
+void __ShimCppDeleteNoThrow(void* address, const std::nothrow_t&) noexcept
+    SHIM_ALIAS_SYMBOL(ShimCppDelete);
+
+__asm__(".symver __ShimCppDeleteArrayNoThrow, _ZdaPvRKSt9nothrow_t@Qt_5");
+void __ShimCppDeleteArrayNoThrow(void* address, const std::nothrow_t&) noexcept
+    SHIM_ALIAS_SYMBOL(ShimCppDeleteArray);
+
+static void* __shimCppNew(size_t size);
+static void* __shimCppNewArray(size_t size);
+static void __shimCppDelete(void *address);
+static void __shimCppDeleteArray(void *address);
+
+static void* ShimCppNew(size_t size) {
+    return __shimCppNew(size);
+}
+
+static void* ShimCppNewArray(size_t size) {
+    return __shimCppNewArray(size);
+}
+
+static void ShimCppDelete(void* address) {
+    __shimCppDelete(address);
+}
+
+static void ShimCppDeleteArray(void* address) {
+    __shimCppDeleteArray(address);
+}
+} // extern "C"
+
+static void* __shimCppNew(size_t size) {
+    return operator new(size);
+}
+
+static void* __shimCppNewArray(size_t size) {
+    return operator new[](size);
+}
+
+static void __shimCppDelete(void* address) {
+    operator delete(address);
+}
+
+static void __shimCppDeleteArray(void* address) {
+    operator delete[](address);
+}
diff --git a/src/core/browser_context_adapter.cpp b/src/core/browser_context_adapter.cpp
index 1da186584ce950e81db4b8b2c94e2995bbf51422..bec76ad810381fa3eacfb5ad4d319e25af3e09b5 100644
--- a/src/core/browser_context_adapter.cpp
+++ b/src/core/browser_context_adapter.cpp
@@ -162,6 +162,8 @@ QWebEngineUrlRequestInterceptor *BrowserContextAdapter::requestInterceptor()
 
 void BrowserContextAdapter::setRequestInterceptor(QWebEngineUrlRequestInterceptor *interceptor)
 {
+    if (m_requestInterceptor == interceptor)
+        return;
     m_requestInterceptor = interceptor;
     if (m_browserContext->url_request_getter_.get())
         m_browserContext->url_request_getter_->updateRequestInterceptor();
diff --git a/src/core/config/mac_osx.pri b/src/core/config/mac_osx.pri
index cdd1ce7b6c423d80168a169f548e360a3ff7d719..ddb397565eb0876fbc1554e6e46386efc8081b40 100644
--- a/src/core/config/mac_osx.pri
+++ b/src/core/config/mac_osx.pri
@@ -38,5 +38,3 @@ use?(spellchecker) {
 } else {
     macos: gn_args += use_browser_spellchecker=false
 }
-
-use?(appstore_compliant_code): gn_args += appstore_compliant_code=true
diff --git a/src/core/delegated_frame_node.cpp b/src/core/delegated_frame_node.cpp
index a4b2a4036c090c2d9ebba0b7dc4933b76e579195..e49bc553f49bc4582fe86d4e83d0300550b37107 100644
--- a/src/core/delegated_frame_node.cpp
+++ b/src/core/delegated_frame_node.cpp
@@ -209,6 +209,7 @@ protected:
     QVector<QSGNode*> *m_sceneGraphNodes;
 };
 
+#if (QT_VERSION >= QT_VERSION_CHECK(5, 8, 0))
 class DelegatedNodeTreeUpdater : public DelegatedNodeTreeHandler
 {
 public:
@@ -303,6 +304,7 @@ public:
 private:
     QVector<QSGNode*>::iterator m_nodeIterator;
 };
+#endif
 
 class DelegatedNodeTreeCreator : public DelegatedNodeTreeHandler
 {
@@ -872,8 +874,13 @@ void DelegatedFrameNode::commit(ChromiumCompositorData *chromiumCompositorData,
     // We first compare if the render passes from the previous frame data are structurally
     // equivalent to the render passes in the current frame data. If they are, we are going
     // to reuse the old nodes. Otherwise, we will delete the old nodes and build a new tree.
+#if (QT_VERSION >= QT_VERSION_CHECK(5, 8, 0))
     cc::DelegatedFrameData *previousFrameData = m_chromiumCompositorData->previousFrameData.get();
     const bool buildNewTree = !areRenderPassStructuresEqual(frameData, previousFrameData) || m_sceneGraphNodes.empty();
+#else
+    // No updates possible with old scenegraph nodes
+    const bool buildNewTree = true;
+#endif
 
     m_chromiumCompositorData->previousFrameData = nullptr;
     SGObjects previousSGObjects;
@@ -887,11 +894,13 @@ void DelegatedFrameNode::commit(ChromiumCompositorData *chromiumCompositorData,
             delete oldChain;
         m_sceneGraphNodes.clear();
         nodeHandler.reset(new DelegatedNodeTreeCreator(&m_sceneGraphNodes, apiDelegate));
+#if (QT_VERSION >= QT_VERSION_CHECK(5, 8, 0))
     } else {
         // Save the texture strong refs so they only go out of scope when the method returns and
         // the new vector of texture strong refs has been filled.
         qSwap(m_sgObjects.textureStrongRefs, textureStrongRefs);
         nodeHandler.reset(new DelegatedNodeTreeUpdater(&m_sceneGraphNodes));
+#endif
     }
     // The RenderPasses list is actually a tree where a parent RenderPass is connected
     // to its dependencies through a RenderPassId reference in one or more RenderPassQuads.
diff --git a/src/core/render_widget_host_view_qt.cpp b/src/core/render_widget_host_view_qt.cpp
index 6568398a8e9b847e0c2cf0c47671b8a439e2f71b..cf22273e450ca91299560501bdcabe4910641ba8 100644
--- a/src/core/render_widget_host_view_qt.cpp
+++ b/src/core/render_widget_host_view_qt.cpp
@@ -97,6 +97,7 @@ enum ImStateFlags {
     TextInputStateUpdated = 1 << 0,
     TextSelectionUpdated = 1 << 1,
     TextSelectionBoundsUpdated = 1 << 2,
+    TextSelectionFlags = TextSelectionUpdated | TextSelectionBoundsUpdated,
     AllFlags = TextInputStateUpdated | TextSelectionUpdated | TextSelectionBoundsUpdated
 };
 
@@ -237,6 +238,19 @@ private:
     float dpiScale;
 };
 
+bool isAccessibilityEnabled() {
+    // On Linux accessibility is disabled by default due to performance issues,
+    // and can be re-enabled by setting the QTWEBENGINE_ENABLE_LINUX_ACCESSIBILITY environment
+    // variable. For details, see QTBUG-59922.
+#ifdef Q_OS_LINUX
+    static bool accessibility_enabled
+            = qEnvironmentVariableIsSet("QTWEBENGINE_ENABLE_LINUX_ACCESSIBILITY");
+#else
+    const bool accessibility_enabled = true;
+#endif
+    return accessibility_enabled;
+}
+
 RenderWidgetHostViewQt::RenderWidgetHostViewQt(content::RenderWidgetHost* widget)
     : m_host(content::RenderWidgetHostImpl::From(widget))
     , m_gestureProvider(QtGestureProviderConfig(), this)
@@ -253,16 +267,18 @@ RenderWidgetHostViewQt::RenderWidgetHostViewQt(content::RenderWidgetHost* widget
     , m_needsBeginFrames(false)
     , m_addedFrameObserver(false)
     , m_imState(0)
-    , m_anchorPositionWithinSelection(0)
-    , m_cursorPositionWithinSelection(0)
+    , m_anchorPositionWithinSelection(-1)
+    , m_cursorPositionWithinSelection(-1)
     , m_cursorPosition(0)
     , m_emptyPreviousSelection(true)
 {
     m_host->SetView(this);
 #ifndef QT_NO_ACCESSIBILITY
-    QAccessible::installActivationObserver(this);
-    if (QAccessible::isActive())
-        content::BrowserAccessibilityStateImpl::GetInstance()->EnableAccessibility();
+    if (isAccessibilityEnabled()) {
+        QAccessible::installActivationObserver(this);
+        if (QAccessible::isActive())
+            content::BrowserAccessibilityStateImpl::GetInstance()->EnableAccessibility();
+    }
 #endif // QT_NO_ACCESSIBILITY
     auto* task_runner = base::ThreadTaskRunnerHandle::Get().get();
     m_beginFrameSource.reset(new cc::DelayBasedBeginFrameSource(
@@ -761,8 +777,10 @@ void RenderWidgetHostViewQt::OnSelectionBoundsChanged(content::TextInputManager
     Q_UNUSED(updated_view);
 
     m_imState |= ImStateFlags::TextSelectionBoundsUpdated;
-    if (m_imState == ImStateFlags::AllFlags)
+    if (m_imState == ImStateFlags::AllFlags
+            || (m_imState == ImStateFlags::TextSelectionFlags && getTextInputType() == ui::TEXT_INPUT_TYPE_NONE)) {
         selectionChanged();
+    }
 }
 
 void RenderWidgetHostViewQt::OnTextSelectionChanged(content::TextInputManager *text_input_manager, RenderWidgetHostViewBase *updated_view)
@@ -779,8 +797,10 @@ void RenderWidgetHostViewQt::OnTextSelectionChanged(content::TextInputManager *t
 #endif // defined(USE_X11)
 
     m_imState |= ImStateFlags::TextSelectionUpdated;
-    if (m_imState == ImStateFlags::AllFlags)
+    if (m_imState == ImStateFlags::AllFlags
+            || (m_imState == ImStateFlags::TextSelectionFlags && getTextInputType() == ui::TEXT_INPUT_TYPE_NONE)) {
         selectionChanged();
+    }
 }
 
 void RenderWidgetHostViewQt::selectionChanged()
@@ -788,6 +808,22 @@ void RenderWidgetHostViewQt::selectionChanged()
     // Reset input manager state
     m_imState = 0;
 
+    // Handle text selection out of an input field
+    if (getTextInputType() == ui::TEXT_INPUT_TYPE_NONE) {
+        if (GetSelectedText().empty() && m_emptyPreviousSelection)
+            return;
+
+        // Reset position values to emit selectionChanged signal when clearing text selection
+        // by clicking into an input field. These values are intended to be used by inputMethodQuery
+        // so they are not expected to be valid when selection is out of an input field.
+        m_anchorPositionWithinSelection = -1;
+        m_cursorPositionWithinSelection = -1;
+
+        m_emptyPreviousSelection = GetSelectedText().empty();
+        m_adapterClient->selectionChanged();
+        return;
+    }
+
     const content::TextInputManager::TextSelection *selection = text_input_manager_->GetTextSelection();
     if (!selection)
         return;
@@ -802,8 +838,8 @@ void RenderWidgetHostViewQt::selectionChanged()
         return;
     }
 
-    uint newAnchorPositionWithinSelection = 0;
-    uint newCursorPositionWithinSelection = 0;
+    int newAnchorPositionWithinSelection = 0;
+    int newCursorPositionWithinSelection = 0;
 
     if (text_input_manager_->GetSelectionRegion()->anchor.type() == gfx::SelectionBound::RIGHT) {
         newAnchorPositionWithinSelection = selection->range.GetMax() - selection->offset;
diff --git a/src/core/render_widget_host_view_qt.h b/src/core/render_widget_host_view_qt.h
index 79993083080768af3debcb350533c1c15f3b16a3..3b679923e950f6b86ffa73dc06673ef445233b80 100644
--- a/src/core/render_widget_host_view_qt.h
+++ b/src/core/render_widget_host_view_qt.h
@@ -263,8 +263,8 @@ private:
     gfx::SizeF m_lastContentsSize;
 
     uint m_imState;
-    uint m_anchorPositionWithinSelection;
-    uint m_cursorPositionWithinSelection;
+    int m_anchorPositionWithinSelection;
+    int m_cursorPositionWithinSelection;
     uint m_cursorPosition;
     bool m_emptyPreviousSelection;
     QString m_surroundingText;
diff --git a/src/core/web_contents_adapter.cpp b/src/core/web_contents_adapter.cpp
index d67d972c839e78d5bf70f09284ec20f47c7626fe..444429c756656affa84e5bbf5d932ec96525f3a4 100644
--- a/src/core/web_contents_adapter.cpp
+++ b/src/core/web_contents_adapter.cpp
@@ -1184,7 +1184,9 @@ void WebContentsAdapter::startDragging(QObject *dragSource, const content::DropD
     bool dValid = true;
     QMetaObject::Connection onDestroyed = QObject::connect(dragSource, &QObject::destroyed, [&dValid](){
         dValid = false;
+#if (QT_VERSION >= QT_VERSION_CHECK(5, 7, 0))
         QDrag::cancel();
+#endif
     });
 
     drag->setMimeData(mimeDataFromDropData(*d->currentDropData));
diff --git a/src/core/web_engine_context.cpp b/src/core/web_engine_context.cpp
index 60622b4ae6fd25368202366dc59df96ca75d7a02..2748d2a0f523e04e42cc5da69ceac1ae300c37ee 100644
--- a/src/core/web_engine_context.cpp
+++ b/src/core/web_engine_context.cpp
@@ -158,8 +158,10 @@ bool usingQtQuick2DRenderer()
         }
     }
 
+#if (QT_VERSION >= QT_VERSION_CHECK(5, 9, 0))
     if (device.isEmpty())
         device = QQuickWindow::sceneGraphBackend();
+#endif
     if (device.isEmpty())
         device = QString::fromLocal8Bit(qgetenv("QT_QUICK_BACKEND"));
     if (device.isEmpty())
@@ -322,6 +324,14 @@ WebEngineContext::WebEngineContext()
     // Enabled on OS X and Linux but currently not working. It worked in 5.7 on OS X.
     parsedCommandLine->AppendSwitch(switches::kDisableGpuMemoryBufferVideoFrames);
 
+#if defined(Q_OS_MACOS)
+    // Accelerated decoding currently does not work on macOS due to issues with OpenGL Rectangle
+    // texture support. See QTBUG-60002.
+    parsedCommandLine->AppendSwitch(switches::kDisableAcceleratedVideoDecode);
+    // Same problem with Pepper using OpenGL images.
+    parsedCommandLine->AppendSwitch(switches::kDisablePepper3DImageChromium);
+#endif
+
     if (useEmbeddedSwitches) {
         // Inspired by the Android port's default switches
         if (!parsedCommandLine->HasSwitch(switches::kDisableOverlayScrollbar))
diff --git a/src/tools/qwebengine_convert_dict/main.cpp b/src/tools/qwebengine_convert_dict/main.cpp
index 61e26c4a38644aacced7fb34b94487d2f75e389b..a86f868b3ffda05efe934298079caaa5b66d5d3d 100644
--- a/src/tools/qwebengine_convert_dict/main.cpp
+++ b/src/tools/qwebengine_convert_dict/main.cpp
@@ -107,6 +107,14 @@ inline bool VerifyWords(const convert_dict::DicReader::WordList& org_words,
     return true;
 }
 
+#if defined(OS_MACOSX) && defined(QT_MAC_FRAMEWORK_BUILD)
+QString frameworkIcuDataPath()
+{
+    return QLibraryInfo::location(QLibraryInfo::LibrariesPath) +
+            QStringLiteral("/QtWebEngineCore.framework/Resources/");
+}
+#endif
+
 int main(int argc, char *argv[])
 {
     QTextStream out(stdout);
@@ -132,6 +140,14 @@ int main(int argc, char *argv[])
         icuDataDir = icuPossibleEnvDataDir;
         icuDataDirFound = true;
     }
+#if defined(OS_MACOSX) && defined(QT_MAC_FRAMEWORK_BUILD)
+    // In a macOS Qt framework build, the resources are inside the QtWebEngineCore framework
+    // Resources directory, rather than in the Qt install location.
+    else if (QFileInfo::exists(frameworkIcuDataPath())) {
+        icuDataDir = frameworkIcuDataPath();
+        icuDataDirFound = true;
+    }
+#endif
     // Try to find the ICU data directory in the installed Qt location.
     else if (QFileInfo::exists(icuDataDir)) {
         icuDataDirFound = true;
diff --git a/src/webengine/api/qquickwebengineprofile.cpp b/src/webengine/api/qquickwebengineprofile.cpp
index f22ec86a4e3c072e7acdc339faca4a157d50ee5d..260d8958b934f0ffb74fea8cddbe7e474486fc44 100644
--- a/src/webengine/api/qquickwebengineprofile.cpp
+++ b/src/webengine/api/qquickwebengineprofile.cpp
@@ -153,6 +153,8 @@ QQuickWebEngineProfilePrivate::QQuickWebEngineProfilePrivate(QSharedPointer<Brow
 
 QQuickWebEngineProfilePrivate::~QQuickWebEngineProfilePrivate()
 {
+    m_browserContextRef->setRequestInterceptor(nullptr);
+
     m_browserContextRef->removeClient(this);
 
     Q_FOREACH (QQuickWebEngineDownloadItem* download, m_ongoingDownloads) {
diff --git a/src/webengine/doc/qtwebengine.qdocconf b/src/webengine/doc/qtwebengine.qdocconf
index bc63addbe56243c6234dec4afe22e099b09b231d..ea9c6f21bb10f3e542f92205c4576cfa81d091e8 100644
--- a/src/webengine/doc/qtwebengine.qdocconf
+++ b/src/webengine/doc/qtwebengine.qdocconf
@@ -33,7 +33,7 @@ qhp.QtWebEngine.subprojects.examples.indexTitle = Qt WebEngine Examples
 qhp.QtWebEngine.subprojects.examples.selectors = doc:example
 qhp.QtWebEngine.subprojects.examples.sortPages = true
 
-manifestmeta.highlighted.names += "QtWebEngine/WebEngine Markdown Editor Example" \
+manifestmeta.highlighted.names += "QtWebEngine/WebEngine Widgets Simple Browser Example" \
                 "QtWebEngine/WebEngine Quick Nano Browser"
 
 tagfile                 = ../../../doc/qtwebengine/qtwebengine.tags
diff --git a/src/webengine/doc/src/qtwebengine-overview.qdoc b/src/webengine/doc/src/qtwebengine-overview.qdoc
index ff35b45cf0cb72e10640c4b0541ef3c3cf565f99..e180b22c01f65b270f4492453a22815d434de458 100644
--- a/src/webengine/doc/src/qtwebengine-overview.qdoc
+++ b/src/webengine/doc/src/qtwebengine-overview.qdoc
@@ -1,6 +1,6 @@
 /****************************************************************************
 **
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2017 The Qt Company Ltd.
 ** Contact: https://www.qt.io/licensing/
 **
 ** This file is part of the documentation of the Qt Toolkit.
@@ -89,7 +89,7 @@
     \l{https://chromium.googlesource.com/chromium/src/+/master/docs/chromium_browser_vs_google_chrome.md}{overview}
     that is part of the documentation in the \l {Chromium Project} upstream source tree.
 
-    This version of Qt WebEngine is based on Chromium version 53.0.2785.148, with
+    This version of Qt WebEngine is based on Chromium version 56.0.2924.122, with
     additional security fixes from newer versions.
 
     \section2 Qt WebEngine Process
diff --git a/src/webengine/doc/src/qtwebengine-platform-notes.qdoc b/src/webengine/doc/src/qtwebengine-platform-notes.qdoc
index 06a4a53a9000f4ed73318f1b00b2348d1ffdd1a4..2eeda6e8a41d3ed19af63fa6382ad8cae57002be 100644
--- a/src/webengine/doc/src/qtwebengine-platform-notes.qdoc
+++ b/src/webengine/doc/src/qtwebengine-platform-notes.qdoc
@@ -114,17 +114,18 @@
 
     \section1 Mac App Store Compatibility
 
-    By default, Qt WebEngine uses private \macos API, which might cause an application to be
-    rejected when submitted to the Mac App Store. To configure Qt WebEngine not to use these API
-    calls, Qt has to be reconfigured with the \c -appstore-compliant switch.
-
-    However, this will cause some behavioral changes, such as:
+    Applications using Qt WebEngine are not compatible with the Mac App Store, because:
 
     \list
-        \li The \macos Kill Ring functionality will no longer work (emacs-like copy pasting).
-        \li Certain Chromium sandboxing cleanup is not done.
-        \li Text areas will be painted with a different style.
-        \li Text fields might be painted with a different style on Mountain Lion (\macos 10.8).
+        \li The Chromium part of the code uses several private API methods, which are prohibited by
+            the App Store.
+        \li Applications submitted to the App Store must be code-signed with the App Sandbox feature
+            enabled. The App Sandbox feature interferes with Chromium's own sandbox
+            initialization, which results in Chromium not being properly initialized. This also
+            ties in with the private API usage. Furthermore, standalone Chromium itself is not
+            officially tested with the App Sandbox enabled, and even if work is done to bypass
+            the App Store's restrictions, that would not guarantee correct behavior of the library.
+
     \endlist
 
     \section1 macOS Airplay Support on MacBooks with Dual GPUs
@@ -161,4 +162,24 @@
     set to 1 or alternatively the \c{--no-sandbox} command line argument can be passed to the user
     application executable.
 
+    \section1 Accessibility and Performance
+
+    Qt WebEngine enables accessibility support for web pages when the following conditions
+    are met:
+
+    \list
+        \li Qt Core is configured and built with accessibility support enabled.
+        \li The QPA plugin is notified by the operating system that accessibility should be
+            activated. This happens for example when using a screen reader application on Windows
+            or VoiceOver on \macos.
+    \endlist
+
+    Due to some limitations, the Linux QPA plugin almost always reports that accessibility should
+    be activated. On big HTML pages, this can cause a significant slowdown in rendering speed.
+
+    Because of that, from Qt 5.9 onwards, Qt WebEngine accessibility support is disabled by default
+    on Linux.
+    It can be re-enabled by setting the \c QTWEBENGINE_ENABLE_LINUX_ACCESSIBILITY environment
+    variable to a non-empty value.
+
 */
diff --git a/src/webengine/ui_delegates_manager.cpp b/src/webengine/ui_delegates_manager.cpp
index 4a47a49ebf56127862342a1984d398d425c6bf29..6cc496d5b643b653b73e35508b2c16e2c76f970a 100644
--- a/src/webengine/ui_delegates_manager.cpp
+++ b/src/webengine/ui_delegates_manager.cpp
@@ -50,6 +50,7 @@
 #include <QQmlContext>
 #include <QQmlEngine>
 #include <QQmlProperty>
+#include <QQuickWindow>
 #include <QCursor>
 #include <QList>
 #include <QScreen>
@@ -559,7 +560,11 @@ void UIDelegatesManager::showToolTip(const QString &text)
     int width = QQmlProperty(m_toolTip.data(), QStringLiteral("width")).read().toInt();
     QSize toolTipSize(width, height);
     QPoint position = m_view->cursor().pos();
+#if (QT_VERSION >= QT_VERSION_CHECK(5, 7, 0))
     position = m_view->mapFromGlobal(calculateToolTipPosition(position, toolTipSize)).toPoint();
+#else
+    position = m_view->window()->mapFromGlobal(calculateToolTipPosition(position, toolTipSize));
+#endif
 
     QQmlProperty(m_toolTip.data(), QStringLiteral("x")).write(position.x());
     QQmlProperty(m_toolTip.data(), QStringLiteral("y")).write(position.y());
diff --git a/src/webenginewidgets/api/qwebenginedownloaditem.cpp b/src/webenginewidgets/api/qwebenginedownloaditem.cpp
index d578bf0e3d2d00ed5a903c337f8c56f76267cf05..c1d9a36985e55bfb2bf0e08d48518808ca07c0db 100644
--- a/src/webenginewidgets/api/qwebenginedownloaditem.cpp
+++ b/src/webenginewidgets/api/qwebenginedownloaditem.cpp
@@ -131,10 +131,8 @@ void QWebEngineDownloadItemPrivate::update(const BrowserContextAdapterClient::Do
 
     Q_ASSERT(downloadState != QWebEngineDownloadItem::DownloadRequested);
 
-    if (toDownloadInterruptReason(info.downloadInterruptReason) != interruptReason) {
+    if (toDownloadInterruptReason(info.downloadInterruptReason) != interruptReason)
         interruptReason = toDownloadInterruptReason(info.downloadInterruptReason);
-        Q_EMIT q->interruptReasonChanged();
-    }
 
     if (toDownloadState(info.state) != downloadState) {
         downloadState = toDownloadState(info.state);
@@ -234,15 +232,6 @@ quint32 QWebEngineDownloadItem::id() const
     \sa totalBytes(), receivedBytes()
 */
 
-/*!
-    \fn QWebEngineDownloadItem::interruptReasonChanged()
-    \since 5.9
-
-    This signal is emitted whenever the reason of the download's interruption changes.
-
-    \sa interruptReason(), QWebEngineDownloadItem::DownloadInterruptReason
-*/
-
 /*!
     \enum QWebEngineDownloadItem::DownloadState
 
diff --git a/src/webenginewidgets/api/qwebenginedownloaditem.h b/src/webenginewidgets/api/qwebenginedownloaditem.h
index 846194f40301b708dabe99660320fe86da254fa9..a4b6c08aa7ebe78ccefbddf638e4dcd07ffc15df 100644
--- a/src/webenginewidgets/api/qwebenginedownloaditem.h
+++ b/src/webenginewidgets/api/qwebenginedownloaditem.h
@@ -134,7 +134,6 @@ Q_SIGNALS:
     void finished();
     void stateChanged(QWebEngineDownloadItem::DownloadState state);
     void downloadProgress(qint64 bytesReceived, qint64 bytesTotal);
-    void interruptReasonChanged();
 
 private:
     Q_DISABLE_COPY(QWebEngineDownloadItem)
diff --git a/src/webenginewidgets/api/qwebengineprofile.cpp b/src/webenginewidgets/api/qwebengineprofile.cpp
index abed066d3303f15b3251798072524d03248b3444..cd4fc8b0260fbda0e1335bc13c4eda01a14a9824 100644
--- a/src/webenginewidgets/api/qwebengineprofile.cpp
+++ b/src/webenginewidgets/api/qwebengineprofile.cpp
@@ -156,6 +156,10 @@ QWebEngineProfilePrivate::QWebEngineProfilePrivate(QSharedPointer<BrowserContext
 
 QWebEngineProfilePrivate::~QWebEngineProfilePrivate()
 {
+    // In the case the user sets this profile as the parent of the interceptor
+    // it can be deleted before the browser-context still referencing it is.
+    m_browserContextRef->setRequestInterceptor(nullptr);
+
     delete m_settings;
     m_settings = 0;
     m_browserContextRef->removeClient(this);
diff --git a/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp b/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp
index 32a518ad8e80da99fb122a8ff01f6e3ab7dddcc3..37c7ae881bef1a00209f6161760c9d2ff001d542 100644
--- a/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp
+++ b/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp
@@ -100,7 +100,8 @@ private Q_SLOTS:
 
     void softwareInputPanel();
     void inputMethods();
-    void textSelection();
+    void textSelectionInInputField();
+    void textSelectionOutOfInputField();
     void hiddenText();
     void emptyInputMethodEvent();
     void imeComposition();
@@ -1584,7 +1585,7 @@ void tst_QWebEngineView::inputMethods()
     QCOMPARE(view.focusProxy()->inputMethodQuery(Qt::ImSurroundingText).toString(), QString("QtWebEngine"));
 }
 
-void tst_QWebEngineView::textSelection()
+void tst_QWebEngineView::textSelectionInInputField()
 {
     QWebEngineView view;
     view.show();
@@ -1662,6 +1663,96 @@ void tst_QWebEngineView::textSelection()
     QCOMPARE(view.focusProxy()->inputMethodQuery(Qt::ImCurrentSelection).toString(), QString("QtWebEngi"));
 }
 
+void tst_QWebEngineView::textSelectionOutOfInputField()
+{
+    QWebEngineView view;
+    view.show();
+
+    QSignalSpy selectionChangedSpy(&view, SIGNAL(selectionChanged()));
+    QSignalSpy loadFinishedSpy(&view, SIGNAL(loadFinished(bool)));
+    view.setHtml("<html><body>"
+                 "  This is a text"
+                 "</body></html>");
+    QVERIFY(loadFinishedSpy.wait());
+
+    QCOMPARE(selectionChangedSpy.count(), 0);
+    QVERIFY(!view.hasSelection());
+    QVERIFY(view.page()->selectedText().isEmpty());
+
+    // Simple click should not update text selection, however it updates selection bounds in Chromium
+    QTest::mouseClick(view.focusProxy(), Qt::LeftButton, 0, view.geometry().center());
+    QCOMPARE(selectionChangedSpy.count(), 0);
+    QVERIFY(!view.hasSelection());
+    QVERIFY(view.page()->selectedText().isEmpty());
+
+    // Workaround for macOS: press ctrl+a without key text
+    QKeyEvent keyPressCtrlA(QEvent::KeyPress, Qt::Key_A, Qt::ControlModifier);
+    QKeyEvent keyReleaseCtrlA(QEvent::KeyRelease, Qt::Key_A, Qt::ControlModifier);
+
+    // Select text by ctrl+a
+    QApplication::sendEvent(view.focusProxy(), &keyPressCtrlA);
+    QApplication::sendEvent(view.focusProxy(), &keyReleaseCtrlA);
+    QVERIFY(selectionChangedSpy.wait());
+    QCOMPARE(selectionChangedSpy.count(), 1);
+    QVERIFY(view.hasSelection());
+    QCOMPARE(view.page()->selectedText(), QString("This is a text"));
+
+    // Deselect text by mouse click
+    QTest::mouseClick(view.focusProxy(), Qt::LeftButton, 0, view.geometry().center());
+    QVERIFY(selectionChangedSpy.wait());
+    QCOMPARE(selectionChangedSpy.count(), 2);
+    QVERIFY(!view.hasSelection());
+    QVERIFY(view.page()->selectedText().isEmpty());
+
+    selectionChangedSpy.clear();
+    view.setHtml("<html><body>"
+                 "  This is a text"
+                 "  <br>"
+                 "  <input type='text' id='input1' value='QtWebEngine' size='50'/>"
+                 "</body></html>");
+    QVERIFY(loadFinishedSpy.wait());
+
+    QCOMPARE(selectionChangedSpy.count(), 0);
+    QVERIFY(!view.hasSelection());
+    QVERIFY(view.page()->selectedText().isEmpty());
+
+    // Make sure the input field does not have the focus
+    evaluateJavaScriptSync(view.page(), "document.getElementById('input1').blur()");
+    QTRY_VERIFY(evaluateJavaScriptSync(view.page(), "document.activeElement.id").toString().isEmpty());
+
+    // Select the whole page by ctrl+a
+    QApplication::sendEvent(view.focusProxy(), &keyPressCtrlA);
+    QApplication::sendEvent(view.focusProxy(), &keyReleaseCtrlA);
+    QVERIFY(selectionChangedSpy.wait());
+    QCOMPARE(selectionChangedSpy.count(), 1);
+    QVERIFY(view.hasSelection());
+    QVERIFY(view.page()->selectedText().startsWith(QString("This is a text")));
+
+    // Remove selection by clicking into an input field
+    QPoint textInputCenter = elementCenter(view.page(), "input1");
+    QTest::mouseClick(view.focusProxy(), Qt::LeftButton, 0, textInputCenter);
+    QVERIFY(selectionChangedSpy.wait());
+    QCOMPARE(evaluateJavaScriptSync(view.page(), "document.activeElement.id").toString(), QStringLiteral("input1"));
+    QCOMPARE(selectionChangedSpy.count(), 2);
+    QVERIFY(!view.hasSelection());
+    QVERIFY(view.page()->selectedText().isEmpty());
+
+    // Select the content of the input field by ctrl+a
+    QApplication::sendEvent(view.focusProxy(), &keyPressCtrlA);
+    QApplication::sendEvent(view.focusProxy(), &keyReleaseCtrlA);
+    QVERIFY(selectionChangedSpy.wait());
+    QCOMPARE(selectionChangedSpy.count(), 3);
+    QVERIFY(view.hasSelection());
+    QCOMPARE(view.page()->selectedText(), QString("QtWebEngine"));
+
+    // Deselect input field's text by mouse click
+    QTest::mouseClick(view.focusProxy(), Qt::LeftButton, 0, view.geometry().center());
+    QVERIFY(selectionChangedSpy.wait());
+    QCOMPARE(selectionChangedSpy.count(), 4);
+    QVERIFY(!view.hasSelection());
+    QVERIFY(view.page()->selectedText().isEmpty());
+}
+
 void tst_QWebEngineView::hiddenText()
 {
     QWebEngineView view;