diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,6 +2,13 @@
 Brick changelog
 ---------------
 
+0.14
+----
+
+This release added support for wide characters. In particular, wide
+characters can now be entered into the text editor widget and used in
+'str' and 'txt' widgets.
+
 0.13
 ----
 
diff --git a/brick.cabal b/brick.cabal
--- a/brick.cabal
+++ b/brick.cabal
@@ -1,5 +1,5 @@
 name:                brick
-version:             0.13
+version:             0.14
 synopsis:            A declarative terminal user interface library
 description:
   Write terminal applications painlessly with 'brick'! You write an
@@ -78,7 +78,7 @@
     Brick.Widgets.Internal
 
   build-depends:       base <= 5,
-                       vty >= 5.11.3,
+                       vty >= 5.12,
                        transformers,
                        data-default,
                        containers,
@@ -102,7 +102,7 @@
   main-is:             CacheDemo.hs
   build-depends:       base,
                        brick,
-                       vty >= 5.11.3,
+                       vty >= 5.12,
                        text,
                        microlens >= 0.3.0.0,
                        microlens-th
@@ -116,7 +116,7 @@
   main-is:             VisibilityDemo.hs
   build-depends:       base,
                        brick,
-                       vty >= 5.11.3,
+                       vty >= 5.12,
                        data-default,
                        text,
                        microlens >= 0.3.0.0,
@@ -132,7 +132,7 @@
   main-is:             ViewportScrollDemo.hs
   build-depends:       base,
                        brick,
-                       vty >= 5.11.3,
+                       vty >= 5.12,
                        data-default,
                        text,
                        microlens
@@ -146,7 +146,7 @@
   main-is:             DialogDemo.hs
   build-depends:       base <= 5,
                        brick,
-                       vty >= 5.11.3,
+                       vty >= 5.12,
                        data-default,
                        text,
                        microlens
@@ -160,7 +160,7 @@
   main-is:             MouseDemo.hs
   build-depends:       base <= 5,
                        brick,
-                       vty >= 5.11.3,
+                       vty >= 5.12,
                        data-default,
                        text,
                        microlens >= 0.3.0.0,
@@ -175,7 +175,7 @@
   main-is:             LayerDemo.hs
   build-depends:       base <= 5,
                        brick,
-                       vty >= 5.11.3,
+                       vty >= 5.12,
                        data-default,
                        text,
                        microlens >= 0.3.0.0,
@@ -190,7 +190,7 @@
   main-is:             SuspendAndResumeDemo.hs
   build-depends:       base <= 5,
                        brick,
-                       vty >= 5.11.3,
+                       vty >= 5.12,
                        data-default,
                        text,
                        microlens >= 0.3.0.0,
@@ -205,7 +205,7 @@
   main-is:             PaddingDemo.hs
   build-depends:       base <= 5,
                        brick,
-                       vty >= 5.11.3,
+                       vty >= 5.12,
                        data-default,
                        text,
                        microlens
@@ -219,7 +219,7 @@
   main-is:             AttrDemo.hs
   build-depends:       base <= 5,
                        brick,
-                       vty >= 5.11.3,
+                       vty >= 5.12,
                        data-default,
                        text,
                        microlens
@@ -233,7 +233,7 @@
   main-is:             MarkupDemo.hs
   build-depends:       base <= 5,
                        brick,
-                       vty >= 5.11.3,
+                       vty >= 5.12,
                        data-default,
                        text,
                        microlens
@@ -247,7 +247,7 @@
   main-is:             ListDemo.hs
   build-depends:       base <= 5,
                        brick,
-                       vty >= 5.11.3,
+                       vty >= 5.12,
                        data-default,
                        text,
                        microlens >= 0.3.0.0,
@@ -262,7 +262,7 @@
   main-is:             CustomEventDemo.hs
   build-depends:       base <= 5,
                        brick,
-                       vty >= 5.11.3,
+                       vty >= 5.12,
                        data-default,
                        text,
                        microlens >= 0.3.0.0,
@@ -277,7 +277,7 @@
   main-is:             HelloWorldDemo.hs
   build-depends:       base <= 5,
                        brick,
-                       vty >= 5.11.3,
+                       vty >= 5.12,
                        data-default,
                        text,
                        microlens
@@ -291,7 +291,7 @@
   main-is:             EditDemo.hs
   build-depends:       base <= 5,
                        brick,
-                       vty >= 5.11.3,
+                       vty >= 5.12,
                        data-default,
                        text,
                        vector,
@@ -308,7 +308,7 @@
   main-is:             BorderDemo.hs
   build-depends:       base <= 5,
                        brick,
-                       vty >= 5.11.3,
+                       vty >= 5.12,
                        data-default,
                        text,
                        microlens
@@ -323,7 +323,7 @@
   main-is:             ProgressBarDemo.hs
   build-depends:       base <= 5,
                        brick,
-                       vty >= 5.5.0,
+                       vty >= 5.12,
                        data-default,
                        text,
                        microlens
diff --git a/programs/MouseDemo.hs b/programs/MouseDemo.hs
--- a/programs/MouseDemo.hs
+++ b/programs/MouseDemo.hs
@@ -3,8 +3,6 @@
 module Main where
 
 import Control.Applicative ((<$>))
-import Control.Concurrent (newChan)
-import Data.Monoid ((<>))
 import Lens.Micro ((^.), (&), (.~))
 import Lens.Micro.TH (makeLenses)
 import Control.Monad (void)
diff --git a/src/Brick/Main.hs b/src/Brick/Main.hs
--- a/src/Brick/Main.hs
+++ b/src/Brick/Main.hs
@@ -346,7 +346,7 @@
                                         rs
         picWithCursor = case theCursor of
             Nothing -> pic { picCursor = NoCursor }
-            Just cloc -> pic { picCursor = Cursor (cloc^.columnL) (cloc^.rowL) }
+            Just cloc -> pic { picCursor = AbsoluteCursor (cloc^.columnL) (cloc^.rowL) }
 
     update vty picWithCursor
 
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
@@ -1,12 +1,14 @@
 {-# LANGUAGE RankNTypes #-}
 {-# LANGUAGE TupleSections #-}
 {-# LANGUAGE MultiParamTypeClasses #-}
+{-# LANGUAGE FlexibleInstances #-}
 -- | This module provides the core widget combinators and rendering
 -- routines. Everything this library does is in terms of these basic
 -- primitives.
 module Brick.Widgets.Core
   ( -- * Basic rendering primitives
-    emptyWidget
+    TextWidth(..)
+  , emptyWidget
   , raw
   , txt
   , str
@@ -88,6 +90,7 @@
 import Control.Monad.Trans.State.Lazy
 import Control.Monad.Trans.Reader
 import Control.Monad.Trans.Class (lift)
+import qualified Data.Foldable as F
 import qualified Data.Text as T
 import Data.Default
 import qualified Data.Map as M
@@ -104,6 +107,19 @@
 import Brick.AttrMap
 import Brick.Widgets.Internal
 
+-- | The class of text types that have widths measured in terminal
+-- columns. NEVER use 'length' etc. to measure the length of a string if
+-- you need to compute how much screen space it will occupy; always use
+-- 'textWidth'.
+class TextWidth a where
+    textWidth :: a -> Int
+
+instance TextWidth T.Text where
+    textWidth = V.wcswidth . T.unpack
+
+instance (F.Foldable f) => TextWidth (f Char) where
+    textWidth = V.wcswidth . F.toList
+
 -- | The class of types that store interface element names.
 class Named a n where
     -- | Get the name of the specified value.
@@ -164,6 +180,19 @@
 unrestricted :: Int
 unrestricted = 100000
 
+-- | Take a substring capable of fitting into the number of specified
+-- columns. This function takes character column widths into
+-- consideration.
+takeColumns :: Int -> String -> String
+takeColumns _ "" = ""
+takeColumns numCols (c:cs) =
+    let w = V.safeWcwidth c
+    in if w == numCols
+       then [c]
+       else if w < numCols
+            then c : takeColumns (numCols - w) cs
+            else ""
+
 -- | Build a widget from a 'String'. Breaks newlines up and space-pads
 -- short lines out to the length of the longest line.
 str :: String -> Widget n
@@ -173,14 +202,14 @@
       let theLines = fixEmpty <$> (dropUnused . lines) s
           fixEmpty [] = " "
           fixEmpty l = l
-          dropUnused l = take (availWidth c) <$> take (availHeight c) l
+          dropUnused l = takeColumns (availWidth c) <$> take (availHeight c) l
       case force theLines of
           [] -> return def
           [one] -> return $ def & imageL .~ (V.string (c^.attrL) one)
           multiple ->
-              let maxLength = maximum $ length <$> multiple
+              let maxLength = maximum $ V.safeWcswidth <$> multiple
                   lineImgs = lineImg <$> multiple
-                  lineImg lStr = V.string (c^.attrL) (lStr ++ replicate (maxLength - length lStr) ' ')
+                  lineImg lStr = V.string (c^.attrL) (lStr ++ replicate (maxLength - V.safeWcswidth lStr) ' ')
               in return $ def & imageL .~ (V.vertCat lineImgs)
 
 -- | Build a widget from a one-line 'T.Text' value. Behaves the same as
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
@@ -45,7 +45,6 @@
 import Brick.Widgets.Core
 import Brick.AttrMap
 
-
 -- | Editor state.  Editors support the following events by default:
 --
 -- * Ctrl-a: go to beginning of line
@@ -148,7 +147,7 @@
 getEditContents e = Z.getText $ e^.editContentsL
 
 -- | Turn an editor state value into a widget
-renderEditor :: (Ord n, Show n, Monoid t)
+renderEditor :: (Ord n, Show n, Monoid t, TextWidth t, Z.GenericTextZipper t)
              => Bool
              -- ^ Whether the editor has focus. It will report a cursor
              -- position if and only if it has focus.
@@ -156,15 +155,28 @@
              -- ^ The editor.
              -> Widget n
 renderEditor foc e =
-    let cp = Z.cursorPosition $ e^.editContentsL
-        cursorLoc = Location (cp^._2, cp^._1)
+    let cp = Z.cursorPosition z
+        z = e^.editContentsL
+        toLeft = Z.take (cp^._2) (Z.currentLine z)
+        cursorLoc = Location (textWidth toLeft, cp^._1)
         limit = case e^.editContentsL.to Z.getLineLimit of
             Nothing -> id
             Just lim -> vLimit lim
+        atChar = charAtCursor $ e^.editContentsL
+        atCharWidth = maybe 1 textWidth atChar
     in withAttr (if foc then editFocusedAttr else editAttr) $
        limit $
        viewport (e^.editorNameL) Both $
        (if foc then showCursor (e^.editorNameL) cursorLoc else id) $
-       visibleRegion cursorLoc (1, 1) $
+       visibleRegion cursorLoc (atCharWidth, 1) $
        e^.editDrawContentsL $
        getEditContents e
+
+charAtCursor :: (Z.GenericTextZipper t) => Z.TextZipper t -> Maybe t
+charAtCursor z =
+    let col = snd $ Z.cursorPosition z
+        curLine = Z.currentLine z
+        toRight = Z.drop col curLine
+    in if Z.length toRight > 0
+       then Just $ Z.take 1 toRight
+       else Nothing
diff --git a/src/Brick/Widgets/ProgressBar.hs b/src/Brick/Widgets/ProgressBar.hs
--- a/src/Brick/Widgets/ProgressBar.hs
+++ b/src/Brick/Widgets/ProgressBar.hs
@@ -11,6 +11,7 @@
 import Lens.Micro ((^.))
 import Data.Maybe (fromMaybe)
 import Data.Monoid
+import Graphics.Vty (safeWcswidth)
 
 import Brick.Types
 import Brick.AttrMap
@@ -38,12 +39,12 @@
         c <- getContext
         let barWidth = c^.availWidthL
             label = fromMaybe "" mLabel
-            labelWidth = length label
+            labelWidth = safeWcswidth label
             spacesWidth = barWidth - labelWidth
             leftPart = replicate (spacesWidth `div` 2) ' '
             rightPart = replicate (barWidth - (labelWidth + length leftPart)) ' '
             fullBar = leftPart <> label <> rightPart
-            completeWidth = round $ progress * toEnum barWidth
+            completeWidth = round $ progress * toEnum (length fullBar)
             completePart = take completeWidth fullBar
             incompletePart = drop completeWidth fullBar
         render $ (withAttr progressCompleteAttr $ str completePart) <+>
