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
+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.
#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;
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);
}
static LRESULT dispatchMessage(const MSG* msg)
{
ASSERT(msg);
-
::TranslateMessage(msg);
return ::DispatchMessage(msg);
}
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);
}
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;
{
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);
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();
}
}
}
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);
}
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);
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;