diff --git a/src/core/render_widget_host_view_qt.cpp b/src/core/render_widget_host_view_qt.cpp
index 6c5b2ac20f5035877bb1c7e68ce3338182a98037..0bb28bd376b95bda9865703e79d20df6eeb4b47d 100644
--- a/src/core/render_widget_host_view_qt.cpp
+++ b/src/core/render_widget_host_view_qt.cpp
@@ -265,7 +265,6 @@ RenderWidgetHostViewQt::RenderWidgetHostViewQt(content::RenderWidgetHost *widget
     , m_adapterClient(0)
     , m_imeInProgress(false)
     , m_receivedEmptyImeEvent(false)
-    , m_initPending(false)
     , m_imState(0)
     , m_anchorPositionWithinSelection(-1)
     , m_cursorPositionWithinSelection(-1)
@@ -319,18 +318,10 @@ void RenderWidgetHostViewQt::setAdapterClient(WebContentsAdapterClient *adapterC
     m_adapterClientDestroyedConnection = QObject::connect(adapterClient->holdingQObject(),
                                                           &QObject::destroyed, [this] {
                                                             m_adapterClient = nullptr; });
-    if (m_initPending)
-        InitAsChild(0);
 }
 
 void RenderWidgetHostViewQt::InitAsChild(gfx::NativeView)
 {
-    if (!m_adapterClient) {
-        m_initPending = true;
-        return;
-    }
-    m_initPending = false;
-    m_delegate->initAsChild(m_adapterClient);
 }
 
 void RenderWidgetHostViewQt::InitAsPopup(content::RenderWidgetHostView*, const gfx::Rect& rect)
@@ -926,13 +917,13 @@ void RenderWidgetHostViewQt::notifyHidden()
 void RenderWidgetHostViewQt::windowBoundsChanged()
 {
     host()->SendScreenRects();
-    if (m_delegate->window())
+    if (m_delegate && m_delegate->window())
         host()->NotifyScreenInfoChanged();
 }
 
 void RenderWidgetHostViewQt::windowChanged()
 {
-    if (m_delegate->window())
+    if (m_delegate && m_delegate->window())
         host()->NotifyScreenInfoChanged();
 }
 
diff --git a/src/core/render_widget_host_view_qt.h b/src/core/render_widget_host_view_qt.h
index ad7fc9f136f2be2dccabb8c4fc0adee3d7fe6047..6a1134ac0a2fb52923d9dd806aaf60cb0425bb46 100644
--- a/src/core/render_widget_host_view_qt.h
+++ b/src/core/render_widget_host_view_qt.h
@@ -246,8 +246,6 @@ private:
     bool m_receivedEmptyImeEvent;
     QPoint m_previousMousePosition;
 
-    bool m_initPending;
-
     gfx::Vector2dF m_lastScrollOffset;
     gfx::SizeF m_lastContentsSize;
     viz::LocalSurfaceId m_localSurfaceId;
diff --git a/src/core/render_widget_host_view_qt_delegate.h b/src/core/render_widget_host_view_qt_delegate.h
index 8936ce63e11e8d5b6a2f4685e0fbaa93152cdd85..991c26ea8e00f4024552439bd4260549d2edee0b 100644
--- a/src/core/render_widget_host_view_qt_delegate.h
+++ b/src/core/render_widget_host_view_qt_delegate.h
@@ -91,7 +91,6 @@ public:
 class QWEBENGINECORE_PRIVATE_EXPORT RenderWidgetHostViewQtDelegate {
 public:
     virtual ~RenderWidgetHostViewQtDelegate() { }
-    virtual void initAsChild(WebContentsAdapterClient*) = 0;
     virtual void initAsPopup(const QRect&) = 0;
     virtual QRectF screenRect() const = 0;
     virtual QRectF contentsRect() const = 0;
diff --git a/src/core/web_contents_adapter.cpp b/src/core/web_contents_adapter.cpp
index 5b9e612682e3da4b1285a3df971c1beb1604e32d..21540f5da7e3527f49d480aa0e6d136b7e5c1052 100644
--- a/src/core/web_contents_adapter.cpp
+++ b/src/core/web_contents_adapter.cpp
@@ -516,14 +516,9 @@ void WebContentsAdapter::initialize(content::SiteInstance *site)
     if (!rvh->IsRenderViewLive())
         static_cast<content::WebContentsImpl*>(m_webContents.get())->CreateRenderViewForRenderManager(rvh, MSG_ROUTING_NONE, MSG_ROUTING_NONE, base::UnguessableToken::Create(), content::FrameReplicationState());
 
-    m_adapterClient->initializationFinished();
-}
+    m_webContentsDelegate->RenderViewHostChanged(nullptr, rvh);
 
-void WebContentsAdapter::reattachRWHV()
-{
-    CHECK_INITIALIZED();
-    if (content::RenderWidgetHostView *rwhv = m_webContents->GetRenderWidgetHostView())
-        rwhv->InitAsChild(0);
+    m_adapterClient->initializationFinished();
 }
 
 bool WebContentsAdapter::canGoBack() const
diff --git a/src/core/web_contents_adapter.h b/src/core/web_contents_adapter.h
index 8e02a852bf6713d49a1462384405a8f42f8a356b..e8e5359beb764c5a8558253466f110374d7a9543 100644
--- a/src/core/web_contents_adapter.h
+++ b/src/core/web_contents_adapter.h
@@ -109,8 +109,6 @@ public:
     void load(const QWebEngineHttpRequest &request);
     void setContent(const QByteArray &data, const QString &mimeType, const QUrl &baseUrl);
 
-    void reattachRWHV();
-
     bool canGoBack() const;
     bool canGoForward() const;
     void stop();
diff --git a/src/core/web_contents_adapter_client.h b/src/core/web_contents_adapter_client.h
index 514d3afb4c90363f2c5729de31cbf9e5ecb50c83..55cbe13ddbf931a6023656a766f720dc49df3238 100644
--- a/src/core/web_contents_adapter_client.h
+++ b/src/core/web_contents_adapter_client.h
@@ -474,6 +474,7 @@ public:
     virtual void setToolTip(const QString& toolTipText) = 0;
     virtual ClientType clientType() = 0;
     virtual void printRequested() = 0;
+    virtual void widgetChanged(RenderWidgetHostViewQtDelegate *newWidget) = 0;
 
     virtual ProfileAdapter *profileAdapter() = 0;
     virtual WebContentsAdapter* webContentsAdapter() = 0;
diff --git a/src/core/web_contents_delegate_qt.cpp b/src/core/web_contents_delegate_qt.cpp
index 9472c0be93b95883acd94b9ca3358fd169b1f796..4bde93fd302e2ee0dc7770de6afbffc2c3483429 100644
--- a/src/core/web_contents_delegate_qt.cpp
+++ b/src/core/web_contents_delegate_qt.cpp
@@ -258,6 +258,14 @@ void WebContentsDelegateQt::RenderFrameDeleted(content::RenderFrameHost *render_
     m_loadingErrorFrameList.removeOne(render_frame_host->GetRoutingID());
 }
 
+void WebContentsDelegateQt::RenderViewHostChanged(content::RenderViewHost *, content::RenderViewHost *newHost)
+{
+    if (newHost && newHost->GetWidget() && newHost->GetWidget()->GetView()) {
+        auto rwhv = static_cast<RenderWidgetHostViewQt *>(newHost->GetWidget()->GetView());
+        m_viewClient->widgetChanged(rwhv->delegate());
+    }
+}
+
 void WebContentsDelegateQt::EmitLoadStarted(const QUrl &url, bool isErrorPage)
 {
     if (m_lastLoadProgress >= 0 && m_lastLoadProgress < 100) // already running
diff --git a/src/core/web_contents_delegate_qt.h b/src/core/web_contents_delegate_qt.h
index 966494ec739d969e0d904e2e4abb81b91dff017e..9c0f8f484521d16a887bdf70db794a4a8eff8f47 100644
--- a/src/core/web_contents_delegate_qt.h
+++ b/src/core/web_contents_delegate_qt.h
@@ -130,6 +130,7 @@ public:
 
     // WebContentsObserver overrides
     void RenderFrameDeleted(content::RenderFrameHost *render_frame_host) override;
+    void RenderViewHostChanged(content::RenderViewHost *old_host, content::RenderViewHost *new_host) override;
     void DidStartNavigation(content::NavigationHandle *navigation_handle) override;
     void DidFinishNavigation(content::NavigationHandle *navigation_handle) override;
     void DidFailLoad(content::RenderFrameHost* render_frame_host, const GURL& validated_url, int error_code, const base::string16& error_description) override;
diff --git a/src/core/web_contents_view_qt.cpp b/src/core/web_contents_view_qt.cpp
index 7910688d3158d8ff4983177dd86804ba24de6cc8..3c4465ae3d5c39998f56d91ad2a0283223f6dadf 100644
--- a/src/core/web_contents_view_qt.cpp
+++ b/src/core/web_contents_view_qt.cpp
@@ -78,8 +78,6 @@ content::RenderWidgetHostViewBase* WebContentsViewQt::CreateViewForWidget(conten
     view->setDelegate(m_factoryClient->CreateRenderWidgetHostViewQtDelegate(view));
     if (m_client)
         view->setAdapterClient(m_client);
-    // Tell the RWHV delegate to attach itself to the native view container.
-    view->InitAsChild(0);
 
     return view;
 }
diff --git a/src/webengine/api/qquickwebengineview.cpp b/src/webengine/api/qquickwebengineview.cpp
index a3a12819b5cc6090b8f5f5a483ea9f24e08be69d..39901e6938863043f485de692ac8121d45090021 100644
--- a/src/webengine/api/qquickwebengineview.cpp
+++ b/src/webengine/api/qquickwebengineview.cpp
@@ -669,6 +669,12 @@ void QQuickWebEngineViewPrivate::printRequested()
     });
 }
 
+void QQuickWebEngineViewPrivate::widgetChanged(RenderWidgetHostViewQtDelegate *newWidgetBase)
+{
+    Q_Q(QQuickWebEngineView);
+    bindViewAndWidget(q, static_cast<RenderWidgetHostViewQtDelegateQuick *>(newWidgetBase));
+}
+
 WebEngineSettings *QQuickWebEngineViewPrivate::webEngineSettings() const
 {
     return m_settings->d_ptr.data();
@@ -846,6 +852,52 @@ void QQuickWebEngineViewPrivate::setFullScreenMode(bool fullscreen)
     }
 }
 
+void QQuickWebEngineViewPrivate::bindViewAndWidget(QQuickWebEngineView *view,
+                                                   RenderWidgetHostViewQtDelegateQuick *widget)
+{
+    auto oldWidget = view ? view->d_func()->widget : nullptr;
+    auto oldView = widget ? widget->m_view : nullptr;
+
+    // Change pointers first.
+
+    if (widget && oldView != view) {
+        if (oldView)
+            oldView->d_func()->widget = nullptr;
+        widget->m_view = view;
+    }
+
+    if (view && oldWidget != widget) {
+        if (oldWidget)
+            oldWidget->m_view = nullptr;
+        view->d_func()->widget = widget;
+    }
+
+    // Then notify.
+
+    if (widget && oldView != view && oldView)
+        oldView->d_func()->widgetChanged(widget, nullptr);
+
+    if (view && oldWidget != widget)
+        view->d_func()->widgetChanged(oldWidget, widget);
+}
+
+void QQuickWebEngineViewPrivate::widgetChanged(RenderWidgetHostViewQtDelegateQuick *oldWidget,
+                                               RenderWidgetHostViewQtDelegateQuick *newWidget)
+{
+    Q_Q(QQuickWebEngineView);
+
+    if (oldWidget)
+        oldWidget->setParentItem(nullptr);
+
+    if (newWidget) {
+        newWidget->setParentItem(q);
+        newWidget->setSize(q->boundingRect().size());
+        // Focus on creation if the view accepts it
+        if (q->activeFocusOnPress())
+            newWidget->setFocus(true);
+    }
+}
+
 void QQuickWebEngineViewPrivate::updateAction(QQuickWebEngineView::WebAction action) const
 {
     QQuickWebEngineAction *a = actions[action];
@@ -1494,11 +1546,9 @@ void QQuickWebEngineView::fullScreenCancelled()
 void QQuickWebEngineView::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry)
 {
     QQuickItem::geometryChanged(newGeometry, oldGeometry);
-    const QList<QQuickItem *> children = childItems();
-    for (QQuickItem *child : children) {
-        if (qobject_cast<RenderWidgetHostViewQtDelegateQuick *>(child))
-            child->setSize(newGeometry.size());
-    }
+    Q_D(QQuickWebEngineView);
+    if (d->widget)
+        d->widget->setSize(newGeometry.size());
 }
 
 void QQuickWebEngineView::itemChange(ItemChange change, const ItemChangeData &value)
diff --git a/src/webengine/api/qquickwebengineview_p_p.h b/src/webengine/api/qquickwebengineview_p_p.h
index d20bfca46616c5e72aac50b0c27e741a5cf3cd43..cbba9b5682550d74d2709e45729a30ba2b03e3a8 100644
--- a/src/webengine/api/qquickwebengineview_p_p.h
+++ b/src/webengine/api/qquickwebengineview_p_p.h
@@ -63,8 +63,9 @@
 #include <QtGui/qaccessibleobject.h>
 
 namespace QtWebEngineCore {
-class WebContentsAdapter;
+class RenderWidgetHostViewQtDelegateQuick;
 class UIDelegatesManager;
+class WebContentsAdapter;
 }
 
 QT_BEGIN_NAMESPACE
@@ -157,6 +158,7 @@ public:
     QtWebEngineCore::ProfileAdapter *profileAdapter() override;
     QtWebEngineCore::WebContentsAdapter *webContentsAdapter() override;
     void printRequested() override;
+    void widgetChanged(QtWebEngineCore::RenderWidgetHostViewQtDelegate *newWidgetBase) override;
 
     void updateAction(QQuickWebEngineView::WebAction) const;
     void adoptWebContents(QtWebEngineCore::WebContentsAdapter *webContents);
@@ -165,6 +167,10 @@ public:
     void ensureContentsAdapter();
     void setFullScreenMode(bool);
 
+    static void bindViewAndWidget(QQuickWebEngineView *view, QtWebEngineCore::RenderWidgetHostViewQtDelegateQuick *widget);
+    void widgetChanged(QtWebEngineCore::RenderWidgetHostViewQtDelegateQuick *oldWidget,
+                       QtWebEngineCore::RenderWidgetHostViewQtDelegateQuick *newWidget);
+
     // QQmlListPropertyHelpers
     static void userScripts_append(QQmlListProperty<QQuickWebEngineScript> *p, QQuickWebEngineScript *script);
     static int userScripts_count(QQmlListProperty<QQuickWebEngineScript> *p);
@@ -198,6 +204,7 @@ public:
     uint m_webChannelWorld;
     bool m_isBeingAdopted;
     mutable QQuickWebEngineAction *actions[QQuickWebEngineView::WebActionCount];
+    QtWebEngineCore::RenderWidgetHostViewQtDelegateQuick *widget = nullptr;
 
     bool profileInitialized() const;
 
diff --git a/src/webengine/render_widget_host_view_qt_delegate_quick.cpp b/src/webengine/render_widget_host_view_qt_delegate_quick.cpp
index baece82f3535f7a4c9469af1bc62e63f4da99942..d23e647746a2a09e7fe918c4bb56dd0a180f2ec9 100644
--- a/src/webengine/render_widget_host_view_qt_delegate_quick.cpp
+++ b/src/webengine/render_widget_host_view_qt_delegate_quick.cpp
@@ -55,7 +55,6 @@ RenderWidgetHostViewQtDelegateQuick::RenderWidgetHostViewQtDelegateQuick(RenderW
     : m_client(client)
     , m_isPopup(isPopup)
     , m_isPasswordInput(false)
-    , m_initialized(false)
 {
     setFlag(ItemHasContents);
     setAcceptedMouseButtons(Qt::AllButtons);
@@ -85,16 +84,9 @@ RenderWidgetHostViewQtDelegateQuick::RenderWidgetHostViewQtDelegateQuick(RenderW
 
 }
 
-void RenderWidgetHostViewQtDelegateQuick::initAsChild(WebContentsAdapterClient* container)
+RenderWidgetHostViewQtDelegateQuick::~RenderWidgetHostViewQtDelegateQuick()
 {
-    QQuickWebEngineView *view = static_cast<QQuickWebEngineViewPrivate *>(container)->q_func();
-    setParentItem(view);
-    setSize(view->boundingRect().size());
-    // Focus on creation if the view accepts it
-    if (view->activeFocusOnPress())
-        setFocus(true);
-    m_initialized = true;
-
+    QQuickWebEngineViewPrivate::bindViewAndWidget(nullptr, this);
 }
 
 void RenderWidgetHostViewQtDelegateQuick::initAsPopup(const QRect &r)
@@ -106,7 +98,6 @@ void RenderWidgetHostViewQtDelegateQuick::initAsPopup(const QRect &r)
     setWidth(rect.width());
     setHeight(rect.height());
     setVisible(true);
-    m_initialized = true;
 }
 
 QRectF RenderWidgetHostViewQtDelegateQuick::screenRect() const
@@ -361,8 +352,7 @@ void RenderWidgetHostViewQtDelegateQuick::itemChange(ItemChange change, const It
                 m_windowConnections.append(connect(value.window, SIGNAL(closing(QQuickCloseEvent *)), SLOT(onHide())));
         }
 
-        if (m_initialized)
-            m_client->windowChanged();
+        m_client->windowChanged();
     } else if (change == QQuickItem::ItemVisibleHasChanged) {
         if (!m_isPopup && !value.boolValue)
             onHide();
diff --git a/src/webengine/render_widget_host_view_qt_delegate_quick.h b/src/webengine/render_widget_host_view_qt_delegate_quick.h
index 74cddf4768c4ed6d59d0daee47dc79f73d4c1c14..6b855c824082987a1597e12c9b131a1b80c48509 100644
--- a/src/webengine/render_widget_host_view_qt_delegate_quick.h
+++ b/src/webengine/render_widget_host_view_qt_delegate_quick.h
@@ -44,6 +44,11 @@
 
 #include <QQuickItem>
 
+QT_BEGIN_NAMESPACE
+class QQuickWebEngineView;
+class QQuickWebEngineViewPrivate;
+QT_END_NAMESPACE
+
 namespace QtWebEngineCore {
 
 class RenderWidgetHostViewQtDelegateQuick : public QQuickItem, public RenderWidgetHostViewQtDelegate
@@ -51,8 +56,8 @@ class RenderWidgetHostViewQtDelegateQuick : public QQuickItem, public RenderWidg
     Q_OBJECT
 public:
     RenderWidgetHostViewQtDelegateQuick(RenderWidgetHostViewQtDelegateClient *client, bool isPopup);
+    ~RenderWidgetHostViewQtDelegateQuick();
 
-    void initAsChild(WebContentsAdapterClient* container) override;
     void initAsPopup(const QRect&) override;
     QRectF screenRect() const override;
     QRectF contentsRect() const override;
@@ -102,12 +107,14 @@ private slots:
     void onHide();
 
 private:
+    friend QQuickWebEngineViewPrivate;
+
     RenderWidgetHostViewQtDelegateClient *m_client;
     QList<QMetaObject::Connection> m_windowConnections;
     bool m_isPopup;
     bool m_isPasswordInput;
-    bool m_initialized;
     QPoint m_lastGlobalPos;
+    QQuickWebEngineView *m_view = nullptr;
 };
 
 } // namespace QtWebEngineCore
diff --git a/src/webengine/render_widget_host_view_qt_delegate_quickwindow.cpp b/src/webengine/render_widget_host_view_qt_delegate_quickwindow.cpp
index dd37ff6faff19b67c74072b9d8c2bc575b0a70ad..d3c88148eab9c016f6050e9a97c17d4866f8b9c2 100644
--- a/src/webengine/render_widget_host_view_qt_delegate_quickwindow.cpp
+++ b/src/webengine/render_widget_host_view_qt_delegate_quickwindow.cpp
@@ -54,13 +54,6 @@ RenderWidgetHostViewQtDelegateQuickWindow::~RenderWidgetHostViewQtDelegateQuickW
 {
 }
 
-void RenderWidgetHostViewQtDelegateQuickWindow::initAsChild(WebContentsAdapterClient *container)
-{
-    Q_UNUSED(container);
-    // We should only use this wrapper class for webUI popups.
-    Q_UNREACHABLE();
-}
-
 void RenderWidgetHostViewQtDelegateQuickWindow::initAsPopup(const QRect &screenRect)
 {
     m_realDelegate->initAsPopup(QRect(QPoint(0, 0), screenRect.size()));
diff --git a/src/webengine/render_widget_host_view_qt_delegate_quickwindow.h b/src/webengine/render_widget_host_view_qt_delegate_quickwindow.h
index 6a1be8b7f7d9c81802ea31c48f53869d5042303d..df241bf3a028b28b1b8e0cbc4b5e2b87c5bceafb 100644
--- a/src/webengine/render_widget_host_view_qt_delegate_quickwindow.h
+++ b/src/webengine/render_widget_host_view_qt_delegate_quickwindow.h
@@ -55,7 +55,6 @@ public:
     RenderWidgetHostViewQtDelegateQuickWindow(RenderWidgetHostViewQtDelegate *realDelegate);
     ~RenderWidgetHostViewQtDelegateQuickWindow();
 
-    void initAsChild(WebContentsAdapterClient* container) override;
     void initAsPopup(const QRect&) override;
     QRectF screenRect() const override;
     QRectF contentsRect() const override;
diff --git a/src/webenginewidgets/api/qwebenginepage.cpp b/src/webenginewidgets/api/qwebenginepage.cpp
index 3a2a075206921b9a89f8c3c438b4c7d7e1d0df08..a6267c2231284bce59371267eff2707cd8425f34 100644
--- a/src/webenginewidgets/api/qwebenginepage.cpp
+++ b/src/webenginewidgets/api/qwebenginepage.cpp
@@ -273,8 +273,6 @@ RenderWidgetHostViewQtDelegate *QWebEnginePagePrivate::CreateRenderWidgetHostVie
     // The new delegate will not be deleted by the parent view though, because we unset the parent
     // when the parent is destroyed. The delegate will be destroyed by Chromium when the popup is
     // dismissed.
-    // If the delegate is not for a popup, but for a newly created QWebEngineView, the parent is 0
-    // just like before.
     return new RenderWidgetHostViewQtDelegateWidget(client, this->view);
 }
 
@@ -718,12 +716,87 @@ const QObject *QWebEnginePagePrivate::holdingQObject() const
     return q;
 }
 
+void QWebEnginePagePrivate::widgetChanged(RenderWidgetHostViewQtDelegate *newWidgetBase)
+{
+    Q_Q(QWebEnginePage);
+    bindPageAndWidget(q, static_cast<RenderWidgetHostViewQtDelegateWidget *>(newWidgetBase));
+}
+
 void QWebEnginePagePrivate::ensureInitialized() const
 {
     if (!adapter->isInitialized())
         adapter->loadDefault();
 }
 
+void QWebEnginePagePrivate::bindPageAndView(QWebEnginePage *page, QWebEngineView *view)
+{
+    auto oldView = page ? page->d_func()->view : nullptr;
+    auto oldPage = view ? view->d_func()->page : nullptr;
+
+    // Change pointers first.
+
+    if (page && oldView != view) {
+        if (oldView)
+            oldView->d_func()->page = nullptr;
+        page->d_func()->view = view;
+    }
+
+    if (view && oldPage != page) {
+        if (oldPage)
+            oldPage->d_func()->view = nullptr;
+        view->d_func()->page = page;
+    }
+
+    // Then notify.
+
+    auto widget = page ? page->d_func()->widget : nullptr;
+    auto oldWidget = oldPage ? oldPage->d_func()->widget : nullptr;
+
+    if (page && oldView != view && oldView) {
+        oldView->d_func()->pageChanged(page, nullptr);
+        if (widget)
+            oldView->d_func()->widgetChanged(widget, nullptr);
+    }
+
+    if (view && oldPage != page) {
+        view->d_func()->pageChanged(oldPage, page);
+        if (oldWidget != widget)
+            view->d_func()->widgetChanged(oldWidget, widget);
+    }
+}
+
+void QWebEnginePagePrivate::bindPageAndWidget(QWebEnginePage *page, RenderWidgetHostViewQtDelegateWidget *widget)
+{
+    auto oldPage = widget ? widget->m_page : nullptr;
+    auto oldWidget = page ? page->d_func()->widget : nullptr;
+
+    // Change pointers first.
+
+    if (widget && oldPage != page) {
+        if (oldPage)
+            oldPage->d_func()->widget = nullptr;
+        widget->m_page = page;
+    }
+
+    if (page && oldWidget != widget) {
+        if (oldWidget)
+            oldWidget->m_page = nullptr;
+        page->d_func()->widget = widget;
+    }
+
+    // Then notify.
+
+    if (widget && oldPage != page && oldPage) {
+        if (auto oldView = oldPage->d_func()->view)
+            oldView->d_func()->widgetChanged(widget, nullptr);
+    }
+
+    if (page && oldWidget != widget) {
+        if (auto view = page->d_func()->view)
+            view->d_func()->widgetChanged(oldWidget, widget);
+    }
+}
+
 QWebEnginePage::QWebEnginePage(QObject* parent)
     : QObject(parent)
     , d_ptr(new QWebEnginePagePrivate())
@@ -895,7 +968,8 @@ QWebEnginePage::~QWebEnginePage()
     Q_D(QWebEnginePage);
     setDevToolsPage(nullptr);
     d->adapter->stopFinding();
-    QWebEngineViewPrivate::removePageFromView(this);
+    QWebEnginePagePrivate::bindPageAndView(this, nullptr);
+    QWebEnginePagePrivate::bindPageAndWidget(this, nullptr);
 }
 
 QWebEngineHistory *QWebEnginePage::history() const
@@ -1064,9 +1138,9 @@ bool QWebEnginePage::recentlyAudible() const
     return d->adapter->isInitialized() && d->adapter->recentlyAudible();
 }
 
-void QWebEnginePage::setView(QWidget *view)
+void QWebEnginePage::setView(QWidget *newViewBase)
 {
-    QWebEngineViewPrivate::bind(qobject_cast<QWebEngineView*>(view), this);
+    QWebEnginePagePrivate::bindPageAndView(this, qobject_cast<QWebEngineView *>(newViewBase));
 }
 
 QWidget *QWebEnginePage::view() const
diff --git a/src/webenginewidgets/api/qwebenginepage_p.h b/src/webenginewidgets/api/qwebenginepage_p.h
index dc8a34af6c4b4db07f380de434e2175e2482ed26..eecbf0b656924e8860362b930c35126546de8ee5 100644
--- a/src/webenginewidgets/api/qwebenginepage_p.h
+++ b/src/webenginewidgets/api/qwebenginepage_p.h
@@ -65,6 +65,7 @@
 
 namespace QtWebEngineCore {
 class RenderWidgetHostViewQtDelegate;
+class RenderWidgetHostViewQtDelegateWidget;
 class WebContentsAdapter;
 }
 
@@ -150,6 +151,7 @@ public:
     void printRequested() override;
     const QObject *holdingQObject() const override;
     ClientType clientType() override { return QtWebEngineCore::WebContentsAdapterClient::WidgetsClient; }
+    void widgetChanged(QtWebEngineCore::RenderWidgetHostViewQtDelegate *newWidget) override;
 
     QtWebEngineCore::ProfileAdapter *profileAdapter() override;
     QtWebEngineCore::WebContentsAdapter *webContentsAdapter() override;
@@ -166,6 +168,10 @@ public:
     void setFullScreenMode(bool);
     void ensureInitialized() const;
 
+    static void bindPageAndView(QWebEnginePage *page, QWebEngineView *view);
+    static void bindPageAndWidget(QWebEnginePage *page,
+                                  QtWebEngineCore::RenderWidgetHostViewQtDelegateWidget *widget);
+
     QSharedPointer<QtWebEngineCore::WebContentsAdapter> adapter;
     QWebEngineHistory *history;
     QWebEngineProfile *profile;
@@ -187,6 +193,7 @@ public:
     bool defaultAudioMuted;
     qreal defaultZoomFactor;
     QTimer wasShownTimer;
+    QtWebEngineCore::RenderWidgetHostViewQtDelegateWidget *widget = nullptr;
 
     mutable QtWebEngineCore::CallbackDirectory m_callbacks;
     mutable QAction *actions[QWebEnginePage::WebActionCount];
diff --git a/src/webenginewidgets/api/qwebengineview.cpp b/src/webenginewidgets/api/qwebengineview.cpp
index e6f9fcb49c7f7986ecccd02efec1e9ca7628ccf7..576baad17de4d66cbcd974edb2ef5197b1bff339 100644
--- a/src/webenginewidgets/api/qwebengineview.cpp
+++ b/src/webenginewidgets/api/qwebengineview.cpp
@@ -41,6 +41,7 @@
 #include "qwebengineview_p.h"
 
 #include "qwebenginepage_p.h"
+#include "render_widget_host_view_qt_delegate_widget.h"
 #include "web_contents_adapter.h"
 
 #if QT_CONFIG(action)
@@ -55,89 +56,61 @@
 
 QT_BEGIN_NAMESPACE
 
-void QWebEngineViewPrivate::notify(QWebEngineView *view, QWebEnginePage *oldPage, QWebEnginePage *newPage)
+void QWebEngineViewPrivate::pageChanged(QWebEnginePage *oldPage, QWebEnginePage *newPage)
 {
-    Q_ASSERT(view);
+    Q_Q(QWebEngineView);
+
+    if (oldPage) {
+        oldPage->disconnect(q);
+    }
+
+    if (newPage) {
+        QObject::connect(newPage, &QWebEnginePage::titleChanged, q, &QWebEngineView::titleChanged);
+        QObject::connect(newPage, &QWebEnginePage::urlChanged, q, &QWebEngineView::urlChanged);
+        QObject::connect(newPage, &QWebEnginePage::iconUrlChanged, q, &QWebEngineView::iconUrlChanged);
+        QObject::connect(newPage, &QWebEnginePage::iconChanged, q, &QWebEngineView::iconChanged);
+        QObject::connect(newPage, &QWebEnginePage::loadStarted, q, &QWebEngineView::loadStarted);
+        QObject::connect(newPage, &QWebEnginePage::loadProgress, q, &QWebEngineView::loadProgress);
+        QObject::connect(newPage, &QWebEnginePage::loadFinished, q, &QWebEngineView::loadFinished);
+        QObject::connect(newPage, &QWebEnginePage::selectionChanged, q, &QWebEngineView::selectionChanged);
+        QObject::connect(newPage, &QWebEnginePage::renderProcessTerminated, q, &QWebEngineView::renderProcessTerminated);
+    }
 
     auto oldUrl = oldPage ? oldPage->url() : QUrl();
     auto newUrl = newPage ? newPage->url() : QUrl();
     if (oldUrl != newUrl)
-        Q_EMIT view->urlChanged(newUrl);
+        Q_EMIT q->urlChanged(newUrl);
 
     auto oldTitle = oldPage ? oldPage->title() : QString();
     auto newTitle = newPage ? newPage->title() : QString();
     if (oldTitle != newTitle)
-        Q_EMIT view->titleChanged(newTitle);
+        Q_EMIT q->titleChanged(newTitle);
 
     auto oldIcon = oldPage ? oldPage->iconUrl() : QUrl();
     auto newIcon = newPage ? newPage->iconUrl() : QUrl();
     if (oldIcon != newIcon) {
-        Q_EMIT view->iconUrlChanged(newIcon);
-        Q_EMIT view->iconChanged(newPage ? newPage->icon() : QIcon());
+        Q_EMIT q->iconUrlChanged(newIcon);
+        Q_EMIT q->iconChanged(newPage ? newPage->icon() : QIcon());
     }
 
     if ((oldPage && oldPage->hasSelection()) || (newPage && newPage->hasSelection()))
-        Q_EMIT view->selectionChanged();
-}
-
-QWebEnginePage* QWebEngineViewPrivate::removeViewFromPage(QWebEngineView *view)
-{
-    Q_ASSERT(view);
-    QWebEnginePage *oldPage = view->d_func()->page;
-
-    if (oldPage) {
-        oldPage->disconnect(view);
-        oldPage->d_func()->view = nullptr;
-        if (oldPage->parent() != view)
-            oldPage->d_func()->adapter->reattachRWHV();
-    }
-    return oldPage;
-}
-
-void QWebEngineViewPrivate::removePageFromView(QWebEnginePage *page)
-{
-    Q_ASSERT(page);
-    if (QWebEngineView *oldView = page->d_func()->view) {
-        page->disconnect(oldView);
-        page->d_func()->view = nullptr;
-        oldView->d_func()->page = nullptr;
-        notify(oldView, page, nullptr);
-    }
+        Q_EMIT q->selectionChanged();
 }
 
-void QWebEngineViewPrivate::bind(QWebEngineView *view, QWebEnginePage *page)
+void QWebEngineViewPrivate::widgetChanged(QtWebEngineCore::RenderWidgetHostViewQtDelegateWidget *oldWidget,
+                                          QtWebEngineCore::RenderWidgetHostViewQtDelegateWidget *newWidget)
 {
-    if (view && page == view->d_func()->page)
-        return;
-
-    if (page) {
-        // Un-bind page from its current view.
-        removePageFromView(page);
-        page->d_func()->view = view;
-        page->d_func()->adapter->reattachRWHV();
-    }
-
-    if (view) {
-        // Un-bind view from its current page.
-        QWebEnginePage *oldPage = removeViewFromPage(view);
-
-        view->d_func()->page = page;
-        notify(view, oldPage, page);
+    Q_Q(QWebEngineView);
 
-        if (oldPage && oldPage->parent() == view)
-            delete oldPage;
+    if (oldWidget) {
+        q->layout()->removeWidget(oldWidget);
+        oldWidget->hide();
     }
 
-    if (view && page) {
-        QObject::connect(page, &QWebEnginePage::titleChanged, view, &QWebEngineView::titleChanged);
-        QObject::connect(page, &QWebEnginePage::urlChanged, view, &QWebEngineView::urlChanged);
-        QObject::connect(page, &QWebEnginePage::iconUrlChanged, view, &QWebEngineView::iconUrlChanged);
-        QObject::connect(page, &QWebEnginePage::iconChanged, view, &QWebEngineView::iconChanged);
-        QObject::connect(page, &QWebEnginePage::loadStarted, view, &QWebEngineView::loadStarted);
-        QObject::connect(page, &QWebEnginePage::loadProgress, view, &QWebEngineView::loadProgress);
-        QObject::connect(page, &QWebEnginePage::loadFinished, view, &QWebEngineView::loadFinished);
-        QObject::connect(page, &QWebEnginePage::selectionChanged, view, &QWebEngineView::selectionChanged);
-        QObject::connect(page, &QWebEnginePage::renderProcessTerminated, view, &QWebEngineView::renderProcessTerminated);
+    if (newWidget) {
+        q->layout()->addWidget(newWidget);
+        q->setFocusProxy(newWidget);
+        newWidget->show();
     }
 }
 
@@ -193,7 +166,8 @@ QWebEngineView::QWebEngineView(QWidget *parent)
 
 QWebEngineView::~QWebEngineView()
 {
-    QWebEngineViewPrivate::removeViewFromPage(this);
+    blockSignals(true);
+    QWebEnginePagePrivate::bindPageAndView(nullptr, this);
 }
 
 QWebEnginePage* QWebEngineView::page() const
@@ -206,9 +180,9 @@ QWebEnginePage* QWebEngineView::page() const
     return d->page;
 }
 
-void QWebEngineView::setPage(QWebEnginePage* page)
+void QWebEngineView::setPage(QWebEnginePage *newPage)
 {
-    QWebEngineViewPrivate::bind(this, page);
+    QWebEnginePagePrivate::bindPageAndView(newPage, this);
 }
 
 void QWebEngineView::load(const QUrl& url)
diff --git a/src/webenginewidgets/api/qwebengineview_p.h b/src/webenginewidgets/api/qwebengineview_p.h
index 1845bfb603d3e35977fc8b687a4e6242db977c23..28fb883aa3608a7c6bd94600e9bfb89b8024cbde 100644
--- a/src/webenginewidgets/api/qwebengineview_p.h
+++ b/src/webenginewidgets/api/qwebengineview_p.h
@@ -55,6 +55,10 @@
 
 #include <QtWidgets/qaccessiblewidget.h>
 
+namespace QtWebEngineCore {
+class RenderWidgetHostViewQtDelegateWidget;
+}
+
 QT_BEGIN_NAMESPACE
 
 class QWebEngineView;
@@ -65,10 +69,9 @@ public:
     Q_DECLARE_PUBLIC(QWebEngineView)
     QWebEngineView *q_ptr;
 
-    static void notify(QWebEngineView *view, QWebEnginePage *oldPage, QWebEnginePage *newPage);
-    static QWebEnginePage* removeViewFromPage(QWebEngineView *view);
-    static void removePageFromView(QWebEnginePage *page);
-    static void bind(QWebEngineView *view, QWebEnginePage *page);
+    void pageChanged(QWebEnginePage *oldPage, QWebEnginePage *newPage);
+    void widgetChanged(QtWebEngineCore::RenderWidgetHostViewQtDelegateWidget *oldWidget,
+                       QtWebEngineCore::RenderWidgetHostViewQtDelegateWidget *newWidget);
 
     QWebEngineViewPrivate();
 
diff --git a/src/webenginewidgets/render_widget_host_view_qt_delegate_widget.cpp b/src/webenginewidgets/render_widget_host_view_qt_delegate_widget.cpp
index 13c65f1ec168d388886c91171c5d2aeb28018a52..7bbd8509133ed2cb46140a74f0ca39ae92b28acb 100644
--- a/src/webenginewidgets/render_widget_host_view_qt_delegate_widget.cpp
+++ b/src/webenginewidgets/render_widget_host_view_qt_delegate_widget.cpp
@@ -165,15 +165,28 @@ RenderWidgetHostViewQtDelegateWidget::RenderWidgetHostViewQtDelegateWidget(Rende
     setAttribute(Qt::WA_OpaquePaintEvent);
     setAttribute(Qt::WA_AlwaysShowToolTips);
 
-    if (parent) {
-        // Unset the popup parent if the parent is being destroyed, thus making sure a double
-        // delete does not happen.
-        // Also in case the delegate is destroyed before its parent (when a popup is simply
-        // dismissed), this connection will automatically be removed by ~QObject(), preventing
-        // a use-after-free.
+    setContent(QUrl(), nullptr, m_rootItem.data());
+
+    connectRemoveParentBeforeParentDelete();
+}
+
+RenderWidgetHostViewQtDelegateWidget::~RenderWidgetHostViewQtDelegateWidget()
+{
+    QWebEnginePagePrivate::bindPageAndWidget(nullptr, this);
+}
+
+void RenderWidgetHostViewQtDelegateWidget::connectRemoveParentBeforeParentDelete()
+{
+    if (QWidget *parent = parentWidget())
         connect(parent, &QObject::destroyed,
                 this, &RenderWidgetHostViewQtDelegateWidget::removeParentBeforeParentDelete);
-    }
+}
+
+void RenderWidgetHostViewQtDelegateWidget::disconnectRemoveParentBeforeParentDelete()
+{
+    if (QWidget *parent = parentWidget())
+        disconnect(parent, &QObject::destroyed,
+                   this, &RenderWidgetHostViewQtDelegateWidget::removeParentBeforeParentDelete);
 }
 
 void RenderWidgetHostViewQtDelegateWidget::removeParentBeforeParentDelete()
@@ -188,29 +201,9 @@ void RenderWidgetHostViewQtDelegateWidget::removeParentBeforeParentDelete()
         close();
 }
 
-void RenderWidgetHostViewQtDelegateWidget::initAsChild(WebContentsAdapterClient* container)
-{
-    setContent(QUrl(), nullptr, m_rootItem.data());
-
-    QWebEnginePagePrivate *pagePrivate = static_cast<QWebEnginePagePrivate *>(container);
-    if (pagePrivate->view) {
-        if (parentWidget())
-            disconnect(parentWidget(), &QObject::destroyed,
-                this, &RenderWidgetHostViewQtDelegateWidget::removeParentBeforeParentDelete);
-        pagePrivate->view->layout()->addWidget(this);
-        if (QWidget *focusProxy = pagePrivate->view->focusProxy())
-            if (focusProxy != this)
-                pagePrivate->view->layout()->removeWidget(focusProxy);
-        pagePrivate->view->setFocusProxy(this);
-        show();
-    } else
-        setParent(0);
-}
-
 void RenderWidgetHostViewQtDelegateWidget::initAsPopup(const QRect& screenRect)
 {
     m_isPopup = true;
-    setContent(QUrl(), nullptr, m_rootItem.data());
 
     // The keyboard events are supposed to go to the parent RenderHostView
     // so the WebUI popups should never have focus. Besides, if the parent view
@@ -422,6 +415,18 @@ bool RenderWidgetHostViewQtDelegateWidget::event(QEvent *event)
 {
     bool handled = false;
 
+    // Track parent to make sure we don't get deleted.
+    switch (event->type()) {
+    case QEvent::ParentAboutToChange:
+        disconnectRemoveParentBeforeParentDelete();
+        break;
+    case QEvent::ParentChange:
+        connectRemoveParentBeforeParentDelete();
+        break;
+    default:
+        break;
+    }
+
     // Mimic QWidget::event() by ignoring mouse, keyboard, touch and tablet events if the widget is
     // disabled.
     if (!isEnabled()) {
diff --git a/src/webenginewidgets/render_widget_host_view_qt_delegate_widget.h b/src/webenginewidgets/render_widget_host_view_qt_delegate_widget.h
index 4dc47dfddd7fcd3c8b48556d946c63c6261063a1..74c9e3413fceba62732f4dcc1ac122c34d693e16 100644
--- a/src/webenginewidgets/render_widget_host_view_qt_delegate_widget.h
+++ b/src/webenginewidgets/render_widget_host_view_qt_delegate_widget.h
@@ -46,6 +46,11 @@
 #include <QQuickItem>
 #include <QQuickWidget>
 
+QT_BEGIN_NAMESPACE
+class QWebEnginePage;
+class QWebEnginePagePrivate;
+QT_END_NAMESPACE
+
 namespace QtWebEngineCore {
 
 // Useful information keyboard and mouse QEvent propagation.
@@ -58,8 +63,8 @@ class RenderWidgetHostViewQtDelegateWidget : public QQuickWidget, public RenderW
     Q_OBJECT
 public:
     RenderWidgetHostViewQtDelegateWidget(RenderWidgetHostViewQtDelegateClient *client, QWidget *parent = 0);
+    ~RenderWidgetHostViewQtDelegateWidget();
 
-    void initAsChild(WebContentsAdapterClient* container) override;
     void initAsPopup(const QRect&) override;
     QRectF screenRect() const override;
     QRectF contentsRect() const override;
@@ -95,9 +100,13 @@ protected:
 
 private slots:
     void onWindowPosChanged();
+    void connectRemoveParentBeforeParentDelete();
+    void disconnectRemoveParentBeforeParentDelete();
     void removeParentBeforeParentDelete();
 
 private:
+    friend QWebEnginePagePrivate;
+
     RenderWidgetHostViewQtDelegateClient *m_client;
     QScopedPointer<QQuickItem> m_rootItem;
     bool m_isPopup;
@@ -105,6 +114,7 @@ private:
     QColor m_clearColor;
     QPoint m_lastGlobalPos;
     QList<QMetaObject::Connection> m_windowConnections;
+    QWebEnginePage *m_page = nullptr;
 };
 
 } // namespace QtWebEngineCore