make unsink event work correctly in widget

if events were unsunk before a widget was attached
to the dom, event bits would still be sunk, due to
the event bits being cached in sinkEvent() in Widget

fixes ISSUE 7882

Change-Id: If4341e0bf33b4c7b36d55024b3f66fce11ff1ac6
Review-Link: https://gwt-review.googlesource.com/#/c/1950/

Review by: skybrian@google.com

git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@11543 8db76d5a-ed1c-0410-87a9-c151d255dfc7
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 758acb4..d127991 100644
--- a/user/src/com/google/gwt/user/client/ui/Widget.java
+++ b/user/src/com/google/gwt/user/client/ui/Widget.java
@@ -244,6 +244,15 @@
     }
   }
 
+  @Override
+  public void unsinkEvents(int eventBitsToRemove) {
+    if (isOrWasAttached()) {
+      super.unsinkEvents(eventBitsToRemove);
+    } else {
+      eventsToSink &= ~eventBitsToRemove;
+    }
+  }
+
   /**
    * Creates the {@link HandlerManager} used by this Widget. You can override
    * this method to create a custom {@link HandlerManager}.
diff --git a/user/test/com/google/gwt/user/client/ui/WidgetTest.java b/user/test/com/google/gwt/user/client/ui/WidgetTest.java
index 8a2d482..3c6f2ed 100644
--- a/user/test/com/google/gwt/user/client/ui/WidgetTest.java
+++ b/user/test/com/google/gwt/user/client/ui/WidgetTest.java
@@ -21,6 +21,7 @@
 import com.google.gwt.event.shared.HandlerManager;
 import com.google.gwt.event.shared.HandlerRegistration;
 import com.google.gwt.junit.client.GWTTestCase;
+import com.google.gwt.user.client.Event;
 
 /**
  * Tests the basic widget infrastructure.
@@ -190,4 +191,23 @@
     assertFalse(w.isAttached());
     assertNull(w.getParent());
   }
+
+  public void testUnsinkEventsIfWidgetHasNotBeenAttachedYet() {
+    Button button = new Button();
+    button.addClickHandler(new ClickHandler() {
+      @Override
+      public void onClick(ClickEvent event) {
+        fail("click event should not fire");
+      }
+    });
+
+    // unsink the event before attaching
+    button.unsinkEvents(Event.ONCLICK);
+    RootPanel.get().add(button);
+
+    button.click();
+    // tests share the DOM
+    // we need to clean up
+    button.removeFromParent();
+  }
 }