diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,6 +2,18 @@
 Brick changelog
 ---------------
 
+0.72
+----
+
+Package changes:
+ * Increased lower bound on `text-zipper` to `0.12`.
+
+API changes:
+ * `handleEditorEvent` now takes a `BrickEvent` rather than just a Vty
+   `Event`.
+ * Brick editors now handle mouse clicks to change their cursor
+   positions.
+
 0.71.1
 ------
 
diff --git a/brick.cabal b/brick.cabal
--- a/brick.cabal
+++ b/brick.cabal
@@ -1,5 +1,5 @@
 name:                brick
-version:             0.71.1
+version:             0.72
 synopsis:            A declarative terminal user interface library
 description:
   Write terminal user interfaces (TUIs) painlessly with 'brick'! You
@@ -128,7 +128,7 @@
                        contravariant,
                        stm >= 2.4.3,
                        text,
-                       text-zipper >= 0.11,
+                       text-zipper >= 0.12,
                        template-haskell,
                        deepseq >= 1.3 && < 1.5,
                        unix,
diff --git a/programs/EditDemo.hs b/programs/EditDemo.hs
--- a/programs/EditDemo.hs
+++ b/programs/EditDemo.hs
@@ -48,17 +48,17 @@
             str "Press Tab to switch between editors, Esc to quit."
 
 appEvent :: St -> T.BrickEvent Name e -> T.EventM Name (T.Next St)
-appEvent st (T.VtyEvent ev) =
-    case ev of
-        V.EvKey V.KEsc [] -> M.halt st
-        V.EvKey (V.KChar '\t') [] -> M.continue $ st & focusRing %~ F.focusNext
-        V.EvKey V.KBackTab [] -> M.continue $ st & focusRing %~ F.focusPrev
-
-        _ -> M.continue =<< case F.focusGetCurrent (st^.focusRing) of
-               Just Edit1 -> T.handleEventLensed st edit1 E.handleEditorEvent ev
-               Just Edit2 -> T.handleEventLensed st edit2 E.handleEditorEvent ev
-               Nothing -> return st
-appEvent st _ = M.continue st
+appEvent st (T.VtyEvent (V.EvKey V.KEsc [])) =
+    M.halt st
+appEvent st (T.VtyEvent (V.EvKey (V.KChar '\t') [])) =
+    M.continue $ st & focusRing %~ F.focusNext
+appEvent st (T.VtyEvent (V.EvKey V.KBackTab [])) =
+    M.continue $ st & focusRing %~ F.focusPrev
+appEvent st ev =
+    M.continue =<< case F.focusGetCurrent (st^.focusRing) of
+      Just Edit1 -> T.handleEventLensed st edit1 E.handleEditorEvent ev
+      Just Edit2 -> T.handleEventLensed st edit2 E.handleEditorEvent ev
+      Nothing -> return st
 
 initialState :: St
 initialState =
diff --git a/programs/MouseDemo.hs b/programs/MouseDemo.hs
--- a/programs/MouseDemo.hs
+++ b/programs/MouseDemo.hs
@@ -3,7 +3,7 @@
 {-# LANGUAGE TemplateHaskell #-}
 module Main where
 
-import Lens.Micro ((^.), (&), (.~), (%~))
+import Lens.Micro ((^.), (&), (.~))
 import Lens.Micro.TH (makeLenses)
 import Control.Monad (void)
 #if !(MIN_VERSION_base(4,11,0))
@@ -20,8 +20,6 @@
 import qualified Brick.Widgets.Center as C
 import qualified Brick.Widgets.Border as B
 import Brick.Widgets.Core
-import Data.Text.Zipper (moveCursor)
-import Data.Tuple (swap)
 
 data Name = Info | Button1 | Button2 | Button3 | Prose | TextBox
           deriving (Show, Ord, Eq)
@@ -86,17 +84,17 @@
                C.hCenter $ str msg
 
 appEvent :: St -> T.BrickEvent Name e -> T.EventM Name (T.Next St)
-appEvent st (T.MouseDown n _ _ loc) = do
-    let T.Location pos = loc
-    M.continue $ st & lastReportedClick .~ Just (n, loc)
-                    & edit %~ E.applyEdit (if n == TextBox then moveCursor (swap pos) else id)
+appEvent st ev@(T.MouseDown n _ _ loc) =
+    M.continue =<< T.handleEventLensed (st & lastReportedClick .~ Just (n, loc))
+                                       edit
+                                       E.handleEditorEvent
+                                       ev
 appEvent st (T.MouseUp {}) = M.continue $ st & lastReportedClick .~ Nothing
 appEvent st (T.VtyEvent (V.EvMouseUp {})) = M.continue $ st & lastReportedClick .~ Nothing
 appEvent st (T.VtyEvent (V.EvKey V.KUp [V.MCtrl])) = M.vScrollBy (M.viewportScroll Prose) (-1) >> M.continue st
 appEvent st (T.VtyEvent (V.EvKey V.KDown [V.MCtrl])) = M.vScrollBy (M.viewportScroll Prose) 1 >> M.continue st
 appEvent st (T.VtyEvent (V.EvKey V.KEsc [])) = M.halt st
-appEvent st (T.VtyEvent ev) = M.continue =<< T.handleEventLensed st edit E.handleEditorEvent ev
-appEvent st _ = M.continue st
+appEvent st ev = M.continue =<< T.handleEventLensed st edit E.handleEditorEvent ev
 
 aMap :: AttrMap
 aMap = attrMap V.defAttr
diff --git a/src/Brick/Forms.hs b/src/Brick/Forms.hs
--- a/src/Brick/Forms.hs
+++ b/src/Brick/Forms.hs
@@ -522,15 +522,13 @@
                      then id
                      else Z.moveCursor pos
         initialText = ini $ initialState ^. stLens
-        handleEvent (VtyEvent e) ed = handleEditorEvent e ed
-        handleEvent _ ed = return ed
 
     in FormFieldState { formFieldState = initVal
                       , formFields = [ FormField n
                                                  (val . getEditContents)
                                                  True
                                                  (\b e -> wrapEditor $ renderEditor renderText b e)
-                                                 handleEvent
+                                                 handleEditorEvent
                                      ]
                       , formFieldLens = stLens
                       , formFieldUpdate = \newVal e ->
diff --git a/src/Brick/Widgets/Edit.hs b/src/Brick/Widgets/Edit.hs
--- a/src/Brick/Widgets/Edit.hs
+++ b/src/Brick/Widgets/Edit.hs
@@ -53,6 +53,7 @@
 import qualified Data.Text.Zipper as Z hiding ( textZipper )
 import qualified Data.Text.Zipper.Generic as Z
 import qualified Data.Text.Zipper.Generic.Words as Z
+import Data.Tuple (swap)
 
 import Brick.Types
 import Brick.Widgets.Core
@@ -114,48 +115,56 @@
 instance DecodeUtf8 String where
     decodeUtf8 bs = T.unpack <$> decodeUtf8 bs
 
-handleEditorEvent :: (DecodeUtf8 t, Eq t, Z.GenericTextZipper t)
-                  => Event -> Editor t n -> EventM n (Editor t n)
-handleEditorEvent e ed =
-        let f = case e of
-                  EvPaste bs -> case decodeUtf8 bs of
-                      Left _ -> id
-                      Right t -> Z.insertMany t
-                  EvKey (KChar 'a') [MCtrl] -> Z.gotoBOL
-                  EvKey (KChar 'e') [MCtrl] -> Z.gotoEOL
-                  EvKey (KChar 'd') [MCtrl] -> Z.deleteChar
-                  EvKey (KChar 'd') [MMeta] -> Z.deleteWord
-                  EvKey (KChar 'k') [MCtrl] -> Z.killToEOL
-                  EvKey (KChar 'u') [MCtrl] -> Z.killToBOL
-                  EvKey KEnter [] -> Z.breakLine
-                  EvKey KDel [] -> Z.deleteChar
-                  EvKey (KChar c) [] | c /= '\t' -> Z.insertChar c
-                  EvKey KUp [] -> Z.moveUp
-                  EvKey KDown [] -> Z.moveDown
-                  EvKey KLeft [] -> Z.moveLeft
-                  EvKey KRight [] -> Z.moveRight
-                  EvKey (KChar 'b') [MCtrl] -> Z.moveLeft
-                  EvKey (KChar 'f') [MCtrl] -> Z.moveRight
-                  EvKey (KChar 'b') [MMeta] -> Z.moveWordLeft
-                  EvKey (KChar 'f') [MMeta] -> Z.moveWordRight
-                  EvKey KBS [] -> Z.deletePrevChar
-                  EvKey (KChar 't') [MCtrl] -> Z.transposeChars
-                  EvKey KHome [] -> Z.gotoBOL
-                  EvKey KEnd [] -> Z.gotoEOL
-                  EvKey (KChar '<') [MMeta] -> Z.gotoBOF
-                  EvKey (KChar '>') [MMeta] -> Z.gotoEOF
-                  _ -> id
-        in return $ applyEdit f ed
+handleEditorEvent :: (Eq n, DecodeUtf8 t, Eq t, Z.GenericTextZipper t)
+                  => BrickEvent n e
+                  -> Editor t n
+                  -> EventM n (Editor t n)
+handleEditorEvent e ed = return $ applyEdit f ed
+    where
+        f = case e of
+              VtyEvent ev ->
+                  handleVtyEvent ev
+              MouseDown n _ _ (Location pos) | n == getName ed ->
+                  Z.moveCursorClosest (swap pos)
+              _ -> id
+        handleVtyEvent ev = case ev of
+            EvPaste bs -> case decodeUtf8 bs of
+                Left _ -> id
+                Right t -> Z.insertMany t
+            EvKey (KChar 'a') [MCtrl] -> Z.gotoBOL
+            EvKey (KChar 'e') [MCtrl] -> Z.gotoEOL
+            EvKey (KChar 'd') [MCtrl] -> Z.deleteChar
+            EvKey (KChar 'd') [MMeta] -> Z.deleteWord
+            EvKey (KChar 'k') [MCtrl] -> Z.killToEOL
+            EvKey (KChar 'u') [MCtrl] -> Z.killToBOL
+            EvKey KEnter [] -> Z.breakLine
+            EvKey KDel [] -> Z.deleteChar
+            EvKey (KChar c) [] | c /= '\t' -> Z.insertChar c
+            EvKey KUp [] -> Z.moveUp
+            EvKey KDown [] -> Z.moveDown
+            EvKey KLeft [] -> Z.moveLeft
+            EvKey KRight [] -> Z.moveRight
+            EvKey (KChar 'b') [MCtrl] -> Z.moveLeft
+            EvKey (KChar 'f') [MCtrl] -> Z.moveRight
+            EvKey (KChar 'b') [MMeta] -> Z.moveWordLeft
+            EvKey (KChar 'f') [MMeta] -> Z.moveWordRight
+            EvKey KBS [] -> Z.deletePrevChar
+            EvKey (KChar 't') [MCtrl] -> Z.transposeChars
+            EvKey KHome [] -> Z.gotoBOL
+            EvKey KEnd [] -> Z.gotoEOL
+            EvKey (KChar '<') [MMeta] -> Z.gotoBOF
+            EvKey (KChar '>') [MMeta] -> Z.gotoEOF
+            _ -> id
 
 -- | Construct an editor over 'Text' values
 editorText :: n
-       -- ^ The editor's name (must be unique)
-       -> Maybe Int
-       -- ^ The limit on the number of lines in the editor ('Nothing'
-       -- means no limit)
-       -> T.Text
-       -- ^ The initial content
-       -> Editor T.Text n
+           -- ^ The editor's name (must be unique)
+           -> Maybe Int
+           -- ^ The limit on the number of lines in the editor ('Nothing'
+           -- means no limit)
+           -> T.Text
+           -- ^ The initial content
+           -> Editor T.Text n
 editorText = editor
 
 -- | Construct an editor over 'String' values
