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());
   }
 
   /**