From db4b7526ad416469882373b87407d3c5ffb1d3cd Mon Sep 17 00:00:00 2001 From: Zeno Albisser <zeno.albisser@digia.com> Date: Wed, 5 Jun 2013 20:58:06 +0200 Subject: [PATCH] Implement support for QtQuick2. The current preliminary implementation uses the QQuickPaintedItem. The RasterWindow is being replaced by an abstract NativeViewQt class, which can be instantiated as QWidgetNativeView or QQuickNativeView. The NativeViewContainerQt builds a wrapper around an instance of these classes and serves as a common api towards chromium. Due to the current design where the view is being created by the shell, we introduce a browser_window.qml which provides a very basic browser UI. The content is then being injected into an item within that browser window. Just executing the example the "regular" way will launch the Widgets example. To launch the QtQuick2 example, the environment variable QQUICKWEBENGINE must be defined. --- lib/backing_store_qt.cpp | 5 +- lib/backing_store_qt.h | 2 +- lib/browser_window.qml | 113 ++++++++++++++++ lib/lib.pro | 11 +- lib/native_view_container_qt.h | 107 +++++++++++++++ lib/native_view_qt.cpp | 208 +++++++++++++++++++++++++++++ lib/native_view_qt.h | 96 +++++++++++++ lib/render_widget_host_view_qt.cpp | 52 ++++---- lib/render_widget_host_view_qt.h | 14 +- lib/shell_qt.cpp | 175 ++++++++++++++---------- lib/signal_connector.cpp | 28 +++- lib/signal_connector.h | 6 +- lib/web_contents_view_qt.h | 8 +- 13 files changed, 701 insertions(+), 124 deletions(-) create mode 100644 lib/browser_window.qml create mode 100644 lib/native_view_container_qt.h create mode 100644 lib/native_view_qt.cpp create mode 100644 lib/native_view_qt.h diff --git a/lib/backing_store_qt.cpp b/lib/backing_store_qt.cpp index 70a801a56..8920b72c3 100644 --- a/lib/backing_store_qt.cpp +++ b/lib/backing_store_qt.cpp @@ -43,7 +43,6 @@ #include "content/browser/renderer_host/render_widget_host_impl.h" #include "content/public/browser/render_process_host.h" -#include "raster_window.h" #include "ui/gfx/rect.h" #include "ui/gfx/rect_conversions.h" @@ -78,11 +77,11 @@ void BackingStoreQt::resize(const QSize& size) } } -void BackingStoreQt::paintToTarget(QPainter* painter, const QRect& rect) +void BackingStoreQt::paintToTarget(QPainter* painter, const QRectF& rect) { if (m_pixelBuffer.isNull()) return; - painter->drawPixmap(rect, m_pixelBuffer); + painter->drawPixmap(rect, m_pixelBuffer, rect); } void BackingStoreQt::PaintToBackingStore(content::RenderProcessHost *process, diff --git a/lib/backing_store_qt.h b/lib/backing_store_qt.h index 6f9722a2f..9f7e807d3 100644 --- a/lib/backing_store_qt.h +++ b/lib/backing_store_qt.h @@ -54,7 +54,7 @@ public: ~BackingStoreQt(); void resize(const QSize& size); - void paintToTarget(QPainter*, const QRect& rect); + void paintToTarget(QPainter*, const QRectF& rect); virtual void PaintToBackingStore(content::RenderProcessHost *process, TransportDIB::Id bitmap, const gfx::Rect &bitmap_rect, const std::vector<gfx::Rect> ©_rects, float scale_factor, const base::Closure &completion_callback, diff --git a/lib/browser_window.qml b/lib/browser_window.qml new file mode 100644 index 000000000..8f3c91cf1 --- /dev/null +++ b/lib/browser_window.qml @@ -0,0 +1,113 @@ +import QtQuick 2.0 + +Item { + id: browserWindow + height: 480 + width: 320 + + signal goBack + signal goForward + signal reload + signal load(string url) + + Rectangle { + id: navigationBar + color: "grey" + anchors.top: parent.top + anchors.left: parent.left + anchors.right: parent.right + height: 26 + + Rectangle { + id: backButton + color: "red" + anchors.top: parent.top + anchors.bottom: parent.bottom + anchors.left: parent.left + width: height + + MouseArea { + anchors.fill: parent + onClicked: { + browserWindow.goBack() + } + } + } + Rectangle { + id: forwardButton + color: "green" + anchors.top: parent.top + anchors.bottom: parent.bottom + anchors.left: backButton.right + width: height + + MouseArea { + anchors.fill: parent + onClicked: { + browserWindow.goForward() + } + } + } + Rectangle { + id: reloadButton + color: "blue" + anchors.top: parent.top + anchors.bottom: parent.bottom + anchors.left: forwardButton.right + width: height + + MouseArea { + anchors.fill: parent + onClicked: { + browserWindow.reload() + } + } + } + TextInput { + id: addressBar + focus: true + anchors.top: parent.top + anchors.bottom: parent.bottom + anchors.left: reloadButton.right + anchors.right: parent.right + + text: "www.google.com" + cursorVisible: true + persistentSelection: true + selectByMouse: true + + onAccepted: { + browserWindow.load(addressBar.text) + } + } + } + + Rectangle { + id: viewContainer + objectName: "viewContainer" + focus: true + color: "blue" + anchors.top: navigationBar.bottom + anchors.bottom: parent.bottom + anchors.left: parent.left + anchors.right: parent.right + + Binding { + target: viewContainer.children[0] + property: 'anchors.fill' + value: viewContainer + when: viewContainer.children.length > 0 + } + } + + Text { + id: info + anchors.top: parent.top + anchors.right: parent.right + horizontalAlignment: "AlignRight" + width: 100 + height: 100 + + text: viewContainer.children[0].width + "x" + viewContainer.children[0].height + } +} diff --git a/lib/lib.pro b/lib/lib.pro index 67dd25ead..1ab187dcb 100644 --- a/lib/lib.pro +++ b/lib/lib.pro @@ -16,19 +16,19 @@ PER_CONFIG_DEFINES = BLINQ_PROCESS_PATH=\\\"$$getOutDir()/%config/$$BLINQ_PROCES # Keep Skia happy CONFIG(release, debug|release): DEFINES += NDEBUG -QT += gui-private widgets +QT += gui-private widgets qml quick SOURCES = \ backing_store_qt.cpp \ blinqapplication.cpp \ blinqpage.cpp \ content_browser_client_qt.cpp \ - raster_window.cpp \ render_widget_host_view_qt.cpp \ resource_context_qt.cpp \ shell_qt.cpp \ signal_connector.cpp \ - web_event_factory.cpp + web_event_factory.cpp \ + native_view_qt.cpp HEADERS = \ backing_store_qt.h \ @@ -36,9 +36,10 @@ HEADERS = \ blinqpage.h \ browser_context_qt.h \ content_browser_client_qt.h \ - raster_window.h \ render_widget_host_view_qt.h \ resource_context_qt.h \ web_event_factory.h \ - signal_connector.h + signal_connector.h \ + native_view_container_qt.h \ + native_view_qt.h diff --git a/lib/native_view_container_qt.h b/lib/native_view_container_qt.h new file mode 100644 index 000000000..6937d146d --- /dev/null +++ b/lib/native_view_container_qt.h @@ -0,0 +1,107 @@ +#ifndef NATIVE_VIEW_CONTAINER_QT_H +#define NATIVE_VIEW_CONTAINER_QT_H + +#include "native_view_qt.h" + +#include <QWindow> +#include <QVBoxLayout> +#include <QQuickItem> + +class NativeViewContainerQt : public QObject +{ + Q_OBJECT +public: + NativeViewContainerQt() + : m_embeddable(0) + , m_currentQQuickNativeView(0) + , m_currentQWidgetNativeView(0) + , m_isQQuick(false) + { + } + + QQuickItem* qQuickItem() + { + if (!m_embeddable) { + QQuickItem* embeddable = new QQuickItem; + m_isQQuick = true; + connect(embeddable, SIGNAL(widthChanged()), this, SLOT(resized())); + connect(embeddable, SIGNAL(heightChanged()), this, SLOT(resized())); + m_embeddable = embeddable; + } + + return static_cast<QQuickItem*>(m_embeddable); + } + + QVBoxLayout* widget() + { + if (!m_embeddable) + m_embeddable = new QVBoxLayout; + return static_cast<QVBoxLayout*>(m_embeddable); + } + + void setWidth(qreal width) + { + if (m_isQQuick && m_currentQQuickNativeView) { + m_currentQQuickNativeView->setWidth(width); + m_currentQQuickNativeView->setContentsSize(QSize(width, m_currentQQuickNativeView->height())); + qQuickItem()->setWidth(width); + } + } + + void setHeight(qreal height) + { + if (m_isQQuick && m_currentQQuickNativeView) { + m_currentQQuickNativeView->setHeight(height); + m_currentQQuickNativeView->setContentsSize(QSize(m_currentQQuickNativeView->width(), height)); + qQuickItem()->setHeight(height); + } + } + + NativeViewQt* createNativeView(content::RenderWidgetHostViewQt* renderWidgetHostView) + { + if (m_isQQuick) { + insert(new QQuickNativeView(renderWidgetHostView)); + return m_currentQQuickNativeView; + } + + insert(new QWidgetNativeView(renderWidgetHostView)); + return m_currentQWidgetNativeView; + } + +protected: + void insert(QWidgetNativeView* nativeView) + { + widget()->removeWidget(m_currentQWidgetNativeView); + widget()->addWidget(nativeView); + m_currentQWidgetNativeView = nativeView; + } + + void insert(QQuickNativeView* nativeView) + { + fprintf(stderr, "replace: %p with %p\n", m_currentQQuickNativeView, nativeView); + if (m_currentQQuickNativeView) + m_currentQQuickNativeView->setParentItem(0); + + nativeView->setParentItem(qQuickItem()); + m_currentQQuickNativeView = nativeView; + setWidth(qQuickItem()->width()); + setHeight(qQuickItem()->height()); + } + +public Q_SLOTS: + void resized() + { + int w = static_cast<unsigned int>(qQuickItem()->width()); + int h = static_cast<unsigned int>(qQuickItem()->height()); + if (m_currentQQuickNativeView) + m_currentQQuickNativeView->resize(w, h); + } + +private: + QObject* m_embeddable; + QWidgetNativeView* m_currentQWidgetNativeView; + QQuickNativeView* m_currentQQuickNativeView; + bool m_isQQuick; +}; + +#endif diff --git a/lib/native_view_qt.cpp b/lib/native_view_qt.cpp new file mode 100644 index 000000000..d95cb6957 --- /dev/null +++ b/lib/native_view_qt.cpp @@ -0,0 +1,208 @@ +#include "native_view_qt.h" + +#include "backing_store_qt.h" +#include "render_widget_host_view_qt.h" +#include <QResizeEvent> +#include <QShowEvent> +#include <QPaintEvent> +#include <QQuickWindow> +#include <QWindow> + +QWidgetNativeView::QWidgetNativeView(content::RenderWidgetHostViewQt* view, QWidget *parent) + : QWidget(parent) + , m_painter(0) + , m_backingStore(0) + , m_view(view) +{ + setFocusPolicy(Qt::ClickFocus); + setAttribute(Qt::WA_OpaquePaintEvent); +} + +QRectF QWidgetNativeView::screenRect() const +{ + return QRectF(x(), y(), width(), height()); +} + +void QWidgetNativeView::show() +{ + QWidget::show(); +} + +void QWidgetNativeView::hide() +{ + QWidget::hide(); +} + + +bool QWidgetNativeView::isVisible() const +{ + return QWidget::isVisible(); +} + +QWindow* QWidgetNativeView::window() const +{ + return QWidget::windowHandle(); +} + +void QWidgetNativeView::update() +{ + QWidget::update(); +} + +void QWidgetNativeView::setBackingStore(BackingStoreQt* backingStore) +{ + m_backingStore = backingStore; + if (m_backingStore) + m_backingStore->resize(size()); +} + +void QWidgetNativeView::paintEvent(QPaintEvent * event) +{ + if (!m_backingStore) + return; + QPainter painter(this); + m_backingStore->paintToTarget(&painter, event->rect()); +} + +QPainter* QWidgetNativeView::painter() +{ + if (!m_painter) + m_painter = new QPainter(this); + return m_painter; +} + +void QWidgetNativeView::resizeEvent(QResizeEvent *resizeEvent) +{ + if (m_backingStore) + m_backingStore->resize(resizeEvent->size()); + QWidget::update(); +} + +bool QWidgetNativeView::event(QEvent *event) +{ + if (!m_view || !m_view->handleEvent(event)) + return QWidget::event(event); + return true; +} + +QQuickNativeView::QQuickNativeView(content::RenderWidgetHostViewQt* view, QQuickItem *parent) + : QQuickPaintedItem(parent) + , m_backingStore(0) + , m_view(view) +{ + setFocus(true); + setAcceptedMouseButtons(Qt::AllButtons); +} + +QRectF QQuickNativeView::screenRect() const +{ + QPointF pos = mapToScene(QPointF(0,0)); + return QRectF(pos.x(), pos.y(), width(), height()); +} + +void QQuickNativeView::show() +{ + setVisible(true); +} + +void QQuickNativeView::hide() +{ + setVisible(true); +} + +bool QQuickNativeView::isVisible() const +{ + return QQuickPaintedItem::isVisible(); +} + +QWindow* QQuickNativeView::window() const +{ + return QQuickPaintedItem::window(); +} + +void QQuickNativeView::update() +{ + QQuickPaintedItem::update(); +} + +void QQuickNativeView::paint(QPainter *painter) +{ + if (!m_backingStore) + return; + + m_backingStore->paintToTarget(painter, boundingRect()); +} + +void QQuickNativeView::setBackingStore(BackingStoreQt* backingStore) +{ + m_backingStore = backingStore; + if (m_backingStore) + m_backingStore->resize(QSize(width(), height())); +} + +QSGNode * QQuickNativeView::updatePaintNode(QSGNode * oldNode, UpdatePaintNodeData * data) +{ + return QQuickPaintedItem::updatePaintNode(oldNode, data); +} + +void QQuickNativeView::resizeBackingStore() +{ + if (m_backingStore) + m_backingStore->resize(QSize(width(), height())); +} + +void QQuickNativeView::resize(int width, int height) +{ + resetWidth(); + resetHeight(); + setWidth(width); + setHeight(height); + resizeBackingStore(); + update(); +} + +void QQuickNativeView::focusInEvent(QFocusEvent *event) +{ + m_view->handleFocusEvent(event); +} + +void QQuickNativeView::focusOutEvent(QFocusEvent *event) +{ + m_view->handleFocusEvent(event); +} + +void QQuickNativeView::mousePressEvent(QMouseEvent *event) +{ + setFocus(true); + m_view->handleMouseEvent(event); +} + +void QQuickNativeView::mouseMoveEvent(QMouseEvent *event) +{ + m_view->handleMouseEvent(event); +} + +void QQuickNativeView::mouseReleaseEvent(QMouseEvent *event) +{ + m_view->handleMouseEvent(event); +} + +void QQuickNativeView::mouseDoubleClickEvent(QMouseEvent *event) +{ + m_view->handleMouseEvent(event); +} + +void QQuickNativeView::keyPressEvent(QKeyEvent *event) +{ + m_view->handleKeyEvent(event); +} + +void QQuickNativeView::keyReleaseEvent(QKeyEvent *event) +{ + m_view->handleKeyEvent(event); +} + +void QQuickNativeView::wheelEvent(QWheelEvent *event) +{ + m_view->handleWheelEvent(event); +} diff --git a/lib/native_view_qt.h b/lib/native_view_qt.h new file mode 100644 index 000000000..99637602b --- /dev/null +++ b/lib/native_view_qt.h @@ -0,0 +1,96 @@ +#ifndef NATIVE_VIEW_QT_H +#define NATIVE_VIEW_QT_H + + +#include <QWidget> +#include <QQuickPaintedItem> + +class BackingStoreQt; +class QWindow; +class QQuickItem; +class QFocusEvent; +class QMouseEvent; +class QKeyEvent; +class QWheelEvent; + +namespace content { + class RenderWidgetHostViewQt; +} + +class NativeViewQt { +public: + virtual void setBackingStore(BackingStoreQt* backingStore) = 0; + virtual QRectF screenRect() const = 0; + virtual void show() = 0; + virtual void hide() = 0; + virtual bool isVisible() const = 0; + virtual QWindow* window() const = 0; + virtual void update() = 0; +}; + +class QWidgetNativeView : public QWidget, public NativeViewQt +{ +public: + QWidgetNativeView(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(); + + 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; +}; + +class QQuickNativeView : public QQuickPaintedItem, public NativeViewQt +{ + Q_OBJECT +public: + QQuickNativeView(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(); + + void paint(QPainter *painter); + void resize(int width, int height); + + 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); + +private: + BackingStoreQt* m_backingStore; + content::RenderWidgetHostViewQt *m_view; + +}; + +#endif diff --git a/lib/render_widget_host_view_qt.cpp b/lib/render_widget_host_view_qt.cpp index aa992da1d..351030c7a 100644 --- a/lib/render_widget_host_view_qt.cpp +++ b/lib/render_widget_host_view_qt.cpp @@ -43,11 +43,11 @@ #include "backing_store_qt.h" #include "web_event_factory.h" -#include "raster_window.h" +#include "native_view_container_qt.h" +#include "native_view_qt.h" #include "content/browser/renderer_host/render_view_host_impl.h" #include "content/common/gpu/gpu_messages.h" -#include "raster_window.h" #include "third_party/WebKit/Source/WebKit/chromium/public/WebScreenInfo.h" #include <QEvent> @@ -56,6 +56,7 @@ #include <QMouseEvent> #include <QWheelEvent> #include <QScreen> +#include <QQuickWindow> static void GetScreenInfoFromNativeWindow(QWindow* window, WebKit::WebScreenInfo* results) { @@ -138,23 +139,21 @@ RenderWidgetHostView* RenderWidgetHostViewQt::CreateViewForWidget(content::Rende void RenderWidgetHostViewQt::InitAsChild(gfx::NativeView parent_view) { - m_view = new RasterWindow(this); + NativeViewContainerQt* container = reinterpret_cast<NativeViewContainerQt*>(parent_view); + m_view = container->createNativeView(this); bool force_create = !m_host->empty(); BackingStoreQt* backing_store = static_cast<BackingStoreQt*>(m_host->GetBackingStore(force_create)); m_view->setBackingStore(backing_store); - - RasterWindowContainer* container = reinterpret_cast<RasterWindowContainer*>(parent_view); - container->insert(m_view); } void RenderWidgetHostViewQt::InitAsPopup(content::RenderWidgetHostView*, const gfx::Rect&) { - m_view = new RasterWindow(this); + // m_view = new RasterWindow(this); } void RenderWidgetHostViewQt::InitAsFullscreen(content::RenderWidgetHostView*) { - m_view = new RasterWindow(this); + // m_view = new RasterWindow(this); } content::RenderWidgetHost* RenderWidgetHostViewQt::GetRenderWidgetHost() const @@ -168,10 +167,8 @@ void RenderWidgetHostViewQt::SetSize(const gfx::Size& size) int height = size.height(); // int width = std::min(size.width(), kMaxWindowWidth); // int height = std::min(size.height(), kMaxWindowHeight); - if (IsPopup()) { - // We're a popup, honor the size request. - m_view->resize(width,height); - } + // if (IsPopup()) + // m_view->resize(width,height); if (m_requestedSize.width() != width || m_requestedSize.height() != height) { @@ -184,9 +181,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_view->setGeometry(rect.x(), rect.y(), rect.width(), rect.height()); - + // if (IsPopup()) + // m_view->setGeometry(rect.x(), rect.y(), rect.width(), rect.height()); SetSize(rect.size()); } @@ -197,7 +193,7 @@ gfx::NativeView RenderWidgetHostViewQt::GetNativeView() const return gfx::NativeView(); } -RasterWindow* RenderWidgetHostViewQt::GetNativeViewQt() const +NativeViewQt* RenderWidgetHostViewQt::GetNativeViewQt() const { return m_view; } @@ -217,12 +213,13 @@ gfx::NativeViewAccessible RenderWidgetHostViewQt::GetNativeViewAccessible() // Set focus to the associated View component. void RenderWidgetHostViewQt::Focus() { - m_view->setFocus(Qt::MouseFocusReason); + // m_view->setFocus(Qt::MouseFocusReason); } bool RenderWidgetHostViewQt::HasFocus() const { - return m_view->hasFocus(); + // return m_view->hasFocus(); + return true; } bool RenderWidgetHostViewQt::IsSurfaceAvailableForCopy() const @@ -248,10 +245,8 @@ bool RenderWidgetHostViewQt::IsShowing() // Retrieve the bounds of the View, in screen coordinates. gfx::Rect RenderWidgetHostViewQt::GetViewBounds() const { - QRect rect = m_view->geometry(); - QPoint screenPos = m_view->mapToGlobal(QPoint(0,0)); - - return gfx::Rect(screenPos.x(), screenPos.y(), rect.width(), rect.height()); + QRectF p = m_view->screenRect(); + return gfx::Rect(p.x(), p.y(), p.width(), p.height()); } // Subclasses should override this method to do what is appropriate to set @@ -348,7 +343,7 @@ void RenderWidgetHostViewQt::ImeCompositionRangeChanged(const ui::Range&, const void RenderWidgetHostViewQt::DidUpdateBackingStore(const gfx::Rect& scroll_rect, const gfx::Vector2d& scroll_delta, const std::vector<gfx::Rect>& copy_rects) { - if (!m_view->isVisible()) + if (!m_view || !m_view->isVisible()) return; Paint(scroll_rect); @@ -444,7 +439,7 @@ bool RenderWidgetHostViewQt::HasAcceleratedSurface(const gfx::Size&) void RenderWidgetHostViewQt::GetScreenInfo(WebKit::WebScreenInfo* results) { - QWindow* window = m_view->window()->windowHandle(); + QWindow* window = m_view->window(); if (!window) return; GetScreenInfoFromNativeWindow(window, results); @@ -452,7 +447,10 @@ void RenderWidgetHostViewQt::GetScreenInfo(WebKit::WebScreenInfo* results) gfx::Rect RenderWidgetHostViewQt::GetBoundsInRootWindow() { - QRect r = m_view->frameGeometry(); + if (!m_view || !m_view->window()) + return gfx::Rect(); + + QRect r = m_view->window()->frameGeometry(); return gfx::Rect(r.x(), r.y(), r.width(), r.height()); } @@ -476,8 +474,8 @@ void RenderWidgetHostViewQt::Paint(const gfx::Rect& scroll_rect) bool force_create = !m_host->empty(); BackingStoreQt* backing_store = static_cast<BackingStoreQt*>(m_host->GetBackingStore(force_create)); if (backing_store && m_view) { - QSize s = m_view->size(); - QRect rect(0, 0, s.width(), s.height()); + QRectF r = m_view->screenRect(); + QRect rect(0, 0, r.width(), r.height()); m_view->setBackingStore(backing_store); m_view->update(); } diff --git a/lib/render_widget_host_view_qt.h b/lib/render_widget_host_view_qt.h index 8f19a4de8..94faf8205 100644 --- a/lib/render_widget_host_view_qt.h +++ b/lib/render_widget_host_view_qt.h @@ -51,7 +51,7 @@ class QFocusEvent; class QKeyEvent; class QMouseEvent; class QWheelEvent; -class RasterWindow; +class NativeViewQt; namespace content { @@ -74,7 +74,7 @@ public: virtual void SetSize(const gfx::Size& size); virtual void SetBounds(const gfx::Rect& rect); virtual gfx::NativeView GetNativeView() const; - virtual RasterWindow* GetNativeViewQt() const OVERRIDE; + virtual NativeViewQt* GetNativeViewQt() const OVERRIDE; virtual gfx::NativeViewId GetNativeViewId() const; virtual gfx::NativeViewAccessible GetNativeViewAccessible(); virtual void Focus(); @@ -123,17 +123,17 @@ public: virtual void SetScrollOffsetPinning(bool, bool); virtual void OnAccessibilityNotifications(const std::vector<AccessibilityHostMsg_NotificationParams>&); -private: - void Paint(const gfx::Rect& scroll_rect); - - bool IsPopup() const; void handleMouseEvent(QMouseEvent*); void handleKeyEvent(QKeyEvent*); void handleWheelEvent(QWheelEvent*); void handleFocusEvent(QFocusEvent*); +private: + void Paint(const gfx::Rect& scroll_rect); + + bool IsPopup() const; content::RenderWidgetHostImpl *m_host; - RasterWindow *m_view; + NativeViewQt *m_view; gfx::Size m_requestedSize; }; diff --git a/lib/shell_qt.cpp b/lib/shell_qt.cpp index 8a24902c0..54ee5cf49 100644 --- a/lib/shell_qt.cpp +++ b/lib/shell_qt.cpp @@ -16,7 +16,6 @@ #include "content/public/common/renderer_preferences.h" #include "content/shell/shell_browser_context.h" #include "content/shell/shell_content_browser_client.h" -#include "raster_window.h" #include "signal_connector.h" #include "web_contents_view_qt.h" @@ -26,9 +25,11 @@ #include <QVBoxLayout> #include <QLineEdit> #include <QToolButton> -#include <QWidget> +#include <QQuickView> #include <QWindow> +static bool isWidgets = false; + namespace content { void Shell::PlatformInitialize(const gfx::Size& default_window_size) @@ -45,13 +46,15 @@ void Shell::PlatformEnableUIControl(UIControl control, bool is_enabled) void Shell::PlatformSetAddressBarURL(const GURL& url) { - if (headless_) - return; + if (headless_) + return; - fprintf(stderr, "Set Address to: %s\n", url.spec().c_str()); + fprintf(stderr, "Set Address to: %s\n", url.spec().c_str()); - QLineEdit* addressLine = reinterpret_cast<QWidget*>(window_)->findChild<QLineEdit*>("AddressLineEdit"); - addressLine->setText(QString::fromStdString(url.spec())); + if (isWidgets) { + QLineEdit* addressLine = reinterpret_cast<QWidget*>(window_)->findChild<QLineEdit*>("AddressLineEdit"); + addressLine->setText(QString::fromStdString(url.spec())); + } } @@ -61,67 +64,83 @@ void Shell::PlatformSetIsLoading(bool loading) } void Shell::PlatformCreateWindow(int width, int height) { - SizeTo(width, height); + SizeTo(width, height); + + if (headless_) + return; - if (headless_) - return; + if (!window_) { + if (qgetenv("QQUICKWEBENGINE").isNull()) { + fprintf(stderr, "Starting Widgets example...\n"); + isWidgets = true; + QWidget* window = new QWidget; + window_ = reinterpret_cast<gfx::NativeWindow>(window); - if (!window_) { + window->setGeometry(100,100, width, height); - // Use oxygen as a fallback. - if (QIcon::themeName().isEmpty()) - QIcon::setThemeName("oxygen"); + QVBoxLayout* layout = new QVBoxLayout; - QWidget* window = new QWidget; - window_ = reinterpret_cast<gfx::NativeWindow>(window); + // Create a widget based address bar. + QHBoxLayout* addressBar = new QHBoxLayout; - window->setGeometry(100,100, width, height); + int buttonWidth = 26; + QToolButton* backButton = new QToolButton; + backButton->setIcon(QIcon::fromTheme("go-previous")); + backButton->setObjectName("BackButton"); + addressBar->addWidget(backButton); - QVBoxLayout* layout = new QVBoxLayout; + QToolButton* forwardButton = new QToolButton; + forwardButton->setIcon(QIcon::fromTheme("go-next")); + forwardButton->setObjectName("ForwardButton"); + addressBar->addWidget(forwardButton); - // Create a widget based address bar. - QHBoxLayout* addressBar = new QHBoxLayout; + QToolButton* reloadButton = new QToolButton; + reloadButton->setIcon(QIcon::fromTheme("view-refresh")); + reloadButton->setObjectName("ReloadButton"); + addressBar->addWidget(reloadButton); - int buttonWidth = 26; - QToolButton* backButton = new QToolButton; - backButton->setIcon(QIcon::fromTheme("go-previous")); - backButton->setObjectName("BackButton"); - addressBar->addWidget(backButton); + QLineEdit* lineEdit = new QLineEdit; + lineEdit->setObjectName("AddressLineEdit"); + addressBar->addWidget(lineEdit); - QToolButton* forwardButton = new QToolButton; - forwardButton->setIcon(QIcon::fromTheme("go-next")); - forwardButton->setObjectName("ForwardButton"); - addressBar->addWidget(forwardButton); + layout->addLayout(addressBar); - QToolButton* reloadButton = new QToolButton; - reloadButton->setIcon(QIcon::fromTheme("view-refresh")); - reloadButton->setObjectName("ReloadButton"); - addressBar->addWidget(reloadButton); + window->setLayout(layout); + window->show(); - QLineEdit* lineEdit = new QLineEdit; - lineEdit->setObjectName("AddressLineEdit"); - addressBar->addWidget(lineEdit); + SignalConnector* signalConnector = new SignalConnector(this, window); + } else { + fprintf(stderr, "Starting QQuick2 example...\n"); + // Use oxygen as a fallback. + if (QIcon::themeName().isEmpty()) + QIcon::setThemeName("oxygen"); - layout->addLayout(addressBar); + QQuickView* window = new QQuickView; + window_ = reinterpret_cast<gfx::NativeWindow>(window); + window->setGeometry(100,100, width, height); - window->setLayout(layout); - window->show(); + window->setSource(QUrl("lib/browser_window.qml")); + window->setResizeMode(QQuickView::SizeRootObjectToView); + window->setTitle("QQuick Example"); - // SignalConnector will act as a proxy for the QObject signals received from - // m_window. m_window will take ownership of the SignalConnector. - // The SignalConnector will search the children list of m_window - // for back/forward/reload buttons and for the address line edit. - // Therefore the layout must be set and completed before the SignalConnector - // is created. - SignalConnector* signalConnector = new SignalConnector(this, window); - } + window->show(); + + // SignalConnector will act as a proxy for the QObject signals received from + // m_window. m_window will take ownership of the SignalConnector. + // The SignalConnector will search the children list of m_window + // for back/forward/reload buttons and for the address line edit. + // Therefore the layout must be set and completed before the SignalConnector + // is created. + SignalConnector* signalConnector = new SignalConnector(this, window); + } + } } void Shell::PlatformSetContents() { if (headless_) - return; + return; content::RendererPreferences* rendererPrefs = web_contents_->GetMutableRendererPrefs(); rendererPrefs->use_custom_colors = true; @@ -129,15 +148,33 @@ void Shell::PlatformSetContents() rendererPrefs->caret_blink_interval = static_cast<double>(qApp->cursorFlashTime())/2000; web_contents_->GetRenderViewHost()->SyncRendererPrefs(); - WebContentsViewQt* content_view = static_cast<WebContentsViewQt*>(web_contents_->GetView()); - QVBoxLayout* layout = qobject_cast<QVBoxLayout*>(reinterpret_cast<QWidget*>(window_)->layout()); - if (layout) - layout->addLayout(content_view->windowContainer()); + if (isWidgets) { + WebContentsViewQt* content_view = static_cast<WebContentsViewQt*>(web_contents_->GetView()); + QVBoxLayout* layout = qobject_cast<QVBoxLayout*>(reinterpret_cast<QWidget*>(window_)->layout()); + if (layout) + layout->addLayout(content_view->windowContainer()->widget()); + } else { + QQuickView* view = reinterpret_cast<QQuickView*>(window_); + if (view->status() != QQuickView::Ready) + fprintf(stderr, "VIEW NOT READY!!!!\n"); + + QQuickItem* rootItem = view->rootObject(); + + QQuickItem* viewContainer = rootItem->findChild<QQuickItem*>("viewContainer"); + if (!viewContainer) + return; + + WebContentsViewQt* content_view = static_cast<WebContentsViewQt*>(web_contents_->GetView()); + QQuickItem* windowContainer = content_view->windowContainer()->qQuickItem(); + windowContainer->setParentItem(viewContainer); + windowContainer->setWidth(100); + windowContainer->setHeight(100); + } } void Shell::SizeTo(int width, int height) { - QT_NOT_YET_IMPLEMENTED + QT_NOT_YET_IMPLEMENTED } void Shell::PlatformResizeSubViews() @@ -147,10 +184,10 @@ void Shell::PlatformResizeSubViews() void Shell::Close() { - if (headless_) { - delete this; - return; - } + if (headless_) { + delete this; + return; + } } void Shell::OnBackButtonClicked(GtkWidget* widget) { } @@ -161,7 +198,7 @@ void Shell::OnReloadButtonClicked(GtkWidget* widget) { } void Shell::OnStopButtonClicked(GtkWidget* widget) { - Stop(); + Stop(); } void Shell::OnURLEntryActivate(GtkWidget* entry) { } @@ -169,8 +206,8 @@ void Shell::OnURLEntryActivate(GtkWidget* entry) { } // Callback for when the main window is destroyed. gboolean Shell::OnWindowDestroyed(GtkWidget* window) { - delete this; - return FALSE; // Don't stop this message. + delete this; + return FALSE; // Don't stop this message. } gboolean Shell::OnCloseWindowKeyPressed(GtkAccelGroup* accel_group, GObject* acceleratable, guint keyval, GdkModifierType modifier) @@ -181,24 +218,24 @@ gboolean Shell::OnCloseWindowKeyPressed(GtkAccelGroup* accel_group, GObject* acc gboolean Shell::OnNewWindowKeyPressed(GtkAccelGroup* accel_group, GObject* acceleratable, guint keyval, GdkModifierType modifier) { - ShellBrowserContext* browser_context = ShellContentBrowserClient::Get()->browser_context(); - Shell::CreateNewWindow(browser_context, GURL(), NULL, MSG_ROUTING_NONE, gfx::Size()); - return TRUE; + ShellBrowserContext* browser_context = ShellContentBrowserClient::Get()->browser_context(); + Shell::CreateNewWindow(browser_context, GURL(), NULL, MSG_ROUTING_NONE, gfx::Size()); + return TRUE; } gboolean Shell::OnHighlightURLView(GtkAccelGroup* accel_group, GObject* acceleratable, guint keyval, GdkModifierType modifier) { - return TRUE; + return TRUE; } void Shell::PlatformSetTitle(const string16& title) { - if (headless_) - return; + if (headless_) + return; - std::string title_utf8 = UTF16ToUTF8(title); - if (window_) - reinterpret_cast<QWidget*>(window_)->setWindowTitle(QString::fromStdString(title_utf8)); + // std::string title_utf8 = UTF16ToUTF8(title); + // if (window_) + // reinterpret_cast<QWidget*>(window_)->setWindowTitle(QString::fromStdString(title_utf8)); } } // namespace content diff --git a/lib/signal_connector.cpp b/lib/signal_connector.cpp index ccdd24c13..b2b2fdfa9 100644 --- a/lib/signal_connector.cpp +++ b/lib/signal_connector.cpp @@ -43,20 +43,36 @@ #include "content/shell/shell.h" #include <QObject> -#include <QWidget> +#include <QQuickView> +#include <QQuickItem> #include <QLineEdit> #include <QToolButton> #include <QDebug> -SignalConnector::SignalConnector(content::Shell* shell, QWidget* window) + +SignalConnector::SignalConnector(content::Shell* shell, QQuickView* window) : m_shell(shell) , m_window(window) { setParent(window); - m_addressLineEdit = m_window->findChild<QLineEdit*>("AddressLineEdit"); - m_backButton = m_window->findChild<QToolButton*>("BackButton"); - m_forwardButton = m_window->findChild<QToolButton*>("ForwardButton"); - m_reloadButton = m_window->findChild<QToolButton*>("ReloadButton"); + + QQuickItem* rootItem = window->rootObject(); + connect(rootItem, SIGNAL(load(QString)), this, SLOT(load(QString))); + QObject::connect(rootItem, SIGNAL(reload()), this, SLOT(reload())); + QObject::connect(rootItem, SIGNAL(goForward()), this, SLOT(goForward())); + QObject::connect(rootItem, SIGNAL(goBack()), this, SLOT(goBack())); +} + +SignalConnector::SignalConnector(content::Shell* shell, QWidget* window) + : m_shell(shell) + , m_widget(window) +{ + setParent(window); + + m_addressLineEdit = m_widget->findChild<QLineEdit*>("AddressLineEdit"); + m_backButton = m_widget->findChild<QToolButton*>("BackButton"); + m_forwardButton = m_widget->findChild<QToolButton*>("ForwardButton"); + m_reloadButton = m_widget->findChild<QToolButton*>("ReloadButton"); connect(m_addressLineEdit, SIGNAL(returnPressed()), this, SLOT(loadAddressFromAddressBar())); connect(m_backButton, SIGNAL(clicked()), this, SLOT(goBack())); diff --git a/lib/signal_connector.h b/lib/signal_connector.h index 3ed8923c1..b1444163a 100644 --- a/lib/signal_connector.h +++ b/lib/signal_connector.h @@ -44,7 +44,7 @@ #include <QObject> -class QWidget; +class QQuickView; class QToolButton; class QLineEdit; @@ -56,6 +56,7 @@ class SignalConnector : public QObject { Q_OBJECT public: + SignalConnector(content::Shell* shell, QQuickView* window); SignalConnector(content::Shell* shell, QWidget* window); public Q_SLOTS: @@ -67,7 +68,8 @@ public Q_SLOTS: private: content::Shell* m_shell; - QWidget* m_window; + QQuickView* m_window; + QWidget* m_widget; QLineEdit* m_addressLineEdit; QToolButton* m_forwardButton; diff --git a/lib/web_contents_view_qt.h b/lib/web_contents_view_qt.h index f5269141a..ed4e9af17 100644 --- a/lib/web_contents_view_qt.h +++ b/lib/web_contents_view_qt.h @@ -48,7 +48,7 @@ #include "content/port/browser/render_view_host_delegate_view.h" #include "content/port/browser/web_contents_view_port.h" #include "render_widget_host_view_qt.h" -#include "raster_window.h" +#include "native_view_container_qt.h" class WebContentsViewQt : public content::WebContentsViewPort @@ -56,7 +56,7 @@ class WebContentsViewQt { public: WebContentsViewQt(content::WebContents* web_contents) - : m_windowContainer(new RasterWindowContainer) + : m_windowContainer(new NativeViewContainerQt) { } content::RenderWidgetHostView* CreateViewForWidget(content::RenderWidgetHost* render_widget_host) @@ -106,10 +106,10 @@ 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 } - RasterWindowContainer* windowContainer() { return m_windowContainer; } + NativeViewContainerQt* windowContainer() { return m_windowContainer; } private: - RasterWindowContainer* m_windowContainer; + NativeViewContainerQt* m_windowContainer; }; #endif -- GitLab