Patch from Adam Treat to convert QWebFrame to a QFrame from a QAbstractScrollArea.
authorstaikos <staikos@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 6 Jul 2007 21:06:34 +0000 (21:06 +0000)
committerstaikos <staikos@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 6 Jul 2007 21:06:34 +0000 (21:06 +0000)
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@24069 268f45cc-cd09-0410-ab3c-d52691b4dbfc

15 files changed:
WebCore/ChangeLog
WebCore/page/qt/EventHandlerQt.cpp
WebCore/platform/ScrollView.h
WebCore/platform/Widget.h
WebCore/platform/qt/PlatformScrollBar.h
WebCore/platform/qt/PlatformScrollBarQt.cpp
WebCore/platform/qt/ScrollViewQt.cpp
WebCore/platform/qt/WidgetQt.cpp
WebKitQt/Api/qwebframe.cpp
WebKitQt/Api/qwebframe.h
WebKitQt/Api/qwebframe_p.h
WebKitQt/Api/qwebobjectpluginconnector.cpp
WebKitQt/ChangeLog
WebKitTools/ChangeLog
WebKitTools/DumpRenderTree/DumpRenderTree.qtproj/DumpRenderTree.cpp

index c96e49d3766cbc1724b11721f2a99d63d3652b65..a09960ee8e6602cd72578615a47724a5dfed2c9e 100644 (file)
@@ -1,3 +1,87 @@
+2007-07-06  Adam Treat  <adam@staikos.net>
+
+        Reviewed by George Staikos.
+
+        Convert QWebFrame to a QFrame from a scroll area.
+
+        * page/qt/EventHandlerQt.cpp:
+        (WebCore::EventHandler::passSubframeEventToSubframe):
+        (WebCore::EventHandler::passWheelEventToWidget):
+        (WebCore::EventHandler::createDraggingClipboard):
+        (WebCore::EventHandler::passMousePressEventToScrollbar):
+        * platform/ScrollView.h:
+        * platform/Widget.h:
+        * platform/qt/PlatformScrollBar.h:
+        * platform/qt/PlatformScrollBarQt.cpp:
+        (WebCore::PlatformScrollbar::setRect):
+        (WebCore::PlatformScrollbar::frameGeometry):
+        (WebCore::PlatformScrollbar::setFrameGeometry):
+        (WebCore::PlatformScrollbar::handleMouseMoveEvent):
+        (WebCore::PlatformScrollbar::handleMousePressEvent):
+        (WebCore::PlatformScrollbar::handleMouseReleaseEvent):
+        * platform/qt/ScrollViewQt.cpp:
+        (WebCore::ScrollView::ScrollViewPrivate::ScrollViewPrivate):
+        (WebCore::ScrollView::ScrollViewPrivate::~ScrollViewPrivate):
+        (WebCore::ScrollView::ScrollViewPrivate::setHasHorizontalScrollbar):
+        (WebCore::ScrollView::ScrollViewPrivate::setHasVerticalScrollbar):
+        (WebCore::ScrollView::ScrollViewPrivate::valueChanged):
+        (WebCore::ScrollView::ScrollViewPrivate::scrollBackingStore):
+        (WebCore::ScrollView::ScrollViewPrivate::windowClipRect):
+        (WebCore::ScrollView::ScrollView):
+        (WebCore::ScrollView::~ScrollView):
+        (WebCore::ScrollView::setScrollArea):
+        (WebCore::ScrollView::horizontalScrollBar):
+        (WebCore::ScrollView::verticalScrollBar):
+        (WebCore::ScrollView::updateContents):
+        (WebCore::ScrollView::update):
+        (WebCore::ScrollView::visibleWidth):
+        (WebCore::ScrollView::visibleHeight):
+        (WebCore::ScrollView::visibleContentRect):
+        (WebCore::ScrollView::setContentsPos):
+        (WebCore::ScrollView::resizeContents):
+        (WebCore::ScrollView::setFrameGeometry):
+        (WebCore::ScrollView::geometryChanged):
+        (WebCore::ScrollView::contentsX):
+        (WebCore::ScrollView::contentsY):
+        (WebCore::ScrollView::contentsWidth):
+        (WebCore::ScrollView::contentsHeight):
+        (WebCore::ScrollView::windowToContents):
+        (WebCore::ScrollView::contentsToWindow):
+        (WebCore::ScrollView::scrollOffset):
+        (WebCore::ScrollView::maximumScroll):
+        (WebCore::ScrollView::scrollBy):
+        (WebCore::ScrollView::scrollRectIntoViewRecursively):
+        (WebCore::ScrollView::hScrollbarMode):
+        (WebCore::ScrollView::vScrollbarMode):
+        (WebCore::ScrollView::suppressScrollbars):
+        (WebCore::ScrollView::setHScrollbarMode):
+        (WebCore::ScrollView::setVScrollbarMode):
+        (WebCore::ScrollView::setScrollbarsMode):
+        (WebCore::ScrollView::setStaticBackground):
+        (WebCore::ScrollView::inWindow):
+        (WebCore::ScrollView::updateScrollbars):
+        (WebCore::ScrollView::scrollbarUnderMouse):
+        (WebCore::ScrollView::addChild):
+        (WebCore::ScrollView::removeChild):
+        (WebCore::ScrollView::paint):
+        (WebCore::ScrollView::wheelEvent):
+        (WebCore::ScrollView::scroll):
+        (WebCore::ScrollView::windowResizerRect):
+        (WebCore::ScrollView::resizerOverlapsContent):
+        (WebCore::ScrollView::adjustOverlappingScrollbarCount):
+        (WebCore::ScrollView::setParent):
+        (WebCore::ScrollView::addToDirtyRegion):
+        (WebCore::ScrollView::scrollBackingStore):
+        (WebCore::ScrollView::updateBackingStore):
+        * platform/qt/WidgetQt.cpp:
+        (WebCore::WidgetPrivate::canvas):
+        (WebCore::WidgetPrivate::setGeometry):
+        (WebCore::WidgetPrivate::geometry):
+        (WebCore::Widget::setQWidget):
+        (WebCore::Widget::paint):
+        (WebCore::Widget::originalGeometry):
+        (WebCore::Widget::geometryChanged):
+
 2007-07-06  Anders Carlsson  <andersca@apple.com>
 
         Reviewed by Mitz.
index b59d9a259ac698991545208ae1b4c4df58a6ffcf..ea9111f3d5ea8f6a14c1993f6bccf0cfc98ee426 100644 (file)
@@ -110,17 +110,42 @@ bool EventHandler::eventActivatedView(const PlatformMouseEvent&) const
 
 bool EventHandler::passSubframeEventToSubframe(MouseEventWithHitTestResults& event, Frame* subframe, HitTestResult*)
 {
-    notImplemented();
-    return false;
+    Q_ASSERT(subframe);
+    PlatformMouseEvent ev = event.event();
+
+    QWidget *frame = subframe->view()->qwidget();
+
+    IntPoint mappedPos(frame->mapFromParent(ev.pos()));
+    IntPoint globalPos(ev.globalX(), ev.globalY());
+
+    PlatformMouseEvent mapped(mappedPos, globalPos, ev.button(), ev.eventType(),
+                              ev.clickCount(), ev.shiftKey(), ev.ctrlKey(),
+                              ev.altKey(), ev.metaKey(), ev.timestamp());
+
+    switch(ev.eventType()) {
+    case MouseEventMoved:
+        return subframe->eventHandler()->handleMouseMoveEvent(mapped);
+    case MouseEventPressed:
+        return subframe->eventHandler()->handleMousePressEvent(mapped);
+    case MouseEventReleased:
+        return subframe->eventHandler()->handleMouseReleaseEvent(mapped);
+    case MouseEventScroll:
+        return subframe->eventHandler()->handleMouseMoveEvent(mapped);
+    default:
+      return false;
+    }
 }
 
 bool EventHandler::passWheelEventToWidget(PlatformWheelEvent& event, Widget* widget)
 {
-    notImplemented();
-    return false;
+    Q_ASSERT(widget);
+    if (!widget->isFrameView())
+        return false;
+
+    return static_cast<FrameView*>(widget)->frame()->eventHandler()->handleWheelEvent(event);
 }
-    
-Clipboard* EventHandler::createDraggingClipboard() const 
+
+Clipboard* EventHandler::createDraggingClipboard() const
 {
     return new ClipboardQt(ClipboardWritable, true);
 }
@@ -142,6 +167,7 @@ bool EventHandler::passMouseReleaseEventToSubframe(MouseEventWithHitTestResults&
 
 bool EventHandler::passMousePressEventToScrollbar(MouseEventWithHitTestResults& event, PlatformScrollbar* scrollbar)
 {
+    Q_ASSERT(scrollbar);
     return scrollbar->handleMousePressEvent(event.event());
 }
 
index 98fad9a3e9a89585fd53e50a613b52c70ec9742e..c8601a0d02310df491f1209408fd1b467f004be3 100644 (file)
@@ -32,7 +32,7 @@
 #include <wtf/HashSet.h>
 
 #if PLATFORM(QT)
-class QAbstractScrollArea;
+class QRegion;
 #endif
 
 #if PLATFORM(GDK)
@@ -170,14 +170,31 @@ namespace WebCore {
         ScrollView();
         ~ScrollView();
 
-        void setScrollArea(QAbstractScrollArea*);
-        void setAllowsScrolling(bool);
+        void setScrollArea(QWidget*);
+
+        virtual void paint(GraphicsContext*, const IntRect&);
+
+        virtual void geometryChanged() const;
+        virtual void setFrameGeometry(const IntRect&);
+
+        IntRect windowResizerRect();
+        bool resizerOverlapsContent() const;
+        void adjustOverlappingScrollbarCount(int overlapDelta);
+
+        virtual void setParent(ScrollView*);
+
+        void addToDirtyRegion(const IntRect&);
+        void scrollBackingStore(int dx, int dy, const IntRect& scrollViewRect, const IntRect& clipRect);
+        void updateBackingStore();
+
+        PlatformScrollbar *horizontalScrollBar() const;
+        PlatformScrollbar *verticalScrollBar() const;
 
     private:
-        QAbstractScrollArea* m_area;
-        bool m_allowsScrolling;
-        int  m_width;
-        int  m_height;
+        void updateScrollbars(const IntSize& desiredOffset);
+        IntSize maximumScroll() const;
+        class ScrollViewPrivate;
+        ScrollViewPrivate* m_data;
 #endif
     };
 
index 29d7d040907bdf6c662088a236802d5cf8450b1e..36f4f5d1dc7d359223ac8f5c763692efa8434648 100644 (file)
@@ -147,6 +147,8 @@ namespace WebCore {
         void setQWidget(QWidget*);
         void setParent(ScrollView*);
         ScrollView* parent() const;
+        IntRect originalGeometry() const;
+        virtual void geometryChanged() const;
 #endif
 
 #if PLATFORM(MAC)
index 3aa2284b9bd1776598c457f8c9bbe0590ca93061..2cd1b213f42a6fc1ee461616cd9ce91748db5c73 100644 (file)
@@ -44,6 +44,10 @@ public:
     virtual int width() const;
     virtual int height() const;
     virtual void setRect(const IntRect&);
+
+    virtual IntRect frameGeometry() const;
+    virtual void setFrameGeometry(const IntRect& r);
+
     virtual void setEnabled(bool);
     virtual void paint(GraphicsContext*, const IntRect& damageRect);
 
index a19a166f1295c914330b26ca638f48b69871a8a0..c292fec43ff0a25af8b92f94955b53d44e42a3be 100644 (file)
@@ -98,6 +98,16 @@ int PlatformScrollbar::height() const
 }
 
 void PlatformScrollbar::setRect(const IntRect& rect)
+{
+    setFrameGeometry(rect);
+}
+
+IntRect PlatformScrollbar::frameGeometry() const
+{
+    return m_opt.rect;
+}
+
+void PlatformScrollbar::setFrameGeometry(const IntRect& rect)
 {
     m_opt.rect = rect;
 }
@@ -185,6 +195,7 @@ int PlatformScrollbar::trackLength() const
 
 bool PlatformScrollbar::handleMouseMoveEvent(const PlatformMouseEvent& evt)
 {
+    //qDebug() << "PlatformScrollbar::handleMouseMoveEvent" << m_opt.rect << evt.pos() << endl;
     m_opt.state |= QStyle::State_MouseOver;
     const QPoint ctlPt = m_opt.rect.topLeft();
     m_opt.rect.moveTo(0, 0);
@@ -259,6 +270,7 @@ bool PlatformScrollbar::handleMouseOutEvent(const PlatformMouseEvent& evt)
 
 bool PlatformScrollbar::handleMousePressEvent(const PlatformMouseEvent& evt)
 {
+    //qDebug() << "PlatformScrollbar::handleMousePressEvent" << m_opt.rect << evt.pos() << endl;
     const QPoint ctlPt = m_opt.rect.topLeft();
     m_opt.rect.moveTo(0, 0);
     QStyle::SubControl sc = QApplication::style()->hitTestComplexControl(QStyle::CC_ScrollBar, &m_opt, QPoint(evt.pos()) - ctlPt, 0);
@@ -285,6 +297,7 @@ bool PlatformScrollbar::handleMousePressEvent(const PlatformMouseEvent& evt)
 
 bool PlatformScrollbar::handleMouseReleaseEvent(const PlatformMouseEvent& evt)
 {
+    //qDebug() << "PlatformScrollbar::handleMouseReleaseEvent" << m_opt.rect << evt.pos() << endl;
     m_opt.state &= ~QStyle::State_Sunken;
     m_pressedPart = QStyle::SC_None;
     m_pressedPos = 0;
index 7b1590c3b53910236c9f4c1b4a6d7c7836002b1a..9a85fcdf821eb4ba30c77eee9946f63a378c39ed 100644 (file)
 #include "FloatRect.h"
 #include "IntPoint.h"
 #include "PlatformMouseEvent.h"
+#include "PlatformWheelEvent.h"
 #include "NotImplemented.h"
 #include "Frame.h"
+#include "Page.h"
+#include "GraphicsContext.h"
+#include "PlatformScrollBar.h"
 
-#include <QAbstractScrollArea>
 #include <QDebug>
-#include <QScrollBar>
+#include <QWidget>
+#include <QPainter>
+
+// #define DEBUG_SCROLLVIEW
 
 namespace WebCore {
 
+class ScrollView::ScrollViewPrivate : public ScrollbarClient
+{
+public:
+    ScrollViewPrivate(ScrollView* view)
+      : m_view(view)
+      , m_hasStaticBackground(false)
+      , m_scrollbarsSuppressed(false)
+      , m_inUpdateScrollbars(false)
+      , m_scrollbarsAvoidingResizer(0)
+      , m_vScrollbarMode(ScrollbarAuto)
+      , m_hScrollbarMode(ScrollbarAuto)
+      , m_area(0)
+    {
+        setHasHorizontalScrollbar(true);
+        setHasVerticalScrollbar(true);
+    }
+
+    ~ScrollViewPrivate()
+    {
+        setHasHorizontalScrollbar(false);
+        setHasVerticalScrollbar(false);
+    }
+
+    void setHasHorizontalScrollbar(bool hasBar);
+    void setHasVerticalScrollbar(bool hasBar);
+
+    virtual void valueChanged(Scrollbar*);
+    virtual IntRect windowClipRect() const;
+
+    void scrollBackingStore(const IntSize& scrollDelta);
+
+    ScrollView* m_view;
+    IntSize m_scrollOffset;
+    IntSize m_contentsSize;
+    bool m_hasStaticBackground;
+    bool m_scrollbarsSuppressed;
+    bool m_inUpdateScrollbars;
+    int m_scrollbarsAvoidingResizer;
+    ScrollbarMode m_vScrollbarMode;
+    ScrollbarMode m_hScrollbarMode;
+    RefPtr<PlatformScrollbar> m_vBar;
+    RefPtr<PlatformScrollbar> m_hBar;
+    QRegion m_dirtyRegion;
+    HashSet<Widget*> m_children;
+    QWidget* m_area;
+};
+
+void ScrollView::ScrollViewPrivate::setHasHorizontalScrollbar(bool hasBar)
+{
+    if (Scrollbar::hasPlatformScrollbars()) {
+        if (hasBar && !m_hBar) {
+            m_hBar = new PlatformScrollbar(this, HorizontalScrollbar, RegularScrollbar);
+            m_view->addChild(m_hBar.get());
+        } else if (!hasBar && m_hBar) {
+            m_view->removeChild(m_hBar.get());;
+            m_hBar = 0;
+        }
+    }
+}
+
+void ScrollView::ScrollViewPrivate::setHasVerticalScrollbar(bool hasBar)
+{
+    if (Scrollbar::hasPlatformScrollbars()) {
+        if (hasBar && !m_vBar) {
+            m_vBar = new PlatformScrollbar(this, VerticalScrollbar, RegularScrollbar);
+            m_view->addChild(m_vBar.get());
+        } else if (!hasBar && m_vBar) {
+            m_view->removeChild(m_vBar.get());
+            m_vBar = 0;
+        }
+    }
+}
+
+void ScrollView::ScrollViewPrivate::valueChanged(Scrollbar* bar)
+{
+    // Figure out if we really moved.
+    IntSize newOffset = m_scrollOffset;
+    if (bar) {
+        if (bar == m_hBar)
+            newOffset.setWidth(bar->value());
+        else if (bar == m_vBar)
+            newOffset.setHeight(bar->value());
+    }
+    IntSize scrollDelta = newOffset - m_scrollOffset;
+    if (scrollDelta == IntSize())
+        return;
+    m_scrollOffset = newOffset;
+
+    if (m_scrollbarsSuppressed)
+        return;
+
+    scrollBackingStore(scrollDelta);
+    static_cast<FrameView*>(m_view)->frame()->sendScrollEvent();
+}
+
+void ScrollView::ScrollViewPrivate::scrollBackingStore(const IntSize& scrollDelta)
+{
+    // Since scrolling is double buffered, we will be blitting the scroll view's intersection
+    // with the clip rect every time to keep it smooth.
+    IntRect clipRect = m_view->windowClipRect();
+    QPoint origin = m_area->mapToParent(QPoint(0, 0));
+    IntRect scrollViewRect = IntRect(origin.x(), origin.y(), m_view->visibleWidth(), m_view->visibleHeight());
+    IntRect updateRect = clipRect;
+    updateRect.intersect(scrollViewRect);
+
+    if (!m_hasStaticBackground) // The main frame can just blit the WebView window
+       // FIXME: Find a way to blit subframes without blitting overlapping content
+       m_view->scrollBackingStore(-scrollDelta.width(), -scrollDelta.height(), scrollViewRect, clipRect);
+    else  {
+       // We need to go ahead and repaint the entire backing store.  Do it now before moving the
+       // plugins.
+       m_view->addToDirtyRegion(updateRect);
+       m_view->updateBackingStore();
+    }
+
+    m_view->geometryChanged();
+
+    // Now update the window (which should do nothing but a blit of the backing store's updateRect and so should
+    // be very fast).
+    m_area->update();
+}
+
+IntRect ScrollView::ScrollViewPrivate::windowClipRect() const
+{
+    if (!m_view->parent())
+        return static_cast<const FrameView*>(m_view)->windowClipRect(false);
+
+    QRect clipRect = m_view->frameGeometry();
+
+    PlatformScrollbar *phBar = m_view->parent()->horizontalScrollBar();
+    PlatformScrollbar *pvBar = m_view->parent()->verticalScrollBar();
+
+    QRegion h;
+    if (phBar) {
+      QRect hrect = phBar->frameGeometry();
+      hrect.moveLeft(clipRect.left()); //anchor
+      hrect.setHeight(clipRect.height() - hrect.height());
+      h = QRegion(hrect);
+    }
+
+    QRegion v;
+    if (pvBar) {
+      QRect vrect = pvBar->frameGeometry();
+      vrect.moveTop(clipRect.top()); //anchor
+      vrect.setWidth(clipRect.width() - vrect.width());
+      v = QRegion(vrect);
+    }
+
+    QRegion clipRegion(clipRect);
+
+    clipRect = clipRegion.subtracted(h).subtracted(v).boundingRect();
+    clipRect.moveTopLeft(QPoint(0, 0));
+
+    return clipRect;
+}
+
 ScrollView::ScrollView()
-    : m_area(0), m_allowsScrolling(true),
-      m_width(0), m_height(0)
+    : m_data(new ScrollViewPrivate(this))
 {
 }
 
 ScrollView::~ScrollView()
 {
+    delete m_data;
 }
 
-void ScrollView::setScrollArea(QAbstractScrollArea* area)
+void ScrollView::setScrollArea(QWidget* area)
 {
-    m_area = area;
-    Widget::setQWidget(m_area);
+    m_data->m_area = area;
+    Widget::setQWidget(m_data->m_area);
 }
 
-void ScrollView::updateContents(const IntRect& updateRect, bool now)
+PlatformScrollbar *ScrollView::horizontalScrollBar() const
 {
-    //Update is fine for both now=true/false cases
-    if (m_area && m_area->viewport() && !updateRect.isEmpty()) {
-        IntRect realCoords(updateRect.x() - scrollOffset().width(),
-                           updateRect.y() - scrollOffset().height(),
-                           updateRect.width(), updateRect.height());
-        m_area->viewport()->update(realCoords);
-    }
+    return m_data->m_hBar.get();
 }
 
-int ScrollView::visibleWidth() const
+PlatformScrollbar *ScrollView::verticalScrollBar() const
+{
+    return m_data->m_vBar.get();
+}
+
+void ScrollView::updateContents(const IntRect& rect, bool now)
 {
-    if (!m_area)
-        return 0;
+    if (rect.isEmpty())
+        return;
+
+    IntPoint windowPoint = contentsToWindow(rect.location());
+    IntRect containingWindowRect = rect;
+    containingWindowRect.setLocation(windowPoint);
 
-    int scrollBarAdjustments = 0;
-    if (m_area->verticalScrollBar()->isVisible())
-        scrollBarAdjustments = m_area->verticalScrollBar()->width();
-    return m_area->maximumViewportSize().width() - scrollBarAdjustments;
+    // Cache the dirty spot.
+    addToDirtyRegion(containingWindowRect);
+
+    m_data->m_area->update(rect);
 }
 
-int ScrollView::visibleHeight() const
+void ScrollView::update()
 {
-    if (!m_area)
-        return 0;
+    m_data->m_area->update();
+}
 
-    int scrollBarAdjustments = 0;
-    if (m_area->horizontalScrollBar()->isVisible())
-        scrollBarAdjustments = m_area->horizontalScrollBar()->height();
-    return m_area->maximumViewportSize().height()-scrollBarAdjustments;
+int ScrollView::visibleWidth() const
+{
+    return width() - (m_data->m_vBar ? m_data->m_vBar->width() : 0);
 }
 
-FloatRect ScrollView::visibleContentRect() const
+int ScrollView::visibleHeight() const
 {
-    if (!m_area)
-        return FloatRect();
+    return height() - (m_data->m_hBar ? m_data->m_hBar->height() : 0);
+}
 
-    return FloatRect(m_area->horizontalScrollBar()->value(),
-                     m_area->verticalScrollBar()->value(),
-                     visibleWidth(),
-                     visibleHeight());
+FloatRect ScrollView::visibleContentRect() const
+{
+    return FloatRect(contentsX(), contentsY(), visibleWidth(), visibleHeight());
 }
 
 FloatRect ScrollView::visibleContentRectConsideringExternalScrollers() const
@@ -112,182 +275,340 @@ FloatRect ScrollView::visibleContentRectConsideringExternalScrollers() const
 
 void ScrollView::setContentsPos(int newX, int newY)
 {
-    if (!m_area)
-        return;
-    m_area->horizontalScrollBar()->setValue(newX);
-    m_area->verticalScrollBar()->setValue(newY);
+    int dx = newX - contentsX();
+    int dy = newY - contentsY();
+    scrollBy(dx, dy);
 }
 
 void ScrollView::resizeContents(int w, int h)
 {
-    m_width = w; m_height = h;
-    QAbstractSlider* hbar = m_area->horizontalScrollBar();
-    QAbstractSlider* vbar = m_area->verticalScrollBar();
+    IntSize newContentsSize(w, h);
+    if (m_data->m_contentsSize != newContentsSize) {
+        m_data->m_contentsSize = newContentsSize;
+        updateScrollbars(m_data->m_scrollOffset);
+    }
+}
+
+void ScrollView::setFrameGeometry(const IntRect& newGeometry)
+{
+    IntRect oldGeometry = frameGeometry();
+    Widget::setFrameGeometry(newGeometry);
+
+    if (newGeometry == oldGeometry)
+        return;
+
+    if (newGeometry.width() != oldGeometry.width() || newGeometry.height() != oldGeometry.height()) {
+        updateScrollbars(m_data->m_scrollOffset);
+        static_cast<FrameView*>(this)->setNeedsLayout();
+    }
+
+    geometryChanged();
+}
 
-    const QSize viewportSize = m_area->viewport()->size();
-    QSize docSize = QSize(contentsWidth(), contentsHeight());
+void ScrollView::geometryChanged() const
+{
+    Widget::geometryChanged();
 
-    hbar->setRange(0, docSize.width() - viewportSize.width());
-    hbar->setPageStep(viewportSize.width());
+    if (parent()) {
+        //Set the mask so we don't receive mouse events for parent scrollbars
+        IntRect clipRect = m_data->windowClipRect();
+        m_data->m_area->setMask(QRegion(clipRect));
+    }
 
-    vbar->setRange(0, docSize.height() - viewportSize.height());
-    vbar->setPageStep(viewportSize.height());
+    HashSet<Widget*>::const_iterator end = m_data->m_children.end();
+    for (HashSet<Widget*>::const_iterator current = m_data->m_children.begin(); current != end; ++current)
+        (*current)->geometryChanged();
 }
 
+
 int ScrollView::contentsX() const
 {
-    if (!m_area)
-        return 0;
-    return m_area->horizontalScrollBar()->value();
+    return scrollOffset().width();
 }
 
 int ScrollView::contentsY() const
 {
-    if (!m_area)
-        return 0;
-    return m_area->verticalScrollBar()->value();
+    return scrollOffset().height();
 }
 
 int ScrollView::contentsWidth() const
 {
-    return m_width;
+    return m_data->m_contentsSize.width();
 }
 
 int ScrollView::contentsHeight() const
 {
-    return m_height;
+    return m_data->m_contentsSize.height();
 }
 
-
-IntPoint ScrollView::contentsToWindow(const IntPoint& point) const
+IntPoint ScrollView::windowToContents(const IntPoint& windowPoint) const
 {
-    QAbstractSlider* hbar = m_area->horizontalScrollBar();
-    QAbstractSlider* vbar = m_area->verticalScrollBar();
-
-    return IntPoint(point.x() - hbar->value(), point.y() - vbar->value());
+//    qDebug() << "windowToContents" << windowPoint << endl;
+    return windowPoint + scrollOffset();
 }
 
-IntPoint ScrollView::windowToContents(const IntPoint& point) const
+IntPoint ScrollView::contentsToWindow(const IntPoint& contentsPoint) const
 {
-    QAbstractSlider* hbar = m_area->horizontalScrollBar();
-    QAbstractSlider* vbar = m_area->verticalScrollBar();
-
-    return IntPoint(point.x() + hbar->value(), point.y() + vbar->value());
+//    qDebug() << "contentsToWindow" << contentsPoint << endl;
+    return contentsPoint - scrollOffset();
 }
 
 IntSize ScrollView::scrollOffset() const
 {
-    if (!m_area)
-        return IntSize();
-    return IntSize(m_area->horizontalScrollBar()->value(), m_area->verticalScrollBar()->value());
+    return m_data->m_scrollOffset;
+}
+
+IntSize ScrollView::maximumScroll() const
+{
+    IntSize delta = (m_data->m_contentsSize - IntSize(visibleWidth(), visibleHeight())) - scrollOffset();
+    delta.clampNegativeToZero();
+    return delta;
 }
 
 void ScrollView::scrollBy(int dx, int dy)
 {
-    if (!m_area)
+    IntSize scrollOffset = m_data->m_scrollOffset;
+    IntSize newScrollOffset = scrollOffset + IntSize(dx, dy).shrunkTo(maximumScroll());
+    newScrollOffset.clampNegativeToZero();
+
+    if (newScrollOffset == scrollOffset)
         return;
-    m_area->horizontalScrollBar()->setValue(m_area->horizontalScrollBar()->value() + dx);
-    m_area->verticalScrollBar()->setValue(m_area->verticalScrollBar()->value() + dy);
+
+    updateScrollbars(newScrollOffset);
 }
 
-ScrollbarMode ScrollView::hScrollbarMode() const
+void ScrollView::scrollRectIntoViewRecursively(const IntRect& r)
 {
-    if (!m_area)
-        return ScrollbarAuto;
-    switch (m_area->horizontalScrollBarPolicy())
-    {
-        case Qt::ScrollBarAsNeeded:
-            return ScrollbarAuto;
-        case Qt::ScrollBarAlwaysOff:
-            return ScrollbarAlwaysOff;
-        case Qt::ScrollBarAlwaysOn:
-            return ScrollbarAlwaysOn;
+    IntPoint p(max(0, r.x()), max(0, r.y()));
+    ScrollView* view = this;
+    ScrollView* oldView = view;
+    while (view) {
+        view->setContentsPos(p.x(), p.y());
+        p.move(view->x() - view->scrollOffset().width(), view->y() - view->scrollOffset().height());
+        view = static_cast<ScrollView*>(parent());
     }
-
-    return ScrollbarAuto;
 }
 
-ScrollbarMode ScrollView::vScrollbarMode() const
+WebCore::ScrollbarMode ScrollView::hScrollbarMode() const
 {
-    if (!m_area)
-        return ScrollbarAuto;
-    switch (m_area->verticalScrollBarPolicy())
-    {
-        case Qt::ScrollBarAsNeeded:
-            return ScrollbarAuto;
-        case Qt::ScrollBarAlwaysOff:
-            return ScrollbarAlwaysOff;
-        case Qt::ScrollBarAlwaysOn:
-            return ScrollbarAlwaysOn;
-    }
+    return m_data->m_hScrollbarMode;
+}
 
-    return ScrollbarAuto;
+WebCore::ScrollbarMode ScrollView::vScrollbarMode() const
+{
+    return m_data->m_vScrollbarMode;
 }
 
-void ScrollView::suppressScrollbars(bool suppressed, bool /* repaintOnSuppress */)
+void ScrollView::suppressScrollbars(bool suppressed, bool repaintOnSuppress)
 {
-    setScrollbarsMode(suppressed ? ScrollbarAlwaysOff : ScrollbarAuto);
+    m_data->m_scrollbarsSuppressed = suppressed;
+    if (repaintOnSuppress && !suppressed) {
+        if (m_data->m_hBar)
+            m_data->m_hBar->invalidate();
+        if (m_data->m_vBar)
+            m_data->m_vBar->invalidate();
+
+        // Invalidate the scroll corner too on unsuppress.
+        IntRect hCorner;
+        if (m_data->m_hBar && width() - m_data->m_hBar->width() > 0) {
+            hCorner = IntRect(m_data->m_hBar->width(),
+                              height() - m_data->m_hBar->height(),
+                              width() - m_data->m_hBar->width(),
+                              m_data->m_hBar->height());
+            invalidateRect(hCorner);
+        }
+
+        if (m_data->m_vBar && height() - m_data->m_vBar->height() > 0) {
+            IntRect vCorner(width() - m_data->m_vBar->width(),
+                            m_data->m_vBar->height(),
+                            m_data->m_vBar->width(),
+                            height() - m_data->m_vBar->height());
+            if (vCorner != hCorner)
+                invalidateRect(vCorner);
+        }
+    }
 }
 
 void ScrollView::setHScrollbarMode(ScrollbarMode newMode)
 {
-    if (!m_area || !m_allowsScrolling)
-        return;
-    switch (newMode)
-    {
-        case ScrollbarAuto:
-            m_area->setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded);
-            break;
-        case ScrollbarAlwaysOff:
-            m_area->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
-            break;
-        case ScrollbarAlwaysOn:
-            m_area->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
-            break;
+    if (m_data->m_hScrollbarMode != newMode) {
+        m_data->m_hScrollbarMode = newMode;
+        updateScrollbars(m_data->m_scrollOffset);
     }
 }
 
 void ScrollView::setVScrollbarMode(ScrollbarMode newMode)
 {
-    if (!m_area || !m_allowsScrolling)
-        return;
-    switch (newMode)
-    {
-        case ScrollbarAuto:
-            m_area->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
-            break;
-        case ScrollbarAlwaysOff:
-            m_area->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
-            break;
-        case ScrollbarAlwaysOn:
-            m_area->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
-            break;
+    if (m_data->m_vScrollbarMode != newMode) {
+        m_data->m_vScrollbarMode = newMode;
+        updateScrollbars(m_data->m_scrollOffset);
     }
 }
 
 void ScrollView::setScrollbarsMode(ScrollbarMode newMode)
 {
-    setHScrollbarMode(newMode);
-    setVScrollbarMode(newMode);
+    if (m_data->m_hScrollbarMode != newMode ||
+        m_data->m_vScrollbarMode != newMode) {
+        m_data->m_hScrollbarMode = m_data->m_vScrollbarMode = newMode;
+        updateScrollbars(m_data->m_scrollOffset);
+    }
 }
 
 void ScrollView::setStaticBackground(bool flag)
 {
-    if (flag) {
-        QPalette pal = m_area->viewport()->palette();
-        pal.setBrush(QPalette::Background, QBrush(QColor(Qt::transparent)));
-        m_area->viewport()->setPalette(pal);
-        m_area->viewport()->setAutoFillBackground(false);
-    } else {
-        m_area->viewport()->setAutoFillBackground(true);
+    m_data->m_hasStaticBackground = flag;
+}
+
+bool ScrollView::inWindow() const
+{
+    return true;
+}
+
+void ScrollView::updateScrollbars(const IntSize& desiredOffset)
+{
+    // Don't allow re-entrancy into this function.
+    if (m_data->m_inUpdateScrollbars)
+        return;
+
+    // FIXME: This code is here so we don't have to fork FrameView.h/.cpp.
+    // In the end, FrameView should just merge with ScrollView.
+    if (static_cast<const FrameView*>(this)->frame()->prohibitsScrolling())
+        return;
+    
+    m_data->m_inUpdateScrollbars = true;
+
+    bool hasVerticalScrollbar = m_data->m_vBar;
+    bool hasHorizontalScrollbar = m_data->m_hBar;
+    bool oldHasVertical = hasVerticalScrollbar;
+    bool oldHasHorizontal = hasHorizontalScrollbar;
+    ScrollbarMode hScroll = m_data->m_hScrollbarMode;
+    ScrollbarMode vScroll = m_data->m_vScrollbarMode;
+    
+    const int cVerticalWidth = PlatformScrollbar::verticalScrollbarWidth();
+    const int cHorizontalHeight = PlatformScrollbar::horizontalScrollbarHeight();
+
+    for (int pass = 0; pass < 2; pass++) {
+        bool scrollsVertically;
+        bool scrollsHorizontally;
+
+        if (!m_data->m_scrollbarsSuppressed && (hScroll == ScrollbarAuto || vScroll == ScrollbarAuto)) {
+            // Do a layout if pending before checking if scrollbars are needed.
+            if (hasVerticalScrollbar != oldHasVertical || hasHorizontalScrollbar != oldHasHorizontal)
+                static_cast<FrameView*>(this)->layout();
+             
+            scrollsVertically = (vScroll == ScrollbarAlwaysOn) || (vScroll == ScrollbarAuto && contentsHeight() > height());
+            if (scrollsVertically)
+                scrollsHorizontally = (hScroll == ScrollbarAlwaysOn) || (hScroll == ScrollbarAuto && contentsWidth() + cVerticalWidth > width());
+            else {
+                scrollsHorizontally = (hScroll == ScrollbarAlwaysOn) || (hScroll == ScrollbarAuto && contentsWidth() > width());
+                if (scrollsHorizontally)
+                    scrollsVertically = (vScroll == ScrollbarAlwaysOn) || (vScroll == ScrollbarAuto && contentsHeight() + cHorizontalHeight > height());
+            }
+        }
+        else {
+            scrollsHorizontally = (hScroll == ScrollbarAuto) ? hasHorizontalScrollbar : (hScroll == ScrollbarAlwaysOn);
+            scrollsVertically = (vScroll == ScrollbarAuto) ? hasVerticalScrollbar : (vScroll == ScrollbarAlwaysOn);
+        }
+        
+        if (hasVerticalScrollbar != scrollsVertically) {
+            m_data->setHasVerticalScrollbar(scrollsVertically);
+            hasVerticalScrollbar = scrollsVertically;
+        }
+
+        if (hasHorizontalScrollbar != scrollsHorizontally) {
+            m_data->setHasHorizontalScrollbar(scrollsHorizontally);
+            hasHorizontalScrollbar = scrollsHorizontally;
+        }
+    }
+    
+    // Set up the range (and page step/line step).
+    IntSize maxScrollPosition(contentsWidth() - visibleWidth(), contentsHeight() - visibleHeight());
+    IntSize scroll = desiredOffset.shrunkTo(maxScrollPosition);
+    scroll.clampNegativeToZero();
+    if (m_data->m_hBar) {
+        int clientWidth = visibleWidth();
+        m_data->m_hBar->setEnabled(contentsWidth() > clientWidth);
+        int pageStep = (clientWidth - PAGE_KEEP);
+        if (pageStep < 0) pageStep = clientWidth;
+        IntRect oldRect(m_data->m_hBar->frameGeometry());
+        IntRect hBarRect = IntRect(0,
+                                   height() - m_data->m_hBar->height(),
+                                   width() - (m_data->m_vBar ? m_data->m_vBar->width() : 0),
+                                   m_data->m_hBar->height());
+        m_data->m_hBar->setRect(hBarRect);
+        if (!m_data->m_scrollbarsSuppressed && oldRect != m_data->m_hBar->frameGeometry())
+            m_data->m_hBar->invalidate();
+
+        m_data->m_hBar->setSteps(LINE_STEP, pageStep);
+        m_data->m_hBar->setProportion(clientWidth, contentsWidth());
+        m_data->m_hBar->setValue(scroll.width());
+    } 
+
+    if (m_data->m_vBar) {
+        int clientHeight = visibleHeight();
+        m_data->m_vBar->setEnabled(contentsHeight() > clientHeight);
+        int pageStep = (clientHeight - PAGE_KEEP);
+        if (pageStep < 0) pageStep = clientHeight;
+        IntRect oldRect(m_data->m_vBar->frameGeometry());
+        IntRect vBarRect = IntRect(width() - m_data->m_vBar->width(), 
+                                   0,
+                                   m_data->m_vBar->width(),
+                                   height() - (m_data->m_hBar ? m_data->m_hBar->height() : 0));
+        m_data->m_vBar->setRect(vBarRect);
+        if (!m_data->m_scrollbarsSuppressed && oldRect != m_data->m_vBar->frameGeometry())
+            m_data->m_vBar->invalidate();
+
+        m_data->m_vBar->setSteps(LINE_STEP, pageStep);
+        m_data->m_vBar->setProportion(clientHeight, contentsHeight());
+        m_data->m_vBar->setValue(scroll.height());
+    }
+
+    if (oldHasVertical != (m_data->m_vBar != 0) || oldHasHorizontal != (m_data->m_hBar != 0))
+        geometryChanged();
+
+    // See if our offset has changed in a situation where we might not have scrollbars.
+    // This can happen when editing a body with overflow:hidden and scrolling to reveal selection.
+    // It can also happen when maximizing a window that has scrollbars (but the new maximized result
+    // does not).
+    IntSize scrollDelta = scroll - m_data->m_scrollOffset;
+    if (scrollDelta != IntSize()) {
+       m_data->m_scrollOffset = scroll;
+       m_data->scrollBackingStore(scrollDelta);
+    }
+
+    m_data->m_inUpdateScrollbars = false;
+}
+
+PlatformScrollbar* ScrollView::scrollbarUnderMouse(const PlatformMouseEvent& mouseEvent)
+{
+    IntPoint viewPoint = mouseEvent.pos();
+
+//     if (m_data->m_hBar && m_data->m_vBar) {
+//       qDebug() << "ScrollView::scrollbarUnderMouse"
+//               << "hbar" << m_data->m_hBar->frameGeometry()
+//               << "vbar" << m_data->m_vBar->frameGeometry()
+//               << "mouse" << viewPoint << endl;
+//     }
+
+    if (m_data->m_hBar && m_data->m_hBar->frameGeometry().contains(viewPoint)) {
+//         qDebug() << "got hbar!!" << endl;
+        return m_data->m_hBar.get();
+    }
+    if (m_data->m_vBar && m_data->m_vBar->frameGeometry().contains(viewPoint)) {
+//         qDebug() << "got vbar!!" << endl;
+        return m_data->m_vBar.get();
     }
+    return 0;
 }
 
 void ScrollView::addChild(Widget* child)
 {
     QWidget* w = child->qwidget();
-    if (w)
-        w->setParent(m_area->viewport());
+    if (w) {
+        w->setParent(m_data->m_area);
+        m_data->m_children.add(child);
+    }
     child->setParent(this);
 }
 
@@ -295,61 +616,193 @@ void ScrollView::removeChild(Widget* child)
 {
     child->setParent(0);
     child->hide();
+    QWidget* w = child->qwidget();
+    if (w) {
+        m_data->m_children.remove(child);
+    }
 }
 
-void ScrollView::scrollRectIntoViewRecursively(const IntRect& r)
+void ScrollView::paint(GraphicsContext* context, const IntRect& rect)
 {
-    int x = r.x();
-    int y = r.y();
+    Q_ASSERT(isFrameView());
+
+    if (context->paintingDisabled())
+        return;
+
+    IntRect documentDirtyRect = rect;
+
+    QPainter *p = context->platformContext();
+    bool ownCanvas = p->device() == m_data->m_area;
+
+    QRect canvasRect = frameGeometry();
 
-    x = (x < 0) ? 0 : x;
-    y = (y < 0) ? 0 : y;
+    context->save();
 
-    m_area->horizontalScrollBar()->setValue(x);
-    m_area->verticalScrollBar()->setValue(y);
+    if (ownCanvas) {
+        canvasRect.moveTopLeft(QPoint(0,0));
+        documentDirtyRect.intersect(canvasRect);
+    } else {
+        canvasRect = originalGeometry();
+        documentDirtyRect.intersect(canvasRect);
+        context->translate(canvasRect.x(), canvasRect.y());
+        documentDirtyRect.move(-canvasRect.x(), -canvasRect.y());
+    }
+
+    context->translate(-contentsX(), -contentsY());
+    documentDirtyRect.move(contentsX(), contentsY());
+
+    IntRect clipRect = enclosingIntRect(visibleContentRect());
+
+    if (!(ownCanvas && parent()))
+    context->clip(clipRect);
+
+#ifdef DEBUG_SCROLLVIEW
+//    if (!(ownCanvas && parent()))
+    qDebug() << "ScrollView::paint --> "
+             << "ownCanvas" << ownCanvas
+             << "rect" << rect
+             << "clipRect" << clipRect
+             << "visibleContentRect" << enclosingIntRect(visibleContentRect())
+             << "frameGeometry" << frameGeometry()
+             << "canvasRect" << canvasRect
+             << "documentDirtyRect" << documentDirtyRect
+             << endl;
+#endif
+
+    static_cast<const FrameView*>(this)->frame()->paint(context, documentDirtyRect);
+
+    context->restore();
+
+    // Now paint the scrollbars.
+    if (!m_data->m_scrollbarsSuppressed && (m_data->m_hBar || m_data->m_vBar)) {
+        context->save();
+
+        IntRect scrollViewDirtyRect = rect;
+        scrollViewDirtyRect.intersect(canvasRect);
+
+        if (!ownCanvas) {
+            context->translate(canvasRect.x(), canvasRect.y());
+            scrollViewDirtyRect.move(-canvasRect.x(), -canvasRect.y());
+        }
+
+        if (m_data->m_hBar)
+            m_data->m_hBar->paint(context, scrollViewDirtyRect);
+        if (m_data->m_vBar)
+            m_data->m_vBar->paint(context, scrollViewDirtyRect);
+
+        // Fill the scroll corner with white.
+        IntRect hCorner;
+        if (m_data->m_hBar && width() - m_data->m_hBar->width() > 0) {
+            hCorner = IntRect(m_data->m_hBar->width(),
+                              height() - m_data->m_hBar->height(),
+                              width() - m_data->m_hBar->width(),
+                              m_data->m_hBar->height());
+            if (hCorner.intersects(scrollViewDirtyRect))
+                context->fillRect(hCorner, Color::white);
+        }
+
+        if (m_data->m_vBar && height() - m_data->m_vBar->height() > 0) {
+            IntRect vCorner(width() - m_data->m_vBar->width(),
+                            m_data->m_vBar->height(),
+                            m_data->m_vBar->width(),
+                            height() - m_data->m_vBar->height());
+            if (vCorner != hCorner && vCorner.intersects(scrollViewDirtyRect))
+                context->fillRect(vCorner, Color::white);
+        }
+
+        context->restore();
+    }
 }
 
-bool ScrollView::inWindow() const
+void ScrollView::wheelEvent(PlatformWheelEvent& e)
 {
-    return true;
+    // Determine how much we want to scroll.  If we can move at all, we will accept the event.
+    IntSize maxScrollDelta = maximumScroll();
+    if ((e.deltaX() < 0 && maxScrollDelta.width() > 0) ||
+        (e.deltaX() > 0 && scrollOffset().width() > 0) ||
+        (e.deltaY() < 0 && maxScrollDelta.height() > 0) ||
+        (e.deltaY() > 0 && scrollOffset().height() > 0))
+        e.accept();
+
+    scrollBy(-e.deltaX() * LINE_STEP, -e.deltaY() * LINE_STEP);
 }
 
-void ScrollView::wheelEvent(PlatformWheelEvent&)
+void ScrollView::scroll(ScrollDirection direction, ScrollGranularity granularity)
 {
-    //we don't do absolutely anything here - we handled it already in ScrollViewCanvasQt
-    // internally in Qt
+    if  ((direction == ScrollUp || direction == ScrollDown) && m_data->m_vBar)
+        m_data->m_vBar->scroll(direction, granularity);
+    else if (m_data->m_hBar)
+        m_data->m_hBar->scroll(direction, granularity);
 }
 
-PlatformScrollbar* ScrollView::scrollbarUnderMouse(const PlatformMouseEvent& mouseEvent)
+IntRect ScrollView::windowResizerRect()
 {
-    // Probably don't care about this.
-#if 0
-    // Not so sure: frames with scrollbars have the wrong mouse cursor over
-    // the scrollbar.  Is this why?  FIXME
-    if (m_area->horizontalScrollBar()->geometry().contains(mouseEvent.pos())) {
-        return m_area->horizontalScrollBar();
-    }
-    if (m_area->verticalScrollBar()->geometry().contains(mouseEvent.pos())) {
-        return m_area->verticalScrollBar();
-    }
-#endif
-    return 0;
+    ASSERT(isFrameView());
+    const FrameView* frameView = static_cast<const FrameView*>(this);
+    Page* page = frameView->frame() ? frameView->frame()->page() : 0;
+    if (!page)
+        return IntRect();
+    return page->chrome()->windowResizerRect();
 }
 
-void ScrollView::setAllowsScrolling(bool allows)
+bool ScrollView::resizerOverlapsContent() const
 {
-    if (!allows)
-        suppressScrollbars(true);
-    m_allowsScrolling = allows;
+    return !m_data->m_scrollbarsAvoidingResizer;
 }
 
-void ScrollView::update()
+void ScrollView::adjustOverlappingScrollbarCount(int overlapDelta)
 {
-    if (m_area && m_area->viewport()) {
-        m_area->viewport()->update();
+    int oldCount = m_data->m_scrollbarsAvoidingResizer;
+    m_data->m_scrollbarsAvoidingResizer += overlapDelta;
+    if (parent() && parent()->isFrameView())
+        static_cast<FrameView*>(parent())->adjustOverlappingScrollbarCount(overlapDelta);
+    else if (!m_data->m_scrollbarsSuppressed) {
+        // If we went from n to 0 or from 0 to n and we're the outermost view,
+        // we need to invalidate the windowResizerRect(), since it will now need to paint
+        // differently.
+        if (oldCount > 0 && m_data->m_scrollbarsAvoidingResizer == 0 ||
+            oldCount == 0 && m_data->m_scrollbarsAvoidingResizer > 0)
+            invalidateRect(windowResizerRect());
     }
 }
 
+void ScrollView::setParent(ScrollView* parentView)
+{
+    if (!parentView && m_data->m_scrollbarsAvoidingResizer && parent() && parent()->isFrameView())
+        static_cast<FrameView*>(parent())->adjustOverlappingScrollbarCount(false);
+    Widget::setParent(parentView);
+}
+
+void ScrollView::addToDirtyRegion(const IntRect& containingWindowRect)
+{
+    ASSERT(isFrameView());
+    const FrameView* frameView = static_cast<const FrameView*>(this);
+    Page* page = frameView->frame() ? frameView->frame()->page() : 0;
+    if (!page)
+        return;
+    page->chrome()->addToDirtyRegion(containingWindowRect);
+}
+
+void ScrollView::scrollBackingStore(int dx, int dy, const IntRect& scrollViewRect, const IntRect& clipRect)
+{
+    ASSERT(isFrameView());
+    const FrameView* frameView = static_cast<const FrameView*>(this);
+    Page* page = frameView->frame() ? frameView->frame()->page() : 0;
+    if (!page)
+        return;
+    page->chrome()->scrollBackingStore(dx, dy, scrollViewRect, clipRect);
+}
+
+void ScrollView::updateBackingStore()
+{
+    ASSERT(isFrameView());
+    const FrameView* frameView = static_cast<const FrameView*>(this);
+    Page* page = frameView->frame() ? frameView->frame()->page() : 0;
+    if (!page)
+        return;
+    page->chrome()->updateBackingStore();
+}
+
 }
 
 // vim: ts=4 sw=4 et
index ce3d07a648d73af45425672afd215af06cd195f0..b471adf48b4da90f5a8da43274d4528e61a9cba8 100644 (file)
 #include "ScrollView.h"
 #include "Widget.h"
 #include "WidgetClient.h"
+#include "PlatformScrollBar.h"
 #include "NotImplemented.h"
 
-#include <QAbstractScrollArea>
-#include <QScrollBar>
+#include <QFrame>
 #include <QWidget>
 
 namespace WebCore {
@@ -52,39 +52,32 @@ struct WidgetPrivate
     ~WidgetPrivate() { delete m_widget; }
 
     QWidget* canvas() const {
-        return m_scrollArea ? m_scrollArea->viewport() : m_widget;
-    }
-
-    QAbstractScrollArea* parentScroll() const {
-        QObject *parent = m_widget->parent();
-        while (parent && !qobject_cast<QAbstractScrollArea*>(parent)) {
-            parent = parent->parent();
-        }
-        if (parent)
-            return static_cast<QAbstractScrollArea*>(parent);
-        return 0;
+        return m_widget;
     }
     void setGeometry(const QRect &rect) {
-        QAbstractScrollArea *mapper = parentScroll();
+        ScrollView *mapper = m_parentScrollView;
         QRect r = rect;
-        if (mapper)
-            r = r.translated(-mapper->horizontalScrollBar()->value(),
-                             -mapper->verticalScrollBar()->value());
+        if (mapper) {
+            int h = -mapper->contentsX();
+            int v = -mapper->contentsY();
+            r = r.translated(h, v);
+        }
         m_widget->setGeometry(r);
+
+        //Store the actual rect that webcore gives us
+        //this is used for drawing subframes on the main
+        //frame canvas.
+        m_originalGeometry = rect;
     }
     QRect geometry() const {
-        QAbstractScrollArea *mapper = parentScroll();
-        QRect r = m_widget->geometry();
-        if (mapper)
-            r = r.translated(-mapper->horizontalScrollBar()->value(),
-                             -mapper->verticalScrollBar()->value());
-        return r;
+        return m_widget->geometry();
     }
 
     WidgetClient* m_client;
 
+    QRect m_originalGeometry;
     QWidget* m_widget;
-    QAbstractScrollArea* m_scrollArea;
+    QFrame* m_scrollArea;
     ScrollView *m_parentScrollView;
 };
 
@@ -145,7 +138,7 @@ void Widget::hide()
 void Widget::setQWidget(QWidget* child)
 {
     data->m_widget = child;
-    data->m_scrollArea = qobject_cast<QAbstractScrollArea*>(child);
+    data->m_scrollArea = qobject_cast<QFrame*>(child);
 }
 
 QWidget* Widget::qwidget() const
@@ -167,7 +160,6 @@ void Widget::setFrameGeometry(const IntRect& r)
 
 void Widget::paint(GraphicsContext *, const IntRect &rect)
 {
-    notImplemented();
 }
 
 bool Widget::isEnabled() const
@@ -224,6 +216,27 @@ ScrollView* Widget::parent() const
     return data->m_parentScrollView;
 }
 
+IntRect Widget::originalGeometry() const
+{
+    if (!data->m_widget)
+        return IntRect();
+
+    if (data->m_originalGeometry.isValid())
+        return data->m_originalGeometry;
+
+    return data->geometry();
+}
+
+void Widget::geometryChanged() const
+{
+    //Re-maps to the parent scroll content.
+    //Useful for when the parent scrolls the
+    //content before webcore explicitly sets
+    //the childrens geometry.
+    if (data->m_originalGeometry.isValid())
+        data->setGeometry(data->m_originalGeometry);
+}
+
 }
 
 // vim: ts=4 sw=4 et
index 6cbf5492b44ceff88d809c842fc085815a3996dc..7f7cf035e20be9285d0dbf85eea5a0b29427a5f7 100644 (file)
@@ -38,6 +38,7 @@
 #include "PlatformWheelEvent.h"
 #include "ResourceRequest.h"
 #include "SelectionController.h"
+#include "PlatformScrollBar.h"
 
 #include "markup.h"
 #include "RenderTreeAsText.h"
@@ -71,8 +72,8 @@ void QWebFramePrivate::init(QWebFrame *qframe, WebCore::Page *page, QWebFrameDat
     q->setFrameShape(QFrame::NoFrame);
     q->setMouseTracking(true);
     q->setFocusPolicy(Qt::ClickFocus);
-    q->verticalScrollBar()->setSingleStep(20);
-    q->horizontalScrollBar()->setSingleStep(20);
+//     q->verticalScrollBar()->setSingleStep(20);
+//     q->horizontalScrollBar()->setSingleStep(20);
 
     frameLoaderClient = new FrameLoaderClientQt();
     frame = new Frame(page, frameData->ownerElement, frameLoaderClient);
@@ -81,29 +82,32 @@ void QWebFramePrivate::init(QWebFrame *qframe, WebCore::Page *page, QWebFrameDat
     frameView = new FrameView(frame.get());
     frameView->deref();
     frameView->setScrollArea(qframe);
-    frameView->setAllowsScrolling(frameData->allowsScrolling);
+    if (!frameData->allowsScrolling)
+        frameView->suppressScrollbars(true);
     frame->setView(frameView.get());
     frame->init();
     eventHandler = frame->eventHandler();
 }
 
-void QWebFramePrivate::_q_adjustScrollbars()
+QWebFrame *QWebFramePrivate::parentFrame()
 {
-    QAbstractSlider *hbar = q->horizontalScrollBar();
-    QAbstractSlider *vbar = q->verticalScrollBar();
-
-    const QSize viewportSize = q->viewport()->size();
-    QSize docSize = QSize(frameView->contentsWidth(), frameView->contentsHeight());
+    return qobject_cast<QWebFrame*>(q->parentWidget());
+}
 
-    hbar->setRange(0, docSize.width() - viewportSize.width());
-    hbar->setPageStep(viewportSize.width());
+WebCore::PlatformScrollbar *QWebFramePrivate::horizontalScrollBar() const
+{
+    Q_ASSERT(frameView);
+    return frameView->horizontalScrollBar();
+}
 
-    vbar->setRange(0, docSize.height() - viewportSize.height());
-    vbar->setPageStep(viewportSize.height());
+WebCore::PlatformScrollbar *QWebFramePrivate::verticalScrollBar() const
+{
+    Q_ASSERT(frameView);
+    return frameView->verticalScrollBar();
 }
 
 QWebFrame::QWebFrame(QWebPage *parent, QWebFrameData *frameData)
-    : QAbstractScrollArea(parent)
+    : QFrame(parent)
     , d(new QWebFramePrivate)
 {
     d->page = parent;
@@ -115,9 +119,8 @@ QWebFrame::QWebFrame(QWebPage *parent, QWebFrameData *frameData)
     }
 }
 
-
 QWebFrame::QWebFrame(QWebFrame *parent, QWebFrameData *frameData)
-    : QAbstractScrollArea(parent->viewport())
+    : QFrame(parent)
     , d(new QWebFramePrivate)
 {
     QPalette pal = palette();
@@ -197,12 +200,11 @@ QString QWebFrame::selectedText() const
 
 void QWebFrame::resizeEvent(QResizeEvent *e)
 {
-    QAbstractScrollArea::resizeEvent(e);
+    QFrame::resizeEvent(e);
     if (d->frame && d->frameView) {
         d->frame->forceLayout();
         d->frame->view()->adjustViewSize();
     }
-    d->_q_adjustScrollbars();
 }
 
 QList<QWebFrame*> QWebFrame::childFrames() const
@@ -221,6 +223,11 @@ QList<QWebFrame*> QWebFrame::childFrames() const
     return rc;
 }
 
+void QWebFrame::suppressScrollbars(bool suppress)
+{
+    d->frameView->suppressScrollbars(suppress);
+}
+
 void QWebFrame::paintEvent(QPaintEvent *ev)
 {
     if (!d->frameView || !d->frame->renderer())
@@ -230,21 +237,17 @@ void QWebFrame::paintEvent(QPaintEvent *ev)
     QTime time;
     time.start();
 #endif
+
     QRect clip = ev->rect();
 
     if (d->frameView->needsLayout()) {
         d->frameView->layout();
     }
-    QPainter p(viewport());
-    GraphicsContext ctx(&p);
-
-    const int xOffset = horizontalScrollBar()->value();
-    const int yOffset = verticalScrollBar()->value();
 
-    ctx.translate(-xOffset, -yOffset);
-    clip.translate(xOffset, yOffset);
+    QPainter p(this);
 
-    d->frame->paint(&ctx, clip);
+    GraphicsContext ctx(&p);
+    d->frameView->paint(&ctx, clip);
     p.end();
 
 #ifdef    QWEBKIT_TIME_RENDERING
@@ -258,9 +261,15 @@ void QWebFrame::mouseMoveEvent(QMouseEvent *ev)
     if (!d->frameView)
         return;
 
+    //WebCore expects all mouse events routed through mainFrame()
+    if (this != d->page->mainFrame()) {
+        ev->ignore();
+        return;
+    }
+
     d->eventHandler->handleMouseMoveEvent(PlatformMouseEvent(ev, 0));
-    const int xOffset = horizontalScrollBar()->value();
-    const int yOffset = verticalScrollBar()->value();
+    const int xOffset = d->horizontalScrollBar() ? d->horizontalScrollBar()->value() : 0;
+    const int yOffset = d->verticalScrollBar() ? d->verticalScrollBar()->value() : 0;
     IntPoint pt(ev->x() + xOffset, ev->y() + yOffset);
     WebCore::HitTestResult result = d->eventHandler->hitTestResultAtPoint(pt, false);
     WebCore::Element *link = result.URLElement();
@@ -275,40 +284,65 @@ void QWebFrame::mousePressEvent(QMouseEvent *ev)
     if (!d->eventHandler)
         return;
 
+    //WebCore expects all mouse events routed through mainFrame()
+    if (this != d->page->mainFrame()) {
+        ev->ignore();
+        return;
+    }
+
     if (ev->button() == Qt::RightButton)
         d->eventHandler->sendContextMenuEvent(PlatformMouseEvent(ev, 1));
-    else d->eventHandler->handleMousePressEvent(PlatformMouseEvent(ev, 1));
+    else
+        d->eventHandler->handleMousePressEvent(PlatformMouseEvent(ev, 1));
     setFocus();
 }
 
 void QWebFrame::mouseDoubleClickEvent(QMouseEvent *ev)
 {
+    //WebCore expects all mouse events routed through mainFrame()
     if (!d->eventHandler)
         return;
 
+    if (this != d->page->mainFrame()) {
+        ev->ignore();
+        return;
+    }
+
     d->eventHandler->handleMousePressEvent(PlatformMouseEvent(ev, 2));
     setFocus();
 }
 
 void QWebFrame::mouseReleaseEvent(QMouseEvent *ev)
 {
+    //WebCore expects all mouse events routed through mainFrame()
     if (!d->frameView)
         return;
 
+    if (this != d->page->mainFrame()) {
+        ev->ignore();
+        return;
+    }
+
     d->eventHandler->handleMouseReleaseEvent(PlatformMouseEvent(ev, 0));
     setFocus();
 }
 
-void QWebFrame::wheelEvent(QWheelEvent *e)
+void QWebFrame::wheelEvent(QWheelEvent *ev)
 {
-    PlatformWheelEvent wkEvent(e);
+    //WebCore expects all mouse events routed through mainFrame()
+    if (this != d->page->mainFrame()) {
+        ev->ignore();
+        return;
+    }
+
+    PlatformWheelEvent wkEvent(ev);
     bool accepted = false;
     if (d->eventHandler)
         accepted = d->eventHandler->handleWheelEvent(wkEvent);
 
-    e->setAccepted(accepted);
+    ev->setAccepted(accepted);
     if (!accepted)
-        QAbstractScrollArea::wheelEvent(e);
+        QFrame::wheelEvent(ev);
     setFocus();
 }
 
@@ -323,40 +357,43 @@ void QWebFrame::keyPressEvent(QKeyEvent *ev)
     if (handled) {
     } else {
         handled = true;
-        QScrollBar *h, *v;
-        h = horizontalScrollBar();
-        v = verticalScrollBar();
+        PlatformScrollbar *h, *v;
+        h = d->horizontalScrollBar();
+        v = d->verticalScrollBar();
+        if (!h || !v)
+          return;
+
         switch (ev->key()) {
             case Qt::Key_Up:
                 v->setValue(v->value() - 10);
-                viewport()->update();
+                update();
                 break;
             case Qt::Key_Down:
                 v->setValue(v->value() + 10);
-                viewport()->update();
+                update();
                 break;
             case Qt::Key_Left:
                 h->setValue(h->value() - 10);
-                viewport()->update();
+                update();
                 break;
             case Qt::Key_Right:
                 h->setValue(h->value() + 10);
-                viewport()->update();
+                update();
                 break;
             case Qt::Key_PageUp:
-                v->setValue(v->value() - viewport()->height());
-                viewport()->update();
+                v->setValue(v->value() - height());
+                update();
                 break;
             case Qt::Key_PageDown:
-                v->setValue(v->value() + viewport()->height());
-                viewport()->update();
+                v->setValue(v->value() + height());
+                update();
                 break;
             default:
                 handled = false;
                 break;
         }
     }
-   
+
     ev->setAccepted(handled);
 }
 
@@ -376,19 +413,19 @@ void QWebFrame::keyReleaseEvent(QKeyEvent *ev)
     ev->setAccepted(handled);
 }
 
-void QWebFrame::focusInEvent(QFocusEvent *e)
+void QWebFrame::focusInEvent(QFocusEvent *ev)
 {
-    if (e->reason() != Qt::PopupFocusReason) {
+    if (ev->reason() != Qt::PopupFocusReason) {
         d->frame->page()->focusController()->setFocusedFrame(d->frame);
         d->frame->setIsActive(true);
     }
-    QAbstractScrollArea::focusInEvent(e);
+    QFrame::focusInEvent(ev);
 }
 
-void QWebFrame::focusOutEvent(QFocusEvent *e)
+void QWebFrame::focusOutEvent(QFocusEvent *ev)
 {
-    QAbstractScrollArea::focusOutEvent(e);
-    if (e->reason() != Qt::PopupFocusReason) {
+    QFrame::focusOutEvent(ev);
+    if (ev->reason() != Qt::PopupFocusReason) {
         d->frame->selectionController()->clear();
         d->frame->setIsActive(false);
     }
@@ -412,11 +449,3 @@ QString QWebFrame::evaluateJavaScript(const QString& scriptSource)
     }
     return rc;
 }
-
-/*!\reimp
-*/
-void QWebFrame::scrollContentsBy(int dx, int dy)
-{
-    viewport()->scroll(dx, dy);
-}
-
index 325d32af98096b882abf3b5218ee949203e5b4ac..bb9cf1df80e54aa5f8de630a84be70ad6ca8108c 100644 (file)
@@ -36,7 +36,7 @@ namespace WebCore {
 }
 class QWebFrameData;
 
-class QWEBKIT_EXPORT QWebFrame : public QAbstractScrollArea
+class QWEBKIT_EXPORT QWebFrame : public QFrame
 {
     Q_OBJECT
 protected:
@@ -56,6 +56,8 @@ public:
 
     QList<QWebFrame*> childFrames() const;
 
+    void suppressScrollbars(bool suppress);
+
 public Q_SLOTS:
     QString evaluateJavaScript(const QString& scriptSource);
 
@@ -66,7 +68,7 @@ signals:
     void hoveringOverLink(const QString &link, const QString &title);
 
 protected:
-    virtual void resizeEvent(QResizeEvent *);
+    virtual void resizeEvent(QResizeEvent*);
     virtual void paintEvent(QPaintEvent*);
     virtual void mouseMoveEvent(QMouseEvent*);
     virtual void mousePressEvent(QMouseEvent*);
@@ -75,17 +77,14 @@ protected:
     virtual void wheelEvent(QWheelEvent*);
     virtual void keyPressEvent(QKeyEvent*);
     virtual void keyReleaseEvent(QKeyEvent*);
-    virtual void scrollContentsBy(int dx, int dy);
-    virtual void focusInEvent(QFocusEvent *e);
-    virtual void focusOutEvent(QFocusEvent *e);
+    virtual void focusInEvent(QFocusEvent*);
+    virtual void focusOutEvent(QFocusEvent*);
     virtual bool focusNextPrevChild(bool next);
-    
+
 private:
     friend class QWebPage;
     friend class WebCore::FrameLoaderClientQt;
     QWebFramePrivate *d;
 };
 
-
-
 #endif
index fb472652929e253132687d4a43731194b552f24c..0169cdbed07ada8517b88e43735640ec6993bf4d 100644 (file)
@@ -39,6 +39,7 @@ namespace WebCore
     class Frame;
     class FrameView;
     class HTMLFrameOwnerElement;
+    class PlatformScrollbar;
 }
 class QWebPage;
 
@@ -71,7 +72,9 @@ public:
     void init(QWebFrame *qframe, WebCore::Page *page,
               QWebFrameData *frameData);
 
-    void _q_adjustScrollbars();
+    QWebFrame *parentFrame();
+    WebCore::PlatformScrollbar *horizontalScrollBar() const;
+    WebCore::PlatformScrollbar *verticalScrollBar() const;
 
     QWebFrame *q;
     WebCore::FrameLoaderClientQt *frameLoaderClient;
index bf91b895c43cae31c51c52d11b991116973756a1..6c29fb0930c12ee3af4cd4e14fd5c4f581856336 100644 (file)
@@ -43,7 +43,7 @@ QWebFrame *QWebObjectPluginConnector::frame() const
 
 QWidget *QWebObjectPluginConnector::pluginParentWidget() const
 {
-    return d->frame->viewport();
+    return d->frame;
 }
 
 QWebNetworkJob *QWebObjectPluginConnector::requestUrl(const QWebNetworkRequest &request, Target target)
index dca398fb27e01708a9d0a0dd3a60d528012681c8..143a154b698d088071a145b5aef48d29e62fce56 100644 (file)
@@ -1,3 +1,32 @@
+2007-07-06  Adam Treat  <adam@staikos.net>
+
+        Reviewed by George Staikos.
+
+        Convert QWebFrame to a QFrame from a scroll area.
+
+        * Api/qwebframe.cpp:
+        (QWebFramePrivate::init):
+        (QWebFramePrivate::parentFrame):
+        (QWebFramePrivate::horizontalScrollBar):
+        (QWebFramePrivate::verticalScrollBar):
+        (QWebFrame::QWebFrame):
+        (QWebFrame::resizeEvent):
+        (QWebFrame::suppressScrollbars):
+        (QWebFrame::paintEvent):
+        (QWebFrame::mouseMoveEvent):
+        (QWebFrame::mousePressEvent):
+        (QWebFrame::mouseDoubleClickEvent):
+        (QWebFrame::mouseReleaseEvent):
+        (QWebFrame::wheelEvent):
+        (QWebFrame::keyPressEvent):
+        (QWebFrame::focusInEvent):
+        (QWebFrame::focusOutEvent):
+        (QWebFrame::evaluateJavaScript):
+        * Api/qwebframe.h:
+        * Api/qwebframe_p.h:
+        * Api/qwebobjectpluginconnector.cpp:
+        (QWebObjectPluginConnector::pluginParentWidget):
+
 2007-07-04  Adam Roben  <aroben@apple.com>
 
         Added a stub for ChromeClientQt::setToolTip
index 61c23efeda7a221ae7cbeacd6af47008e201fec7..e30a96bd6ab8a0105ddbe2e622a52c10f12fe153 100644 (file)
@@ -1,3 +1,12 @@
+2007-07-06  Adam Treat  <adam@staikos.net>
+
+        Reviewed by George Staikos.
+
+        Adjust for conversion of QWebFrame to a QFrame from a scroll area.
+
+        * DumpRenderTree/DumpRenderTree.qtproj/DumpRenderTree.cpp:
+        (WebCore::DumpRenderTree::DumpRenderTree):
+
 2007-07-06  George Staikos  <staikos@kde.org>
 
         Reviewed by Anders.
index 749f782a50cde6986180e923bba053f63ea5bd15..89440c50f64954b047f5736803a49c4710d92ae6 100644 (file)
@@ -70,8 +70,7 @@ DumpRenderTree::DumpRenderTree()
     page = new WebPage(0);
     page->resize(maxViewWidth, maxViewHeight);
     frame = page->mainFrame();
-    frame->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
-    frame->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
+    frame->suppressScrollbars(true);
     frame->setFrameShape(QFrame::NoFrame);
 
     // hack to force the right size on the frame