diff --git a/lib/FRP/Netwire/Input.hs b/lib/FRP/Netwire/Input.hs
--- a/lib/FRP/Netwire/Input.hs
+++ b/lib/FRP/Netwire/Input.hs
@@ -23,7 +23,8 @@
 import Control.Monad (liftM)
 import Control.Monad.Fix
 import Control.Wire
-import Data.Monoid
+
+import FRP.Netwire.Input.Util
 --------------------------------------------------------------------------------
 
 --------------------------------------------------------------------------------
@@ -102,15 +103,18 @@
     then return (Right x)
     else return (Left mempty)
 
--- | Ignores its input and returns True whenever the mouse button is pressed
+-- | Ignores its input and returns 'True' whenever the mouse button is pressed,
+-- 'False' otherwise.
 --
 -- * Inhibits: never
-isMousePressed :: (Monoid e, MonadMouse mb m) => mb -> Wire s e m a Bool
-isMousePressed b = mousePressed b . pure True <|> pure False
+isMousePressed :: MonadMouse mb m => mb -> Wire s e m a Bool
+isMousePressed = mkGen_ . const . liftM Right . mbIsPressed
 
 -- | Behaves like the identity wire for a signle instant when the mouse button
--- is pressed and otherwise inhibits
--- 
+-- is pressed and otherwise inhibits. Note that this wire causing the button
+-- to be treated as released by all other wires after the instant when it is
+-- pressed.
+--
 -- * Depends: the instant at which the mouse button is pressed
 -- * Inhibits: when the mouse button is not pressed or after it has been pressed
 mouseDebounced :: (Monoid e, MonadMouse mb m) => mb -> Wire s e m a a
@@ -120,15 +124,29 @@
     then releaseButton mouse >> return (Right x)
     else return (Left mempty)
 
+-- | Fires an event the instant the given mouse button is pressed after not
+-- being pressed.
+--
+-- * Inhibits: never
+mousePressedEvent :: MonadMouse mb m => mb -> Wire s e m a (Event a)
+mousePressedEvent mb = eventToId (became id . isMousePressed mb)
+
+-- | Fires an event the instant the given mouse button is released after being
+-- pressed.
+--
+-- * Inhibits: never
+mouseReleasedEvent :: MonadMouse mb m => mb -> Wire s e m a (Event a)
+mouseReleasedEvent mb = eventToId (noLonger id . isMousePressed mb)
+
 -- | The mouse scroll is the offset from zero at each time instant.
--- 
+--
 -- * Depends: now
 -- * Inhibits: never
 mouseScroll :: (Monoid e, MonadMouse mb m) => Wire s e m a (Double, Double)
 mouseScroll = mkGen_ $ \_ -> liftM Right scroll
 
 -- | The amount that the mouse has scrolled over the course of the entire wire.
--- 
+--
 -- * Depends: now
 -- * Inhibits: never
 mouseScrolled :: (Monoid e, MonadMouse mb m) => Wire s e m a (Double, Double)
@@ -144,7 +162,7 @@
 -- @
 --   cursorMode CursorMode'Disabled --> mkId
 -- @
--- 
+--
 -- * Inhibits: after now
 cursorMode :: (MonadMouse mb m, Monoid e) => CursorMode -> Wire s e m a a
 cursorMode mode =
@@ -168,7 +186,7 @@
 
 -- | Behaves like the identity wire when the key is pressed
 -- and inhibits otherwise
--- 
+--
 -- * Inhibits: when the key is not pressed
 keyPressed :: (Monoid e, MonadKeyboard k m) => k -> Wire s e m a a
 keyPressed key = mkGen_ $ \x -> do
@@ -177,15 +195,9 @@
     then return (Right x)
     else return (Left mempty)
 
--- | Ignores its input and returns True whenever the key is pressed
---
--- * Inhibits: never
-isKeyPressed :: (Monoid e, MonadKeyboard k m) => k -> Wire s e m a Bool
-isKeyPressed key = keyPressed key . pure True <|> pure False
-
 -- | Behaves like the identity wire when the key is not pressed
 -- and inhibits otherwise
--- 
+--
 -- * Inhibits: when the key is pressed
 keyNotPressed :: (Monoid e, MonadKeyboard k m) => k -> Wire s e m a a
 keyNotPressed key = mkGen_ $ \x -> do
@@ -194,9 +206,18 @@
     then return (Left mempty)
     else return (Right x)
 
--- | Behaves like the identity wire for a signle instant when the key
--- is pressed and otherwise inhibits
--- 
+-- | Ignores its input and returns 'True' whenever the key is pressed, 'False'
+-- otherwise.
+--
+-- * Inhibits: never
+isKeyPressed :: MonadKeyboard k m => k -> Wire s e m a Bool
+isKeyPressed = mkGen_ . const . liftM Right . keyIsPressed
+
+-- | Behaves like the identity wire for a single instant when the key
+-- is pressed and otherwise inhibits. Note that this wire causes the key
+-- to be treated as released by all other wires after the instant when it is
+-- pressed.
+--
 -- * Inhibits: when the key is not pressed or after it has been pressed
 keyDebounced :: (Monoid e, MonadKeyboard k m) => k -> Wire s e m a a
 keyDebounced key = mkGen_ $ \x -> do
@@ -204,3 +225,15 @@
   if pressed
     then releaseKey key >> return (Right x)
     else return (Left mempty)
+
+-- | Fires an event the instant the given key is pressed after not being pressed.
+--
+-- * Inhibits: never
+keyPressedEvent :: MonadKeyboard k m => k -> Wire s e m a (Event a)
+keyPressedEvent key = eventToId (became id . isKeyPressed key)
+
+-- | Fires an event the instant the given key is released after being pressed.
+--
+-- * Inhibits: never
+keyReleasedEvent :: MonadKeyboard k m => k -> Wire s e m a (Event a)
+keyReleasedEvent key = eventToId (noLonger id . isKeyPressed key)
diff --git a/lib/FRP/Netwire/Input/Util.hs b/lib/FRP/Netwire/Input/Util.hs
new file mode 100644
--- /dev/null
+++ b/lib/FRP/Netwire/Input/Util.hs
@@ -0,0 +1,23 @@
+{-|
+Module      : FRP.Netwire.Input.Util
+Description : Utility functions used but not exported by netwire-input.
+Copyright   : (c) Bradley Hardy, 2015
+License     : MIT
+Maintainer  : Krajcevski@gmail.com
+Stability   : experimental
+Portability : POSIX
+
+This module contains utility functions used but not exported by
+'FRP.Netwire.Input'.
+
+-}
+module FRP.Netwire.Input.Util where
+
+import Prelude hiding (id, (.))
+import Control.Wire
+
+-- | Take an wire that produces an arbitrary event, and change the contents
+-- of those events to instead be the same as the input value at the time of
+-- the event's occurrence.
+eventToId :: Monad m => Wire s e m a (Event b) -> Wire s e m a (Event a)
+eventToId wire = uncurry (fmap . const) <$> (id &&& wire)
diff --git a/netwire-input.cabal b/netwire-input.cabal
--- a/netwire-input.cabal
+++ b/netwire-input.cabal
@@ -2,20 +2,21 @@
 -- documentation, see http://haskell.org/cabal/users-guide/
 
 name:                netwire-input
-version:             0.0.4
+version:             0.0.6
 synopsis:            Input handling abstractions for netwire
-description:         This package contains a collection of Monad typeclasses that support
-                     interaction with input devices such as keyboard and mice. Moreover, these
-                     typeclasses are used to create wires from the netwire package the produce
-                     mouse and keyboard input values in a reactive way. This package cannot
-                     be used independently and must be used with another package that provides
-                     instantiation of these typeclasses such as netwire-input-glfw.
+description:         This package contains a collection of Monad typeclasses that
+                     support interaction with input devices such as keyboard and
+                     mice. Moreover, these typeclasses are used to create wires from
+                     the netwire package the produce mouse and keyboard input values
+                     in a reactive way. This package cannot be used independently
+                     and must be used with another package that provides instantiation
+                     of these typeclasses such as netwire-input-glfw.
 homepage:            https://www.github.com/Mokosha/netwire-input
 license:             MIT
 license-file:        LICENSE
 author:              Pavel Krajcevski
 maintainer:          Krajcevski@gmail.com
-copyright:           Pavel Krajcevski, 2014
+copyright:           Pavel Krajcevski, 2015
 category:            Game
 build-type:          Simple
 extra-source-files:  README.md
@@ -29,7 +30,8 @@
   default-extensions:  FunctionalDependencies
                        MultiParamTypeClasses
   exposed-modules:     FRP.Netwire.Input
-  build-depends:       base >= 4.6 && < 4.10,
+  other-modules:       FRP.Netwire.Input.Util
+  build-depends:       base >= 4.6 && < 6,
                        netwire >= 5
   hs-source-dirs:      lib
   default-language:    Haskell2010
