diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,6 +2,31 @@
 Brick changelog
 ---------------
 
+0.5
+---
+
+Functionality changes:
+ * Markup: make markup support multi-line strings (fixes #41)
+ * brick-edit-demo: support shift-tab to switch editors
+ * Core: improve box layout algorithm (when rendering boxes, track
+   remaining space while rendering high-priority children to use
+   successively more constrained primary dimensions)
+ * Core: make fixed padding take precedence over padded widgets (fixes #42)
+   Prior to this commit, padding a widget meant that if there was room
+   after rendering the widget, the specified amount of padding would be
+   added. This meant that under tight layout constraints padding would
+   disappear before a padded widget would. This is often a desirable
+   outcome but it also led to unexpected behavior when adding padding
+   to a widget that grows greedily: fixed padding would never show up
+   because it was placed in a box adjacent to the widget in question,
+   and boxes always render greedy children before fixed ones. As a
+   result fixed padding would disappear under these conditions. Instead,
+   in the case of fixed padding, since we often intend to *guarantee*
+   that padding is present, all of the padding combinators have been
+   modified so that when the padded widget is rendered with fixed
+   padding in the amount V, the widget is given V fewer rows/columns
+   when it is rendered so that the padding always has room.
+
 0.4.1
 -----
 
diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -86,10 +86,6 @@
 use that, you'll also be helping to test whether the exported interface
 is usable and complete!
 
-The development of this library has revealed some bugs in `vty`, and
-I've tried to report those as I go. If they haven't been resolved,
-you'll see them arise when using `brick`.
-
 Reporting bugs
 --------------
 
diff --git a/brick.cabal b/brick.cabal
--- a/brick.cabal
+++ b/brick.cabal
@@ -1,5 +1,5 @@
 name:                brick
-version:             0.4.1
+version:             0.5
 synopsis:            A declarative terminal user interface library
 description:
   Write terminal applications painlessly with 'brick'! You write an
diff --git a/programs/EditDemo.hs b/programs/EditDemo.hs
--- a/programs/EditDemo.hs
+++ b/programs/EditDemo.hs
@@ -60,6 +60,7 @@
     case ev of
         V.EvKey V.KEsc [] -> M.halt st
         V.EvKey (V.KChar '\t') [] -> M.continue $ switchEditors st
+        V.EvKey V.KBackTab [] -> M.continue $ switchEditors st
         _ -> M.continue =<< T.handleEventLensed st (currentEditorL st) ev
 
 initialState :: St
diff --git a/programs/MarkupDemo.hs b/programs/MarkupDemo.hs
--- a/programs/MarkupDemo.hs
+++ b/programs/MarkupDemo.hs
@@ -7,9 +7,12 @@
 import Brick.Main (App(..), defaultMain, resizeOrQuit, neverShowCursor)
 import Brick.Types
   ( Widget
+  , Padding(..)
   )
 import Brick.Widgets.Core
   ( (<=>)
+  , (<+>)
+  , padLeft
   )
 import Brick.Util (on, fg)
 import Brick.Markup (markup, (@?))
@@ -17,10 +20,11 @@
 import Data.Text.Markup ((@@))
 
 ui :: Widget
-ui = m1 <=> m2
+ui = (m1 <=> m2) <+> (padLeft (Pad 1) m3)
     where
         m1 = markup $ ("Hello" @@ fg V.blue) <> ", " <> ("world!" @@ fg V.red)
         m2 = markup $ ("Hello" @? "keyword1") <> ", " <> ("world!" @? "keyword2")
+        m3 = markup $ ("Hello," @? "keyword1") <> "\n" <> ("world!" @? "keyword2")
 
 theMap :: AttrMap
 theMap = attrMap V.defAttr
diff --git a/src/Brick/Markup.hs b/src/Brick/Markup.hs
--- a/src/Brick/Markup.hs
+++ b/src/Brick/Markup.hs
@@ -17,7 +17,7 @@
 import Data.Text.Markup
 import Data.Default (def)
 
-import Graphics.Vty (Attr, horizCat, string)
+import Graphics.Vty (Attr, vertCat, horizCat, string)
 
 import Brick.AttrMap
 import Brick.Types
@@ -47,8 +47,11 @@
 markup :: (Eq a, GetAttr a) => Markup a -> Widget
 markup m =
     Widget Fixed Fixed $ do
-      let pairs = markupToList m
-      imgs <- forM pairs $ \(t, aSrc) -> do
-          a <- getAttr aSrc
-          return $ string a $ T.unpack t
-      return $ def & imageL .~ horizCat imgs
+      let markupLines = markupToList m
+          mkLine pairs = do
+              is <- forM pairs $ \(t, aSrc) -> do
+                  a <- getAttr aSrc
+                  return $ string a $ T.unpack t
+              return $ horizCat is
+      lineImgs <- mapM mkLine markupLines
+      return $ def & imageL .~ vertCat lineImgs
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
@@ -153,7 +153,11 @@
           Max -> (id, Greedy)
           Pad i -> (hLimit i, hSize p)
     in Widget sz (vSize p) $ do
-        result <- render p
+        c <- getContext
+        let lim = case padding of
+              Max -> c^.availWidthL
+              Pad i -> c^.availWidthL - i
+        result <- render $ hLimit lim p
         render $ (f $ vLimit (result^.imageL.to V.imageHeight) $ fill ' ') <+>
                  (Widget Fixed Fixed $ return result)
 
@@ -166,7 +170,11 @@
           Max -> (id, Greedy)
           Pad i -> (hLimit i, hSize p)
     in Widget sz (vSize p) $ do
-        result <- render p
+        c <- getContext
+        let lim = case padding of
+              Max -> c^.availWidthL
+              Pad i -> c^.availWidthL - i
+        result <- render $ hLimit lim p
         render $ (Widget Fixed Fixed $ return result) <+>
                  (f $ vLimit (result^.imageL.to V.imageHeight) $ fill ' ')
 
@@ -178,7 +186,11 @@
           Max -> (id, Greedy)
           Pad i -> (vLimit i, vSize p)
     in Widget (hSize p) sz $ do
-        result <- render p
+        c <- getContext
+        let lim = case padding of
+              Max -> c^.availHeightL
+              Pad i -> c^.availHeightL - i
+        result <- render $ vLimit lim p
         render $ (f $ hLimit (result^.imageL.to V.imageWidth) $ fill ' ') <=>
                  (Widget Fixed Fixed $ return result)
 
@@ -191,7 +203,11 @@
           Max -> (id, Greedy)
           Pad i -> (vLimit i, vSize p)
     in Widget (hSize p) sz $ do
-        result <- render p
+        c <- getContext
+        let lim = case padding of
+              Max -> c^.availHeightL
+              Pad i -> c^.availHeightL - i
+        result <- render $ vLimit lim p
         render $ (Widget Fixed Fixed $ return result) <=>
                  (f $ hLimit (result^.imageL.to V.imageWidth) $ fill ' ')
 
@@ -344,7 +360,17 @@
       let pairsIndexed = zip [(0::Int)..] ws
           (his, lows) = partition (\p -> (primaryWidgetSize br $ snd p) == Fixed) pairsIndexed
 
-      renderedHis <- mapM (\(i, prim) -> (i,) <$> render prim) his
+      let availPrimary = c^.(contextPrimary br)
+          availSecondary = c^.(contextSecondary br)
+
+          renderHis _ prev [] = return prev
+          renderHis remainingPrimary prev ((i, prim):rest) = do
+              result <- render $ limitPrimary br remainingPrimary
+                               $ limitSecondary br availSecondary
+                               $ cropToContext prim
+              renderHis (remainingPrimary - (result^.imageL.(to $ imagePrimary br))) (prev ++ [(i, result)]) rest
+
+      renderedHis <- renderHis availPrimary [] his
 
       renderedLows <- case lows of
           [] -> return []
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
@@ -9,7 +9,7 @@
 module Brick.Widgets.List
   ( List(listElements, listSelected, listName, listItemHeight)
 
-  -- * Consructing a list
+  -- * Constructing a list
   , list
 
   -- * Rendering a list
@@ -139,11 +139,11 @@
 
             off = start * (l^.listItemHeightL)
 
-            drawnElements = (flip V.imap) es $ \i e ->
+            drawnElements = flip V.imap es $ \i e ->
                 let isSelected = Just (i + start) == l^.listSelectedL
                     elemWidget = drawElem isSelected e
                     makeVisible = if isSelected
-                                  then (visible . withDefAttr listSelectedAttr)
+                                  then visible . withDefAttr listSelectedAttr
                                   else id
                 in makeVisible elemWidget
 
@@ -180,13 +180,10 @@
                  | otherwise =
     let newSel = case l^.listSelectedL of
           Nothing -> 0
-          Just s  -> if pos == 0
-                     then 0
-                     else if pos == s
-                          then pos - 1
-                          else if pos < s
-                               then s - 1
-                               else s
+          Just s | pos == 0 -> 0
+                 | pos == s -> pos - 1
+                 | pos  < s -> s - 1
+                 | otherwise -> s
         (front, back) = V.splitAt pos es
         es' = front V.++ V.tail back
         es = l^.listElementsL
@@ -224,7 +221,7 @@
 listMoveTo :: Int -> List e -> List e
 listMoveTo pos l =
     let len = V.length (l^.listElementsL)
-        newSel = clamp 0 (len - 1) $ if pos < 0 then (len - pos) else pos
+        newSel = clamp 0 (len - 1) $ if pos < 0 then len - pos else pos
     in l & listSelectedL .~ if len > 0
                             then Just newSel
                             else Nothing
diff --git a/src/Data/Text/Markup.hs b/src/Data/Text/Markup.hs
--- a/src/Data/Text/Markup.hs
+++ b/src/Data/Text/Markup.hs
@@ -45,7 +45,7 @@
 
 -- | Extract the text from markup, discarding the markup metadata.
 toText :: (Eq a) => Markup a -> T.Text
-toText = T.concat . (fst <$>) . markupToList
+toText = T.concat . (fst <$>) . concat . markupToList
 
 -- | Set the metadata for a range of character positions in a piece of
 -- markup. This is useful for, e.g., syntax highlighting.
@@ -59,11 +59,17 @@
         (theOldEntries, theTail) = splitAt len theLongTail
         theNewEntries = zip (fst <$> theOldEntries) (repeat val)
 
--- | Convert markup to a list of pairs in which each pair contains the
--- longest subsequence of characters having the same metadata.
-markupToList :: (Eq a) => Markup a -> [(T.Text, a)]
-markupToList (Markup thePairs) = toList thePairs
+-- | Convert markup to a list of lines. Each line is represented by a
+-- list of pairs in which each pair contains the longest subsequence of
+-- characters having the same metadata.
+markupToList :: (Eq a) => Markup a -> [[(T.Text, a)]]
+markupToList (Markup thePairs) = toList <$> toLines [] [] thePairs
     where
+        toLines ls cur [] = ls ++ [cur]
+        toLines ls cur ((ch, val):rest)
+            | ch == '\n' = toLines (ls ++ [cur]) [] rest
+            | otherwise = toLines ls (cur ++ [(ch, val)]) rest
+
         toList [] = []
         toList ((ch, val):rest) = (T.pack $ ch : (fst <$> matching), val) : toList remaining
             where
