diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,6 +2,14 @@
 Brick changelog
 ---------------
 
+2.8.1
+-----
+
+* Fixed a long-standing bug in `cropToContext` that resulted in some
+  extents getting left around when they should be dropped, possibly
+  leading to application bugs when handling mouse clicks in extent
+  regions that should have been removed from the rendering result.
+
 2.8
 ---
 
diff --git a/brick.cabal b/brick.cabal
--- a/brick.cabal
+++ b/brick.cabal
@@ -1,5 +1,5 @@
 name:                brick
-version:             2.8
+version:             2.8.1
 synopsis:            A declarative terminal user interface library
 description:
   Write terminal user interfaces (TUIs) painlessly with 'brick'! You
diff --git a/src/Brick/Widgets/Core.hs b/src/Brick/Widgets/Core.hs
--- a/src/Brick/Widgets/Core.hs
+++ b/src/Brick/Widgets/Core.hs
@@ -719,12 +719,11 @@
                             (concatMap extents allTranslatedResults)
                             newBorders
 
-catDynBorder
-    :: Lens' (Edges BorderSegment) BorderSegment
-    -> Lens' (Edges BorderSegment) BorderSegment
-    -> DynBorder
-    -> DynBorder
-    -> Maybe DynBorder
+catDynBorder :: Lens' (Edges BorderSegment) BorderSegment
+             -> Lens' (Edges BorderSegment) BorderSegment
+             -> DynBorder
+             -> DynBorder
+             -> Maybe DynBorder
 catDynBorder towardsA towardsB a b
     -- Currently, we check if the 'BorderStyle's are exactly the same. In the
     -- future, it might be nice to relax this restriction. For example, if a
@@ -742,12 +741,11 @@
     = Just (a & dbSegmentsL.towardsB.bsDrawL .~ True)
     | otherwise = Nothing
 
-catDynBorders
-    :: Lens' (Edges BorderSegment) BorderSegment
-    -> Lens' (Edges BorderSegment) BorderSegment
-    -> I.IMap DynBorder
-    -> I.IMap DynBorder
-    -> I.IMap DynBorder
+catDynBorders :: Lens' (Edges BorderSegment) BorderSegment
+              -> Lens' (Edges BorderSegment) BorderSegment
+              -> I.IMap DynBorder
+              -> I.IMap DynBorder
+              -> I.IMap DynBorder
 catDynBorders towardsA towardsB am bm = I.mapMaybe id
     $ I.intersectionWith (catDynBorder towardsA towardsB) am bm
 
@@ -757,9 +755,8 @@
 -- images to keep the image in sync with the border information.
 --
 -- The input borders are assumed to be disjoint. This property is not checked.
-catBorders
-    :: (border ~ BM.BorderMap DynBorder, rewrite ~ I.IMap V.Image)
-    => BoxRenderer n -> border -> border -> ((rewrite, rewrite), border)
+catBorders :: (border ~ BM.BorderMap DynBorder, rewrite ~ I.IMap V.Image)
+           => BoxRenderer n -> border -> border -> ((rewrite, rewrite), border)
 catBorders br r l = if lCoord + 1 == rCoord
     then ((lRe, rRe), lr')
     else ((I.empty, I.empty), lr)
@@ -788,20 +785,20 @@
 -- overlap and are strictly increasing in the primary direction), produce: a
 -- list of rewrites for the lo and hi directions of each border, respectively,
 -- and the borders describing the fully concatenated object.
-catAllBorders ::
-    BoxRenderer n ->
-    [BM.BorderMap DynBorder] ->
-    ([(I.IMap V.Image, I.IMap V.Image)], BM.BorderMap DynBorder)
+catAllBorders :: BoxRenderer n
+              -> [BM.BorderMap DynBorder]
+              -> ([(I.IMap V.Image, I.IMap V.Image)], BM.BorderMap DynBorder)
 catAllBorders _ [] = ([], BM.empty)
 catAllBorders br (bm:bms) = (zip ([I.empty]++los) (his++[I.empty]), bm') where
     (rewrites, bm') = runState (traverse (state . catBorders br) bms) bm
     (his, los) = unzip rewrites
 
-rewriteEdge ::
-    (Int -> V.Image -> V.Image) ->
-    (Int -> V.Image -> V.Image) ->
-    ([V.Image] -> V.Image) ->
-    I.IMap V.Image -> V.Image -> V.Image
+rewriteEdge :: (Int -> V.Image -> V.Image)
+            -> (Int -> V.Image -> V.Image)
+            -> ([V.Image] -> V.Image)
+            -> I.IMap V.Image
+            -> V.Image
+            -> V.Image
 rewriteEdge splitLo splitHi combine = (combine .) . go . offsets 0 . I.unsafeToAscList where
 
     -- convert absolute positions into relative ones
diff --git a/src/Brick/Widgets/Internal.hs b/src/Brick/Widgets/Internal.hs
--- a/src/Brick/Widgets/Internal.hs
+++ b/src/Brick/Widgets/Internal.hs
@@ -114,29 +114,31 @@
 cropExtents :: Context n -> [Extent n] -> [Extent n]
 cropExtents ctx es = mapMaybe cropExtent es
     where
-        -- An extent is cropped in places where it is not within the
-        -- region described by the context.
-        --
-        -- If its entirety is outside the context region, it is dropped.
-        --
-        -- Otherwise its size is adjusted so that it is contained within
-        -- the context region.
         cropExtent (Extent n (Location (c, r)) (w, h)) =
-            -- Determine the new lower-right corner
-            let endCol = c + w
-                endRow = r + h
-                -- Then clamp the lower-right corner based on the
-                -- context
-                endCol' = min (ctx^.availWidthL) endCol
-                endRow' = min (ctx^.availHeightL) endRow
-                -- Then compute the new width and height from the
-                -- clamped lower-right corner.
-                w' = endCol' - c
-                h' = endRow' - r
-                e = Extent n (Location (c, r)) (w', h')
-            in if w' < 0 || h' < 0
-               then Nothing
-               else Just e
+            -- Clamp the original extent's UL corner to the context.
+            --
+            -- Clamp the original extent's LR corner to the context.
+            --
+            -- Keep the modified extent (i.e. with clamped corners)
+            -- only if the resulting extent has non-zero size in both
+            -- dimensions.
+            let nonEmpty = nonEmptyH && nonEmptyV
+                nonEmptyH = newWidth > 0
+                nonEmptyV = newHeight > 0
+                newWidth = newEndCol - newStartCol
+                newHeight = newEndRow - newStartRow
+                (newStartCol, newStartRow) = clampCorner (c, r)
+                (newEndCol, newEndRow) = clampCorner (c + w, r + h)
+                clampCorner (cols, rows) =
+                    ( clampRange (ctx^.availWidthL) cols
+                    , clampRange (ctx^.availHeightL) rows
+                    )
+                clampRange bound val =
+                    min bound $ max 0 val
+                newExtent = Extent n (Location (newStartCol, newStartRow)) (newWidth, newHeight)
+            in if nonEmpty
+               then Just newExtent
+               else Nothing
 
 cropBorders :: Context n -> BorderMap DynBorder -> BorderMap DynBorder
 cropBorders ctx = BM.crop Edges
