diff --git a/ghcjs-dom.cabal b/ghcjs-dom.cabal
--- a/ghcjs-dom.cabal
+++ b/ghcjs-dom.cabal
@@ -1,5 +1,5 @@
 name: ghcjs-dom
-version: 0.0.6
+version: 0.0.7
 cabal-version: >=1.10
 build-type: Simple
 license: MIT
@@ -187,9 +187,9 @@
         cpp-options: -DUSE_WEBKIT
         build-depends:  glib >=0.12.3.1 && <0.13, transformers >=0.3.0.0 && <0.4
         if flag(gtk3)
-            build-depends: gtk3 >=0.12.4 && <0.13, webkitgtk3 >=0.12.5.1 && <0.13
+            build-depends: gtk3 >=0.12.4 && <0.13, webkitgtk3 >=0.12.6.0 && <0.13
         else
-            build-depends: gtk >=0.12.4 && <0.13, webkit >=0.12.5.1 && <0.13
+            build-depends: gtk >=0.12.4 && <0.13, webkit >=0.12.6.0 && <0.13
         c-sources:      cbits/ghcjs_stubs.c
 
     hs-source-dirs: src
diff --git a/src/GHCJS/DOM/EventM.hs b/src/GHCJS/DOM/EventM.hs
--- a/src/GHCJS/DOM/EventM.hs
+++ b/src/GHCJS/DOM/EventM.hs
@@ -67,7 +67,7 @@
 import GHCJS.DOM.EventTargetClosures
 import Data.Word (Word)
 
-type Signal target callback = target -> callback -> IO Bool
+type Signal target callback = target -> callback -> IO (IO ())
 
 type EventM e t a = ReaderT (t, e) IO a
 
@@ -259,6 +259,6 @@
 mouseToElement :: IsMouseEvent e => EventM e t (Maybe Node)
 mouseToElement = event >>= (liftIO . mouseEventGetToElement)
 
-connect :: (GObjectClass t, IsEvent e) => String -> t -> EventM e t () -> IO Bool
+connect :: (GObjectClass t, IsEvent e) => String -> t -> EventM e t () -> IO (IO ())
 connect eventName target callback =
   eventTargetAddEventListener target eventName False $ curry (runReaderT callback)
diff --git a/src/GHCJS/DOM/EventTargetClosures.hs b/src/GHCJS/DOM/EventTargetClosures.hs
--- a/src/GHCJS/DOM/EventTargetClosures.hs
+++ b/src/GHCJS/DOM/EventTargetClosures.hs
@@ -14,22 +14,38 @@
         "($1[\"addEventListener\"]($2, $3, $4) ? 1 : 0)"
         ghcjs_dom_event_target_add_event_listener ::
         JSRef GObject -> JSString -> JSRef a -> Bool -> IO Bool
+
+foreign import javascript unsafe
+        "($1[\"removeEventListener\"]($2, $3, $4) ? 1 : 0)"
+        ghcjs_dom_event_target_remove_event_listener ::
+        JSRef GObject -> JSString -> JSRef a -> Bool -> IO Bool
 #else
 ghcjs_dom_event_target_add_event_listener ::
         JSRef GObject -> JSString -> JSRef a -> Bool -> IO Bool
 ghcjs_dom_event_target_add_event_listener = undefined
+
+ghcjs_dom_event_target_remove_event_listener ::
+        JSRef GObject -> JSString -> JSRef a -> Bool -> IO Bool
+ghcjs_dom_event_target_remove_event_listener = undefined
 #endif
 
 eventTargetAddEventListener ::
                          (GObjectClass self, IsEvent event) =>
-                           self -> String -> Bool -> (self -> event -> IO ()) -> IO Bool
+                           self -> String -> Bool -> (self -> event -> IO ()) -> IO (IO ())
 eventTargetAddEventListener self eventName bubble user = do
-    callback <- syncCallback1 NeverRetain True $ \e -> user self (unsafeCastGObject $ GObject e)
+    callback <- syncCallback1 AlwaysRetain True $ \e -> user self (unsafeCastGObject $ GObject e)
     ghcjs_dom_event_target_add_event_listener
         (unGObject (toGObject self))
         (toJSString eventName)
         callback
         bubble
+    return $ do
+        ghcjs_dom_event_target_remove_event_listener
+            (unGObject (toGObject self))
+            (toJSString eventName)
+            callback
+            bubble
+        release callback
 #else
 module GHCJS.DOM.EventTargetClosures (
   module Graphics.UI.Gtk.WebKit.DOM.EventTargetClosures
