Title: [88982] trunk/Source/WebCore
Revision
88982
Author
[email protected]
Date
2011-06-15 16:13:23 -0700 (Wed, 15 Jun 2011)

Log Message

https://bugs.webkit.org/show_bug.cgi?id=62746
Crash possible when switching scrollbar appearance preference on Mac
-and corresponding-
<rdar://problem/9323983>
        
Reviewed by Simon Fraser.

This crash happens because the current mechanism that is intended to flag 
ScrollAnimators as being in the page cache or not does not work correctly. 
Long-term the fix for this is to move the ScrollableArea HashSet to a more 
appropriate place. In the meantime, this patch addresses the crash by getting 
rid of the m_isActive bool on ScrollAnimator that was intended to represent 
whether or not the ScrollableArea is in the page cache. Instead, ScrollableArea 
implementations now have their own functions to compute whether they are in 
active pages. ScrollAnimator::setIsActive() needs to be kept around even though 
there is no bool to flip anymore because scrollbars may need to be properly 
updated if the appearance was switched while the document was in the page cache.

No longer call FrameView::setAnimatorsAreActive() from 
Document::setIsInPageCache(), instead call it in 
Document::documentDidBecomeActive()
* dom/Document.cpp:
(WebCore::Document::setInPageCache):
(WebCore::Document::documentDidBecomeActive):

ScrollableAreas can now assess whether or not they are on active pages (ie, not 
in the page cache).
* platform/ScrollableArea.h:
(WebCore::ScrollableArea::isOnActivePage):
* rendering/RenderLayer.cpp:
(WebCore::RenderLayer::isOnActivePage):
* rendering/RenderLayer.h:
* rendering/RenderListBox.cpp:
(WebCore::RenderListBox::isOnActivePage):
* rendering/RenderListBox.h:

A FrameView cannot access its Document when it's in the page cache, so it 
usually determines whether it's in the page cache by checking if its frame 
points to a FrameView other than itself.
* page/FrameView.cpp:
(WebCore::FrameView::isOnActivePage):
        
Make sure ScrollableAreas are on active pages before setting them as 
active. This will not be necessary when the HashSet become a per-web page 
HashSet.
(WebCore::FrameView::setAnimatorsAreActive):
* page/FrameView.h:
        
ScrollAnimator no longer tracks the m_isActive bool. 
* platform/ScrollAnimator.cpp:
(WebCore::ScrollAnimator::ScrollAnimator):
* platform/ScrollAnimator.h:
(WebCore::ScrollAnimator::setIsActive):
        
setIsActive() now exclusively calls updateScrollStyle() if there is a pending 
need to do so.
* platform/mac/ScrollAnimatorMac.h:
* platform/mac/ScrollAnimatorMac.mm:
(WebCore::ScrollAnimatorMac::setIsActive):
        
Return early if the ScrollableArea is in the page cache. 
(WebCore::ScrollAnimatorMac::updateScrollerStyle):

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (88981 => 88982)


--- trunk/Source/WebCore/ChangeLog	2011-06-15 23:08:56 UTC (rev 88981)
+++ trunk/Source/WebCore/ChangeLog	2011-06-15 23:13:23 UTC (rev 88982)
@@ -1,3 +1,68 @@
+2011-06-15  Beth Dakin  <[email protected]>
+
+        Reviewed by Simon Fraser.
+
+        https://bugs.webkit.org/show_bug.cgi?id=62746
+        Crash possible when switching scrollbar appearance preference on Mac
+        -and corresponding-
+        <rdar://problem/9323983>
+        
+        This crash happens because the current mechanism that is intended to flag 
+        ScrollAnimators as being in the page cache or not does not work correctly. 
+        Long-term the fix for this is to move the ScrollableArea HashSet to a more 
+        appropriate place. In the meantime, this patch addresses the crash by getting 
+        rid of the m_isActive bool on ScrollAnimator that was intended to represent 
+        whether or not the ScrollableArea is in the page cache. Instead, ScrollableArea 
+        implementations now have their own functions to compute whether they are in 
+        active pages. ScrollAnimator::setIsActive() needs to be kept around even though 
+        there is no bool to flip anymore because scrollbars may need to be properly 
+        updated if the appearance was switched while the document was in the page cache.
+
+        No longer call FrameView::setAnimatorsAreActive() from 
+        Document::setIsInPageCache(), instead call it in 
+        Document::documentDidBecomeActive()
+        * dom/Document.cpp:
+        (WebCore::Document::setInPageCache):
+        (WebCore::Document::documentDidBecomeActive):
+
+        ScrollableAreas can now assess whether or not they are on active pages (ie, not 
+        in the page cache).
+        * platform/ScrollableArea.h:
+        (WebCore::ScrollableArea::isOnActivePage):
+        * rendering/RenderLayer.cpp:
+        (WebCore::RenderLayer::isOnActivePage):
+        * rendering/RenderLayer.h:
+        * rendering/RenderListBox.cpp:
+        (WebCore::RenderListBox::isOnActivePage):
+        * rendering/RenderListBox.h:
+
+        A FrameView cannot access its Document when it's in the page cache, so it 
+        usually determines whether it's in the page cache by checking if its frame 
+        points to a FrameView other than itself.
+        * page/FrameView.cpp:
+        (WebCore::FrameView::isOnActivePage):
+        
+        Make sure ScrollableAreas are on active pages before setting them as 
+        active. This will not be necessary when the HashSet become a per-web page 
+        HashSet.
+        (WebCore::FrameView::setAnimatorsAreActive):
+        * page/FrameView.h:
+        
+        ScrollAnimator no longer tracks the m_isActive bool. 
+        * platform/ScrollAnimator.cpp:
+        (WebCore::ScrollAnimator::ScrollAnimator):
+        * platform/ScrollAnimator.h:
+        (WebCore::ScrollAnimator::setIsActive):
+        
+        setIsActive() now exclusively calls updateScrollStyle() if there is a pending 
+        need to do so.
+        * platform/mac/ScrollAnimatorMac.h:
+        * platform/mac/ScrollAnimatorMac.mm:
+        (WebCore::ScrollAnimatorMac::setIsActive):
+        
+        Return early if the ScrollableArea is in the page cache. 
+        (WebCore::ScrollAnimatorMac::updateScrollerStyle):
+
 2011-06-15  Simon Fraser  <[email protected]>
 
         Reviewed by Dan Bernstein.

Modified: trunk/Source/WebCore/dom/Document.cpp (88981 => 88982)


--- trunk/Source/WebCore/dom/Document.cpp	2011-06-15 23:08:56 UTC (rev 88981)
+++ trunk/Source/WebCore/dom/Document.cpp	2011-06-15 23:13:23 UTC (rev 88982)
@@ -3820,9 +3820,6 @@
         if (childNeedsStyleRecalc())
             scheduleStyleRecalc();
     }
-
-    if (v)
-        v->setAnimatorsAreActive(!m_inPageCache);
 }
 
 void Document::documentWillBecomeInactive() 
@@ -3848,6 +3845,9 @@
         renderView()->didMoveOnscreen();
 #endif
 
+    if (FrameView* frameView = view())
+        frameView->setAnimatorsAreActive();
+
     ASSERT(m_frame);
     m_frame->loader()->client()->dispatchDidBecomeFrameset(isFrameSet());
 }

Modified: trunk/Source/WebCore/page/FrameView.cpp (88981 => 88982)


--- trunk/Source/WebCore/page/FrameView.cpp	2011-06-15 23:08:56 UTC (rev 88981)
+++ trunk/Source/WebCore/page/FrameView.cpp	2011-06-15 23:13:23 UTC (rev 88982)
@@ -2226,12 +2226,19 @@
     return page->chrome()->client()->notifyScrollerThumbIsVisibleInRect(scrollerThumb);
 }
 
+bool FrameView::isOnActivePage() const
+{
+    if (m_frame->view() != this)
+        return false;
+    return !m_frame->document()->inPageCache();
+}
+
 bool FrameView::shouldSuspendScrollAnimations() const
 {
     return m_frame->loader()->state() != FrameStateComplete;
 }
 
-void FrameView::setAnimatorsAreActive(bool active)
+void FrameView::setAnimatorsAreActive()
 {
     Page* page = m_frame->page();
     if (!page)
@@ -2242,8 +2249,14 @@
         return;
 
     HashSet<ScrollableArea*>::const_iterator end = scrollableAreas->end(); 
-    for (HashSet<ScrollableArea*>::const_iterator it = scrollableAreas->begin(); it != end; ++it)
-        (*it)->scrollAnimator()->setIsActive(active);
+    for (HashSet<ScrollableArea*>::const_iterator it = scrollableAreas->begin(); it != end; ++it) {
+        // FIXME: This extra check to make sure the ScrollableArea is on an active page needs 
+        // to be here as long as the ScrollableArea HashSet lives on Page. But it should really be
+        // moved to the top-level Document or a similar class that really represents a single 
+        // web page. https://bugs.webkit.org/show_bug.cgi?id=62762
+        if ((*it)->isOnActivePage())
+            (*it)->scrollAnimator()->setIsActive();
+    }
 }
 
 void FrameView::notifyPageThatContentAreaWillPaint() const

Modified: trunk/Source/WebCore/page/FrameView.h (88981 => 88982)


--- trunk/Source/WebCore/page/FrameView.h	2011-06-15 23:08:56 UTC (rev 88981)
+++ trunk/Source/WebCore/page/FrameView.h	2011-06-15 23:13:23 UTC (rev 88982)
@@ -277,7 +277,7 @@
 
     virtual bool shouldSuspendScrollAnimations() const;
 
-    void setAnimatorsAreActive(bool);
+    void setAnimatorsAreActive();
 
 protected:
     virtual bool scrollContentsFastPath(const IntSize& scrollDelta, const IntRect& rectToScroll, const IntRect& clipRect);
@@ -328,6 +328,7 @@
     virtual void didStartAnimatedScroll() const;
     virtual void didCompleteAnimatedScroll() const;
     virtual void setVisibleScrollerThumbRect(const IntRect&);
+    virtual bool isOnActivePage() const;
 #if USE(ACCELERATED_COMPOSITING)
     virtual GraphicsLayer* layerForHorizontalScrollbar() const;
     virtual GraphicsLayer* layerForVerticalScrollbar() const;

Modified: trunk/Source/WebCore/platform/ScrollAnimator.cpp (88981 => 88982)


--- trunk/Source/WebCore/platform/ScrollAnimator.cpp	2011-06-15 23:08:56 UTC (rev 88981)
+++ trunk/Source/WebCore/platform/ScrollAnimator.cpp	2011-06-15 23:13:23 UTC (rev 88982)
@@ -52,7 +52,6 @@
     : m_scrollableArea(scrollableArea)
     , m_currentPosX(0)
     , m_currentPosY(0)
-    , m_isActive(true)
 {
 }
 

Modified: trunk/Source/WebCore/platform/ScrollAnimator.h (88981 => 88982)


--- trunk/Source/WebCore/platform/ScrollAnimator.h	2011-06-15 23:08:56 UTC (rev 88981)
+++ trunk/Source/WebCore/platform/ScrollAnimator.h	2011-06-15 23:13:23 UTC (rev 88982)
@@ -61,8 +61,7 @@
 
     ScrollableArea* scrollableArea() const { return m_scrollableArea; }
 
-    virtual void setIsActive(bool active) { m_isActive = active; }
-    bool isActive() const { return m_isActive; }
+    virtual void setIsActive() { }
 
     virtual void handleWheelEvent(PlatformWheelEvent&);
 #if ENABLE(GESTURE_EVENTS)
@@ -96,7 +95,6 @@
     ScrollableArea* m_scrollableArea;
     float m_currentPosX; // We avoid using a FloatPoint in order to reduce
     float m_currentPosY; // subclass code complexity.
-    bool m_isActive;
 };
 
 } // namespace WebCore

Modified: trunk/Source/WebCore/platform/ScrollableArea.h (88981 => 88982)


--- trunk/Source/WebCore/platform/ScrollableArea.h	2011-06-15 23:08:56 UTC (rev 88981)
+++ trunk/Source/WebCore/platform/ScrollableArea.h	2011-06-15 23:13:23 UTC (rev 88982)
@@ -136,6 +136,8 @@
     virtual bool shouldSuspendScrollAnimations() const { return true; }
     virtual void scrollbarStyleChanged() { }
     virtual void setVisibleScrollerThumbRect(const IntRect&) { }
+
+    virtual bool isOnActivePage() const { ASSERT_NOT_REACHED(); return true; }
     
     bool isHorizontalScrollerPinnedToMinimumPosition() const { return !horizontalScrollbar() || scrollPosition(horizontalScrollbar()) <= minimumScrollPosition().x(); }
     bool isHorizontalScrollerPinnedToMaximumPosition() const { return !horizontalScrollbar() || scrollPosition(horizontalScrollbar()) >= maximumScrollPosition().x(); }

Modified: trunk/Source/WebCore/platform/mac/ScrollAnimatorMac.h (88981 => 88982)


--- trunk/Source/WebCore/platform/mac/ScrollAnimatorMac.h	2011-06-15 23:08:56 UTC (rev 88981)
+++ trunk/Source/WebCore/platform/mac/ScrollAnimatorMac.h	2011-06-15 23:13:23 UTC (rev 88982)
@@ -83,7 +83,7 @@
 
     bool haveScrolledSincePageLoad() const { return m_haveScrolledSincePageLoad; }
 
-    virtual void setIsActive(bool);
+    virtual void setIsActive();
 
 #if USE(WK_SCROLLBAR_PAINTER)
     void updateScrollerStyle();

Modified: trunk/Source/WebCore/platform/mac/ScrollAnimatorMac.mm (88981 => 88982)


--- trunk/Source/WebCore/platform/mac/ScrollAnimatorMac.mm	2011-06-15 23:08:56 UTC (rev 88981)
+++ trunk/Source/WebCore/platform/mac/ScrollAnimatorMac.mm	2011-06-15 23:13:23 UTC (rev 88982)
@@ -1216,10 +1216,8 @@
 }
 #endif
 
-void ScrollAnimatorMac::setIsActive(bool active)
+void ScrollAnimatorMac::setIsActive()
 {
-    ScrollAnimator::setIsActive(active);
-
 #if USE(WK_SCROLLBAR_PAINTER)
     if (needsScrollerStyleUpdate())
         updateScrollerStyle();
@@ -1229,7 +1227,7 @@
 #if USE(WK_SCROLLBAR_PAINTER)
 void ScrollAnimatorMac::updateScrollerStyle()
 {
-    if (!isActive()) {
+    if (!scrollableArea()->isOnActivePage()) {
         setNeedsScrollerStyleUpdate(true);
         return;
     }

Modified: trunk/Source/WebCore/rendering/RenderLayer.cpp (88981 => 88982)


--- trunk/Source/WebCore/rendering/RenderLayer.cpp	2011-06-15 23:08:56 UTC (rev 88981)
+++ trunk/Source/WebCore/rendering/RenderLayer.cpp	2011-06-15 23:13:23 UTC (rev 88982)
@@ -1817,6 +1817,11 @@
     return view->frameView()->shouldSuspendScrollAnimations();
 }
 
+bool RenderLayer::isOnActivePage() const
+{
+    return !m_renderer->document()->inPageCache();
+}
+
 IntPoint RenderLayer::currentMousePosition() const
 {
     return renderer()->frame() ? renderer()->frame()->eventHandler()->currentMousePosition() : IntPoint();

Modified: trunk/Source/WebCore/rendering/RenderLayer.h (88981 => 88982)


--- trunk/Source/WebCore/rendering/RenderLayer.h	2011-06-15 23:08:56 UTC (rev 88981)
+++ trunk/Source/WebCore/rendering/RenderLayer.h	2011-06-15 23:13:23 UTC (rev 88982)
@@ -546,6 +546,7 @@
     virtual IntPoint currentMousePosition() const;
     virtual void didCompleteRubberBand(const IntSize&) const;
     virtual bool shouldSuspendScrollAnimations() const;
+    virtual bool isOnActivePage() const;
 
     // Rectangle encompassing the scroll corner and resizer rect.
     IntRect scrollCornerAndResizerRect() const;

Modified: trunk/Source/WebCore/rendering/RenderListBox.cpp (88981 => 88982)


--- trunk/Source/WebCore/rendering/RenderListBox.cpp	2011-06-15 23:08:56 UTC (rev 88981)
+++ trunk/Source/WebCore/rendering/RenderListBox.cpp	2011-06-15 23:13:23 UTC (rev 88982)
@@ -801,6 +801,11 @@
     return view->frameView()->shouldSuspendScrollAnimations();
 }
 
+bool RenderListBox::isOnActivePage() const
+{
+    return !document()->inPageCache();
+}
+
 PassRefPtr<Scrollbar> RenderListBox::createScrollbar()
 {
     RefPtr<Scrollbar> widget;

Modified: trunk/Source/WebCore/rendering/RenderListBox.h (88981 => 88982)


--- trunk/Source/WebCore/rendering/RenderListBox.h	2011-06-15 23:08:56 UTC (rev 88981)
+++ trunk/Source/WebCore/rendering/RenderListBox.h	2011-06-15 23:13:23 UTC (rev 88982)
@@ -117,6 +117,7 @@
     virtual int visibleWidth() const;
     virtual IntPoint currentMousePosition() const;
     virtual bool shouldSuspendScrollAnimations() const;
+    virtual bool isOnActivePage() const;
 
     virtual void disconnectFromPage() { m_page = 0; }
 
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to