Fixes a bug where MouseEvent.getX/Y() returns the incorrect value when the event is captured because the currentEventTarget is always the window on some browsers. Now, widgets send the relativeElement (themselves) with the MouseEvent so getX/Y() can be calculated.
Patch by: jgw
Review by: jlabanca
git-svn-id: https://google-web-toolkit.googlecode.com/svn/releases/1.6@5035 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/user/src/com/google/gwt/dom/client/DOMImplSafari.java b/user/src/com/google/gwt/dom/client/DOMImplSafari.java
index ca512ac..d75edc7 100644
--- a/user/src/com/google/gwt/dom/client/DOMImplSafari.java
+++ b/user/src/com/google/gwt/dom/client/DOMImplSafari.java
@@ -48,6 +48,11 @@
}
@Override
+ public native EventTarget eventGetCurrentTarget(NativeEvent event) /*-{
+ return event.currentTarget || $wnd;
+ }-*/;
+
+ @Override
public native int eventGetMouseWheelVelocityY(NativeEvent evt) /*-{
return Math.round(-evt.wheelDelta / 40) || 0;
}-*/;
diff --git a/user/src/com/google/gwt/event/dom/client/DomEvent.java b/user/src/com/google/gwt/event/dom/client/DomEvent.java
index bf279db..4961054 100644
--- a/user/src/com/google/gwt/event/dom/client/DomEvent.java
+++ b/user/src/com/google/gwt/event/dom/client/DomEvent.java
@@ -15,6 +15,7 @@
*/
package com.google.gwt.event.dom.client;
+import com.google.gwt.dom.client.Element;
import com.google.gwt.dom.client.NativeEvent;
import com.google.gwt.event.shared.EventHandler;
import com.google.gwt.event.shared.GwtEvent;
@@ -87,16 +88,35 @@
*/
public static void fireNativeEvent(NativeEvent nativeEvent,
HasHandlers handlerSource) {
+ fireNativeEvent(nativeEvent, handlerSource, null);
+ }
+
+ /**
+ * Fires the given native event on the specified handlers.
+ *
+ * @param nativeEvent the native event
+ * @param handlerSource the source of the handlers to fire
+ * @param relativeElem the element relative to which event coordinates will be
+ * measured
+ */
+ public static void fireNativeEvent(NativeEvent nativeEvent,
+ HasHandlers handlerSource, Element relativeElem) {
assert nativeEvent != null : "nativeEvent must not be null";
+
if (registered != null) {
final DomEvent.Type<?> typeKey = registered.unsafeGet(nativeEvent.getType());
if (typeKey != null) {
// Store and restore native event just in case we are in recursive
// loop.
NativeEvent currentNative = typeKey.flyweight.nativeEvent;
+ Element currentRelativeElem = typeKey.flyweight.relativeElem;
typeKey.flyweight.setNativeEvent(nativeEvent);
+ typeKey.flyweight.setRelativeElement(relativeElem);
+
handlerSource.fireEvent(typeKey.flyweight);
+
typeKey.flyweight.setNativeEvent(currentNative);
+ typeKey.flyweight.setRelativeElement(currentRelativeElem);
}
}
}
@@ -107,6 +127,7 @@
}
private NativeEvent nativeEvent;
+ private Element relativeElem;
@Override
public abstract DomEvent.Type<H> getAssociatedType();
@@ -117,6 +138,18 @@
}
/**
+ * Gets the element relative to which event coordinates will be measured.
+ * If this element is <code>null</code>, event coordinates will be measured
+ * relative to the window's client area.
+ *
+ * @return the event's relative element
+ */
+ public final Element getRelativeElement() {
+ assertLive();
+ return relativeElem;
+ }
+
+ /**
* Prevents the wrapped native event's default action.
*/
public void preventDefault() {
@@ -135,6 +168,15 @@
}
/**
+ * Gets the element relative to which event coordinates will be measured.
+ *
+ * @param relativeElem the event's relative element
+ */
+ public void setRelativeElement(Element relativeElem) {
+ this.relativeElem = relativeElem;
+ }
+
+ /**
* Stops the propagation of the underlying native event.
*/
public void stopPropagation() {
diff --git a/user/src/com/google/gwt/event/dom/client/MouseEvent.java b/user/src/com/google/gwt/event/dom/client/MouseEvent.java
index 6b2eb40..e9be08c 100644
--- a/user/src/com/google/gwt/event/dom/client/MouseEvent.java
+++ b/user/src/com/google/gwt/event/dom/client/MouseEvent.java
@@ -16,7 +16,6 @@
package com.google.gwt.event.dom.client;
import com.google.gwt.dom.client.Element;
-import com.google.gwt.dom.client.EventTarget;
import com.google.gwt.dom.client.NativeEvent;
import com.google.gwt.event.shared.EventHandler;
@@ -108,9 +107,9 @@
* @return the relative x-position
*/
public int getX() {
- EventTarget currentTarget = getNativeEvent().getCurrentEventTarget();
- if (Element.is(currentTarget)) {
- return getRelativeX(Element.as(currentTarget));
+ Element relativeElem = getRelativeElement();
+ if (relativeElem != null) {
+ return getRelativeX(relativeElem);
}
return getClientX();
}
@@ -121,9 +120,9 @@
* @return the relative y-position
*/
public int getY() {
- EventTarget currentTarget = getNativeEvent().getCurrentEventTarget();
- if (Element.is(currentTarget)) {
- return getRelativeY(Element.as(currentTarget));
+ Element relativeElem = getRelativeElement();
+ if (relativeElem != null) {
+ return getRelativeY(relativeElem);
}
return getClientY();
}
diff --git a/user/src/com/google/gwt/user/client/ui/Widget.java b/user/src/com/google/gwt/user/client/ui/Widget.java
index e2e5860..8c998b3 100644
--- a/user/src/com/google/gwt/user/client/ui/Widget.java
+++ b/user/src/com/google/gwt/user/client/ui/Widget.java
@@ -87,7 +87,7 @@
}
break;
}
- DomEvent.fireNativeEvent(event, this);
+ DomEvent.fireNativeEvent(event, this, this.getElement());
}
/**