[SCM] WebKit Debian packaging branch, debian/unstable, updated. debian/1.1.15-1-40151-g37bb677

trey trey at 268f45cc-cd09-0410-ab3c-d52691b4dbfc
Sat Sep 26 08:48:37 UTC 2009


The following commit has been merged in the debian/unstable branch:
commit bc2147c33c63a30f6ebd2601957aff16440d7c46
Author: trey <trey at 268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date:   Thu Jul 1 02:07:43 2004 +0000

    WebCore:
    
    	Dragging within a web view should be allowed to start when the window isn't key.
    
    	A few months ago, Chris made this work, but it relied on the fact that all dragging
    	was done in WebKit.  When WebCore got involved in dragging, it was broken.  Now we
    	have a new scheme that gets it working again that properly involves WebCore.
    
    	The general idea is that when AK asks us whether to accept the first mouse and do
    	"delayed window ordering", we must consult WC to see if we might start a drag.  In
    	addition, instead of these drags in non-active windows being started as a special
    	case in WK, they go through the normal WK-WC drag machinery.
    
            Reviewed by John.
    
            * khtml/khtml_part.cpp:
            (KHTMLPart::shouldDragAutoNode):  New x,y args.
            * khtml/khtml_part.h:
            * khtml/rendering/render_object.cpp:
            (RenderObject::draggableNode):  Pass through new x,y args.
            * khtml/rendering/render_object.h:
            * kwq/KWQKHTMLPart.h:
            (KWQKHTMLPart::setActivationEventNumber):  New setter.
            * kwq/KWQKHTMLPart.mm:
            (KWQKHTMLPart::KWQKHTMLPart):  Init new ivar.
            (KWQKHTMLPart::eventMayStartDrag):  New routine that checks if we might start
    	a drag in response to a mouseDown.
            (KWQKHTMLPart::khtmlMouseMoveEvent):  Pass x,y to the routine that finds a draggable
    	node.  This eventually gets back up to WK's _mayStartDragAtEventLocation:.
    	Delay requirement when dragging the selection now implemented here.
            (KWQKHTMLPart::khtmlMouseReleaseEvent):  Must avoid changing the selection if we
    	wind up here as part of the first click in a window (because we started handling
    	the click to possible start a drag, but that never came through).
            (KWQKHTMLPart::mouseDown): Save away event timestamp.
            (KWQKHTMLPart::shouldDragAutoNode):  Pass location up to WK instead of the
    	most recent event we stashed.
            * kwq/WebCoreBridge.h:
            * kwq/WebCoreBridge.mm:
            (-[WebCoreBridge setActivationEventNumber:]):  Trivial glue.
            (-[WebCoreBridge eventMayStartDrag:]):  Ditto.
    
    WebKit:
    
    	Dragging within a web view should be allowed to start when the window isn't key.
    
    	A few months ago, Chris made this work, but it relied on the fact that all dragging
    	was done in WebKit.  When WebCore got involved in dragging, it was broken.  Now we
    	have a new scheme that gets it working again that properly involves WebCore.
    
    	The general idea is that when AK asks us whether to accept the first mouse and do
    	"delayed window ordering", we must consult WC to see if we might start a drag.  In
    	addition, instead of these drags in non-active windows being started as a special
    	case in WK, they go through the normal WK-WC drag machinery.  Finally to work in
    	frames we have to drill to the deepest hit view in acceptsFirstMouse, because previous
    	hacks to hitTest make the top-most WebHTMLView field all events for its view tree
    	(which leads to it fielding all acceptFirstMouse messages too).
    
            Reviewed by John.
    
            * WebCoreSupport.subproj/WebBridge.m:
            (-[WebBridge mayStartDragAtEventLocation:]):  Glue change for new arg type.
            * WebView.subproj/WebHTMLView.m:
            (-[WebHTMLView _startDraggingImage:at:operation:event:sourceIsDHTML:DHTMLWroteData:]):
    	firstMouseDownEvent ivar is no longer needed.
            (-[WebHTMLView _mayStartDragAtEventLocation:]):  Receives a location instead of a drag
    	event, since we need to do this work when we have no drag event.  This means the
    	check of the delay for text dragging is moved down to WebCore.
            (-[WebHTMLView acceptsFirstMouse:]):  Respond based on whether we might do a drag.
    	This includes drilling to the deepest view the event hits, whereas we used to only
    	respond considering the topmost WebHTMLView.
            (-[WebHTMLView shouldDelayWindowOrderingForEvent:]):  Ditto.
            (-[WebHTMLView mouseDown:]):  Get rid of special case where some activating
    	mouseDown events weren't sent to WC.  We need to go through the whole pipeline
    	now to get a drag started properly.
            (-[WebHTMLView mouseDragged:]):  Ditto, let WC start the drag.
            (-[WebHTMLView mouseUp:]):  firstMouseDownEvent ivar is no longer needed.
            * WebView.subproj/WebHTMLViewInternal.h:
            * WebView.subproj/WebHTMLViewPrivate.h:
    
    
    git-svn-id: http://svn.webkit.org/repository/webkit/trunk@6954 268f45cc-cd09-0410-ab3c-d52691b4dbfc

diff --git a/WebCore/ChangeLog-2005-08-23 b/WebCore/ChangeLog-2005-08-23
index 8668db6..5e1a805 100644
--- a/WebCore/ChangeLog-2005-08-23
+++ b/WebCore/ChangeLog-2005-08-23
@@ -1,3 +1,44 @@
+2004-06-30  Trey Matteson  <trey at apple.com>
+
+	Dragging within a web view should be allowed to start when the window isn't key.
+
+	A few months ago, Chris made this work, but it relied on the fact that all dragging
+	was done in WebKit.  When WebCore got involved in dragging, it was broken.  Now we
+	have a new scheme that gets it working again that properly involves WebCore.
+
+	The general idea is that when AK asks us whether to accept the first mouse and do
+	"delayed window ordering", we must consult WC to see if we might start a drag.  In
+	addition, instead of these drags in non-active windows being started as a special
+	case in WK, they go through the normal WK-WC drag machinery.
+
+        Reviewed by John.
+
+        * khtml/khtml_part.cpp:
+        (KHTMLPart::shouldDragAutoNode):  New x,y args.
+        * khtml/khtml_part.h:
+        * khtml/rendering/render_object.cpp:
+        (RenderObject::draggableNode):  Pass through new x,y args.
+        * khtml/rendering/render_object.h:
+        * kwq/KWQKHTMLPart.h:
+        (KWQKHTMLPart::setActivationEventNumber):  New setter.
+        * kwq/KWQKHTMLPart.mm:
+        (KWQKHTMLPart::KWQKHTMLPart):  Init new ivar.
+        (KWQKHTMLPart::eventMayStartDrag):  New routine that checks if we might start
+	a drag in response to a mouseDown.
+        (KWQKHTMLPart::khtmlMouseMoveEvent):  Pass x,y to the routine that finds a draggable
+	node.  This eventually gets back up to WK's _mayStartDragAtEventLocation:.
+	Delay requirement when dragging the selection now implemented here.
+        (KWQKHTMLPart::khtmlMouseReleaseEvent):  Must avoid changing the selection if we
+	wind up here as part of the first click in a window (because we started handling
+	the click to possible start a drag, but that never came through).
+        (KWQKHTMLPart::mouseDown): Save away event timestamp.
+        (KWQKHTMLPart::shouldDragAutoNode):  Pass location up to WK instead of the
+	most recent event we stashed.
+        * kwq/WebCoreBridge.h:
+        * kwq/WebCoreBridge.mm:
+        (-[WebCoreBridge setActivationEventNumber:]):  Trivial glue.
+        (-[WebCoreBridge eventMayStartDrag:]):  Ditto.
+
 2004-06-29  Trey Matteson  <trey at apple.com>
 
 	Need to tighten up JS error checking for requesting drag props
diff --git a/WebCore/khtml/khtml_part.cpp b/WebCore/khtml/khtml_part.cpp
index 8ce13a5..5f0acad 100644
--- a/WebCore/khtml/khtml_part.cpp
+++ b/WebCore/khtml/khtml_part.cpp
@@ -4265,7 +4265,7 @@ bool KHTMLPart::dndEnabled() const
   return d->m_bDnd;
 }
 
-bool KHTMLPart::shouldDragAutoNode(DOM::NodeImpl *node) const
+bool KHTMLPart::shouldDragAutoNode(DOM::NodeImpl *node, int x, int y) const
 {
     // No KDE impl yet
     return false;
diff --git a/WebCore/khtml/khtml_part.h b/WebCore/khtml/khtml_part.h
index c151b45..87bae96 100644
--- a/WebCore/khtml/khtml_part.h
+++ b/WebCore/khtml/khtml_part.h
@@ -302,7 +302,7 @@ public:
   /**
    * Implementation of CSS property -khtml-user-drag == auto
    */
-  virtual bool shouldDragAutoNode(DOM::NodeImpl*) const;
+  virtual bool shouldDragAutoNode(DOM::NodeImpl*, int x, int y) const;
   
   /**
    * Enables/disables Java applet support. Note that calling this function
diff --git a/WebCore/khtml/rendering/render_object.cpp b/WebCore/khtml/rendering/render_object.cpp
index c2fdedd..39455e6 100644
--- a/WebCore/khtml/rendering/render_object.cpp
+++ b/WebCore/khtml/rendering/render_object.cpp
@@ -1391,7 +1391,7 @@ bool RenderObject::shouldSelect() const
     return node->dispatchHTMLEvent(DOM::EventImpl::SELECTSTART_EVENT, true, true);
 }
 
-DOM::NodeImpl* RenderObject::draggableNode(bool dhtmlOK, bool uaOK, bool& dhtmlWillDrag) const
+DOM::NodeImpl* RenderObject::draggableNode(bool dhtmlOK, bool uaOK, int x, int y, bool& dhtmlWillDrag) const
 {
     if (!dhtmlOK && !uaOK)
         return 0;
@@ -1402,7 +1402,7 @@ DOM::NodeImpl* RenderObject::draggableNode(bool dhtmlOK, bool uaOK, bool& dhtmlW
         if (elt && elt->nodeType() == Node::TEXT_NODE) {
             // Since there's no way for the author to address the -khtml-user-drag style for a text node,
             // we use our own judgement.
-            if (uaOK && canvas()->view()->part()->shouldDragAutoNode(curr->node())) {
+            if (uaOK && canvas()->view()->part()->shouldDragAutoNode(curr->node(), x, y)) {
                 dhtmlWillDrag = false;
                 return curr->node();
             } else if (curr->shouldSelect()) {
@@ -1417,7 +1417,7 @@ DOM::NodeImpl* RenderObject::draggableNode(bool dhtmlOK, bool uaOK, bool& dhtmlW
                 dhtmlWillDrag = true;
                 return curr->node();
             } else if (uaOK && dragMode == DRAG_AUTO
-                       && canvas()->view()->part()->shouldDragAutoNode(curr->node()))
+                       && canvas()->view()->part()->shouldDragAutoNode(curr->node(), x, y))
             {
                 dhtmlWillDrag = false;
                 return curr->node();
diff --git a/WebCore/khtml/rendering/render_object.h b/WebCore/khtml/rendering/render_object.h
index 33be313..925e263 100644
--- a/WebCore/khtml/rendering/render_object.h
+++ b/WebCore/khtml/rendering/render_object.h
@@ -704,7 +704,7 @@ public:
     virtual void setSelectionState(SelectionState) {}
     bool shouldSelect() const;
 
-    DOM::NodeImpl* draggableNode(bool dhtmlOK, bool uaOK, bool& dhtmlWillDrag) const;
+    DOM::NodeImpl* draggableNode(bool dhtmlOK, bool uaOK, int x, int y, bool& dhtmlWillDrag) const;
 
     /**
      * Returns the content coordinates of the caret within this render object.
diff --git a/WebCore/kwq/KWQKHTMLPart.h b/WebCore/kwq/KWQKHTMLPart.h
index 8aed333..b2690e0 100644
--- a/WebCore/kwq/KWQKHTMLPart.h
+++ b/WebCore/kwq/KWQKHTMLPart.h
@@ -231,7 +231,9 @@ public:
     void mouseMoved(NSEvent *);
     bool keyEvent(NSEvent *);
     bool lastEventIsMouseUp();
+    void setActivationEventNumber(int num) { _activationEventNumber = num; }
 
+    bool eventMayStartDrag(NSEvent *);
     void dragSourceMovedTo(const QPoint &loc);
     void dragSourceEndedAt(const QPoint &loc, NSDragOperation operation);
 
@@ -317,7 +319,7 @@ public:
     void partClearedInBegin();
     
     // Implementation of CSS property -khtml-user-drag == auto
-    bool shouldDragAutoNode(DOM::NodeImpl*) const;
+    bool shouldDragAutoNode(DOM::NodeImpl*, int x, int y) const;
 
 private:
     virtual void khtmlMousePressEvent(khtml::MousePressEvent *);
@@ -363,6 +365,8 @@ private:
     int _mouseDownWinX, _mouseDownWinY;
     // in our view's coords
     int _mouseDownX, _mouseDownY;
+    float _mouseDownTimestamp;
+    int _activationEventNumber;
     
     static NSEvent *_currentEvent;
     static NSResponder *_firstResponderAtMouseDownTime;
diff --git a/WebCore/kwq/KWQKHTMLPart.mm b/WebCore/kwq/KWQKHTMLPart.mm
index db2aa45..0e58613 100644
--- a/WebCore/kwq/KWQKHTMLPart.mm
+++ b/WebCore/kwq/KWQKHTMLPart.mm
@@ -179,6 +179,7 @@ KWQKHTMLPart::KWQKHTMLPart()
     , _sendingEventToSubview(false)
     , _mouseDownMayStartDrag(false)
     , _mouseDownMayStartSelect(false)
+    , _activationEventNumber(0)
     , _formValuesAboutToBeSubmitted(nil)
     , _formAboutToBeSubmitted(nil)
     , _windowWidget(NULL)
@@ -1715,6 +1716,7 @@ void KWQKHTMLPart::khtmlMousePressEvent(MousePressEvent *event)
     // If we got the event back, that must mean it wasn't prevented,
     // so it's allowed to start a drag or selection.
     _mouseDownMayStartSelect = true;
+    // Careful that the drag starting logic stays in sync with eventMayStartDrag()
     _mouseDownMayStartDrag = singleClick;
 
     if (!passWidgetMouseDownEventToWidget(event)) {
@@ -1910,7 +1912,9 @@ NSView *KWQKHTMLPart::mouseDownViewIfStillGood()
 #define LinkDragHysteresis              40.0
 #define ImageDragHysteresis              5.0
 #define TextDragHysteresis               3.0
-#define GeneralDragHysterisis            3.0
+#define GeneralDragHysteresis            3.0
+
+#define TextDragDelay                    0.15
 
 bool KWQKHTMLPart::dragHysteresisExceeded(float dragLocationX, float dragLocationY) const
 {
@@ -1919,7 +1923,7 @@ bool KWQKHTMLPart::dragHysteresisExceeded(float dragLocationX, float dragLocatio
     float deltaX = QABS(dragX - _mouseDownX);
     float deltaY = QABS(dragY - _mouseDownY);
 
-    float threshold = GeneralDragHysterisis;
+    float threshold = GeneralDragHysteresis;
     if (_dragSrcIsImage) {
         threshold = ImageDragHysteresis;
     } else if (_dragSrcIsLink) {
@@ -1937,6 +1941,32 @@ bool KWQKHTMLPart::dispatchDragSrcEvent(int eventId, const QPoint &loc) const
     return !noDefaultProc;
 }
 
+bool KWQKHTMLPart::eventMayStartDrag(NSEvent *event)
+{
+    // 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 khtmlMouseMoveEvent() and the way we set
+    // _mouseDownMayStartDrag in khtmlMousePressEvent
+    
+    if ([event type] != NSLeftMouseDown || [event clickCount] != 1) {
+        return false;
+    }
+    
+    BOOL DHTMLFlag, UAFlag;
+    [_bridge allowDHTMLDrag:&DHTMLFlag UADrag:&UAFlag];
+    if (!DHTMLFlag && !UAFlag) {
+        return false;
+    }
+
+    NSPoint loc = [event locationInWindow];
+    int mouseDownX, mouseDownY;
+    d->m_view->viewportToContents((int)loc.x, (int)loc.y, mouseDownX, mouseDownY);
+    RenderObject::NodeInfo nodeInfo(true, false);
+    renderer()->layer()->nodeAtPoint(nodeInfo, mouseDownX, mouseDownY);
+    bool srcIsDHTML;
+    Node possibleSrc = nodeInfo.innerNode()->renderer()->draggableNode(DHTMLFlag, UAFlag, mouseDownX, mouseDownY, srcIsDHTML);
+    return !possibleSrc.isNull();
+}
+
 void KWQKHTMLPart::khtmlMouseMoveEvent(MouseMoveEvent *event)
 {
     KWQ_BLOCK_EXCEPTIONS;
@@ -1951,6 +1981,8 @@ void KWQKHTMLPart::khtmlMouseMoveEvent(MouseMoveEvent *event)
             return;
         }
 
+        // Careful that the drag starting logic stays in sync with eventMayStartDrag()
+    
 	if (_mouseDownMayStartDrag && _dragSrc.isNull()) {
             BOOL tempFlag1, tempFlag2;
             [_bridge allowDHTMLDrag:&tempFlag1 UADrag:&tempFlag2];
@@ -1965,7 +1997,7 @@ void KWQKHTMLPart::khtmlMouseMoveEvent(MouseMoveEvent *event)
             // try to find an element that wants to be dragged
             RenderObject::NodeInfo nodeInfo(true, false);
             renderer()->layer()->nodeAtPoint(nodeInfo, _mouseDownX, _mouseDownY);
-            _dragSrc = nodeInfo.innerNode()->renderer()->draggableNode(_dragSrcMayBeDHTML, _dragSrcMayBeUA, _dragSrcIsDHTML);
+            _dragSrc = nodeInfo.innerNode()->renderer()->draggableNode(_dragSrcMayBeDHTML, _dragSrcMayBeUA, _mouseDownX, _mouseDownY, _dragSrcIsDHTML);
             if (_dragSrc.isNull()) {
                 _mouseDownMayStartDrag = false;     // no element is draggable
             } else {
@@ -1979,6 +2011,16 @@ void KWQKHTMLPart::khtmlMouseMoveEvent(MouseMoveEvent *event)
                 _dragSrcInSelection = isPointInsideSelection(_mouseDownX, _mouseDownY);
             }                
         }
+        
+        // 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;
+            // ...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) {
             // We are starting a text/image/url drag, so the cursor should be an arrow
@@ -2173,7 +2215,14 @@ void KWQKHTMLPart::khtmlMouseReleaseEvent(MouseReleaseEvent *event)
 {
     NSView *view = mouseDownViewIfStillGood();
     if (!view) {
-        KHTMLPart::khtmlMouseReleaseEvent(event);
+        // If this was the first click in the window, we don't even want to clear the selection.
+        // This case occurs when the user clicks on a draggable element, since we have to process
+        // the mouse down and drag events to see if we might start a drag.  For other first clicks
+        // in a window, we just don't acceptFirstMouse, and the whole down-drag-up sequence gets
+        // ignored upstream of this layer.
+        if (_activationEventNumber != [_currentEvent eventNumber]) {
+            KHTMLPart::khtmlMouseReleaseEvent(event);
+        }
         return;
     }
     
@@ -2275,6 +2324,7 @@ void KWQKHTMLPart::mouseDown(NSEvent *event)
     _mouseDownWinX = (int)loc.x;
     _mouseDownWinY = (int)loc.y;
     d->m_view->viewportToContents(_mouseDownWinX, _mouseDownWinY, _mouseDownX, _mouseDownY);
+    _mouseDownTimestamp = [event timestamp];
 
     NSResponder *oldFirstResponderAtMouseDownTime = _firstResponderAtMouseDownTime;
     // Unlike other places in WebCore where we get the first
@@ -2459,14 +2509,17 @@ void KWQKHTMLPart::mouseMoved(NSEvent *event)
 }
 
 // Called as we walk up the element chain for nodes with CSS property -khtml-user-drag == auto
-bool KWQKHTMLPart::shouldDragAutoNode(DOM::NodeImpl* node) const
+bool KWQKHTMLPart::shouldDragAutoNode(DOM::NodeImpl* node, int x, int y) const
 {
     // We assume that WebKit only cares about dragging things that can be leaf nodes (text, images, urls).
     // This saves a bunch of expensive calls (creating WC and WK element dicts) as we walk farther up
     // the node hierarchy, and we also don't have to cook up a way to ask WK about non-leaf nodes
     // (since right now WK just hit-tests using a cached lastMouseDown).
-    if (!node->hasChildNodes()) {
-        return [_bridge mayStartDragWithMouseDragged:_currentEvent];
+    if (!node->hasChildNodes() && d->m_view) {
+        int windowX, windowY;
+        d->m_view->contentsToViewport(x, y, windowX, windowY);
+        NSPoint eventLoc = {windowX, windowY};
+        return [_bridge mayStartDragAtEventLocation:eventLoc];
     } else {
         return NO;
     }
diff --git a/WebCore/kwq/WebCoreBridge.h b/WebCore/kwq/WebCoreBridge.h
index ba3b5c3..ef6af6e 100644
--- a/WebCore/kwq/WebCoreBridge.h
+++ b/WebCore/kwq/WebCoreBridge.h
@@ -189,6 +189,7 @@ typedef enum {
 
 - (void)setShowsFirstResponder:(BOOL)flag;
 
+- (void)setActivationEventNumber:(int)num;
 - (void)mouseDown:(NSEvent *)event;
 - (void)mouseUp:(NSEvent *)event;
 - (void)mouseMoved:(NSEvent *)event;
@@ -319,6 +320,7 @@ typedef enum {
 - (WebScriptObject *)windowScriptObject;
 - (NPObject *)windowScriptNPObject;
 
+- (BOOL)eventMayStartDrag:(NSEvent *)event;
 - (NSDragOperation)dragOperationForDraggingInfo:(id <NSDraggingInfo>)info;
 - (void)dragExitedWithDraggingInfo:(id <NSDraggingInfo>)info;
 - (BOOL)concludeDragForDraggingInfo:(id <NSDraggingInfo>)info;
@@ -440,7 +442,7 @@ 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)mayStartDragWithMouseDragged:(NSEvent *)event;
+- (BOOL)mayStartDragAtEventLocation:(NSPoint)location;
 
 - (int)historyLength;
 - (void)goBackOrForward:(int)distance;
diff --git a/WebCore/kwq/WebCoreBridge.mm b/WebCore/kwq/WebCoreBridge.mm
index d136629..3c306cd 100644
--- a/WebCore/kwq/WebCoreBridge.mm
+++ b/WebCore/kwq/WebCoreBridge.mm
@@ -759,6 +759,11 @@ static BOOL nowPrinting(WebCoreBridge *self)
     _part->view()->initScrollBars();
 }
 
+- (void)setActivationEventNumber:(int)num
+{
+    _part->setActivationEventNumber(num);
+}
+
 - (void)mouseDown:(NSEvent *)event
 {
     _part->mouseDown(event);
@@ -1570,6 +1575,11 @@ static HTMLFormElementImpl *formElementFromDOMElement(DOMElement *element)
 
 // [info draggingLocation] is in window coords
 
+- (BOOL)eventMayStartDrag:(NSEvent *)event
+{
+    return _part ? _part->eventMayStartDrag(event) : NO;
+}
+
 - (NSDragOperation)dragOperationForDraggingInfo:(id <NSDraggingInfo>)info
 {
     NSDragOperation op = NSDragOperationNone;
diff --git a/WebKit/ChangeLog b/WebKit/ChangeLog
index 942b4df..5ff93bd 100644
--- a/WebKit/ChangeLog
+++ b/WebKit/ChangeLog
@@ -1,3 +1,41 @@
+2004-06-30  Trey Matteson  <trey at apple.com>
+
+	Dragging within a web view should be allowed to start when the window isn't key.
+
+	A few months ago, Chris made this work, but it relied on the fact that all dragging
+	was done in WebKit.  When WebCore got involved in dragging, it was broken.  Now we
+	have a new scheme that gets it working again that properly involves WebCore.
+
+	The general idea is that when AK asks us whether to accept the first mouse and do
+	"delayed window ordering", we must consult WC to see if we might start a drag.  In
+	addition, instead of these drags in non-active windows being started as a special
+	case in WK, they go through the normal WK-WC drag machinery.  Finally to work in
+	frames we have to drill to the deepest hit view in acceptsFirstMouse, because previous
+	hacks to hitTest make the top-most WebHTMLView field all events for its view tree
+	(which leads to it fielding all acceptFirstMouse messages too).
+
+        Reviewed by John.
+
+        * WebCoreSupport.subproj/WebBridge.m:
+        (-[WebBridge mayStartDragAtEventLocation:]):  Glue change for new arg type.
+        * WebView.subproj/WebHTMLView.m:
+        (-[WebHTMLView _startDraggingImage:at:operation:event:sourceIsDHTML:DHTMLWroteData:]):
+	firstMouseDownEvent ivar is no longer needed.
+        (-[WebHTMLView _mayStartDragAtEventLocation:]):  Receives a location instead of a drag
+	event, since we need to do this work when we have no drag event.  This means the
+	check of the delay for text dragging is moved down to WebCore.
+        (-[WebHTMLView acceptsFirstMouse:]):  Respond based on whether we might do a drag.
+	This includes drilling to the deepest view the event hits, whereas we used to only
+	respond considering the topmost WebHTMLView.
+        (-[WebHTMLView shouldDelayWindowOrderingForEvent:]):  Ditto.
+        (-[WebHTMLView mouseDown:]):  Get rid of special case where some activating
+	mouseDown events weren't sent to WC.  We need to go through the whole pipeline
+	now to get a drag started properly.
+        (-[WebHTMLView mouseDragged:]):  Ditto, let WC start the drag.
+        (-[WebHTMLView mouseUp:]):  firstMouseDownEvent ivar is no longer needed.
+        * WebView.subproj/WebHTMLViewInternal.h:
+        * WebView.subproj/WebHTMLViewPrivate.h:
+
 2004-06-25  Trey Matteson  <trey at apple.com>
 
 	Added new utility method.
diff --git a/WebKit/WebCoreSupport.subproj/WebBridge.m b/WebKit/WebCoreSupport.subproj/WebBridge.m
index d1283ae..5d63e76 100644
--- a/WebKit/WebCoreSupport.subproj/WebBridge.m
+++ b/WebKit/WebCoreSupport.subproj/WebBridge.m
@@ -1023,13 +1023,13 @@ static BOOL loggedObjectCacheSize = NO;
     [docView _handleAutoscrollForMouseDragged:event];
 }
 
-- (BOOL)mayStartDragWithMouseDragged:(NSEvent *)event
+- (BOOL)mayStartDragAtEventLocation:(NSPoint)location
 {
     WebHTMLView *docView = (WebHTMLView *)[[_frame frameView] documentView];
 
     ASSERT([docView isKindOfClass:[WebHTMLView class]]);
 
-    return [docView _mayStartDragWithMouseDragged:event];
+    return [docView _mayStartDragAtEventLocation:location];
 }
 
 - (int)historyLength
diff --git a/WebKit/WebView.subproj/WebHTMLView.m b/WebKit/WebView.subproj/WebHTMLView.m
index 205f0da..20ef8f3 100644
--- a/WebKit/WebView.subproj/WebHTMLView.m
+++ b/WebKit/WebView.subproj/WebHTMLView.m
@@ -52,8 +52,6 @@
 
 #import <CoreGraphics/CGContextGState.h>
 
-#define TextDragDelay                    0.15
-
 // By imaging to a width a little wider than the available pixels,
 // thin pages will be scaled down a little, matching the way they
 // print in IE and Camino. This lets them use fewer sheets than they
@@ -781,9 +779,6 @@ static WebHTMLView *lastHitView = nil;
 
 - (BOOL)_startDraggingImage:(NSImage *)wcDragImage at:(NSPoint)wcDragLoc operation:(NSDragOperation)op event:(NSEvent *)mouseDraggedEvent sourceIsDHTML:(BOOL)srcIsDHTML DHTMLWroteData:(BOOL)dhtmlWroteData
 {
-    // Once we start a drag session we may not get a mouseup, so clear this out here as well as mouseUp:
-    _private->firstMouseDownEvent = nil;
-
     NSPoint mouseDownPoint = [self convertPoint:[_private->mouseDownEvent locationInWindow] fromView:nil];
     NSDictionary *element = [self elementAtPoint:mouseDownPoint];
 
@@ -919,9 +914,9 @@ static WebHTMLView *lastHitView = nil;
     [self _startAutoscrollTimer:event];
 }
 
-- (BOOL)_mayStartDragWithMouseDragged:(NSEvent *)mouseDraggedEvent
+- (BOOL)_mayStartDragAtEventLocation:(NSPoint)location
 {
-    NSPoint mouseDownPoint = [self convertPoint:[_private->mouseDownEvent locationInWindow] fromView:nil];
+    NSPoint mouseDownPoint = [self convertPoint:location fromView:nil];
     NSDictionary *mouseDownElement = [self elementAtPoint:mouseDownPoint];
 
     if ([mouseDownElement objectForKey: WebElementImageURLKey] != nil && 
@@ -936,7 +931,6 @@ static WebHTMLView *lastHitView = nil;
     }
     
     if ([[mouseDownElement objectForKey:WebElementIsSelectedKey] boolValue] &&
-        (([mouseDraggedEvent timestamp] - [_private->mouseDownEvent timestamp]) > TextDragDelay) &&
         (_private->dragSourceActionMask & WebDragSourceActionSelection)) {
         return YES;
     }
@@ -1729,22 +1723,37 @@ static WebHTMLView *lastHitView = nil;
     [[self _pluginController] destroyAllPlugins];
 }
 
-- (BOOL)_isSelectionEvent:(NSEvent *)event
-{
-    NSPoint point = [self convertPoint:[event locationInWindow] fromView:nil];
-    return [[[self elementAtPoint:point] objectForKey:WebElementIsSelectedKey] boolValue];
-}
-
 - (BOOL)acceptsFirstMouse:(NSEvent *)event
 {
-    // We don't retain this because we never dispatch to it; we only check its value.
-    _private->firstMouseDownEvent = event;
-    return [self _isSelectionEvent:event];
+    // We hack AK's hitTest method to catch all events at the topmost WebHTMLView.  However, for
+    // the purposes of this method we want to really query the deepest view, so we forward to it.
+    forceRealHitTest = YES;
+    NSView *hitView = [[[self window] contentView] hitTest:[event locationInWindow]];
+    forceRealHitTest = NO;
+    
+    if ([hitView isKindOfClass:[self class]]) {
+        WebHTMLView *hitHTMLView = (WebHTMLView *)hitView;
+        [[hitHTMLView _bridge] setActivationEventNumber:[event eventNumber]];
+        return [[hitHTMLView _bridge] eventMayStartDrag:event];
+    } else {
+        return [hitView acceptsFirstMouse:event];
+    }
 }
 
 - (BOOL)shouldDelayWindowOrderingForEvent:(NSEvent *)event
 {
-    return [self _isSelectionEvent:event];
+    // We hack AK's hitTest method to catch all events at the topmost WebHTMLView.  However, for
+    // the purposes of this method we want to really query the deepest view, so we forward to it.
+    forceRealHitTest = YES;
+    NSView *hitView = [[[self window] contentView] hitTest:[event locationInWindow]];
+    forceRealHitTest = NO;
+    
+    if ([hitView isKindOfClass:[self class]]) {
+        WebHTMLView *hitHTMLView = (WebHTMLView *)hitView;
+        return [[hitHTMLView _bridge] eventMayStartDrag:event];
+    } else {
+        return [hitView shouldDelayWindowOrderingForEvent:event];
+    }
 }
 
 - (void)mouseDown:(NSEvent *)event
@@ -1764,12 +1773,9 @@ static WebHTMLView *lastHitView = nil;
     // Don't do any mouseover while the mouse is down.
     [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(_updateMouseoverWithFakeEvent) object:nil];
 
-    // Don't tell WebCore about the first mouse down event since only dragging can occur on the first mouse down.
-    if (_private->firstMouseDownEvent != event) {
-        // Let KHTML get a chance to deal with the event. This will call back to us
-        // to start the autoscroll timer if appropriate.
-        [[self _bridge] mouseDown:event];
-    }
+    // Let KHTML get a chance to deal with the event. This will call back to us
+    // to start the autoscroll timer if appropriate.
+    [[self _bridge] mouseDown:event];
 }
 
 - (void)dragImage:(NSImage *)dragImage
@@ -1793,14 +1799,7 @@ static WebHTMLView *lastHitView = nil;
 
 - (void)mouseDragged:(NSEvent *)event
 {
-    // If this drag started from a mouse down in an inactive window, we only allow it to drag out an existing selection, so don't tell WebCore about it.
-    if (_private->mouseDownEvent == _private->firstMouseDownEvent) {
-        // Handle the drag directly instead of getting callbacks from WebCore.
-        // FIXME - how does this play with DHTML dragging?
-        if ([self _mayStartDragWithMouseDragged:event]) {
-            [self _startDraggingImage:nil at:NSZeroPoint operation:NSDragOperationNone event:event sourceIsDHTML:NO DHTMLWroteData:NO];
-        }
-    } else if (!_private->ignoringMouseDraggedEvents) {
+    if (!_private->ignoringMouseDraggedEvents) {
         [[self _bridge] mouseDragged:event];
     }
 }
@@ -1983,7 +1982,6 @@ static WebHTMLView *lastHitView = nil;
 
 - (void)mouseUp:(NSEvent *)event
 {
-    _private->firstMouseDownEvent = nil;
     [self _stopAutoscrollTimer];
     [[self _bridge] mouseUp:event];
     [self _updateMouseoverWithFakeEvent];
diff --git a/WebKit/WebView.subproj/WebHTMLViewInternal.h b/WebKit/WebView.subproj/WebHTMLViewInternal.h
index 7f7643d..1aed5dc 100644
--- a/WebKit/WebView.subproj/WebHTMLViewInternal.h
+++ b/WebKit/WebView.subproj/WebHTMLViewInternal.h
@@ -22,7 +22,6 @@
     BOOL subviewsSetAside;
 
     NSEvent *mouseDownEvent;
-    NSEvent *firstMouseDownEvent;
 
     NSURL *draggingImageURL;
     unsigned int dragSourceActionMask;
diff --git a/WebKit/WebView.subproj/WebHTMLViewPrivate.h b/WebKit/WebView.subproj/WebHTMLViewPrivate.h
index 8d042f2..8260297 100644
--- a/WebKit/WebView.subproj/WebHTMLViewPrivate.h
+++ b/WebKit/WebView.subproj/WebHTMLViewPrivate.h
@@ -47,7 +47,7 @@
 - (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)_mayStartDragWithMouseDragged:(NSEvent *)event;
+- (BOOL)_mayStartDragAtEventLocation:(NSPoint)location;
 
 - (WebPluginController *)_pluginController;
 

-- 
WebKit Debian packaging



More information about the Pkg-webkit-commits mailing list