diff options
author | Jocelyn Turcotte <jocelyn.turcotte@digia.com> | 2013-06-17 18:58:06 +0200 |
---|---|---|
committer | Jocelyn Turcotte <jocelyn.turcotte@digia.com> | 2013-06-19 12:19:11 +0200 |
commit | bbeaf3278de08da00f56aba3511951aaf6a8d233 (patch) | |
tree | f59de9808a942a2668f2bb73d0b03a1bebcd4b0f /lib | |
parent | 2d2da7d717d6bd354f5febe3deb8615685ca3280 (diff) |
Allow the API class to provide the page widget rendering implementation.
- Rename NativeViewQt to RenderWidgetHostViewQtDelegate to keep the
context obvious.
- Use an interface to handle the parenting instead of the
NativeViewContainerQt mechanism that was needed with the Shell.
Diffstat (limited to 'lib')
-rw-r--r-- | lib/lib.pro | 4 | ||||
-rw-r--r-- | lib/qquickwebcontentsview.cpp | 39 | ||||
-rw-r--r-- | lib/qquickwebcontentsview.h | 3 | ||||
-rw-r--r-- | lib/qwebcontentsview.cpp | 21 | ||||
-rw-r--r-- | lib/qwebcontentsview_p.h | 4 | ||||
-rw-r--r-- | lib/render_widget_host_view_qt_delegate_quick.cpp | 125 | ||||
-rw-r--r-- | lib/render_widget_host_view_qt_delegate_quick.h | 59 | ||||
-rw-r--r-- | lib/render_widget_host_view_qt_delegate_widget.cpp | 84 | ||||
-rw-r--r-- | lib/render_widget_host_view_qt_delegate_widget.h | 41 | ||||
-rw-r--r-- | lib/web_contents_view_qt.h | 22 |
10 files changed, 377 insertions, 25 deletions
diff --git a/lib/lib.pro b/lib/lib.pro index 54a35b226..e4f75a65c 100644 --- a/lib/lib.pro +++ b/lib/lib.pro @@ -23,6 +23,8 @@ SOURCES = \ content_browser_client_qt.cpp \ qquickwebcontentsview.cpp \ qwebcontentsview.cpp \ + render_widget_host_view_qt_delegate_quick.cpp \ + render_widget_host_view_qt_delegate_widget.cpp \ resource_context_qt.cpp \ url_request_context_getter_qt.cpp \ web_contents_delegate_qt.cpp \ @@ -34,6 +36,8 @@ HEADERS = \ qquickwebcontentsview.h \ qwebcontentsview.h \ qwebcontentsview_p.h \ + render_widget_host_view_qt_delegate_quick.h \ + render_widget_host_view_qt_delegate_widget.h \ resource_context_qt.h \ url_request_context_getter_qt.h \ web_contents_delegate_qt.h \ diff --git a/lib/qquickwebcontentsview.cpp b/lib/qquickwebcontentsview.cpp index e540b0d32..ee68301b0 100644 --- a/lib/qquickwebcontentsview.cpp +++ b/lib/qquickwebcontentsview.cpp @@ -46,12 +46,12 @@ #include "browser_context_qt.h" #include "content_browser_client_qt.h" +#include "render_widget_host_view_qt_delegate_quick.h" #include "web_contents_delegate_qt.h" #include "web_contents_view_qt.h" #include "web_engine_context.h" #include <QUrl> -#include <QQmlProperty> void QQuickWebContentsView::registerType() { @@ -59,12 +59,15 @@ void QQuickWebContentsView::registerType() qmlRegisterType<QQuickWebContentsView>("QtWebEngine", 1, 0, "WebContentsView"); } -struct QQuickWebContentsViewPrivate +class QQuickWebContentsViewPrivate : public WebContentsViewQtClient { QQuickWebContentsView *q_ptr; Q_DECLARE_PUBLIC(QQuickWebContentsView) +public: QQuickWebContentsViewPrivate(); + RenderWidgetHostViewQtDelegate* CreateRenderWidgetHostViewQtDelegate(content::RenderWidgetHostViewQt *view) Q_DECL_OVERRIDE; + scoped_refptr<WebEngineContext> context; scoped_ptr<WebContentsDelegateQt> webContentsDelegate; }; @@ -75,18 +78,10 @@ QQuickWebContentsView::QQuickWebContentsView() d_ptr->q_ptr = this; Q_D(QQuickWebContentsView); - content::BrowserContext* browser_context = static_cast<ContentBrowserClientQt*>(content::GetContentClient()->browser())->browser_context(); - d->webContentsDelegate.reset(new WebContentsDelegateQt(browser_context, NULL, MSG_ROUTING_NONE, gfx::Size())); - WebContentsDelegateQt* delegate = d->webContentsDelegate.get(); connect(delegate, SIGNAL(titleChanged(QString)), this, SIGNAL(titleChanged(QString))); connect(delegate, SIGNAL(urlChanged(QUrl)), this, SIGNAL(urlChanged())); connect(delegate, SIGNAL(loadingStateChanged()), this, SIGNAL(loadingStateChanged())); - - WebContentsViewQt* content_view = static_cast<WebContentsViewQt*>(d->webContentsDelegate->web_contents()->GetView()); - QQuickItem* windowContainer = content_view->windowContainer()->qQuickItem(); - windowContainer->setParentItem(this); - QQmlProperty::write(windowContainer, QStringLiteral("anchors.fill"), QVariant::fromValue(this)); } QQuickWebContentsView::~QQuickWebContentsView() @@ -171,8 +166,32 @@ bool QQuickWebContentsView::canGoForward() const return d->webContentsDelegate->web_contents()->GetController().CanGoForward(); } +void QQuickWebContentsView::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry) +{ + QQuickItem::geometryChanged(newGeometry, oldGeometry); + + Q_FOREACH(QQuickItem *child, childItems()) { + Q_ASSERT(qobject_cast<RenderWidgetHostViewQtDelegateQuick *>(child)); + child->setSize(newGeometry.size()); + } +} + QQuickWebContentsViewPrivate::QQuickWebContentsViewPrivate() // This has to be the first thing we do. : context(WebEngineContext::current()) { + content::BrowserContext* browser_context = static_cast<ContentBrowserClientQt*>(content::GetContentClient()->browser())->browser_context(); + webContentsDelegate.reset(new WebContentsDelegateQt(browser_context, NULL, MSG_ROUTING_NONE, gfx::Size())); + + WebContentsViewQt* contents_view = static_cast<WebContentsViewQt*>(webContentsDelegate->web_contents()->GetView()); + contents_view->SetClient(this); +} + +RenderWidgetHostViewQtDelegate *QQuickWebContentsViewPrivate::CreateRenderWidgetHostViewQtDelegate(content::RenderWidgetHostViewQt *view) +{ + Q_Q(QQuickWebContentsView); + // Parent the RWHV directly, this might have to be changed to handle popups and fullscreen. + RenderWidgetHostViewQtDelegateQuick *viewDelegate = new RenderWidgetHostViewQtDelegateQuick(view, q); + viewDelegate->setSize(QSizeF(q->width(), q->height())); + return viewDelegate; } diff --git a/lib/qquickwebcontentsview.h b/lib/qquickwebcontentsview.h index 81459c490..2c19bce0a 100644 --- a/lib/qquickwebcontentsview.h +++ b/lib/qquickwebcontentsview.h @@ -79,6 +79,9 @@ Q_SIGNALS: void urlChanged(); void loadingStateChanged(); +protected: + void geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry); + private: Q_DECLARE_PRIVATE(QQuickWebContentsView) // Hides QObject::d_ptr allowing us to use the convenience macros. diff --git a/lib/qwebcontentsview.cpp b/lib/qwebcontentsview.cpp index 3f6c69990..c8f5535dd 100644 --- a/lib/qwebcontentsview.cpp +++ b/lib/qwebcontentsview.cpp @@ -46,6 +46,7 @@ #include "browser_context_qt.h" #include "content_browser_client_qt.h" +#include "render_widget_host_view_qt_delegate_widget.h" #include "web_contents_delegate_qt.h" #include "web_contents_view_qt.h" #include "web_engine_context.h" @@ -60,9 +61,6 @@ QWebContentsView::QWebContentsView() d_ptr->q_ptr = this; Q_D(QWebContentsView); - content::BrowserContext* browser_context = static_cast<ContentBrowserClientQt*>(content::GetContentClient()->browser())->browser_context(); - d->webContentsDelegate.reset(new WebContentsDelegateQt(browser_context, NULL, MSG_ROUTING_NONE, gfx::Size())); - QVBoxLayout *layout = new QVBoxLayout; layout->setContentsMargins(0, 0, 0, 0); setLayout(layout); @@ -71,9 +69,6 @@ QWebContentsView::QWebContentsView() connect(delegate, SIGNAL(titleChanged(const QString&)), this, SIGNAL(titleChanged(const QString&))); connect(delegate, SIGNAL(urlChanged(const QUrl&)), this, SIGNAL(urlChanged(const QUrl&))); connect(delegate, SIGNAL(loadingStateChanged()), d, SLOT(loadingStateChanged())); - - WebContentsViewQt* content_view = static_cast<WebContentsViewQt*>(d->webContentsDelegate->web_contents()->GetView()); - layout->addLayout(content_view->windowContainer()->widget()); } QWebContentsView::~QWebContentsView() @@ -145,6 +140,11 @@ QWebContentsViewPrivate::QWebContentsViewPrivate() : context(WebEngineContext::current()) , m_isLoading(false) { + content::BrowserContext* browser_context = static_cast<ContentBrowserClientQt*>(content::GetContentClient()->browser())->browser_context(); + webContentsDelegate.reset(new WebContentsDelegateQt(browser_context, NULL, MSG_ROUTING_NONE, gfx::Size())); + + WebContentsViewQt* contents_view = static_cast<WebContentsViewQt*>(webContentsDelegate->web_contents()->GetView()); + contents_view->SetClient(this); } void QWebContentsViewPrivate::loadingStateChanged() @@ -159,3 +159,12 @@ void QWebContentsViewPrivate::loadingStateChanged() Q_EMIT q->loadFinished(true); } } + +RenderWidgetHostViewQtDelegate *QWebContentsViewPrivate::CreateRenderWidgetHostViewQtDelegate(content::RenderWidgetHostViewQt *view) +{ + Q_Q(QWebContentsView); + RenderWidgetHostViewQtDelegateWidget *viewDelegate = new RenderWidgetHostViewQtDelegateWidget(view, q); + // Parent the RWHV directly, this might have to be changed to handle popups and fullscreen. + q->layout()->addWidget(viewDelegate); + return viewDelegate; +} diff --git a/lib/qwebcontentsview_p.h b/lib/qwebcontentsview_p.h index 9d2190ee2..c2009c7ac 100644 --- a/lib/qwebcontentsview_p.h +++ b/lib/qwebcontentsview_p.h @@ -51,7 +51,7 @@ #include <QScopedPointer> #include <QObject> -class QWebContentsViewPrivate : public QObject +class QWebContentsViewPrivate : public QObject, public WebContentsViewQtClient { QWebContentsView *q_ptr; Q_DECLARE_PUBLIC(QWebContentsView) @@ -59,6 +59,8 @@ class QWebContentsViewPrivate : public QObject public: QWebContentsViewPrivate(); + RenderWidgetHostViewQtDelegate* CreateRenderWidgetHostViewQtDelegate(content::RenderWidgetHostViewQt *view) Q_DECL_OVERRIDE; + public Q_SLOTS: void loadingStateChanged(); diff --git a/lib/render_widget_host_view_qt_delegate_quick.cpp b/lib/render_widget_host_view_qt_delegate_quick.cpp new file mode 100644 index 000000000..754e68239 --- /dev/null +++ b/lib/render_widget_host_view_qt_delegate_quick.cpp @@ -0,0 +1,125 @@ +#include "render_widget_host_view_qt_delegate_quick.h" + +#include "shared/backing_store_qt.h" +#include "shared/render_widget_host_view_qt.h" +#include <QQuickWindow> +#include <QWindow> + +RenderWidgetHostViewQtDelegateQuick::RenderWidgetHostViewQtDelegateQuick(content::RenderWidgetHostViewQt* view, QQuickItem *parent) + : QQuickPaintedItem(parent) + , m_backingStore(0) + , m_view(view) +{ + setFocus(true); + setAcceptedMouseButtons(Qt::AllButtons); +} + +QRectF RenderWidgetHostViewQtDelegateQuick::screenRect() const +{ + QPointF pos = mapToScene(QPointF(0,0)); + return QRectF(pos.x(), pos.y(), width(), height()); +} + +void RenderWidgetHostViewQtDelegateQuick::show() +{ + setVisible(true); +} + +void RenderWidgetHostViewQtDelegateQuick::hide() +{ + setVisible(false); +} + +bool RenderWidgetHostViewQtDelegateQuick::isVisible() const +{ + return QQuickPaintedItem::isVisible(); +} + +QWindow* RenderWidgetHostViewQtDelegateQuick::window() const +{ + return QQuickPaintedItem::window(); +} + +void RenderWidgetHostViewQtDelegateQuick::update(const QRect& rect) +{ + QQuickPaintedItem::update(rect); +} + +void RenderWidgetHostViewQtDelegateQuick::paint(QPainter *painter) +{ + if (!m_backingStore) + return; + + m_backingStore->paintToTarget(painter, boundingRect()); +} + +void RenderWidgetHostViewQtDelegateQuick::setBackingStore(BackingStoreQt* backingStore) +{ + m_backingStore = backingStore; + if (m_backingStore) + m_backingStore->resize(QSize(width(), height())); +} + +QSGNode * RenderWidgetHostViewQtDelegateQuick::updatePaintNode(QSGNode * oldNode, UpdatePaintNodeData * data) +{ + return QQuickPaintedItem::updatePaintNode(oldNode, data); +} + +void RenderWidgetHostViewQtDelegateQuick::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry) +{ + QQuickPaintedItem::geometryChanged(newGeometry, oldGeometry); + + resizeBackingStore(); +} + +void RenderWidgetHostViewQtDelegateQuick::resizeBackingStore() +{ + if (m_backingStore) + m_backingStore->resize(QSize(width(), height())); +} + +void RenderWidgetHostViewQtDelegateQuick::focusInEvent(QFocusEvent *event) +{ + m_view->handleFocusEvent(event); +} + +void RenderWidgetHostViewQtDelegateQuick::focusOutEvent(QFocusEvent *event) +{ + m_view->handleFocusEvent(event); +} + +void RenderWidgetHostViewQtDelegateQuick::mousePressEvent(QMouseEvent *event) +{ + setFocus(true); + m_view->handleMouseEvent(event); +} + +void RenderWidgetHostViewQtDelegateQuick::mouseMoveEvent(QMouseEvent *event) +{ + m_view->handleMouseEvent(event); +} + +void RenderWidgetHostViewQtDelegateQuick::mouseReleaseEvent(QMouseEvent *event) +{ + m_view->handleMouseEvent(event); +} + +void RenderWidgetHostViewQtDelegateQuick::mouseDoubleClickEvent(QMouseEvent *event) +{ + m_view->handleMouseEvent(event); +} + +void RenderWidgetHostViewQtDelegateQuick::keyPressEvent(QKeyEvent *event) +{ + m_view->handleKeyEvent(event); +} + +void RenderWidgetHostViewQtDelegateQuick::keyReleaseEvent(QKeyEvent *event) +{ + m_view->handleKeyEvent(event); +} + +void RenderWidgetHostViewQtDelegateQuick::wheelEvent(QWheelEvent *event) +{ + m_view->handleWheelEvent(event); +} diff --git a/lib/render_widget_host_view_qt_delegate_quick.h b/lib/render_widget_host_view_qt_delegate_quick.h new file mode 100644 index 000000000..20725c621 --- /dev/null +++ b/lib/render_widget_host_view_qt_delegate_quick.h @@ -0,0 +1,59 @@ +#ifndef RENDER_WIDGET_HOST_VIEW_QT_DELEGATE_QUICK_H +#define RENDER_WIDGET_HOST_VIEW_QT_DELEGATE_QUICK_H + +#include "shared/render_widget_host_view_qt_delegate.h" + +#include <QQuickPaintedItem> + +class BackingStoreQt; +class QWindow; +class QQuickItem; +class QFocusEvent; +class QMouseEvent; +class QKeyEvent; +class QWheelEvent; + +namespace content { + class RenderWidgetHostViewQt; +} + +class RenderWidgetHostViewQtDelegateQuick : public QQuickPaintedItem, public RenderWidgetHostViewQtDelegate +{ + Q_OBJECT +public: + RenderWidgetHostViewQtDelegateQuick(content::RenderWidgetHostViewQt* view, QQuickItem *parent = 0); + + virtual void setBackingStore(BackingStoreQt* backingStore); + virtual QRectF screenRect() const; + virtual void show(); + virtual void hide(); + virtual bool isVisible() const; + virtual QWindow* window() const; + virtual void update(const QRect& rect = QRect()); + + void paint(QPainter *painter); + + void focusInEvent(QFocusEvent*); + void focusOutEvent(QFocusEvent*); + void mousePressEvent(QMouseEvent*); + void mouseMoveEvent(QMouseEvent*); + void mouseReleaseEvent(QMouseEvent*); + void mouseDoubleClickEvent(QMouseEvent*); + void keyPressEvent(QKeyEvent*); + void keyReleaseEvent(QKeyEvent*); + void wheelEvent(QWheelEvent*); + +protected Q_SLOTS: + void resizeBackingStore(); + +protected: + QSGNode* updatePaintNode(QSGNode * oldNode, UpdatePaintNodeData * data); + void geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry); + +private: + BackingStoreQt* m_backingStore; + content::RenderWidgetHostViewQt *m_view; + +}; + +#endif diff --git a/lib/render_widget_host_view_qt_delegate_widget.cpp b/lib/render_widget_host_view_qt_delegate_widget.cpp new file mode 100644 index 000000000..8be1d308f --- /dev/null +++ b/lib/render_widget_host_view_qt_delegate_widget.cpp @@ -0,0 +1,84 @@ +#include "render_widget_host_view_qt_delegate_widget.h" + +#include "shared/backing_store_qt.h" +#include "shared/render_widget_host_view_qt.h" + +#include <QResizeEvent> +#include <QPaintEvent> + +RenderWidgetHostViewQtDelegateWidget::RenderWidgetHostViewQtDelegateWidget(content::RenderWidgetHostViewQt* view, QWidget *parent) + : QWidget(parent) + , m_painter(0) + , m_backingStore(0) + , m_view(view) +{ + setFocusPolicy(Qt::ClickFocus); + setAttribute(Qt::WA_OpaquePaintEvent); +} + +QRectF RenderWidgetHostViewQtDelegateWidget::screenRect() const +{ + return QRectF(x(), y(), width(), height()); +} + +void RenderWidgetHostViewQtDelegateWidget::show() +{ + QWidget::show(); +} + +void RenderWidgetHostViewQtDelegateWidget::hide() +{ + QWidget::hide(); +} + + +bool RenderWidgetHostViewQtDelegateWidget::isVisible() const +{ + return QWidget::isVisible(); +} + +QWindow* RenderWidgetHostViewQtDelegateWidget::window() const +{ + return QWidget::windowHandle(); +} + +void RenderWidgetHostViewQtDelegateWidget::update(const QRect& rect) +{ + QWidget::update(rect); +} + +void RenderWidgetHostViewQtDelegateWidget::setBackingStore(BackingStoreQt* backingStore) +{ + m_backingStore = backingStore; + if (m_backingStore) + m_backingStore->resize(size()); +} + +void RenderWidgetHostViewQtDelegateWidget::paintEvent(QPaintEvent * event) +{ + if (!m_backingStore) + return; + QPainter painter(this); + m_backingStore->paintToTarget(&painter, event->rect()); +} + +QPainter* RenderWidgetHostViewQtDelegateWidget::painter() +{ + if (!m_painter) + m_painter = new QPainter(this); + return m_painter; +} + +void RenderWidgetHostViewQtDelegateWidget::resizeEvent(QResizeEvent *resizeEvent) +{ + if (m_backingStore) + m_backingStore->resize(resizeEvent->size()); + QWidget::update(); +} + +bool RenderWidgetHostViewQtDelegateWidget::event(QEvent *event) +{ + if (!m_view || !m_view->handleEvent(event)) + return QWidget::event(event); + return true; +} diff --git a/lib/render_widget_host_view_qt_delegate_widget.h b/lib/render_widget_host_view_qt_delegate_widget.h new file mode 100644 index 000000000..9087ba017 --- /dev/null +++ b/lib/render_widget_host_view_qt_delegate_widget.h @@ -0,0 +1,41 @@ +#ifndef RENDER_WIDGET_HOST_VIEW_QT_DELEGATE_WIDGET_H +#define RENDER_WIDGET_HOST_VIEW_QT_DELEGATE_WIDGET_H + +#include "shared/render_widget_host_view_qt_delegate.h" + +#include <QWidget> + +class BackingStoreQt; +class QWindow; + +namespace content { + class RenderWidgetHostViewQt; +} + +class RenderWidgetHostViewQtDelegateWidget : public QWidget, public RenderWidgetHostViewQtDelegate +{ +public: + RenderWidgetHostViewQtDelegateWidget(content::RenderWidgetHostViewQt* view, QWidget *parent = 0); + + virtual void setBackingStore(BackingStoreQt* backingStore); + virtual QRectF screenRect() const; + virtual void show(); + virtual void hide(); + virtual bool isVisible() const; + virtual QWindow* window() const; + virtual void update(const QRect& rect = QRect()); + + QPainter* painter(); + +protected: + void paintEvent(QPaintEvent * event); + bool event(QEvent *event); + void resizeEvent(QResizeEvent *resizeEvent); + +private: + BackingStoreQt* m_backingStore; + QPainter* m_painter; + content::RenderWidgetHostViewQt *m_view; +}; + +#endif diff --git a/lib/web_contents_view_qt.h b/lib/web_contents_view_qt.h index 46e7fe7a9..d20f8fec6 100644 --- a/lib/web_contents_view_qt.h +++ b/lib/web_contents_view_qt.h @@ -49,7 +49,12 @@ #include "content/port/browser/web_contents_view_port.h" #include "shared/render_widget_host_view_qt.h" -#include "shared/native_view_container_qt.h" + +class WebContentsViewQtClient { +public: + virtual ~WebContentsViewQtClient() { } + virtual RenderWidgetHostViewQtDelegate* CreateRenderWidgetHostViewQtDelegate(content::RenderWidgetHostViewQt *view) = 0; +}; class WebContentsViewQt : public content::WebContentsViewPort @@ -57,13 +62,16 @@ class WebContentsViewQt { public: WebContentsViewQt(content::WebContents* web_contents) - : m_windowContainer(new NativeViewContainerQt) + : m_client(0) { } - content::RenderWidgetHostView* CreateViewForWidget(content::RenderWidgetHost* render_widget_host) + void SetClient(WebContentsViewQtClient* client) { m_client = client; } + + virtual content::RenderWidgetHostView *CreateViewForWidget(content::RenderWidgetHost* render_widget_host) { - content::RenderWidgetHostView* view = content::RenderWidgetHostView::CreateViewForWidget(render_widget_host); - view->InitAsChild(reinterpret_cast<gfx::NativeView>(m_windowContainer)); + content::RenderWidgetHostViewQt *view = new content::RenderWidgetHostViewQt(render_widget_host); + RenderWidgetHostViewQtDelegate *viewDelegate = m_client->CreateRenderWidgetHostViewQtDelegate(view); + view->SetDelegate(viewDelegate); return view; } @@ -107,10 +115,8 @@ public: virtual void ShowPopupMenu(const gfx::Rect& bounds, int item_height, double item_font_size, int selected_item, const std::vector<WebMenuItem>& items, bool right_aligned, bool allow_multiple_selection) { QT_NOT_YET_IMPLEMENTED } - NativeViewContainerQt* windowContainer() { return m_windowContainer; } - private: - NativeViewContainerQt* m_windowContainer; + WebContentsViewQtClient* m_client; }; #endif |