WebCore:
authoradele <adele@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 10 Oct 2006 21:18:03 +0000 (21:18 +0000)
committeradele <adele@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 10 Oct 2006 21:18:03 +0000 (21:18 +0000)
        Reviewed by Beth.

        - Fix for <rdar://problem/4707489> After timers fix, crash below RenderLayer::autoscroll after moving/destroying active <input type=text>
          and <rdar://problem/4707519> After timers fix, crash below RenderLayer::autoscroll after moving/destroying active textarea

        Moved autoscroll code to the Frame class

        * bridge/mac/FrameMac.h: Moved _mouseDownMayStartDrag and _mouseDownMayStartAutoscroll flags to the frame.
        * bridge/mac/FrameMac.mm: Use new getters and setters for drag and autoscroll flags.  Moved autoscroll code to Frame::handleMouseMoveEvent.
        (WebCore::FrameMac::FrameMac):
        (WebCore::FrameMac::handleMousePressEvent):
        (WebCore::FrameMac::eventMayStartDrag):
        (WebCore::FrameMac::handleMouseMoveEvent):
        (WebCore::FrameMac::mouseDown):

        * bridge/mac/WebCoreFrameBridge.h: Removed handleAutoscrollForMouseDragged, which called over the bridge for AppKit to do autoscroll for us.
        Now we scroll our views in WebCore.

        * page/Frame.cpp:
        (WebCore::Frame::handleMousePressEvent): Initialize the mouseDownMayStartAutoscroll flag.
        (WebCore::Frame::handleMouseMoveEvent): Now kicks off autoscroll if appropriate.  Moved from FrameMac.
        (WebCore::Frame::updateSelectionForMouseDragOverPosition): Factored code out from handleMouseMoveEvent so we can update the selection from autoscroll too.
        (WebCore::Frame::mouseDownMayStartAutoscroll): Added.
        (WebCore::Frame::setMouseDownMayStartAutoscroll): Added.
        (WebCore::Frame::mouseDownMayStartDrag): Added.
        (WebCore::Frame::setMouseDownMayStartDrag): Added.
        (WebCore::Frame::autoscrollRenderer): Added
        (WebCore::Frame::setAutoscrollRenderer): Added.
        (WebCore::Frame::handleAutoscroll): Updated to use autoscrollRenderer getter and setter.
        (WebCore::Frame::autoscrollTimerFired): ditto.
        (WebCore::Frame::stopAutoscrollTimer): ditto.
        * page/Frame.h: Made autoscrollRenderer and stopAutoscrollTimer public, so the renderer being autoscrolled can kill the timer when it dies.

        * page/FramePrivate.h:
        (WebCore::FramePrivate::FramePrivate): Added mouseDownMayStartDrag and mouseDownMayStartAutoscroll flags.  Moved from FrameMac.

        * page/FrameView.cpp: Store the current mouse position in window coordinates.  The callers can convert to their own coordinate space.
        (WebCore::FrameView::handleMousePressEvent):
        (WebCore::FrameView::handleMouseDoubleClickEvent):
        (WebCore::FrameView::handleMouseMoveEvent):
        (WebCore::FrameView::handleMouseReleaseEvent):

        * rendering/RenderLayer.cpp:
        (WebCore::RenderLayer::autoscroll): Rewrote this to scroll recursively, and to scroll based on the mouse position (not the selection).
         We also need to update the selection here, since autoscroll can occur without a mouseMove event, and the selection needs to get reset as we scroll.

        * rendering/RenderListBox.cpp:
        (WebCore::RenderListBox::autoscroll): Convert the mouse coordinates to the right space.

        * rendering/RenderObject.cpp:
        (WebCore::RenderObject::shouldAutoscroll): Also return true if the renderer is a root (so we know to autoscroll views too)
        (WebCore::RenderObject::destroy): If this renderer is being autoscrolled, stop the frame's autoscroll timer.

WebKit:

        Reviewed by Beth.

        Removed handleAutoscrollForMouseDragged.  Except for autoscroll caused by drag and drop, all other
        autoscrolling should be done in WebCore instead of in AppKit.

        * WebCoreSupport/WebFrameBridge.m:
        * WebView/WebHTMLView.m:
        * WebView/WebHTMLViewPrivate.h:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@16975 268f45cc-cd09-0410-ab3c-d52691b4dbfc

15 files changed:
WebCore/ChangeLog
WebCore/bridge/mac/FrameMac.h
WebCore/bridge/mac/FrameMac.mm
WebCore/bridge/mac/WebCoreFrameBridge.h
WebCore/page/Frame.cpp
WebCore/page/Frame.h
WebCore/page/FramePrivate.h
WebCore/page/FrameView.cpp
WebCore/rendering/RenderLayer.cpp
WebCore/rendering/RenderListBox.cpp
WebCore/rendering/RenderObject.cpp
WebKit/ChangeLog
WebKit/WebCoreSupport/WebFrameBridge.m
WebKit/WebView/WebHTMLView.m
WebKit/WebView/WebHTMLViewPrivate.h

index bb3ab3ef9306a4824c14a77d2ce729d4352931fe..059de859ecfb98214dc93e935ac1a52bd909e77c 100644 (file)
@@ -1,3 +1,59 @@
+2006-10-10  Adele Peterson  <adele@apple.com>
+
+        Reviewed by Beth. 
+
+
+        - Fix for <rdar://problem/4707489> After timers fix, crash below RenderLayer::autoscroll after moving/destroying active <input type=text>
+          and <rdar://problem/4707519> After timers fix, crash below RenderLayer::autoscroll after moving/destroying active textarea
+
+        Moved autoscroll code to the Frame class
+
+        * bridge/mac/FrameMac.h: Moved _mouseDownMayStartDrag and _mouseDownMayStartAutoscroll flags to the frame.
+        * bridge/mac/FrameMac.mm: Use new getters and setters for drag and autoscroll flags.  Moved autoscroll code to Frame::handleMouseMoveEvent.
+        (WebCore::FrameMac::FrameMac):
+        (WebCore::FrameMac::handleMousePressEvent):
+        (WebCore::FrameMac::eventMayStartDrag):
+        (WebCore::FrameMac::handleMouseMoveEvent):
+        (WebCore::FrameMac::mouseDown):
+
+        * bridge/mac/WebCoreFrameBridge.h: Removed handleAutoscrollForMouseDragged, which called over the bridge for AppKit to do autoscroll for us.
+        Now we scroll our views in WebCore.
+
+        * page/Frame.cpp:
+        (WebCore::Frame::handleMousePressEvent): Initialize the mouseDownMayStartAutoscroll flag.
+        (WebCore::Frame::handleMouseMoveEvent): Now kicks off autoscroll if appropriate.  Moved from FrameMac.
+        (WebCore::Frame::updateSelectionForMouseDragOverPosition): Factored code out from handleMouseMoveEvent so we can update the selection from autoscroll too.
+        (WebCore::Frame::mouseDownMayStartAutoscroll): Added.
+        (WebCore::Frame::setMouseDownMayStartAutoscroll): Added.
+        (WebCore::Frame::mouseDownMayStartDrag): Added.
+        (WebCore::Frame::setMouseDownMayStartDrag): Added.
+        (WebCore::Frame::autoscrollRenderer): Added
+        (WebCore::Frame::setAutoscrollRenderer): Added.
+        (WebCore::Frame::handleAutoscroll): Updated to use autoscrollRenderer getter and setter.
+        (WebCore::Frame::autoscrollTimerFired): ditto.
+        (WebCore::Frame::stopAutoscrollTimer): ditto. 
+        * page/Frame.h: Made autoscrollRenderer and stopAutoscrollTimer public, so the renderer being autoscrolled can kill the timer when it dies.
+
+        * page/FramePrivate.h:
+        (WebCore::FramePrivate::FramePrivate): Added mouseDownMayStartDrag and mouseDownMayStartAutoscroll flags.  Moved from FrameMac.
+
+        * page/FrameView.cpp: Store the current mouse position in window coordinates.  The callers can convert to their own coordinate space.
+        (WebCore::FrameView::handleMousePressEvent):
+        (WebCore::FrameView::handleMouseDoubleClickEvent):
+        (WebCore::FrameView::handleMouseMoveEvent):
+        (WebCore::FrameView::handleMouseReleaseEvent):
+
+        * rendering/RenderLayer.cpp:
+        (WebCore::RenderLayer::autoscroll): Rewrote this to scroll recursively, and to scroll based on the mouse position (not the selection).  
+         We also need to update the selection here, since autoscroll can occur without a mouseMove event, and the selection needs to get reset as we scroll.
+
+        * rendering/RenderListBox.cpp:
+        (WebCore::RenderListBox::autoscroll): Convert the mouse coordinates to the right space.
+
+        * rendering/RenderObject.cpp:
+        (WebCore::RenderObject::shouldAutoscroll): Also return true if the renderer is a root (so we know to autoscroll views too)
+        (WebCore::RenderObject::destroy): If this renderer is being autoscrolled, stop the frame's autoscroll timer.
+
 2006-10-10  Darin Adler  <darin@apple.com>
 
         Rubber stamped by Maciej.
index 8543cb5f13919708946587a7395c034f52d9682f..2c8ddfddd6d70b0cbcd507842f9becddc74f4363 100644 (file)
@@ -353,9 +353,7 @@ private:
     NSView* _mouseDownView;
     bool _mouseDownWasInSubframe;
     bool _sendingEventToSubview;
-    bool _mouseDownMayStartDrag;
     bool _mouseDownMayStartSelect;
-    bool _mouseDownMayStartAutoscroll;
     PlatformMouseEvent m_mouseDown;
     // in our view's coords
     IntPoint m_mouseDownPos;
index a0ff89a7e1f9776dea8d5a68608da719cf310a6d..912b30a2b95822e123be712696317a308022a44d 100644 (file)
@@ -152,9 +152,7 @@ FrameMac::FrameMac(Page* page, Element* ownerElement)
     , _bridge(nil)
     , _mouseDownView(nil)
     , _sendingEventToSubview(false)
-    , _mouseDownMayStartDrag(false)
     , _mouseDownMayStartSelect(false)
-    , _mouseDownMayStartAutoscroll(false)
     , _activationEventNumber(0)
     , _bindingRoot(0)
     , _windowScriptObject(0)
@@ -1408,11 +1406,9 @@ void FrameMac::handleMousePressEvent(const MouseEventWithHitTestResults& event)
     _mouseDownMayStartSelect = canMouseDownStartSelect(event.targetNode());
     
     // Careful that the drag starting logic stays in sync with eventMayStartDrag()
-    _mouseDownMayStartDrag = singleClick;
+    setMouseDownMayStartDrag(singleClick);
 
     d->m_mousePressNode = event.targetNode();
-
-    _mouseDownMayStartAutoscroll = d->m_mousePressNode && d->m_mousePressNode->renderer() && d->m_mousePressNode->renderer()->shouldAutoscroll();
     
     if (!passWidgetMouseDownEventToWidget(event)) {
         // We don't do this at the start of mouse down handling (before calling into WebCore),
@@ -1587,8 +1583,8 @@ NSView *FrameMac::mouseDownViewIfStillGood()
 bool FrameMac::eventMayStartDrag(NSEvent *event) const
 {
     // This is a pre-flight check of whether the event might lead to a drag being started.  Be careful
-    // that its logic needs to stay in sync with handleMouseMoveEvent() and the way we set
-    // _mouseDownMayStartDrag in handleMousePressEvent
+    // that its logic needs to stay in sync with handleMouseMoveEvent() and the way we setMouseDownMayStartDrag
+    // in handleMousePressEvent
     
     if ([event type] != NSLeftMouseDown || [event clickCount] != 1) {
         return false;
@@ -1650,24 +1646,24 @@ void FrameMac::handleMouseMoveEvent(const MouseEventWithHitTestResults& event)
 
         // Careful that the drag starting logic stays in sync with eventMayStartDrag()
     
-        if (_mouseDownMayStartDrag && !_dragSrc) {
+        if (mouseDownMayStartDrag() && !_dragSrc) {
             BOOL tempFlag1, tempFlag2;
             [_bridge allowDHTMLDrag:&tempFlag1 UADrag:&tempFlag2];
             _dragSrcMayBeDHTML = tempFlag1;
             _dragSrcMayBeUA = tempFlag2;
             if (!_dragSrcMayBeDHTML && !_dragSrcMayBeUA) {
-                _mouseDownMayStartDrag = false;     // no element is draggable
+                setMouseDownMayStartDrag(false);     // no element is draggable
             }
         }
         
-        if (_mouseDownMayStartDrag && !_dragSrc) {
+        if (mouseDownMayStartDrag() && !_dragSrc) {
             // try to find an element that wants to be dragged
             RenderObject::NodeInfo nodeInfo(true, false);
             renderer()->layer()->hitTest(nodeInfo, m_mouseDownPos);
             Node *node = nodeInfo.innerNode();
             _dragSrc = (node && node->renderer()) ? node->renderer()->draggableNode(_dragSrcMayBeDHTML, _dragSrcMayBeUA, m_mouseDownPos.x(), m_mouseDownPos.y(), _dragSrcIsDHTML) : 0;
             if (!_dragSrc) {
-                _mouseDownMayStartDrag = false;     // no element is draggable
+                setMouseDownMayStartDrag(false);     // no element is draggable
             } else {
                 // remember some facts about this source, while we have a NodeInfo handy
                 node = nodeInfo.URLElement();
@@ -1682,15 +1678,15 @@ void FrameMac::handleMouseMoveEvent(const MouseEventWithHitTestResults& event)
         
         // For drags starting in the selection, the user must wait between the mousedown and mousedrag,
         // or else we bail on the dragging stuff and allow selection to occur
-        if (_mouseDownMayStartDrag && _dragSrcInSelection && [_currentEvent timestamp] - _mouseDownTimestamp < TextDragDelay) {
-            _mouseDownMayStartDrag = false;
+        if (mouseDownMayStartDrag() && _dragSrcInSelection && [_currentEvent timestamp] - _mouseDownTimestamp < TextDragDelay) {
+            setMouseDownMayStartDrag(false);
             // ...but if this was the first click in the window, we don't even want to start selection
             if (_activationEventNumber == [_currentEvent eventNumber]) {
                 _mouseDownMayStartSelect = false;
             }
         }
 
-        if (_mouseDownMayStartDrag) {
+        if (mouseDownMayStartDrag()) {
             // We are starting a text/image/url drag, so the cursor should be an arrow
             d->m_view->setCursor(pointerCursor());
             
@@ -1723,12 +1719,12 @@ void FrameMac::handleMouseMoveEvent(const MouseEventWithHitTestResults& event)
                         _dragClipboard->setDragImageElement(_dragSrc.get(), IntPoint() + delta);
                     } 
 
-                    _mouseDownMayStartDrag = dispatchDragSrcEvent(dragstartEvent, m_mouseDown) && mayCopy();
+                    setMouseDownMayStartDrag(dispatchDragSrcEvent(dragstartEvent, m_mouseDown) && mayCopy());
                     // Invalidate clipboard here against anymore pasteboard writing for security.  The drag
                     // image can still be changed as we drag, but not the pasteboard data.
                     _dragClipboard->setAccessPolicy(ClipboardMac::ImageWritable);
                     
-                    if (_mouseDownMayStartDrag) {
+                    if (mouseDownMayStartDrag()) {
                         // gather values from DHTML element, if it set any
                         _dragClipboard->sourceOperation(&srcOp);
 
@@ -1746,17 +1742,17 @@ void FrameMac::handleMouseMoveEvent(const MouseEventWithHitTestResults& event)
                     }
                 }
                 
-                if (_mouseDownMayStartDrag) {
+                if (mouseDownMayStartDrag()) {
                     BOOL startedDrag = [_bridge startDraggingImage:dragImage at:dragLoc operation:srcOp event:_currentEvent sourceIsDHTML:_dragSrcIsDHTML DHTMLWroteData:wcWrotePasteboard];
                     if (!startedDrag && _dragSrcMayBeDHTML) {
                         // WebKit canned the drag at the last minute - we owe _dragSrc a DRAGEND event
                         PlatformMouseEvent event(PlatformMouseEvent::currentEvent);
                         dispatchDragSrcEvent(dragendEvent, event);
-                        _mouseDownMayStartDrag = false;
+                        setMouseDownMayStartDrag(false);
                     }
                 } 
 
-                if (!_mouseDownMayStartDrag) {
+                if (!mouseDownMayStartDrag()) {
                     // something failed to start the drag, cleanup
                     freeClipboard();
                     _dragSrc = 0;
@@ -1766,30 +1762,8 @@ void FrameMac::handleMouseMoveEvent(const MouseEventWithHitTestResults& event)
             // No more default handling (like selection), whether we're past the hysteresis bounds or not
             return;
         }
-        if (!_mouseDownMayStartSelect && !_mouseDownMayStartAutoscroll) {
+        if (!mouseDownMayStartSelect() && !mouseDownMayStartAutoscroll())
             return;
-        }
-
-        // Don't allow dragging or click handling after we've started selecting.
-        _mouseDownMayStartDrag = false;
-        d->m_view->invalidateClick();
-
-        Node* node = event.targetNode();
-        RenderObject* renderer = 0;
-        if (node)
-            renderer = node->renderer();
-            
-        // If the selection is contained in a layer that can scroll, that layer should handle the autoscroll
-        // Otherwise, let the bridge handle it so the view can scroll itself.
-        while (renderer && !renderer->shouldAutoscroll())
-            renderer = renderer->parent();
-        if (renderer)
-            handleAutoscroll(renderer);
-        else {
-            if (!d->m_autoscrollTimer.isActive())
-                startAutoscrollTimer();
-            [_bridge handleAutoscrollForMouseDragged:_currentEvent];
-        }
             
     } else {
         // If we allowed the other side of the bridge to handle a drag
@@ -2008,10 +1982,10 @@ void FrameMac::mouseDown(NSEvent *event)
     m_mouseDownPos = d->m_view->windowToContents(IntPoint(loc));
     _mouseDownTimestamp = [event timestamp];
 
-    _mouseDownMayStartDrag = false;
+    setMouseDownMayStartDrag(false);
     _mouseDownMayStartSelect = false;
-    _mouseDownMayStartAutoscroll = false;
-
+    setMouseDownMayStartAutoscroll(false);
+    
     v->handleMousePressEvent(event);
     
     ASSERT(_currentEvent == event);
index 5ec6b6d9cf476a6a7c60f767eebfedc4f71c2bcf..59bc04459bdce0d873e1622a9d6b7fffb4921241 100644 (file)
@@ -625,7 +625,6 @@ typedef enum {
 
 - (void)allowDHTMLDrag:(BOOL *)flagDHTML UADrag:(BOOL *)flagUA;
 - (BOOL)startDraggingImage:(NSImage *)dragImage at:(NSPoint)dragLoc operation:(NSDragOperation)op event:(NSEvent *)event sourceIsDHTML:(BOOL)flag DHTMLWroteData:(BOOL)dhtmlWroteData;
-- (void)handleAutoscrollForMouseDragged:(NSEvent *)event;
 - (BOOL)mayStartDragAtEventLocation:(NSPoint)location;
 
 - (BOOL)selectWordBeforeMenuEvent;
index eda76afaa4a843fa4002fe879ff5da2ec7be7d2c..2a7b9d071d146f5b86609bf0b06a0463aa7104ef 100644 (file)
@@ -1932,6 +1932,9 @@ void Frame::handleMousePressEvent(const MouseEventWithHitTestResults& event)
         }
         handleMousePressEventSingleClick(event);
     }
+    
+   setMouseDownMayStartAutoscroll(mouseDownMayStartSelect() || 
+        (d->m_mousePressNode && d->m_mousePressNode->renderer() && d->m_mousePressNode->renderer()->shouldAutoscroll()));
 }
 
 void Frame::handleMouseMoveEvent(const MouseEventWithHitTestResults& event)
@@ -1942,14 +1945,34 @@ void Frame::handleMouseMoveEvent(const MouseEventWithHitTestResults& event)
 
     Node *innerNode = event.targetNode();
 
-    if (event.event().button() != 0 || !innerNode || !innerNode->renderer() || !mouseDownMayStartSelect() || !innerNode->renderer()->shouldSelect())
+    if (event.event().button() != 0 || !innerNode || !innerNode->renderer())
         return;
 
-    // handle making selection
+     if (mouseDownMayStartAutoscroll()) {            
+        // If the selection is contained in a layer that can scroll, that layer should handle the autoscroll
+        // Otherwise, let the bridge handle it so the view can scroll itself.
+        RenderObject* renderer = innerNode->renderer();
+        while (renderer && !renderer->shouldAutoscroll())
+            renderer = renderer->parent();
+        if (renderer)
+            handleAutoscroll(renderer);
+                
+        setMouseDownMayStartDrag(false);
+        view()->invalidateClick();
+    }
+    
+    if (mouseDownMayStartSelect() && innerNode->renderer()->shouldSelect()) {
+        // handle making selection
+        IntPoint vPoint = view()->windowToContents(event.event().pos());        
+        VisiblePosition pos(innerNode->renderer()->positionForPoint(vPoint));
 
-    IntPoint vPoint = view()->windowToContents(event.event().pos());
-    VisiblePosition pos(innerNode->renderer()->positionForPoint(vPoint));
+        updateSelectionForMouseDragOverPosition(pos);
+    }
 
+}
+
+void Frame::updateSelectionForMouseDragOverPosition(const VisiblePosition& pos)
+{
     // Don't modify the selection if we're not on a node.
     if (pos.isNull())
         return;
@@ -2627,6 +2650,26 @@ void Frame::selectFrameElementInParentIfFullySelected()
     }
 }
 
+bool Frame::mouseDownMayStartAutoscroll() const
+{
+    return d->m_mouseDownMayStartAutoscroll;
+}
+
+void Frame::setMouseDownMayStartAutoscroll(bool b)
+{
+    d->m_mouseDownMayStartAutoscroll = b;
+}
+
+bool Frame::mouseDownMayStartDrag() const
+{
+    return d->m_mouseDownMayStartDrag;
+}
+
+void Frame::setMouseDownMayStartDrag(bool b)
+{
+    d->m_mouseDownMayStartDrag = b;
+}
+
 void Frame::handleFallbackContent()
 {
     Element* owner = ownerElement();
@@ -2846,7 +2889,7 @@ void Frame::handleAutoscroll(RenderObject* renderer)
 {
     if (d->m_autoscrollTimer.isActive())
         return;
-    d->m_autoscrollRenderer = renderer;
+    setAutoscrollRenderer(renderer);
     startAutoscrollTimer();
 }
 
@@ -2856,9 +2899,18 @@ void Frame::autoscrollTimerFired(Timer<Frame>*)
         stopAutoscrollTimer();
         return;
     }
-    if (d->m_autoscrollRenderer) {
-        d->m_autoscrollRenderer->autoscroll();
-    } 
+    if (RenderObject* r = autoscrollRenderer())
+        r->autoscroll();
+}
+
+RenderObject* Frame::autoscrollRenderer() const
+{
+    return d->m_autoscrollRenderer;
+}
+
+void Frame::setAutoscrollRenderer(RenderObject* renderer)
+{
+    d->m_autoscrollRenderer = renderer;
 }
 
 RenderObject::NodeInfo Frame::nodeInfoAtPoint(const IntPoint& point, bool allowShadowContent)
@@ -2922,7 +2974,7 @@ void Frame::startAutoscrollTimer()
 
 void Frame::stopAutoscrollTimer()
 {
-    d->m_autoscrollRenderer = 0;
+    setAutoscrollRenderer(0);
     d->m_autoscrollTimer.stop();
 }
 
index f45301f9bd4391eb807ac5bb99048cfdd8f40ca6..8929ad9e54b35def59ee068c3114e34a6244b054 100644 (file)
@@ -524,6 +524,8 @@ public:
   virtual void handleMouseMoveEvent(const MouseEventWithHitTestResults&);
   virtual void handleMouseReleaseEvent(const MouseEventWithHitTestResults&);
   
+  void updateSelectionForMouseDragOverPosition(const VisiblePosition&);
+
   void selectClosestWordFromMouseEvent(const PlatformMouseEvent&, Node* innerNode);
 
   virtual void urlSelected(const DeprecatedString& url, const String& target);
@@ -640,7 +642,12 @@ public:
   void selectFrameElementInParentIfFullySelected();
   
   virtual bool mouseDownMayStartSelect() const { return true; }
+  bool mouseDownMayStartAutoscroll() const;
+  void setMouseDownMayStartAutoscroll(bool b);
 
+  bool mouseDownMayStartDrag() const;
+  void setMouseDownMayStartDrag(bool b);
+  
   void handleFallbackContent();
 
 private:
@@ -749,6 +756,9 @@ private:
     void setNeedsReapplyStyles();
 
   virtual IntRect windowResizerRect() const { return IntRect(); }
+  
+  void stopAutoscrollTimer();
+  RenderObject* autoscrollRenderer() const;
 
 protected:
     virtual void startRedirectionTimer();
@@ -758,7 +768,7 @@ protected:
     
     void handleAutoscroll(RenderObject*);
     void startAutoscrollTimer();
-    void stopAutoscrollTimer();
+    void setAutoscrollRenderer(RenderObject*);
 
  private:
   void emitLoadEvent();
index 6ae0566943b2e32c142a2170afdc89901cf79c39..dc8d0d3b7f56100906f294b3a954342f061e534a 100644 (file)
@@ -102,6 +102,8 @@ namespace WebCore {
             , m_iconLoader(0)
             , m_autoscrollTimer(thisFrame, &Frame::autoscrollTimerFired)
             , m_autoscrollRenderer(0)
+            , m_mouseDownMayStartAutoscroll(false)
+            , m_mouseDownMayStartDrag(false)
             , m_paintRestriction(PaintRestrictionNone)
             , m_markedTextUsesUnderlines(false)
             , m_highlightTextMatches(false)
@@ -222,6 +224,8 @@ namespace WebCore {
         
         Timer<Frame> m_autoscrollTimer;
         RenderObject* m_autoscrollRenderer;
+        bool m_mouseDownMayStartAutoscroll;
+        bool m_mouseDownMayStartDrag;
         
         RefPtr<Node> m_elementToDraw;
         PaintRestriction m_paintRestriction;
index e30a3bf8bb939ec23449aedda817f069a426a221..392aaa999dcc6c3cf07e3db5a7023e4de99a0759 100644 (file)
@@ -588,7 +588,7 @@ void FrameView::handleMousePressEvent(const PlatformMouseEvent& mouseEvent)
     RefPtr<FrameView> protector(this);
 
     d->mousePressed = true;
-    d->m_currentMousePosition = windowToContents(mouseEvent.pos());
+    d->m_currentMousePosition = mouseEvent.pos();
     
     MouseEventWithHitTestResults mev = prepareMouseEvent(false, true, false, mouseEvent);
 
@@ -647,7 +647,7 @@ void FrameView::handleMouseDoubleClickEvent(const PlatformMouseEvent& mouseEvent
 
     // We get this instead of a second mouse-up 
     d->mousePressed = false;
-    d->m_currentMousePosition = windowToContents(mouseEvent.pos());
+    d->m_currentMousePosition = mouseEvent.pos();
 
     MouseEventWithHitTestResults mev = prepareMouseEvent(false, true, false, mouseEvent);
     Frame* subframe = subframeForTargetNode(mev.targetNode());
@@ -803,7 +803,7 @@ void FrameView::handleMouseMoveEvent(const PlatformMouseEvent& mouseEvent)
         return;
 
     RefPtr<FrameView> protector(this);
-    d->m_currentMousePosition = windowToContents(mouseEvent.pos());
+    d->m_currentMousePosition = mouseEvent.pos();
    
     if (d->hoverTimer.isActive())
         d->hoverTimer.stop();
@@ -879,7 +879,7 @@ void FrameView::handleMouseReleaseEvent(const PlatformMouseEvent& mouseEvent)
     RefPtr<FrameView> protector(this);
 
     d->mousePressed = false;
-    d->m_currentMousePosition = windowToContents(mouseEvent.pos());
+    d->m_currentMousePosition = mouseEvent.pos();
 
     if (d->resizingFrameSet) {
         dispatchMouseEvent(mouseupEvent, d->resizingFrameSet.get(), true, d->clickCount, mouseEvent, false);
index 92ef434bd8633e11c1728f1a0a1a2a816c4bfa44..b619e04752c1ffdbb1f8b22188ce3cabe7f375f9 100644 (file)
@@ -754,32 +754,19 @@ IntRect RenderLayer::getRectToExpose(const IntRect &visibleRect, const IntRect &
 }
 
 void RenderLayer::autoscroll()
-{    
-    int xOffset = scrollXOffset();
-    int yOffset = scrollYOffset();
-
-    // Get the rectangle for the extent of the selection
-    Selection selection(renderer()->document()->frame()->selectionController()->selection());
-    IntRect extentRect = VisiblePosition(selection.extent()).caretRect();
-    extentRect.move(xOffset, yOffset);
-
-    IntRect bounds = IntRect(xPos() + xOffset, yPos() + yOffset, width() - verticalScrollbarWidth(), height() - horizontalScrollbarHeight());
-    
-    // Calculate how much the layer should scroll horizontally.
-    int diffX = 0;
-    if (extentRect.right() > bounds.right())
-        diffX = extentRect.right() - bounds.right();
-    else if (extentRect.x() < bounds.x())
-        diffX = extentRect.x() - bounds.x();
+{
+    if (!renderer() || !renderer()->document() || !renderer()->document()->frame() || !renderer()->document()->frame()->view())
+        return;
         
-    // Calculate how much the layer should scroll vertically.
-    int diffY = 0;
-    if (extentRect.bottom() > bounds.bottom())
-        diffY = extentRect.bottom() - bounds.bottom();
-    else if (extentRect.y() < bounds.y())
-        diffY = extentRect.y() - bounds.y();
-
-    scrollToOffset(xOffset + diffX, yOffset + diffY);
+    Frame* currentFrame = renderer()->document()->frame();
+    IntPoint currentPos = currentFrame->view()->windowToContents(currentFrame->view()->currentMousePosition());
+    
+    if (currentFrame->mouseDownMayStartSelect()) {
+        VisiblePosition pos(renderer()->positionForPoint(currentPos));
+        currentFrame->updateSelectionForMouseDragOverPosition(pos);
+    }
+
+    scrollRectToVisible(IntRect(currentPos, IntSize(1, 1)), gAlignToEdgeIfNeeded, gAlignToEdgeIfNeeded);    
 }
 
 void RenderLayer::resize(const PlatformMouseEvent& evt, const IntSize& offsetFromResizeCorner)
index 6a0745161049adf352835c01e4cfce4bcb678e01..446f5b5d84424830a18441fc2884748440625e3c 100644 (file)
@@ -355,8 +355,7 @@ HTMLOptionElement* RenderListBox::optionAtPoint(int x, int y)
 
 void RenderListBox::autoscroll()
 {
-    int mouseX = document()->frame()->view()->currentMousePosition().x();
-    int mouseY = document()->frame()->view()->currentMousePosition().y();
+    IntPoint pos = document()->frame()->view()->windowToContents(document()->frame()->view()->currentMousePosition());
     IntRect bounds = absoluteBoundingBoxRect();
 
     HTMLSelectElement* select = static_cast<HTMLSelectElement*>(node());
@@ -364,12 +363,12 @@ void RenderListBox::autoscroll()
     HTMLOptionElement* element = 0;
     int rows = size();
     int offset = m_indexOffset;
-    if (mouseY < bounds.y() && scrollToRevealElementAtListIndex(offset - 1) && items[offset - 1]->hasTagName(optionTag))
+    if (pos.y() < bounds.y() && scrollToRevealElementAtListIndex(offset - 1) && items[offset - 1]->hasTagName(optionTag))
         element = static_cast<HTMLOptionElement*>(items[offset - 1]);
-    else if (mouseY > bounds.bottom() && scrollToRevealElementAtListIndex(offset + rows) && items[offset + rows - 1]->hasTagName(optionTag))
+    else if (pos.y() > bounds.bottom() && scrollToRevealElementAtListIndex(offset + rows) && items[offset + rows - 1]->hasTagName(optionTag))
         element = static_cast<HTMLOptionElement*>(items[offset + rows - 1]);
     else
-        element = optionAtPoint(mouseX, mouseY);
+        element = optionAtPoint(pos.x(), pos.y());
         
     if (element) {
         select->setSelectedIndex(element->index(), !select->multiple());
index 1a91c1936357fb40ccd3fe95b2a2e49b01475c8c..503d56e1d6d4fefb74182cd25317cbd57bc72395 100644 (file)
@@ -685,7 +685,7 @@ bool RenderObject::scroll(ScrollDirection direction, ScrollGranularity granulari
 
 bool RenderObject::shouldAutoscroll() const
 {
-    return (hasOverflowClip() && (scrollsOverflow() || (node() && node()->isContentEditable())));
+    return ((isRoot()) || (hasOverflowClip() && (scrollsOverflow() || (node() && node()->isContentEditable()))));
 }
 
 void RenderObject::autoscroll()
@@ -2420,6 +2420,10 @@ bool RenderObject::documentBeingDestroyed() const
 
 void RenderObject::destroy()
 {
+    // If this renderer is being autoscrolled, stop the autoscroll timer
+    if (document() && document()->frame() && document()->frame()->autoscrollRenderer() == this)
+        document()->frame()->stopAutoscrollTimer();
+
     if (m_hasCounterNodeMap) {
         RenderObjectsToCounterNodeMaps* objectsMap = getRenderObjectsToCounterNodeMaps();
         if (CounterNodeMap* counterNodesMap = objectsMap->get(this)) {
index 00766d4d4f7a72008fd16e9eecae83a14d9c7989..133eafce82341b94acff50d5d3d20cc38e48bd2a 100644 (file)
@@ -1,3 +1,14 @@
+2006-10-10  Adele Peterson  <adele@apple.com>
+
+        Reviewed by Beth.
+
+        Removed handleAutoscrollForMouseDragged.  Except for autoscroll caused by drag and drop, all other
+        autoscrolling should be done in WebCore instead of in AppKit.
+
+        * WebCoreSupport/WebFrameBridge.m:
+        * WebView/WebHTMLView.m:
+        * WebView/WebHTMLViewPrivate.h:
+
 2006-10-10  Darin Adler  <darin@apple.com>
 
         - corrected an archive regression caused by loader refactoring
index 54717510f971f0c960201e514c55330ed2b24e4b..e4d3375aaabaf05b68a597f27086e93aa5e91855 100644 (file)
@@ -1202,15 +1202,6 @@ static BOOL loggedObjectCacheSize = NO;
     return [docView _startDraggingImage:dragImage at:dragLoc operation:op event:event sourceIsDHTML:flag DHTMLWroteData:dhtmlWroteData];
 }
 
-- (void)handleAutoscrollForMouseDragged:(NSEvent *)event;
-{
-    WebHTMLView *docView = (WebHTMLView *)[[_frame frameView] documentView];
-
-    ASSERT([docView isKindOfClass:[WebHTMLView class]]);
-
-    [docView _handleAutoscrollForMouseDragged:event];
-}
-
 - (BOOL)mayStartDragAtEventLocation:(NSPoint)location
 {
     WebHTMLView *docView = (WebHTMLView *)[[_frame frameView] documentView];
index d343ae106c549f23aea89caf22111348867cac96..202a3b4007af95c2e7d5c2f633ed9c15458d7ebc 100644 (file)
@@ -1467,12 +1467,6 @@ static WebHTMLView *lastHitView = nil;
     return startedDrag;
 }
 
-- (void)_handleAutoscrollForMouseDragged:(NSEvent *)event
-{
-    [self autoscroll:event];
-    [self _startAutoscrollTimer:event];
-}
-
 - (BOOL)_mayStartDragAtEventLocation:(NSPoint)location
 {
     WebHTMLView *topHTMLView = [self _topHTMLView];
index b836d8283c91479d16d86614ac365c5f6c8aec76..f0af7e42ef57a80db5ae36f5946789c763f62bdc 100644 (file)
@@ -69,7 +69,6 @@
 
 - (NSImage *)_dragImageForLinkElement:(NSDictionary *)element;
 - (BOOL)_startDraggingImage:(NSImage *)dragImage at:(NSPoint)dragLoc operation:(NSDragOperation)op event:(NSEvent *)event sourceIsDHTML:(BOOL)flag DHTMLWroteData:(BOOL)dhtmlWroteData;
-- (void)_handleAutoscrollForMouseDragged:(NSEvent *)event;
 - (BOOL)_mayStartDragAtEventLocation:(NSPoint)location;
 
 - (WebPluginController *)_pluginController;