diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,6 +2,18 @@
 Brick changelog
 ---------------
 
+0.59
+----
+
+API changes:
+ * `Brick.Widgets.List` got `listMoveToBeginning` and `listMoveToEnd`
+   functions
+ * `Extent`: removed the unused `extentOffset` field
+
+Bug fixes:
+ * Fixed a crash in the border rewriting code that attempted to rewrite
+   empty images (#305) (thanks @dmwit)
+
 0.58.1
 ------
 
diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -69,6 +69,8 @@
 | [`hascard`](https://github.com/Yvee1/hascard) | A program for reviewing "flash card" notes |
 | [`ttyme`](https://github.com/evuez/ttyme) | A TUI for [Harvest](https://www.getharvest.com/) |
 | [`ghcup`](https://www.haskell.org/ghcup/) | A TUI for `ghcup`, the Haskell toolchain manager |
+| [`cbookview`](https://github.com/mlang/chessIO) | A TUI for exploring polyglot chess opening book files |
+| [`thock`](https://github.com/rmehri01/thock) | A modern TUI typing game featuring online racing against friends |
 
 These third-party packages also extend `brick`:
 
diff --git a/brick.cabal b/brick.cabal
--- a/brick.cabal
+++ b/brick.cabal
@@ -1,5 +1,5 @@
 name:                brick
-version:             0.58.1
+version:             0.59
 synopsis:            A declarative terminal user interface library
 description:
   Write terminal user interfaces (TUIs) painlessly with 'brick'! You
diff --git a/docs/guide.rst b/docs/guide.rst
--- a/docs/guide.rst
+++ b/docs/guide.rst
@@ -620,7 +620,7 @@
 that will always consume the same number of rows or columns no
 matter how many it is given. Widgets can advertise different
 vertical and horizontal growth policies for example, the
-``Brick.Widgets.Border.hCenter`` function centers a widget and is
+``Brick.Widgets.Center.hCenter`` function centers a widget and is
 ``Greedy`` horizontally and defers to the widget it centers for vertical
 growth behavior.
 
diff --git a/src/Brick/Main.hs b/src/Brick/Main.hs
--- a/src/Brick/Main.hs
+++ b/src/Brick/Main.hs
@@ -309,15 +309,15 @@
         VtyEvent (EvMouseDown c r button mods) -> do
             let matching = findClickedExtents_ (c, r) exts
             case matching of
-                (Extent n (Location (ec, er)) _ (Location (oC, oR)):_) ->
+                (Extent n (Location (ec, er)) _:_) ->
                     -- If the clicked extent was registered as
                     -- clickable, send a click event. Otherwise, just
                     -- send the raw mouse event
                     case n `elem` firstRS^.clickableNamesL of
                         True -> do
                             let localCoords = Location (lc, lr)
-                                lc = c - ec + oC
-                                lr = r - er + oR
+                                lc = c - ec
+                                lr = r - er
 
                                 -- If the clicked extent was a viewport,
                                 -- adjust the local coordinates by
@@ -334,15 +334,15 @@
         VtyEvent (EvMouseUp c r button) -> do
             let matching = findClickedExtents_ (c, r) exts
             case matching of
-                (Extent n (Location (ec, er)) _ (Location (oC, oR)):_) ->
+                (Extent n (Location (ec, er)) _:_) ->
                     -- If the clicked extent was registered as
                     -- clickable, send a click event. Otherwise, just
                     -- send the raw mouse event
                     case n `elem` firstRS^.clickableNamesL of
                         True -> do
                             let localCoords = Location (lc, lr)
-                                lc = c - ec + oC
-                                lr = r - er + oR
+                                lc = c - ec
+                                lr = r - er
                                 -- If the clicked extent was a viewport,
                                 -- adjust the local coordinates by
                                 -- adding the viewport upper-left corner
@@ -386,7 +386,7 @@
 -- | Did the specified mouse coordinates (column, row) intersect the
 -- specified extent?
 clickedExtent :: (Int, Int) -> Extent n -> Bool
-clickedExtent (c, r) (Extent _ (Location (lc, lr)) (w, h) _) =
+clickedExtent (c, r) (Extent _ (Location (lc, lr)) (w, h)) =
    c >= lc && c < (lc + w) &&
    r >= lr && r < (lr + h)
 
@@ -395,7 +395,7 @@
 lookupExtent :: (Eq n) => n -> EventM n (Maybe (Extent n))
 lookupExtent n = EventM $ asks (listToMaybe . filter f . latestExtents)
     where
-        f (Extent n' _ _ _) = n == n'
+        f (Extent n' _ _) = n == n'
 
 -- | Given a mouse click location, return the extents intersected by the
 -- click. The returned extents are sorted such that the first extent in
diff --git a/src/Brick/Types/Internal.hs b/src/Brick/Types/Internal.hs
--- a/src/Brick/Types/Internal.hs
+++ b/src/Brick/Types/Internal.hs
@@ -123,7 +123,6 @@
 data Extent n = Extent { extentName      :: n
                        , extentUpperLeft :: Location
                        , extentSize      :: (Int, Int)
-                       , extentOffset    :: Location
                        }
                        deriving (Show, Read, Generic, NFData)
 
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
@@ -196,7 +196,7 @@
 addVisibilityOffset off r = r & visibilityRequestsL.each.vrPositionL %~ (off <>)
 
 addExtentOffset :: Location -> Result n -> Result n
-addExtentOffset off r = r & extentsL.each %~ (\(Extent n l sz o) -> Extent n (off <> l) sz o)
+addExtentOffset off r = r & extentsL.each %~ (\(Extent n l sz) -> Extent n (off <> l) sz)
 
 addDynBorderOffset :: Location -> Result n -> Result n
 addDynBorderOffset off r = r & bordersL %~ BM.translate off
@@ -207,7 +207,7 @@
 reportExtent n p =
     Widget (hSize p) (vSize p) $ do
         result <- render p
-        let ext = Extent n (Location (0, 0)) sz (Location (0, 0))
+        let ext = Extent n (Location (0, 0)) sz
             sz = ( result^.imageL.to V.imageWidth
                  , result^.imageL.to V.imageHeight
                  )
@@ -753,13 +753,13 @@
     size = imagePrimary br old
     go = rewriteEdge (splitLoSecondary br) (splitHiSecondary br) (concatenateSecondary br)
     rewriteLo img
-        | I.null loRewrite = img
+        | I.null loRewrite || size == 0 = img
         | otherwise = concatenatePrimary br
             [ go loRewrite (splitLoPrimary br 1 img)
             , splitHiPrimary br 1 img
             ]
     rewriteHi img
-        | I.null hiRewrite = img
+        | I.null hiRewrite || size == 0 = img
         | otherwise = concatenatePrimary br
             [ splitLoPrimary br (size-1) img
             , go hiRewrite (splitHiPrimary br (size-1) img)
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
@@ -97,14 +97,10 @@
         --
         -- Otherwise its size and upper left corner are adjusted so that
         -- they are contained within the context region.
-        cropExtent (Extent n (Location (c, r)) (w, h) (Location (oC, oR))) =
+        cropExtent (Extent n (Location (c, r)) (w, h)) =
             -- First, clamp the upper-left corner to at least (0, 0).
             let c' = max c 0
                 r' = max r 0
-                -- Compute deltas for the offset since if the upper-left
-                -- corner moved, so should the offset.
-                dc = c' - c
-                dr = r' - r
                 -- Then, determine the new lower-right corner based on
                 -- the clamped corner.
                 endCol = c' + w
@@ -117,7 +113,7 @@
                 -- clamped lower-right corner.
                 w' = endCol' - c'
                 h' = endRow' - r'
-                e = Extent n (Location (c', r')) (w', h') (Location (oC + dc, oR + dr))
+                e = Extent n (Location (c', r')) (w', h')
             in if w' < 0 || h' < 0
                then Nothing
                else Just e
diff --git a/src/Brick/Widgets/List.hs b/src/Brick/Widgets/List.hs
--- a/src/Brick/Widgets/List.hs
+++ b/src/Brick/Widgets/List.hs
@@ -55,6 +55,8 @@
   , listMoveByPages
   , listMovePageUp
   , listMovePageDown
+  , listMoveToBeginning
+  , listMoveToEnd
   , listInsert
   , listRemove
   , listReplace
@@ -203,8 +205,8 @@
     case e of
         EvKey KUp [] -> return $ listMoveUp theList
         EvKey KDown [] -> return $ listMoveDown theList
-        EvKey KHome [] -> return $ listMoveTo 0 theList
-        EvKey KEnd [] -> return $ listMoveTo (length $ listElements theList) theList
+        EvKey KHome [] -> return $ listMoveToBeginning theList
+        EvKey KEnd [] -> return $ listMoveToEnd theList
         EvKey KPageDown [] -> listMovePageDown theList
         EvKey KPageUp [] -> listMovePageUp theList
         _ -> return theList
@@ -233,13 +235,25 @@
     case e of
         EvKey (KChar 'k') [] -> return $ listMoveUp theList
         EvKey (KChar 'j') [] -> return $ listMoveDown theList
-        EvKey (KChar 'g') [] -> return $ listMoveTo 0 theList
-        EvKey (KChar 'G') [] -> return $ listMoveTo (length $ listElements theList) theList
+        EvKey (KChar 'g') [] -> return $ listMoveToBeginning theList
+        EvKey (KChar 'G') [] -> return $ listMoveToEnd theList
         EvKey (KChar 'f') [MCtrl] -> listMovePageDown theList
         EvKey (KChar 'b') [MCtrl] -> listMovePageUp theList
         EvKey (KChar 'd') [MCtrl] -> listMoveByPages (0.5::Double) theList
         EvKey (KChar 'u') [MCtrl] -> listMoveByPages (-0.5::Double) theList
         _ -> fallback e theList
+
+-- | Move the list selection to the first element in the list.
+listMoveToBeginning :: (Foldable t, Splittable t)
+                    => GenericList n t e
+                    -> GenericList n t e
+listMoveToBeginning = listMoveTo 0
+
+-- | Move the list selection to the last element in the list.
+listMoveToEnd :: (Foldable t, Splittable t)
+              => GenericList n t e
+              -> GenericList n t e
+listMoveToEnd l = listMoveTo (length $ listElements l) l
 
 -- | The top-level attribute used for the entire list.
 listAttr :: AttrName
