WebKit Bugzilla
New
Browse
Search+
Log In
×
Sign in with GitHub
or
Remember my login
Create Account
·
Forgot Password
Forgotten password account recovery
[patch]
Rudimentary leapForward support (small fix)
bug-38853-20100528135001.patch (text/plain), 18.00 KB, created by
Martin Robinson
on 2010-05-28 04:50:03 PDT
(
hide
)
Description:
Rudimentary leapForward support (small fix)
Filename:
MIME Type:
Creator:
Martin Robinson
Created:
2010-05-28 04:50:03 PDT
Size:
18.00 KB
patch
obsolete
>diff --git a/WebKitTools/ChangeLog b/WebKitTools/ChangeLog >index 4bac60ff92843cf16beb26aff53bf51a032c16a4..6f8cc51a4bbc52d7f9009b4e25703025c4020da3 100644 >--- a/WebKitTools/ChangeLog >+++ b/WebKitTools/ChangeLog >@@ -1,3 +1,32 @@ >+2010-05-27 Martin Robinson <mrobinson@igalia.com> >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ [GTK] Double clicks cause three button press events >+ https://bugs.webkit.org/show_bug.cgi?id=38853 >+ >+ Add rudimentary leapForward support to the GTK+ DRT. leapForward allows a test >+ to pause for a specified amount of time. It is used in the processing of drag- >+ -and-drop data as well as to separate distinct mouse double-clicks in some tests. >+ This patch enables tests that rely on the latter behavior to pass. >+ >+ * DumpRenderTree/gtk/DumpRenderTree.cpp: >+ (webViewWindowObjectCleared): Only initialize the EventSender when loading the top frame. >+ * DumpRenderTree/gtk/EventSender.cpp: >+ (leapForwardCallback): Add support for adjusting the time offset on leapForward(). >+ (contextClickCallback): Use sendOrQueueEvent. >+ (updateClickCount): Take the time offset into account when counting clicks. >+ (mouseDownCallback): Use sendOrQueueEvent. >+ (getStateFlags): Change down/currentEventButton into buttonCurrentlyDown/lastClickButton. >+ (mouseUpCallback): Use sendOrQueueEvent. >+ (mouseMoveToCallback): Ditto. >+ (mouseWheelToCallback): Ditto. >+ (sendOrQueueEvent): Added. >+ (dispatchEvent): Added. >+ (replaySavedEvents): Pause when an event has a delay and defer to dispatchEvent. >+ (makeEventSender): Only initialize the EventSender when loading the top frame. >+ * DumpRenderTree/gtk/EventSender.h: Ditto. >+ > 2010-05-27 Luiz Agostini <luiz.agostini@openbossa.org> > > Reviewed by Kenneth Rohde Christiansen. >diff --git a/WebKitTools/DumpRenderTree/gtk/DumpRenderTree.cpp b/WebKitTools/DumpRenderTree/gtk/DumpRenderTree.cpp >index 02c0abb976edba0bba78c6fe3e8c6c8b69d216f2..5c3937f6c2456c8dd140c346074018062cc99eed 100644 >--- a/WebKitTools/DumpRenderTree/gtk/DumpRenderTree.cpp >+++ b/WebKitTools/DumpRenderTree/gtk/DumpRenderTree.cpp >@@ -663,7 +663,7 @@ static void webViewWindowObjectCleared(WebKitWebView* view, WebKitWebFrame* fram > ASSERT(!exception); > > JSStringRef eventSenderStr = JSStringCreateWithUTF8CString("eventSender"); >- JSValueRef eventSender = makeEventSender(context); >+ JSValueRef eventSender = makeEventSender(context, !webkit_web_frame_get_parent(frame)); > JSObjectSetProperty(context, windowObject, eventSenderStr, eventSender, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete, 0); > JSStringRelease(eventSenderStr); > } >diff --git a/WebKitTools/DumpRenderTree/gtk/EventSender.cpp b/WebKitTools/DumpRenderTree/gtk/EventSender.cpp >index 9c27d8c89f0c00628dcbe52c70066d034d9bd7fd..fac1d9dd2d3f73bff428d825ea383494c76e4ee2 100644 >--- a/WebKitTools/DumpRenderTree/gtk/EventSender.cpp >+++ b/WebKitTools/DumpRenderTree/gtk/EventSender.cpp >@@ -45,28 +45,27 @@ > #include <gdk/gdkkeysyms.h> > #include <string.h> > >-// TODO: Currently drag and drop related code is left out and >-// should be merged once we have drag and drop support in WebCore. >+// FIXME: Implement support for synthesizing drop events. > > extern "C" { > extern void webkit_web_frame_layout(WebKitWebFrame* frame); > } > >-static bool down = false; >-static bool currentEventButton = 1; >-static bool dragMode = true; >-static bool replayingSavedEvents = false; >+static bool dragMode; >+static int timeOffset = 0; >+ > static int lastMousePositionX; > static int lastMousePositionY; >- > static int lastClickPositionX; > static int lastClickPositionY; >-static int clickCount = 0; >+static int lastClickTimeOffset; >+static int lastClickButton; >+static int buttonCurrentlyDown; >+static int clickCount; > > struct DelayedMessage { > GdkEvent event; > gulong delay; >- gboolean isDragEvent; > }; > > static DelayedMessage msgQueue[1024]; >@@ -84,6 +83,10 @@ enum KeyLocationCode { > DOM_KEY_LOCATION_NUMPAD = 0x03 > }; > >+static void sendOrQueueEvent(GdkEvent event); >+static void dispatchEvent(GdkEvent event); >+static guint getStateFlags(); >+ > static JSValueRef getDragModeCallback(JSContextRef context, JSObjectRef object, JSStringRef propertyName, JSValueRef* exception) > { > return JSValueMakeBoolean(context, dragMode); >@@ -97,14 +100,17 @@ static bool setDragModeCallback(JSContextRef context, JSObjectRef object, JSStri > > static JSValueRef leapForwardCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) > { >- // FIXME: Add proper support for forward leaps >+ if (argumentCount > 0) { >+ msgQueue[endOfQueue].delay = JSValueToNumber(context, arguments[0], exception); >+ timeOffset += msgQueue[endOfQueue].delay; >+ ASSERT(!exception || !*exception); >+ } >+ > return JSValueMakeUndefined(context); > } > > static JSValueRef contextClickCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) > { >- webkit_web_frame_layout(mainFrame); >- > WebKitWebView* view = webkit_web_frame_get_web_view(mainFrame); > if (!view) > return JSValueMakeUndefined(context); >@@ -116,22 +122,20 @@ static JSValueRef contextClickCallback(JSContextRef context, JSObjectRef functio > event.button.y = lastMousePositionY; > event.button.window = GTK_WIDGET(view)->window; > >- gboolean return_val; >- down = true; > event.type = GDK_BUTTON_PRESS; >- g_signal_emit_by_name(view, "button_press_event", &event, &return_val); >- >- down = false; >+ sendOrQueueEvent(event); > event.type = GDK_BUTTON_RELEASE; >- g_signal_emit_by_name(view, "button_release_event", &event, &return_val); >+ sendOrQueueEvent(event); > > return JSValueMakeUndefined(context); > } > > static void updateClickCount(int button) > { >- // FIXME: take the last clicked button number and the time of last click into account. >- if (lastClickPositionX != lastMousePositionX || lastClickPositionY != lastMousePositionY || currentEventButton != button) >+ if (lastClickPositionX != lastMousePositionX >+ || lastClickPositionY != lastMousePositionY >+ || lastClickButton != button >+ || timeOffset - lastClickTimeOffset >= 1) > clickCount = 1; > else > clickCount++; >@@ -158,24 +162,24 @@ static JSValueRef mouseDownCallback(JSContextRef context, JSObjectRef function, > if (!view) > return JSValueMakeUndefined(context); > >- down = true; >- > GdkEvent event; > memset(&event, 0, sizeof(event)); >- event.type = GDK_BUTTON_PRESS; > event.button.button = 1; > > if (argumentCount == 1) { >- event.button.button = (int)JSValueToNumber(context, arguments[0], exception) + 1; >+ event.button.button = (int)(JSValueToNumber(context, arguments[0], exception)) + 1; > g_return_val_if_fail((!exception || !*exception), JSValueMakeUndefined(context)); > } > >- currentEventButton = event.button.button; >- > event.button.x = lastMousePositionX; > event.button.y = lastMousePositionY; > event.button.window = GTK_WIDGET(view)->window; >- event.button.time = GDK_CURRENT_TIME; >+ >+ // Mouse up & down events dispatched via g_signal_emit_by_name must offset >+ // their time value, so that WebKit can detect where sequences of mouse >+ // clicks begin and end. This should not interfere with GDK or GTK+ event >+ // processing, because the event is only seen by the widget. >+ event.motion.time = GDK_CURRENT_TIME + timeOffset; > event.button.device = gdk_device_get_core_pointer(); > > int x_root, y_root; >@@ -184,45 +188,31 @@ static JSValueRef mouseDownCallback(JSContextRef context, JSObjectRef function, > #else > getRootCoords(GTK_WIDGET(view), &x_root, &y_root); > #endif >- > event.button.x_root = x_root; > event.button.y_root = y_root; > >- updateClickCount(event.button.button); >- >- if (!msgQueue[endOfQueue].delay) { >- webkit_web_frame_layout(mainFrame); >+ event.type = GDK_BUTTON_PRESS; >+ sendOrQueueEvent(event); > >- gboolean return_val; >- g_signal_emit_by_name(view, "button_press_event", &event, &return_val); >- if (clickCount == 2) { >- event.type = GDK_2BUTTON_PRESS; >- g_signal_emit_by_name(view, "button_press_event", &event, &return_val); >- } >- } else { >- // replaySavedEvents should have the required logic to make leapForward delays work >- msgQueue[endOfQueue++].event = event; >- replaySavedEvents(); >+ updateClickCount(event.button.button); >+ if (clickCount == 2) { >+ event.type = GDK_2BUTTON_PRESS; >+ sendOrQueueEvent(event); > } > >+ buttonCurrentlyDown = event.button.button; > return JSValueMakeUndefined(context); > } > > static guint getStateFlags() > { >- guint state = 0; >- >- if (down) { >- if (currentEventButton == 1) >- state = GDK_BUTTON1_MASK; >- else if (currentEventButton == 2) >- state = GDK_BUTTON2_MASK; >- else if (currentEventButton == 3) >- state = GDK_BUTTON3_MASK; >- } else >- state = 0; >- >- return state; >+ if (buttonCurrentlyDown == 1) >+ return GDK_BUTTON1_MASK; >+ if (buttonCurrentlyDown == 2) >+ return GDK_BUTTON2_MASK; >+ if (buttonCurrentlyDown == 3) >+ return GDK_BUTTON3_MASK; >+ return 0; > } > > static JSValueRef mouseUpCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) >@@ -234,7 +224,6 @@ static JSValueRef mouseUpCallback(JSContextRef context, JSObjectRef function, JS > > GdkEvent event; > memset(&event, 0, sizeof(event)); >- event.type = GDK_BUTTON_RELEASE; > event.button.button = 1; > > if (argumentCount == 1) { >@@ -242,17 +231,18 @@ static JSValueRef mouseUpCallback(JSContextRef context, JSObjectRef function, JS > g_return_val_if_fail((!exception || !*exception), JSValueMakeUndefined(context)); > } > >- currentEventButton = event.button.button; >- > event.button.x = lastMousePositionX; > event.button.y = lastMousePositionY; > event.button.window = GTK_WIDGET(view)->window; >- event.button.time = GDK_CURRENT_TIME; >+ >+ // Mouse up & down events dispatched via g_signal_emit_by_name must offset >+ // their time value, so that WebKit can detect where sequences of mouse >+ // clicks begin and end. This should not interfere with GDK or GTK+ event >+ // processing, because the event is only seen by the widget. >+ event.button.time = GDK_CURRENT_TIME + timeOffset; > event.button.device = gdk_device_get_core_pointer(); > event.button.state = getStateFlags(); > >- down = false; >- > int x_root, y_root; > #if GTK_CHECK_VERSION(2,17,3) > gdk_window_get_root_coords(GTK_WIDGET(view)->window, lastMousePositionX, lastMousePositionY, &x_root, &y_root); >@@ -263,20 +253,14 @@ static JSValueRef mouseUpCallback(JSContextRef context, JSObjectRef function, JS > event.button.x_root = x_root; > event.button.y_root = y_root; > >- if ((dragMode && !replayingSavedEvents) || msgQueue[endOfQueue].delay) { >- msgQueue[endOfQueue].event = event; >- msgQueue[endOfQueue++].isDragEvent = true; >- replaySavedEvents(); >- } else { >- webkit_web_frame_layout(mainFrame); >- >- gboolean return_val; >- g_signal_emit_by_name(view, "button_release_event", &event, &return_val); >- } >- > lastClickPositionX = lastMousePositionX; > lastClickPositionY = lastMousePositionY; >+ lastClickButton = buttonCurrentlyDown; >+ lastClickTimeOffset = timeOffset; >+ buttonCurrentlyDown = 0; > >+ event.type = GDK_BUTTON_RELEASE; >+ sendOrQueueEvent(event); > return JSValueMakeUndefined(context); > } > >@@ -299,6 +283,7 @@ static JSValueRef mouseMoveToCallback(JSContextRef context, JSObjectRef function > event.type = GDK_MOTION_NOTIFY; > event.motion.x = lastMousePositionX; > event.motion.y = lastMousePositionY; >+ > event.motion.time = GDK_CURRENT_TIME; > event.motion.window = GTK_WIDGET(view)->window; > event.motion.device = gdk_device_get_core_pointer(); >@@ -309,22 +294,12 @@ static JSValueRef mouseMoveToCallback(JSContextRef context, JSObjectRef function > #else > getRootCoords(GTK_WIDGET(view), &x_root, &y_root); > #endif >- > event.motion.x_root = x_root; > event.motion.y_root = y_root; >- >- event.motion.state = getStateFlags(); >- >- if (dragMode && down && !replayingSavedEvents) { >- msgQueue[endOfQueue].event = event; >- msgQueue[endOfQueue++].isDragEvent = true; >- } else { >- webkit_web_frame_layout(mainFrame); > >- gboolean return_val; >- g_signal_emit_by_name(view, "motion_notify_event", &event, &return_val); >- } >+ event.motion.state = getStateFlags(); > >+ sendOrQueueEvent(event); > return JSValueMakeUndefined(context); > } > >@@ -363,14 +338,7 @@ static JSValueRef mouseWheelToCallback(JSContextRef context, JSObjectRef functio > else > g_assert_not_reached(); > >- if (dragMode && down && !replayingSavedEvents) { >- msgQueue[endOfQueue].event = event; >- msgQueue[endOfQueue++].isDragEvent = true; >- } else { >- webkit_web_frame_layout(mainFrame); >- gtk_main_do_event(&event); >- } >- >+ sendOrQueueEvent(event); > return JSValueMakeUndefined(context); > } > >@@ -383,49 +351,54 @@ static JSValueRef beginDragWithFilesCallback(JSContextRef context, JSObjectRef f > return JSValueMakeUndefined(context); > } > >-void replaySavedEvents() >+static void sendOrQueueEvent(GdkEvent event) > { >- // FIXME: This doesn't deal with forward leaps, but it should. >+ // Mouse move events are queued if the previous event was queued or if a >+ // delay was set up by leapForward(). >+ if (endOfQueue != startOfQueue || msgQueue[endOfQueue].delay) { >+ msgQueue[endOfQueue++].event = event; >+ replaySavedEvents(); >+ return; >+ } > >+ dispatchEvent(event); >+} >+ >+static void dispatchEvent(GdkEvent event) >+{ >+ webkit_web_frame_layout(mainFrame); > WebKitWebView* view = webkit_web_frame_get_web_view(mainFrame); > if (!view) > return; > >- replayingSavedEvents = true; >- >- for (unsigned queuePos = 0; queuePos < endOfQueue; queuePos++) { >- GdkEvent event = msgQueue[queuePos].event; >- gboolean return_val; >- >- switch (event.type) { >- case GDK_BUTTON_RELEASE: >- g_signal_emit_by_name(view, "button_release_event", &event, &return_val); >- break; >- case GDK_BUTTON_PRESS: >- g_signal_emit_by_name(view, "button_press_event", &event, &return_val); >- break; >- case GDK_MOTION_NOTIFY: >- g_signal_emit_by_name(view, "motion_notify_event", &event, &return_val); >- break; >- default: >- continue; >- } >+ gboolean returnValue; >+ if (event.type == GDK_BUTTON_PRESS || event.type == GDK_2BUTTON_PRESS) >+ g_signal_emit_by_name(view, "button_press_event", &event, &returnValue); >+ else if (event.type == GDK_BUTTON_RELEASE) >+ g_signal_emit_by_name(view, "button_release_event", &event, &returnValue); >+ else if (event.type == GDK_MOTION_NOTIFY) >+ g_signal_emit_by_name(view, "motion_notify_event", &event, &returnValue); >+ else if (event.type == GDK_SCROLL) >+ gtk_main_do_event(&event); >+} > >- startOfQueue++; >- } >+void replaySavedEvents() >+{ >+ // FIXME: Eventually we may need to have more sophisticated logic to >+ // track drag-and-drop operations. >+ >+ // First send all the events that are ready to be sent >+ while (startOfQueue < endOfQueue) { >+ if (msgQueue[startOfQueue].delay) { >+ g_usleep(msgQueue[startOfQueue].delay * 1000); >+ msgQueue[startOfQueue].delay = 0; >+ } > >- int numQueuedMessages = endOfQueue - startOfQueue; >- if (!numQueuedMessages) { >- startOfQueue = 0; >- endOfQueue = 0; >- replayingSavedEvents = false; >- return; >+ dispatchEvent(msgQueue[startOfQueue++].event); > } > > startOfQueue = 0; > endOfQueue = 0; >- >- replayingSavedEvents = false; > } > > static JSValueRef keyDownCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) >@@ -661,17 +634,24 @@ static JSClassRef getClass(JSContextRef context) > return eventSenderClass; > } > >-JSObjectRef makeEventSender(JSContextRef context) >+JSObjectRef makeEventSender(JSContextRef context, bool isTopFrame) > { >- down = false; >- dragMode = true; >- lastMousePositionX = lastMousePositionY = 0; >- lastClickPositionX = lastClickPositionY = 0; >- >- if (!replayingSavedEvents) { >- // This function can be called in the middle of a test, even >- // while replaying saved events. Resetting these while doing that >- // can break things. >+ if (isTopFrame) { >+ dragMode = true; >+ >+ // Fly forward in time one second when the main frame loads. This will >+ // ensure that when a test begins clicking in the same location as >+ // a previous test, those clicks won't be interpreted as continuations >+ // of the previous test's click sequences. >+ timeOffset += 1000; >+ >+ lastMousePositionX = lastMousePositionY = 0; >+ lastClickPositionX = lastClickPositionY = 0; >+ lastClickTimeOffset = 0; >+ lastClickButton = 0; >+ buttonCurrentlyDown = 0; >+ clickCount = 0; >+ > endOfQueue = 0; > startOfQueue = 0; > } >diff --git a/WebKitTools/DumpRenderTree/gtk/EventSender.h b/WebKitTools/DumpRenderTree/gtk/EventSender.h >index 272e8a9402079d9272c015087b6bed97a49422cb..ce33ccc952aca5607da6b4a483c607cee9916cb8 100644 >--- a/WebKitTools/DumpRenderTree/gtk/EventSender.h >+++ b/WebKitTools/DumpRenderTree/gtk/EventSender.h >@@ -33,7 +33,7 @@ > typedef const struct OpaqueJSContext* JSContextRef; > typedef struct OpaqueJSValue* JSObjectRef; > >-JSObjectRef makeEventSender(JSContextRef context); >+JSObjectRef makeEventSender(JSContextRef context, bool isTopFrame); > void replaySavedEvents(); > > #endif
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Formatted Diff
|
Diff
Attachments on
bug 38853
:
55577
|
55579
|
55607
|
55642
|
55648
|
55653
|
55917
|
55918
|
55919
|
55922
|
55933
|
56076
|
56092
|
57235
| 57317