diff options
author | Pierre Rossi <pierre.rossi@digia.com> | 2014-01-30 18:26:21 +0100 |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2014-02-12 13:15:24 +0100 |
commit | 9c198939be1ef064d1a2430a4b9991f2fe16f359 (patch) | |
tree | 1b081d0379c82c8cc34a0d80aa2846e36f37951e /src/webenginewidgets/api | |
parent | f2cd2e0a32e8da3a0fbff6271dd9c257d8e8867f (diff) |
[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>
Diffstat (limited to 'src/webenginewidgets/api')
-rw-r--r-- | src/webenginewidgets/api/qwebenginepage.cpp | 68 | ||||
-rw-r--r-- | src/webenginewidgets/api/qwebenginepage.h | 1 | ||||
-rw-r--r-- | src/webenginewidgets/api/qwebenginepage_p.h | 3 | ||||
-rw-r--r-- | src/webenginewidgets/api/qwebengineview.cpp | 33 | ||||
-rw-r--r-- | src/webenginewidgets/api/qwebengineview.h | 2 |
5 files changed, 98 insertions, 9 deletions
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); |