summaryrefslogtreecommitdiffstats
path: root/WebKit/qt/Api/qgraphicswebview.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'WebKit/qt/Api/qgraphicswebview.cpp')
-rw-r--r--WebKit/qt/Api/qgraphicswebview.cpp186
1 files changed, 181 insertions, 5 deletions
diff --git a/WebKit/qt/Api/qgraphicswebview.cpp b/WebKit/qt/Api/qgraphicswebview.cpp
index b25b53b..8d4f3ba 100644
--- a/WebKit/qt/Api/qgraphicswebview.cpp
+++ b/WebKit/qt/Api/qgraphicswebview.cpp
@@ -22,24 +22,71 @@
#include "qgraphicswebview.h"
#include "qwebframe.h"
+#include "qwebframe_p.h"
#include "qwebpage.h"
#include "qwebpage_p.h"
#include "QWebPageClient.h"
-#include <QtGui/QGraphicsScene>
-#include <QtGui/QGraphicsView>
+#include <FrameView.h>
+#include <QtCore/qsharedpointer.h>
+#include <QtCore/qtimer.h>
#include <QtGui/qapplication.h>
+#include <QtGui/qgraphicsscene.h>
#include <QtGui/qgraphicssceneevent.h>
+#include <QtGui/qgraphicsview.h>
+#include <QtGui/qpixmapcache.h>
#include <QtGui/qstyleoption.h>
#if defined(Q_WS_X11)
#include <QX11Info>
#endif
+#include <Settings.h>
+
+#if USE(ACCELERATED_COMPOSITING)
+
+// the overlay is here for one reason only: to have the scroll-bars and other
+// extra UI elements appear on top of any QGraphicsItems created by CSS compositing layers
+class QGraphicsWebViewOverlay : public QGraphicsItem {
+ public:
+ QGraphicsWebViewOverlay(QGraphicsWebView* view)
+ :QGraphicsItem(view)
+ , q(view)
+ {
+ setPos(0, 0);
+ setFlag(QGraphicsItem::ItemUsesExtendedStyleOption, true);
+ setCacheMode(QGraphicsItem::DeviceCoordinateCache);
+ }
+
+ QRectF boundingRect() const
+ {
+ return q->boundingRect();
+ }
+
+ void paint(QPainter* painter, const QStyleOptionGraphicsItem* options, QWidget*)
+ {
+ q->page()->mainFrame()->render(painter, static_cast<QWebFrame::RenderLayer>(QWebFrame::AllLayers&(~QWebFrame::ContentsLayer)), options->exposedRect.toRect());
+ }
+
+ friend class QGraphicsWebView;
+ QGraphicsWebView* q;
+};
+
+#endif
class QGraphicsWebViewPrivate : public QWebPageClient {
public:
QGraphicsWebViewPrivate(QGraphicsWebView* parent)
: q(parent)
, page(0)
- {}
+#if USE(ACCELERATED_COMPOSITING)
+ , rootGraphicsLayer(0)
+ , shouldSync(true)
+#endif
+ {
+#if USE(ACCELERATED_COMPOSITING)
+ // the overlay and stays alive for the lifetime of
+ // this QGraphicsWebView as the scrollbars are needed when there's no compositing
+ q->setFlag(QGraphicsItem::ItemUsesExtendedStyleOption);
+#endif
+ }
virtual ~QGraphicsWebViewPrivate();
virtual void scroll(int dx, int dy, const QRect&);
@@ -61,14 +108,97 @@ public:
virtual QObject* pluginParent() const;
+ virtual QStyle* style() const;
+
+#if USE(ACCELERATED_COMPOSITING)
+ virtual void setRootGraphicsLayer(QGraphicsItem* layer);
+ virtual void markForSync(bool scheduleSync);
+ void updateCompositingScrollPosition();
+#endif
+
+ void syncLayers();
void _q_doLoadFinished(bool success);
QGraphicsWebView* q;
QWebPage* page;
+#if USE(ACCELERATED_COMPOSITING)
+ QGraphicsItem* rootGraphicsLayer;
+
+ // the overlay gets instantiated when the root layer is attached, and get deleted when it's detached
+ QSharedPointer<QGraphicsWebViewOverlay> overlay;
+
+ // we need to sync the layers if we get a special call from the WebCore
+ // compositor telling us to do so. We'll get that call from ChromeClientQt
+ bool shouldSync;
+
+ // we need to put the root graphics layer behind the overlay (which contains the scrollbar)
+ enum { RootGraphicsLayerZValue, OverlayZValue };
+#endif
};
QGraphicsWebViewPrivate::~QGraphicsWebViewPrivate()
{
+#if USE(ACCELERATED_COMPOSITING)
+ if (rootGraphicsLayer) {
+ // we don't need to delete the root graphics layer
+ // The lifecycle is managed in GraphicsLayerQt.cpp
+ rootGraphicsLayer->setParentItem(0);
+ q->scene()->removeItem(rootGraphicsLayer);
+ }
+#endif
+}
+
+#if USE(ACCELERATED_COMPOSITING)
+void QGraphicsWebViewPrivate::setRootGraphicsLayer(QGraphicsItem* layer)
+{
+ if (rootGraphicsLayer) {
+ rootGraphicsLayer->setParentItem(0);
+ q->scene()->removeItem(rootGraphicsLayer);
+ QWebFramePrivate::core(q->page()->mainFrame())->view()->syncCompositingStateRecursive();
+ }
+
+ rootGraphicsLayer = layer;
+
+ if (layer) {
+ layer->setFlag(QGraphicsItem::ItemClipsChildrenToShape, true);
+ layer->setParentItem(q);
+ layer->setZValue(RootGraphicsLayerZValue);
+ if (!overlay) {
+ overlay = QSharedPointer<QGraphicsWebViewOverlay>(new QGraphicsWebViewOverlay(q));
+ overlay->setZValue(OverlayZValue);
+ }
+ updateCompositingScrollPosition();
+ } else {
+ // we don't have compositing layers, we can render the scrollbars and content in one go
+ overlay.clear();
+ }
+}
+
+void QGraphicsWebViewPrivate::markForSync(bool scheduleSync)
+{
+ shouldSync = true;
+ if (scheduleSync)
+ QTimer::singleShot(0, q, SLOT(syncLayers()));
+}
+
+void QGraphicsWebViewPrivate::updateCompositingScrollPosition()
+{
+ if (rootGraphicsLayer && q->page() && q->page()->mainFrame()) {
+ const QPoint scrollPosition = q->page()->mainFrame()->scrollPosition();
+ rootGraphicsLayer->setPos(-scrollPosition);
+ }
+}
+
+#endif
+
+void QGraphicsWebViewPrivate::syncLayers()
+{
+#if USE(ACCELERATED_COMPOSITING)
+ if (shouldSync) {
+ QWebFramePrivate::core(q->page()->mainFrame())->view()->syncCompositingStateRecursive();
+ shouldSync = false;
+ }
+#endif
}
void QGraphicsWebViewPrivate::_q_doLoadFinished(bool success)
@@ -83,11 +213,18 @@ void QGraphicsWebViewPrivate::_q_doLoadFinished(bool success)
void QGraphicsWebViewPrivate::scroll(int dx, int dy, const QRect& rectToScroll)
{
q->scroll(qreal(dx), qreal(dy), QRectF(rectToScroll));
+#if USE(ACCELERATED_COMPOSITING)
+ updateCompositingScrollPosition();
+#endif
}
void QGraphicsWebViewPrivate::update(const QRect & dirtyRect)
{
q->update(QRectF(dirtyRect));
+#if USE(ACCELERATED_COMPOSITING)
+ if (overlay)
+ overlay->update(QRectF(dirtyRect));
+#endif
}
@@ -156,6 +293,11 @@ QObject* QGraphicsWebViewPrivate::pluginParent() const
return q;
}
+QStyle* QGraphicsWebViewPrivate::style() const
+{
+ return q->style();
+}
+
/*!
\class QGraphicsWebView
\brief The QGraphicsWebView class allows Web content to be added to a GraphicsView.
@@ -244,7 +386,11 @@ QGraphicsWebView::QGraphicsWebView(QGraphicsItem* parent)
#endif
setAcceptDrops(true);
setAcceptHoverEvents(true);
+#if QT_VERSION >= QT_VERSION_CHECK(4, 6, 0)
+ setAcceptTouchEvents(true);
+#endif
setFocusPolicy(Qt::StrongFocus);
+ setFlag(QGraphicsItem::ItemClipsChildrenToShape, true);
}
/*!
@@ -294,7 +440,12 @@ QWebPage* QGraphicsWebView::page() const
*/
void QGraphicsWebView::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget*)
{
- page()->mainFrame()->render(painter, option->exposedRect.toRect());
+#if USE(ACCELERATED_COMPOSITING)
+ page()->mainFrame()->render(painter, d->overlay ? QWebFrame::ContentsLayer : QWebFrame::AllLayers, option->exposedRect.toAlignedRect());
+ d->syncLayers();
+#else
+ page()->mainFrame()->render(painter, QWebFrame::AllLayers, option->exposedRect.toRect());
+#endif
}
/*! \reimp
@@ -302,6 +453,17 @@ void QGraphicsWebView::paint(QPainter* painter, const QStyleOptionGraphicsItem*
bool QGraphicsWebView::sceneEvent(QEvent* event)
{
// Re-implemented in order to allows fixing event-related bugs in patch releases.
+
+#if QT_VERSION >= QT_VERSION_CHECK(4, 6, 0)
+ if (d->page && (event->type() == QEvent::TouchBegin
+ || event->type() == QEvent::TouchEnd
+ || event->type() == QEvent::TouchUpdate)) {
+ d->page->event(event);
+ if (event->isAccepted())
+ return true;
+ }
+#endif
+
return QGraphicsWidget::sceneEvent(event);
}
@@ -411,6 +573,10 @@ void QGraphicsWebView::setPage(QWebPage* page)
d->page = page;
if (!d->page)
return;
+#if USE(ACCELERATED_COMPOSITING)
+ if (d->overlay)
+ d->overlay->prepareGeometryChange();
+#endif
d->page->d->client = d; // set the page client
QSize size = geometry().size().toSize();
@@ -494,7 +660,6 @@ QIcon QGraphicsWebView::icon() const
/*!
\property QGraphicsWebView::zoomFactor
- \since 4.5
\brief the zoom factor for the view
*/
@@ -515,6 +680,12 @@ qreal QGraphicsWebView::zoomFactor() const
*/
void QGraphicsWebView::updateGeometry()
{
+
+#if USE(ACCELERATED_COMPOSITING)
+ if (d->overlay)
+ d->overlay->prepareGeometryChange();
+#endif
+
QGraphicsWidget::updateGeometry();
if (!d->page)
@@ -530,6 +701,11 @@ void QGraphicsWebView::setGeometry(const QRectF& rect)
{
QGraphicsWidget::setGeometry(rect);
+#if USE(ACCELERATED_COMPOSITING)
+ if (d->overlay)
+ d->overlay->prepareGeometryChange();
+#endif
+
if (!d->page)
return;