From 9c198939be1ef064d1a2430a4b9991f2fe16f359 Mon Sep 17 00:00:00 2001
From: Pierre Rossi <pierre.rossi@digia.com>
Date: Thu, 30 Jan 2014 18:26:21 +0100
Subject: [PATCH] [Widgets] RenderWidgetHostViewQtDelegate refactoring

Break up the delegate implementation into two distinct subclasses.
The first one offers a way for the WebPage to tap into the
RenderWidgetHostView directly, while a different implementation
that is backed by a top-level widget can be used to show WebUI
popups on screen.

This has the benefit of not having a child widget in the webview
among other things. It also fixes our popups and allows them to fall
outside the window frame.

Change-Id: I80dc1e4f21bb91ff47c75a626d330f88eacce8c6
Reviewed-by: Jocelyn Turcotte <jocelyn.turcotte@digia.com>
---
 src/core/backing_store_qt.cpp                 |   3 +-
 src/core/render_widget_host_view_qt.cpp       |   7 +-
 .../render_widget_host_view_qt_delegate.h     |   1 +
 src/core/web_contents_adapter.cpp             |   7 -
 src/core/web_contents_adapter.h               |   1 -
 src/core/web_contents_adapter_client.h        |   1 +
 src/core/web_contents_view_qt.cpp             |  14 +-
 src/webengine/api/qquickwebengineview_p_p.h   |   1 +
 ...ender_widget_host_view_qt_delegate_quick.h |   2 +
 src/webenginewidgets/api/qwebenginepage.cpp   |  68 +++++++-
 src/webenginewidgets/api/qwebenginepage.h     |   1 +
 src/webenginewidgets/api/qwebenginepage_p.h   |   3 +
 src/webenginewidgets/api/qwebengineview.cpp   |  33 +++-
 src/webenginewidgets/api/qwebengineview.h     |   2 +
 ...er_widget_host_view_qt_delegate_popup.cpp} |  87 ++++------
 ...nder_widget_host_view_qt_delegate_popup.h} |  17 +-
 ...r_widget_host_view_qt_delegate_webpage.cpp | 155 ++++++++++++++++++
 ...der_widget_host_view_qt_delegate_webpage.h |  91 ++++++++++
 src/webenginewidgets/webenginewidgets.pro     |   6 +-
 19 files changed, 411 insertions(+), 89 deletions(-)
 rename src/webenginewidgets/{render_widget_host_view_qt_delegate_widget.cpp => render_widget_host_view_qt_delegate_popup.cpp} (54%)
 rename src/webenginewidgets/{render_widget_host_view_qt_delegate_widget.h => render_widget_host_view_qt_delegate_popup.h} (86%)
 create mode 100644 src/webenginewidgets/render_widget_host_view_qt_delegate_webpage.cpp
 create mode 100644 src/webenginewidgets/render_widget_host_view_qt_delegate_webpage.h

diff --git a/src/core/backing_store_qt.cpp b/src/core/backing_store_qt.cpp
index 613dfdbbc..fda60d094 100644
--- a/src/core/backing_store_qt.cpp
+++ b/src/core/backing_store_qt.cpp
@@ -70,11 +70,12 @@ BackingStoreQt::~BackingStoreQt()
 {
 }
 
-void BackingStoreQt::paintToTarget(QPainter* painter, const QRectF& rect)
+void BackingStoreQt::paintToTarget(QPainter* painter, const QRectF& clipRect)
 {
     if (m_pixelBuffer.isNull())
         return;
 
+    QRectF rect = clipRect.isNull() ? m_pixelBuffer.rect() : clipRect;
     qreal x = rect.x() * m_deviceScaleFactor;
     qreal y = rect.y() * m_deviceScaleFactor;
     qreal w = rect.width() * m_deviceScaleFactor;
diff --git a/src/core/render_widget_host_view_qt.cpp b/src/core/render_widget_host_view_qt.cpp
index 4fb9a1fed..39c95098e 100644
--- a/src/core/render_widget_host_view_qt.cpp
+++ b/src/core/render_widget_host_view_qt.cpp
@@ -217,8 +217,8 @@ void RenderWidgetHostViewQt::SetSize(const gfx::Size& size)
 void RenderWidgetHostViewQt::SetBounds(const gfx::Rect& rect)
 {
     // This is called when webkit has sent us a Move message.
-    // if (IsPopup())
-        // m_delegate->setGeometry(rect.x(), rect.y(), rect.width(), rect.height());
+     if (IsPopup())
+         m_delegate->move(QPoint(rect.x(), rect.y()));
     SetSize(rect.size());
 }
 
@@ -260,7 +260,8 @@ gfx::NativeViewAccessible RenderWidgetHostViewQt::GetNativeViewAccessible()
 void RenderWidgetHostViewQt::Focus()
 {
     m_host->SetInputMethodActive(true);
-    m_delegate->setKeyboardFocus();
+    if (!IsPopup())
+        m_delegate->setKeyboardFocus();
     m_host->Focus();
 }
 
diff --git a/src/core/render_widget_host_view_qt_delegate.h b/src/core/render_widget_host_view_qt_delegate.h
index a780335ef..e71c79582 100644
--- a/src/core/render_widget_host_view_qt_delegate.h
+++ b/src/core/render_widget_host_view_qt_delegate.h
@@ -87,6 +87,7 @@ public:
     virtual void update(const QRect& rect = QRect()) = 0;
     virtual void updateCursor(const QCursor &) = 0;
     virtual void resize(int width, int height) = 0;
+    virtual void move(const QPoint &) = 0;
     virtual void inputMethodStateChanged(bool editorVisible) = 0;
     virtual bool supportsHardwareAcceleration() const = 0;
 };
diff --git a/src/core/web_contents_adapter.cpp b/src/core/web_contents_adapter.cpp
index 6325a380f..ba458c80b 100644
--- a/src/core/web_contents_adapter.cpp
+++ b/src/core/web_contents_adapter.cpp
@@ -230,13 +230,6 @@ void WebContentsAdapter::initialize(WebContentsAdapterClient *adapterClient)
 
 }
 
-void WebContentsAdapter::reattachRWHV()
-{
-    Q_D(WebContentsAdapter);
-    if (content::RenderWidgetHostView *rwhv = d->webContents->GetRenderWidgetHostView())
-        rwhv->InitAsChild(0);
-}
-
 bool WebContentsAdapter::canGoBack() const
 {
     Q_D(const WebContentsAdapter);
diff --git a/src/core/web_contents_adapter.h b/src/core/web_contents_adapter.h
index 0e8eb1b21..de537541d 100644
--- a/src/core/web_contents_adapter.h
+++ b/src/core/web_contents_adapter.h
@@ -60,7 +60,6 @@ public:
     WebContentsAdapter(WebContentsAdapterClient::RenderingMode renderingMode, content::WebContents *webContents = 0);
     ~WebContentsAdapter();
     void initialize(WebContentsAdapterClient *adapterClient);
-    void reattachRWHV();
 
     bool canGoBack() const;
     bool canGoForward() const;
diff --git a/src/core/web_contents_adapter_client.h b/src/core/web_contents_adapter_client.h
index 5a11fc8d8..b07521734 100644
--- a/src/core/web_contents_adapter_client.h
+++ b/src/core/web_contents_adapter_client.h
@@ -115,6 +115,7 @@ public:
     virtual ~WebContentsAdapterClient() { }
 
     virtual RenderWidgetHostViewQtDelegate* CreateRenderWidgetHostViewQtDelegate(RenderWidgetHostViewQtDelegateClient *client, RenderingMode mode) = 0;
+    virtual RenderWidgetHostViewQtDelegate* CreateRenderWidgetHostViewQtDelegateForPopup(RenderWidgetHostViewQtDelegateClient *client, RenderingMode mode) = 0;
     virtual void titleChanged(const QString&) = 0;
     virtual void urlChanged(const QUrl&) = 0;
     virtual void iconChanged(const QUrl&) = 0;
diff --git a/src/core/web_contents_view_qt.cpp b/src/core/web_contents_view_qt.cpp
index a4cb3556e..8fdcf4679 100644
--- a/src/core/web_contents_view_qt.cpp
+++ b/src/core/web_contents_view_qt.cpp
@@ -61,8 +61,12 @@ void WebContentsViewQt::initialize(WebContentsAdapterClient* client)
 
 content::RenderWidgetHostView* WebContentsViewQt::CreateViewForWidget(content::RenderWidgetHost* render_widget_host)
 {
-    content::RenderWidgetHostView* view = CreateViewForPopupWidget(render_widget_host);
+    RenderWidgetHostViewQt *view = new RenderWidgetHostViewQt(render_widget_host);
 
+    Q_ASSERT(m_factoryClient);
+    view->setDelegate(m_factoryClient->CreateRenderWidgetHostViewQtDelegate(view, WebEngineContext::current()->renderingMode()));
+    if (m_client)
+        view->setAdapterClient(m_client);
     // Tell the RWHV delegate to attach itself to the native view container.
     view->InitAsChild(0);
 
@@ -72,12 +76,8 @@ content::RenderWidgetHostView* WebContentsViewQt::CreateViewForWidget(content::R
 content::RenderWidgetHostView* WebContentsViewQt::CreateViewForPopupWidget(content::RenderWidgetHost* render_widget_host)
 {
     RenderWidgetHostViewQt *view = new RenderWidgetHostViewQt(render_widget_host);
-
-    Q_ASSERT(m_factoryClient);
-    view->setDelegate(m_factoryClient->CreateRenderWidgetHostViewQtDelegate(view, WebEngineContext::current()->renderingMode()));
-    if (m_client)
-        view->setAdapterClient(m_client);
-
+    Q_ASSERT(m_client);
+    view->setDelegate(m_client->CreateRenderWidgetHostViewQtDelegateForPopup(view, WebEngineContext::current()->renderingMode()));
     return view;
 }
 
diff --git a/src/webengine/api/qquickwebengineview_p_p.h b/src/webengine/api/qquickwebengineview_p_p.h
index f61e439d0..c7fecd477 100644
--- a/src/webengine/api/qquickwebengineview_p_p.h
+++ b/src/webengine/api/qquickwebengineview_p_p.h
@@ -132,6 +132,7 @@ public:
     UIDelegatesManager *ui();
 
     virtual RenderWidgetHostViewQtDelegate* CreateRenderWidgetHostViewQtDelegate(RenderWidgetHostViewQtDelegateClient *client, RenderingMode) Q_DECL_OVERRIDE;
+    virtual RenderWidgetHostViewQtDelegate* CreateRenderWidgetHostViewQtDelegateForPopup(RenderWidgetHostViewQtDelegateClient *client, RenderingMode mode) Q_DECL_OVERRIDE {  return CreateRenderWidgetHostViewQtDelegate(client, mode);   }
     virtual void titleChanged(const QString&) Q_DECL_OVERRIDE;
     virtual void urlChanged(const QUrl&) Q_DECL_OVERRIDE;
     virtual void iconChanged(const QUrl&) Q_DECL_OVERRIDE;
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 8f32689d0..9edcb1819 100644
--- a/src/webengine/render_widget_host_view_qt_delegate_quick.h
+++ b/src/webengine/render_widget_host_view_qt_delegate_quick.h
@@ -135,6 +135,8 @@ public:
         return false;
     }
 
+    virtual void move(const QPoint&) Q_DECL_OVERRIDE {}
+
     void focusInEvent(QFocusEvent *event)
     {
         m_client->forwardEvent(event);
diff --git a/src/webenginewidgets/api/qwebenginepage.cpp b/src/webenginewidgets/api/qwebenginepage.cpp
index ec64b8df5..e95433747 100644
--- a/src/webenginewidgets/api/qwebenginepage.cpp
+++ b/src/webenginewidgets/api/qwebenginepage.cpp
@@ -28,7 +28,8 @@
 #include "qwebenginehistory_p.h"
 #include "qwebengineview.h"
 #include "qwebengineview_p.h"
-#include "render_widget_host_view_qt_delegate_widget.h"
+#include "render_widget_host_view_qt_delegate_popup.h"
+#include "render_widget_host_view_qt_delegate_webpage.h"
 #include "web_contents_adapter.h"
 
 #include <QAction>
@@ -37,7 +38,6 @@
 #include <QFileDialog>
 #include <QIcon>
 #include <QInputDialog>
-#include <QLayout>
 #include <QMenu>
 #include <QMessageBox>
 #include <QStandardPaths>
@@ -52,7 +52,6 @@ QWebEnginePagePrivate::QWebEnginePagePrivate()
     , view(0)
     , m_isLoading(false)
 {
-    adapter->initialize(this);
     memset(actions, 0, sizeof(actions));
 }
 
@@ -73,7 +72,13 @@ QWebEnginePagePrivate::~QWebEnginePagePrivate()
 RenderWidgetHostViewQtDelegate *QWebEnginePagePrivate::CreateRenderWidgetHostViewQtDelegate(RenderWidgetHostViewQtDelegateClient *client, RenderingMode mode)
 {
     Q_UNUSED(mode);
-    return new RenderWidgetHostViewQtDelegateWidget(client);
+    return new RenderWidgetHostViewQtDelegateWebPage(client);
+}
+
+RenderWidgetHostViewQtDelegate *QWebEnginePagePrivate::CreateRenderWidgetHostViewQtDelegateForPopup(RenderWidgetHostViewQtDelegateClient *client, WebContentsAdapterClient::RenderingMode)
+{
+    Q_ASSERT(m_rwhvDelegate);
+    return new RenderWidgetHostViewQtDelegatePopup(client, view);
 }
 
 void QWebEnginePagePrivate::titleChanged(const QString &title)
@@ -230,6 +235,8 @@ void QWebEnginePagePrivate::_q_webActionTriggered(bool checked)
 QWebEnginePage::QWebEnginePage(QObject* parent)
     : QObject(*new QWebEnginePagePrivate, parent)
 {
+    Q_D(QWebEnginePage);
+    d->adapter->initialize(d);
 }
 
 QWebEnginePage::~QWebEnginePage()
@@ -323,6 +330,28 @@ void QWebEnginePage::triggerAction(WebAction action, bool)
     }
 }
 
+void QWebEnginePage::setViewportSize(const QSize &size) const
+{
+    Q_UNUSED(size)
+    Q_D(const QWebEnginePage);
+    if (d->m_rwhvDelegate)
+        d->m_rwhvDelegate->notifyResize();
+}
+
+bool QWebEnginePage::event(QEvent *e)
+{
+    Q_D(QWebEnginePage);
+    if (!d->m_rwhvDelegate) {
+        // FIXME: implement a signal when the render process crashes and keep track of it at this level
+        // Ideally, this should be Q_ASSERT(!d->m_renderProcessLive) or something along those lines
+        qWarning("%s: no render process running?\n", Q_FUNC_INFO);
+        return false;
+    }
+    if (!d->m_rwhvDelegate->forwardEvent(e))
+        return QObject::event(e);
+    return true;
+}
+
 bool QWebEnginePagePrivate::contextMenuRequested(const WebEngineContextMenuData &data)
 {
     if (!view)
@@ -519,6 +548,22 @@ QUrl QWebEnginePage::url() const
     return d->adapter->activeUrl();
 }
 
+void QWebEnginePage::render(QPainter *p, const QRegion &clip)
+{
+    Q_D(const QWebEnginePage);
+    if (!d->m_rwhvDelegate) {
+        // Most likely the render process crashed. See QWebEnginePage::event
+        return;
+    }
+    if (!clip.isNull()) {
+        p->save();
+        p->setClipRegion(clip);
+    }
+    d->m_rwhvDelegate->paint(p, QRectF(clip.boundingRect()));
+    if (!clip.isNull())
+        p->restore();
+}
+
 qreal QWebEnginePage::zoomFactor() const
 {
     Q_D(const QWebEnginePage);
@@ -531,6 +576,21 @@ void QWebEnginePage::setZoomFactor(qreal factor)
     d->adapter->setZoomFactor(factor);
 }
 
+bool QWebEnginePage::hasFocus() const
+{
+    Q_D(const QWebEnginePage);
+    if (d->view)
+        return d->view->hasFocus();
+    return false;
+}
+
+void QWebEnginePage::setFocus()
+{
+    Q_D(QWebEnginePage);
+    if (d->view)
+        d->view->setFocus();
+}
+
 void QWebEnginePage::runJavaScript(const QString &scriptSource, const QString &xPath)
 {
     Q_D(QWebEnginePage);
diff --git a/src/webenginewidgets/api/qwebenginepage.h b/src/webenginewidgets/api/qwebenginepage.h
index c50111199..f8b40f507 100644
--- a/src/webenginewidgets/api/qwebenginepage.h
+++ b/src/webenginewidgets/api/qwebenginepage.h
@@ -364,6 +364,7 @@ public:
     void setPreferredContentsSize(const QSize &size) const;
     void setActualVisibleContentRect(const QRect& rect) const;
 
+    virtual bool event(QEvent*);
     bool focusNextPrevChild(bool next);
 
     QVariant inputMethodQuery(Qt::InputMethodQuery property) const;
diff --git a/src/webenginewidgets/api/qwebenginepage_p.h b/src/webenginewidgets/api/qwebenginepage_p.h
index 0fa4299d8..b905cee6d 100644
--- a/src/webenginewidgets/api/qwebenginepage_p.h
+++ b/src/webenginewidgets/api/qwebenginepage_p.h
@@ -45,6 +45,7 @@
 #include "qwebenginepage.h"
 
 #include "web_contents_adapter_client.h"
+#include "render_widget_host_view_qt_delegate_webpage.h"
 #include <QtCore/private/qobject_p.h>
 #include <QtCore/qcompilerdetection.h>
 #include <QSharedData>
@@ -66,6 +67,7 @@ public:
     ~QWebEnginePagePrivate();
 
     virtual RenderWidgetHostViewQtDelegate* CreateRenderWidgetHostViewQtDelegate(RenderWidgetHostViewQtDelegateClient *client, RenderingMode mode) Q_DECL_OVERRIDE;
+    virtual RenderWidgetHostViewQtDelegate* CreateRenderWidgetHostViewQtDelegateForPopup(RenderWidgetHostViewQtDelegateClient *client, RenderingMode) Q_DECL_OVERRIDE;
     virtual void titleChanged(const QString&) Q_DECL_OVERRIDE;
     virtual void urlChanged(const QUrl&) Q_DECL_OVERRIDE;
     virtual void iconChanged(const QUrl&) Q_DECL_OVERRIDE;
@@ -99,6 +101,7 @@ public:
     mutable QAction *actions[QWebEnginePage::WebActionCount];
     bool m_isLoading;
     WebEngineContextMenuData m_menuData;
+    QPointer<RenderWidgetHostViewQtDelegateWebPage> m_rwhvDelegate;
 
     typedef QtWebEnginePrivate::QWebEngineCallbackPrivateBase<const QVariant&> VariantCallback;
     typedef QtWebEnginePrivate::QWebEngineCallbackPrivateBase<const QString&> StringCallback;
diff --git a/src/webenginewidgets/api/qwebengineview.cpp b/src/webenginewidgets/api/qwebengineview.cpp
index fc72d1241..eee68d65d 100644
--- a/src/webenginewidgets/api/qwebengineview.cpp
+++ b/src/webenginewidgets/api/qwebengineview.cpp
@@ -48,7 +48,6 @@
 #include <QAction>
 #include <QMenu>
 #include <QContextMenuEvent>
-#include <QStackedLayout>
 
 QT_BEGIN_NAMESPACE
 
@@ -64,7 +63,6 @@ void QWebEngineViewPrivate::bind(QWebEngineView *view, QWebEnginePage *page)
             oldView->d_func()->page = 0;
         }
         page->d_func()->view = view;
-        page->d_func()->adapter->reattachRWHV();
     }
 
     if (view) {
@@ -94,8 +92,10 @@ QWebEngineViewPrivate::QWebEngineViewPrivate()
 QWebEngineView::QWebEngineView(QWidget *parent)
     : QWidget(*(new QWebEngineViewPrivate), parent, 0)
 {
-    // This causes the child RenderWidgetHostViewQtDelegateWidgets to fill this widget.
-    setLayout(new QStackedLayout);
+    setFocusPolicy(Qt::ClickFocus);
+    setMouseTracking(true);
+    setAttribute(Qt::WA_AcceptTouchEvents);
+    setAttribute(Qt::WA_OpaquePaintEvent);
 }
 
 QWebEngineView::~QWebEngineView()
@@ -205,15 +205,38 @@ void QWebEngineView::setZoomFactor(qreal factor)
 
 bool QWebEngineView::event(QEvent *ev)
 {
+    Q_D(QWebEngineView);
     // We swallow spontaneous contextMenu events and synthethize those back later on when we get the
     // HandleContextMenu callback from chromium
     if (ev->type() == QEvent::ContextMenu) {
         ev->accept();
         return true;
-    }
+    } else if (ev->type() == QEvent::MetaCall)
+        // Meta calls are not safe to forward to the page, as they could be widget specific (e.g. QWidgetPrivate::_q_showIfNotHidden)
+        return QWidget::event(ev);
+    if (d->page && d->page->event(ev))
+            return true;
+
     return QWidget::event(ev);
 }
 
+void QWebEngineView::paintEvent(QPaintEvent *ev)
+{
+    Q_D(QWebEngineView);
+    if (!d->page)
+        return;
+    QPainter painter(this);
+    d->page->render(&painter, QRegion(ev->rect()));
+}
+
+void QWebEngineView::resizeEvent(QResizeEvent *ev)
+{
+    Q_D(QWebEngineView);
+    if (!d->page)
+        return;
+    d->page->setViewportSize(ev->size());
+}
+
 void QWebEngineView::contextMenuEvent(QContextMenuEvent *event)
 {
     QMenu *menu = page()->createStandardContextMenu();
diff --git a/src/webenginewidgets/api/qwebengineview.h b/src/webenginewidgets/api/qwebengineview.h
index 2c649d46f..46b144d14 100644
--- a/src/webenginewidgets/api/qwebengineview.h
+++ b/src/webenginewidgets/api/qwebengineview.h
@@ -132,6 +132,8 @@ protected:
     virtual QWebEngineView *createWindow(QWebEnginePage::WebWindowType type);
     virtual void contextMenuEvent(QContextMenuEvent*) Q_DECL_OVERRIDE;
     virtual bool event(QEvent*) Q_DECL_OVERRIDE;
+    virtual void paintEvent(QPaintEvent *) Q_DECL_OVERRIDE;
+    virtual void resizeEvent(QResizeEvent *) Q_DECL_OVERRIDE;
 
 private:
     Q_DECLARE_PRIVATE(QWebEngineView);
diff --git a/src/webenginewidgets/render_widget_host_view_qt_delegate_widget.cpp b/src/webenginewidgets/render_widget_host_view_qt_delegate_popup.cpp
similarity index 54%
rename from src/webenginewidgets/render_widget_host_view_qt_delegate_widget.cpp
rename to src/webenginewidgets/render_widget_host_view_qt_delegate_popup.cpp
index d0bc44a5b..7900ed9b5 100644
--- a/src/webenginewidgets/render_widget_host_view_qt_delegate_widget.cpp
+++ b/src/webenginewidgets/render_widget_host_view_qt_delegate_popup.cpp
@@ -39,7 +39,7 @@
 **
 ****************************************************************************/
 
-#include "render_widget_host_view_qt_delegate_widget.h"
+#include "render_widget_host_view_qt_delegate_popup.h"
 
 #include "qwebengineview.h"
 #include "qwebenginepage_p.h"
@@ -51,121 +51,106 @@
 #include <QWindow>
 #include <QtWidgets/QApplication>
 
-RenderWidgetHostViewQtDelegateWidget::RenderWidgetHostViewQtDelegateWidget(RenderWidgetHostViewQtDelegateClient *client, QWidget *parent)
-    : QWidget(parent)
-    , m_client(client)
+RenderWidgetHostViewQtDelegatePopup::RenderWidgetHostViewQtDelegatePopup(RenderWidgetHostViewQtDelegateClient *client, QWidget *parent)
+    : m_client(client)
+    , m_parentView(parent)
 {
-    setFocusPolicy(Qt::ClickFocus);
     setMouseTracking(true);
     setAttribute(Qt::WA_AcceptTouchEvents);
-    setAttribute(Qt::WA_OpaquePaintEvent);
+    // The keyboard events are supposed to go to the parent RenderHostView
+    // so the WebUI popups should never have focus. Besides, if the parent view
+    // loses focus, WebKit will cause its associated popups (including this one)
+    // to be destroyed.
+    setAttribute(Qt::WA_ShowWithoutActivating);
+    setFocusPolicy(Qt::NoFocus);
+    setWindowFlags(Qt::ToolTip | Qt::FramelessWindowHint | Qt::WindowDoesNotAcceptFocus);
 }
 
-void RenderWidgetHostViewQtDelegateWidget::initAsChild(WebContentsAdapterClient* container)
+void RenderWidgetHostViewQtDelegatePopup::initAsChild(WebContentsAdapterClient*)
 {
-    QWebEnginePagePrivate *pagePrivate = static_cast<QWebEnginePagePrivate *>(container);
-    if (pagePrivate->view) {
-        pagePrivate->view->layout()->addWidget(this);
-        QWidget::show();
-    } else
-        setParent(0);
+    Q_UNREACHABLE();
 }
 
-void RenderWidgetHostViewQtDelegateWidget::initAsPopup(const QRect& rect)
+void RenderWidgetHostViewQtDelegatePopup::initAsPopup(const QRect& rect)
 {
-    QPoint pos = QWidget::mapToGlobal(rect.topLeft());
+    QPoint pos = m_parentView ? m_parentView->mapToGlobal(rect.topLeft()) : QPoint(0,0);
     QRect qrect = QRect(pos, rect.size());
     setGeometry(qrect);
+    raise();
     show();
 }
 
-QRectF RenderWidgetHostViewQtDelegateWidget::screenRect() const
+QRectF RenderWidgetHostViewQtDelegatePopup::screenRect() const
 {
     return QRectF(x(), y(), width(), height());
 }
 
-void RenderWidgetHostViewQtDelegateWidget::setKeyboardFocus()
+void RenderWidgetHostViewQtDelegatePopup::setKeyboardFocus()
 {
-    setFocus();
+    Q_UNREACHABLE();
 }
 
-bool RenderWidgetHostViewQtDelegateWidget::hasKeyboardFocus()
+bool RenderWidgetHostViewQtDelegatePopup::hasKeyboardFocus()
 {
-    return hasFocus();
+    return false;
 }
 
-void RenderWidgetHostViewQtDelegateWidget::show()
+void RenderWidgetHostViewQtDelegatePopup::show()
 {
-    // Check if we're attached to a QWebEngineView, we don't want to show as top-level.
-    if (parent())
-        QWidget::show();
+    QWidget::show();
 }
 
-void RenderWidgetHostViewQtDelegateWidget::hide()
+void RenderWidgetHostViewQtDelegatePopup::hide()
 {
     QWidget::hide();
 }
 
-bool RenderWidgetHostViewQtDelegateWidget::isVisible() const
+bool RenderWidgetHostViewQtDelegatePopup::isVisible() const
 {
     return QWidget::isVisible();
 }
 
-QWindow* RenderWidgetHostViewQtDelegateWidget::window() const
+QWindow* RenderWidgetHostViewQtDelegatePopup::window() const
 {
     const QWidget* root = QWidget::window();
-    return root ? root->windowHandle() : 0;
+    return root ? root->windowHandle() : Q_NULLPTR;
 }
 
-void RenderWidgetHostViewQtDelegateWidget::update(const QRect& rect)
+void RenderWidgetHostViewQtDelegatePopup::update(const QRect& rect)
 {
     QWidget::update(rect);
 }
 
-void RenderWidgetHostViewQtDelegateWidget::updateCursor(const QCursor &cursor)
+void RenderWidgetHostViewQtDelegatePopup::updateCursor(const QCursor &cursor)
 {
     QWidget::setCursor(cursor);
 }
 
-void RenderWidgetHostViewQtDelegateWidget::resize(int width, int height)
+void RenderWidgetHostViewQtDelegatePopup::resize(int width, int height)
 {
     QWidget::resize(width, height);
 }
 
-void RenderWidgetHostViewQtDelegateWidget::inputMethodStateChanged(bool editorVisible)
-{
-    if (qApp->inputMethod()->isVisible() == editorVisible)
-        return;
-
-    QWidget::setAttribute(Qt::WA_InputMethodEnabled, editorVisible);
-    qApp->inputMethod()->update(Qt::ImQueryInput | Qt::ImEnabled | Qt::ImHints);
-    qApp->inputMethod()->setVisible(editorVisible);
-}
-
-QVariant RenderWidgetHostViewQtDelegateWidget::inputMethodQuery(Qt::InputMethodQuery query) const
+void RenderWidgetHostViewQtDelegatePopup::move(const QPoint &pos)
 {
-    return m_client->inputMethodQuery(query);
-}
-
-bool RenderWidgetHostViewQtDelegateWidget::supportsHardwareAcceleration() const
-{
-    return false;
+    QPoint mapped = m_parentView ? m_parentView->mapToGlobal(pos) : pos;
+    QWidget::move(mapped);
 }
 
-void RenderWidgetHostViewQtDelegateWidget::paintEvent(QPaintEvent * event)
+void RenderWidgetHostViewQtDelegatePopup::paintEvent(QPaintEvent *event)
 {
     QPainter painter(this);
     m_client->fetchBackingStore();
     m_client->paint(&painter, event->rect());
 }
 
-void RenderWidgetHostViewQtDelegateWidget::resizeEvent(QResizeEvent *resizeEvent)
+void RenderWidgetHostViewQtDelegatePopup::resizeEvent(QResizeEvent *resizeEvent)
 {
     Q_UNUSED(resizeEvent);
     m_client->notifyResize();
 }
 
-bool RenderWidgetHostViewQtDelegateWidget::event(QEvent *event)
+bool RenderWidgetHostViewQtDelegatePopup::event(QEvent *event)
 {
     if (!m_client->forwardEvent(event))
         return QWidget::event(event);
diff --git a/src/webenginewidgets/render_widget_host_view_qt_delegate_widget.h b/src/webenginewidgets/render_widget_host_view_qt_delegate_popup.h
similarity index 86%
rename from src/webenginewidgets/render_widget_host_view_qt_delegate_widget.h
rename to src/webenginewidgets/render_widget_host_view_qt_delegate_popup.h
index 5102fe0e7..330afc25e 100644
--- a/src/webenginewidgets/render_widget_host_view_qt_delegate_widget.h
+++ b/src/webenginewidgets/render_widget_host_view_qt_delegate_popup.h
@@ -39,12 +39,13 @@
 **
 ****************************************************************************/
 
-#ifndef RENDER_WIDGET_HOST_VIEW_QT_DELEGATE_WIDGET_H
-#define RENDER_WIDGET_HOST_VIEW_QT_DELEGATE_WIDGET_H
+#ifndef RENDER_WIDGET_HOST_VIEW_QT_DELEGATE_POPUP_H
+#define RENDER_WIDGET_HOST_VIEW_QT_DELEGATE_POPUP_H
 
 #include "render_widget_host_view_qt_delegate.h"
 #include "web_contents_adapter_client.h"
 
+#include <QBasicTimer>
 #include <QWidget>
 
 class BackingStoreQt;
@@ -53,10 +54,10 @@ QT_BEGIN_NAMESPACE
 class QWindow;
 QT_END_NAMESPACE
 
-class RenderWidgetHostViewQtDelegateWidget : public QWidget, public RenderWidgetHostViewQtDelegate
+class RenderWidgetHostViewQtDelegatePopup : public QWidget, public RenderWidgetHostViewQtDelegate
 {
 public:
-    RenderWidgetHostViewQtDelegateWidget(RenderWidgetHostViewQtDelegateClient *client, QWidget *parent = 0);
+    RenderWidgetHostViewQtDelegatePopup(RenderWidgetHostViewQtDelegateClient *client, QWidget *);
 
     virtual void initAsChild(WebContentsAdapterClient* container) Q_DECL_OVERRIDE;
     virtual void initAsPopup(const QRect&) Q_DECL_OVERRIDE;
@@ -70,18 +71,18 @@ public:
     virtual void update(const QRect& rect = QRect()) Q_DECL_OVERRIDE;
     virtual void updateCursor(const QCursor &) Q_DECL_OVERRIDE;
     virtual void resize(int width, int height) Q_DECL_OVERRIDE;
-    virtual void inputMethodStateChanged(bool editorVisible) Q_DECL_OVERRIDE;
-    virtual bool supportsHardwareAcceleration() const Q_DECL_OVERRIDE;
+    virtual void move(const QPoint &) Q_DECL_OVERRIDE;
+    virtual void inputMethodStateChanged(bool) Q_DECL_OVERRIDE {}
+    virtual bool supportsHardwareAcceleration() const Q_DECL_OVERRIDE { return false; }
 
 protected:
     void paintEvent(QPaintEvent * event);
     bool event(QEvent *event);
     void resizeEvent(QResizeEvent *resizeEvent);
 
-    QVariant inputMethodQuery(Qt::InputMethodQuery query) const;
-
 private:
     RenderWidgetHostViewQtDelegateClient *m_client;
+    QWidget *m_parentView;
 };
 
 #endif
diff --git a/src/webenginewidgets/render_widget_host_view_qt_delegate_webpage.cpp b/src/webenginewidgets/render_widget_host_view_qt_delegate_webpage.cpp
new file mode 100644
index 000000000..2da55f66e
--- /dev/null
+++ b/src/webenginewidgets/render_widget_host_view_qt_delegate_webpage.cpp
@@ -0,0 +1,155 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia.  For licensing terms and
+** conditions see http://qt.digia.com/licensing.  For further information
+** use the contact form at http://qt.digia.com/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 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file.  Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights.  These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.  Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "render_widget_host_view_qt_delegate_webpage.h"
+
+#include "qwebengineview.h"
+#include "qwebenginepage.h"
+#include "qwebenginepage_p.h"
+#include <QtGlobal>
+#include <QResizeEvent>
+#include <QPainter>
+#include <QPaintEvent>
+#include <QWindow>
+#include <QtWidgets/QApplication>
+
+RenderWidgetHostViewQtDelegateWebPage::RenderWidgetHostViewQtDelegateWebPage(RenderWidgetHostViewQtDelegateClient *client)
+    : m_client(client)
+    , m_page(0)
+{
+}
+
+void RenderWidgetHostViewQtDelegateWebPage::initAsChild(WebContentsAdapterClient* container)
+{
+    QWebEnginePagePrivate *pagePrivate = static_cast<QWebEnginePagePrivate *>(container);
+    pagePrivate->m_rwhvDelegate = this;
+    m_page = pagePrivate->q_func();
+    Q_ASSERT(m_page);
+}
+
+QRectF RenderWidgetHostViewQtDelegateWebPage::screenRect() const
+{
+    if (m_page && m_page->view())
+        return m_page->view()->rect();
+    // FIXME: figure out what to do with QWebFrame::contentsSize vs. preferedContentsSize
+    return QRectF(0, 0, 800, 600);
+}
+
+void RenderWidgetHostViewQtDelegateWebPage::setKeyboardFocus()
+{
+    if (m_page)
+        m_page->setFocus();
+}
+
+bool RenderWidgetHostViewQtDelegateWebPage::hasKeyboardFocus()
+{
+    return m_page && m_page->hasFocus();
+}
+
+bool RenderWidgetHostViewQtDelegateWebPage::isVisible() const
+{
+    if (m_page && m_page->view())
+        return m_page->view()->isVisible();
+    return false;
+}
+
+QWindow* RenderWidgetHostViewQtDelegateWebPage::window() const
+{
+    if (!m_page || !m_page->view())
+        return Q_NULLPTR;
+    return m_page->view()->window()->windowHandle();
+}
+
+void RenderWidgetHostViewQtDelegateWebPage::update(const QRect& rect)
+{
+    if (m_page->view())
+        m_page->view()->update(rect);
+}
+
+void RenderWidgetHostViewQtDelegateWebPage::updateCursor(const QCursor &cursor)
+{
+    if (m_page->view())
+        m_page->view()->setCursor(cursor);
+}
+
+void RenderWidgetHostViewQtDelegateWebPage::resize(int width, int height)
+{
+    Q_UNUSED(width)
+    Q_UNUSED(height)
+    QT_NOT_YET_IMPLEMENTED;
+}
+
+void RenderWidgetHostViewQtDelegateWebPage::inputMethodStateChanged(bool editorVisible)
+{
+    if (qApp->inputMethod()->isVisible() == editorVisible)
+        return;
+
+    if (m_page && m_page->view())
+        m_page->view()->setAttribute(Qt::WA_InputMethodEnabled, editorVisible);
+    qApp->inputMethod()->update(Qt::ImQueryInput | Qt::ImEnabled | Qt::ImHints);
+    qApp->inputMethod()->setVisible(editorVisible);
+}
+
+QVariant RenderWidgetHostViewQtDelegateWebPage::inputMethodQuery(Qt::InputMethodQuery query) const
+{
+    return m_client->inputMethodQuery(query);
+}
+
+bool RenderWidgetHostViewQtDelegateWebPage::supportsHardwareAcceleration() const
+{
+    return false;
+}
+
+void RenderWidgetHostViewQtDelegateWebPage::paint(QPainter *painter, const QRectF &boundingRect)
+{
+    m_client->fetchBackingStore();
+    m_client->paint(painter, boundingRect);
+}
+
+void RenderWidgetHostViewQtDelegateWebPage::notifyResize()
+{
+    m_client->notifyResize();
+}
+
+bool RenderWidgetHostViewQtDelegateWebPage::forwardEvent(QEvent *event)
+{
+    return m_client->forwardEvent(event);
+}
diff --git a/src/webenginewidgets/render_widget_host_view_qt_delegate_webpage.h b/src/webenginewidgets/render_widget_host_view_qt_delegate_webpage.h
new file mode 100644
index 000000000..5674e61c1
--- /dev/null
+++ b/src/webenginewidgets/render_widget_host_view_qt_delegate_webpage.h
@@ -0,0 +1,91 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** 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 Digia.  For licensing terms and
+** conditions see http://qt.digia.com/licensing.  For further information
+** use the contact form at http://qt.digia.com/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 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file.  Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights.  These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file.  Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef RENDER_WIDGET_HOST_VIEW_QT_DELEGATE_WEBPAGE_H
+#define RENDER_WIDGET_HOST_VIEW_QT_DELEGATE_WEBPAGE_H
+
+#include "render_widget_host_view_qt_delegate.h"
+#include "web_contents_adapter_client.h"
+
+#include <QObject>
+
+class BackingStoreQt;
+
+QT_BEGIN_NAMESPACE
+class QWindow;
+class QWebEnginePage;
+QT_END_NAMESPACE
+
+class RenderWidgetHostViewQtDelegateWebPage : public QObject, public RenderWidgetHostViewQtDelegate
+{
+public:
+    RenderWidgetHostViewQtDelegateWebPage(RenderWidgetHostViewQtDelegateClient *client);
+
+    virtual void initAsChild(WebContentsAdapterClient* container) Q_DECL_OVERRIDE;
+    virtual void initAsPopup(const QRect&) Q_DECL_OVERRIDE { Q_UNREACHABLE(); }
+    virtual QRectF screenRect() const Q_DECL_OVERRIDE;
+    virtual void setKeyboardFocus() Q_DECL_OVERRIDE;
+    virtual bool hasKeyboardFocus() Q_DECL_OVERRIDE;
+    virtual void show() Q_DECL_OVERRIDE {}
+    virtual void hide() Q_DECL_OVERRIDE {}
+    virtual bool isVisible() const Q_DECL_OVERRIDE;
+    virtual QWindow* window() const Q_DECL_OVERRIDE;
+    virtual void update(const QRect& rect = QRect()) Q_DECL_OVERRIDE;
+    virtual void updateCursor(const QCursor &) Q_DECL_OVERRIDE;
+    virtual void resize(int width, int height) Q_DECL_OVERRIDE;
+    virtual void move(const QPoint&) Q_DECL_OVERRIDE {}
+    virtual void inputMethodStateChanged(bool editorVisible) Q_DECL_OVERRIDE;
+    virtual bool supportsHardwareAcceleration() const Q_DECL_OVERRIDE;
+
+    void paint(QPainter *painter, const QRectF &boundingRect);
+    void notifyResize();
+    bool forwardEvent(QEvent *event);
+
+protected:
+
+    QVariant inputMethodQuery(Qt::InputMethodQuery query) const;
+
+private:
+    RenderWidgetHostViewQtDelegateClient *m_client;
+    QWebEnginePage *m_page;
+};
+
+#endif
diff --git a/src/webenginewidgets/webenginewidgets.pro b/src/webenginewidgets/webenginewidgets.pro
index a683998af..61aa621a7 100644
--- a/src/webenginewidgets/webenginewidgets.pro
+++ b/src/webenginewidgets/webenginewidgets.pro
@@ -26,7 +26,8 @@ SOURCES = \
         api/qwebenginehistory.cpp \
         api/qwebenginepage.cpp \
         api/qwebengineview.cpp\
-        render_widget_host_view_qt_delegate_widget.cpp
+        render_widget_host_view_qt_delegate_popup.cpp \
+        render_widget_host_view_qt_delegate_webpage.cpp
 
 HEADERS = \
         api/qtwebenginewidgetsglobal.h \
@@ -34,7 +35,8 @@ HEADERS = \
         api/qwebenginepage.h \
         api/qwebengineview.h \
         api/qwebengineview_p.h \
-        render_widget_host_view_qt_delegate_widget.h
+        render_widget_host_view_qt_delegate_popup.h \
+        render_widget_host_view_qt_delegate_webpage.h
 
 load(qt_module)
 
-- 
GitLab