Partial fix for <rdar://5621244> Drag & Drop doesn't work correctly in DRT
authoroliver@apple.com <oliver@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 5 Feb 2008 06:18:23 +0000 (06:18 +0000)
committeroliver@apple.com <oliver@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 5 Feb 2008 06:18:23 +0000 (06:18 +0000)
Reviewed by Steve F.

iImplement required DRT functionality to allow majority of Drag and Drop testcases to work.
Issues include:
  * Uses Sleep() to implement leapForward reliably.
  * 3 DND tests still fail for reasons that i have not yet determined
  * Has to explicitly ignore an extraneous WM_MOUSELEAVE that i am at a loss to explain

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

LayoutTests/ChangeLog
LayoutTests/editing/selection/select-from-textfield-outwards.html
LayoutTests/platform/win/Skipped
WebKitTools/ChangeLog
WebKitTools/DumpRenderTree/win/EventSender.cpp
WebKitTools/DumpRenderTree/win/UIDelegate.cpp

index ae74b98..483e81c 100644 (file)
@@ -1,3 +1,14 @@
+2008-02-04  Oliver Hunt  <oliver@apple.com>
+
+        Reviewed by Steve F.
+        
+        Update the windows platform skip list to remove the majority of DND tests.
+        Minor change to select-from-textfield-outwards.html, as the use of leapForward
+        appears to be unnecessary but breaks in windows with the new leapForward logic.
+
+        * editing/selection/select-from-textfield-outwards.html:
+        * platform/win/Skipped:
+
 2008-02-04  Robert Sesek  <rsesek@bluestatic.org>
 
         Reviewed by Darin Adler.
index f9a9b8c..9452b14 100644 (file)
@@ -13,7 +13,6 @@ function editingTest() {
     // middle
     eventSender.mouseMoveTo(middleX, middleY);
     eventSender.mouseDown();
-    eventSender.leapForward(1000);
     eventSender.mouseUp();
     eventSender.mouseDown();
     // left
index 992c5fd..1064f40 100644 (file)
@@ -86,29 +86,9 @@ svg/hixie/viewbox/preserveAspectRatio/002.xml
 editing/execCommand/copy-without-selection.html
 
 # Drag & Drop doesn't work correctly in DRT <rdar://5621244>
-editing/pasteboard/4861080.html
-editing/pasteboard/4947130.html
-editing/pasteboard/drag-drop-dead-frame.html
-editing/pasteboard/drag-drop-modifies-page.html
 editing/pasteboard/drag-image-in-about-blank-frame.html
-editing/pasteboard/drag-image-to-contenteditable-in-iframe.html
-editing/pasteboard/drag-selected-image-to-contenteditable.html
-editing/pasteboard/drop-link.html
-editing/pasteboard/drop-text-without-selection.html
-editing/pasteboard/subframe-dragndrop-1.html
-editing/selection/4895428-1.html
-editing/selection/4895428-4.html
-editing/selection/drag-select-1.html
-editing/selection/drag-to-contenteditable-iframe.html
-editing/selection/selection-background.html
-fast/events/5056619.html
 fast/events/drag-in-frames.html
-fast/events/ondragenter.html
 fast/events/standalone-image-drag-to-editable.html
-fast/forms/drag-into-textarea.html
-fast/forms/drag-out-of-textarea.html
-fast/forms/textfield-drag-into-disabled.html
-fast/lists/drag-into-marker.html
 
 # <rdar://problem/5643675> window.scrollTo scrolls a window with no scrollbars
 fast/events/attempt-scroll-with-no-scrollbars.html
index 9bff36c..6618203 100644 (file)
@@ -1,3 +1,33 @@
+2008-02-04  Oliver Hunt  <oliver@apple.com>
+
+        Reviewed by Steve F.
+
+        Partial fix for <rdar://5621244> Drag & Drop doesn't work correctly in DRT
+
+        Implement required DRT functionality to allow majority of Drag and Drop testcases to work.
+        Issues include:
+          * Uses Sleep() to implement leapForward reliably.
+          * 3 DND tests still fail for reasons that i have not yet determined
+          * Has to explicitly ignore an extraneous WM_MOUSELEAVE that i am at a loss to explain 
+
+        * DumpRenderTree/win/EventSender.cpp:
+        (leapForwardCallback):
+        (mouseDownCallback):
+        (doMouseUp):
+        (mouseUpCallback):
+        (doMouseMove):
+        (mouseMoveToCallback):
+          Minor updates to these functions to handle the different message queue structure.
+
+        (replaySavedEvents):
+          More complicated now.  Where possible we just use the old while-loop model of execution,
+          but when leapForward has been used we have to jump through some hoops and set up an 
+          inner event loop so that we can ensure messages get the correct time stamp.
+
+        * DumpRenderTree/win/UIDelegate.cpp:
+        (UIDelegate::doDragDrop):
+          Call replaySavedEvents directly to force synchronous handling of drag and drop.
+
 2008-02-04  Rodney Dawes  <dobey@wayofthemonkey.com>
 
         Reviewed by Alp Toker and Mark Rowe.
index f65c152..66d8772 100644 (file)
 #include <WebKit/IWebFramePrivate.h>
 #include <windows.h>
 
+#define WM_DRT_SEND_QUEUED_EVENT (WM_APP+1)
+
 static bool down;
 static bool dragMode = true;
 static bool replayingSavedEvents;
 static int timeOffset;
 static POINT lastMousePosition;
 
-static MSG msgQueue[1024];
+struct DelayedMessage {
+    MSG msg;
+    unsigned delay;
+};
+
+static DelayedMessage msgQueue[1024];
 static unsigned endOfQueue;
 static unsigned startOfQueue;
 
@@ -89,7 +96,7 @@ static JSValueRef getConstantCallback(JSContextRef context, JSObjectRef object,
 static JSValueRef leapForwardCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
 {
     if (argumentCount > 0) {
-        timeOffset += JSValueToNumber(context, arguments[0], exception);
+        msgQueue[endOfQueue].delay = JSValueToNumber(context, arguments[0], exception);
         ASSERT(!exception || !*exception);
     }
 
@@ -117,7 +124,6 @@ static MSG makeMsg(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
 static LRESULT dispatchMessage(const MSG* msg)
 {
     ASSERT(msg);
-
     ::TranslateMessage(msg);
     return ::DispatchMessage(msg);
 }
@@ -146,7 +152,13 @@ static JSValueRef mouseDownCallback(JSContextRef context, JSObjectRef function,
 
     down = true;
     MSG msg = makeMsg(webViewWindow, WM_LBUTTONDOWN, 0, MAKELPARAM(lastMousePosition.x, lastMousePosition.y));
-    dispatchMessage(&msg);
+    if (!msgQueue[endOfQueue].delay)
+        dispatchMessage(&msg);
+    else {
+        // replaySavedEvents has the required logic to make leapForward delays work
+        msgQueue[endOfQueue++].msg = msg;
+        replaySavedEvents();
+    }
 
     return JSValueMakeUndefined(context);
 }
@@ -173,9 +185,13 @@ static void doMouseUp(MSG msg)
         COMPtr<IDropTarget> webViewDropTarget;
         if (SUCCEEDED(frame->webView(&webView)) && SUCCEEDED(webView->QueryInterface(IID_IDropTarget, (void**)&webViewDropTarget))) {
             POINT screenPoint = msg.pt;
+            DWORD effect = 0;
             ::ClientToScreen(webViewWindow, &screenPoint);
+            if (!didDragEnter) {
+                webViewDropTarget->DragEnter(draggingInfo->dataObject(), 0, pointl(screenPoint), &effect);
+                didDragEnter = true;
+            }
             HRESULT hr = draggingInfo->dropSource()->QueryContinueDrag(0, 0);
-            DWORD effect = 0;
             webViewDropTarget->DragOver(0, pointl(screenPoint), &effect);
             if (hr == DRAGDROP_S_DROP && effect != DROPEFFECT_NONE) {
                 DWORD effect = 0;
@@ -193,8 +209,8 @@ static JSValueRef mouseUpCallback(JSContextRef context, JSObjectRef function, JS
 {
     MSG msg = makeMsg(webViewWindow, WM_LBUTTONUP, 0, MAKELPARAM(lastMousePosition.x, lastMousePosition.y));
 
-    if (dragMode && !replayingSavedEvents) {
-        msgQueue[endOfQueue++] = msg;
+    if ((dragMode && !replayingSavedEvents) || msgQueue[endOfQueue].delay) {
+        msgQueue[endOfQueue++].msg = msg;
         replaySavedEvents();
     } else
         doMouseUp(msg);
@@ -221,11 +237,10 @@ static void doMouseMove(MSG msg)
             if (didDragEnter)
                 webViewDropTarget->DragOver(MK_LBUTTON, pointl(screenPoint), &effect);
             else {
-                webViewDropTarget->DragEnter(draggingInfo->dataObject(), MK_LBUTTON, pointl(screenPoint), &effect);
+                webViewDropTarget->DragEnter(draggingInfo->dataObject(), 0, pointl(screenPoint), &effect);
                 didDragEnter = true;
             }
             draggingInfo->dropSource()->GiveFeedback(effect);
-            replaySavedEvents();
         }
     }
 }
@@ -243,7 +258,7 @@ static JSValueRef mouseMoveToCallback(JSContextRef context, JSObjectRef function
     MSG msg = makeMsg(webViewWindow, WM_MOUSEMOVE, down ? MK_LBUTTON : 0, MAKELPARAM(lastMousePosition.x, lastMousePosition.y));
 
     if (dragMode && down && !replayingSavedEvents) {
-        msgQueue[endOfQueue++] = msg;
+        msgQueue[endOfQueue++].msg = msg;
         return JSValueMakeUndefined(context);
     }
 
@@ -255,10 +270,11 @@ static JSValueRef mouseMoveToCallback(JSContextRef context, JSObjectRef function
 void replaySavedEvents()
 {
     replayingSavedEvents = true;
+  
+    MSG msg = { 0 };
 
-    MSG emptyMsg = {0};
-    while (startOfQueue < endOfQueue) {
-        MSG msg = msgQueue[startOfQueue++];
+    while (startOfQueue < endOfQueue && !msgQueue[startOfQueue].delay) {
+        msg = msgQueue[startOfQueue++].msg;
         switch (msg.message) {
             case WM_LBUTTONUP:
                 doMouseUp(msg);
@@ -266,10 +282,58 @@ void replaySavedEvents()
             case WM_MOUSEMOVE:
                 doMouseMove(msg);
                 break;
+            case WM_LBUTTONDOWN:
+                dispatchMessage(&msg);
+                break;
+            default:
+                // Not reached
+                break;
+        }
+    }
+
+    int numQueuedMessages = endOfQueue - startOfQueue;
+    if (!numQueuedMessages) {
+        startOfQueue = 0;
+        endOfQueue = 0;
+        replayingSavedEvents = false;
+        ASSERT(!down);
+        return;
+    }
+
+    if (msgQueue[startOfQueue].delay) {
+        ::Sleep(msgQueue[startOfQueue].delay);
+        msgQueue[startOfQueue].delay = 0;
+    }
+
+    ::PostMessage(webViewWindow, WM_DRT_SEND_QUEUED_EVENT, 0, 0);
+    while (::GetMessage(&msg, webViewWindow, 0, 0)) {
+        // FIXME: Why do we get a WM_MOUSELEAVE? it breaks tests
+        if (msg.message == WM_MOUSELEAVE)
+            continue;
+        if (msg.message != WM_DRT_SEND_QUEUED_EVENT) {
+            dispatchMessage(&msg);
+            continue;
+        }
+        msg = msgQueue[startOfQueue++].msg;
+        switch (msg.message) {
+            case WM_LBUTTONUP:
+                doMouseUp(msg);
+                break;
+            case WM_MOUSEMOVE:
+                doMouseMove(msg);
+                break;
+            case WM_LBUTTONDOWN:
+                dispatchMessage(&msg);
+                break;
             default:
                 // Not reached
                 break;
         }
+        if (startOfQueue >= endOfQueue)
+            break;
+        ::Sleep(msgQueue[startOfQueue].delay);
+        msgQueue[startOfQueue].delay = 0;
+        ::PostMessage(webViewWindow, WM_DRT_SEND_QUEUED_EVENT, 0, 0);
     }
     startOfQueue = 0;
     endOfQueue = 0;
index b72442c..750e67a 100755 (executable)
@@ -354,7 +354,7 @@ HRESULT STDMETHODCALLTYPE UIDelegate::doDragDrop(
     *performedEffect = 0;
 
     draggingInfo = new DraggingInfo(object, source);
-
+    replaySavedEvents();
     return S_OK;
 }