diff --git a/CHANGELOG b/CHANGELOG
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,3 +1,10 @@
+concurrent-output (1.10.9) unstable; urgency=medium
+
+  * waitDisplayChange would deadlock if the STM action passed to it did not
+    cause any changes to the display. That is now safe to do.
+
+ -- Joey Hess <id@joeyh.name>  Mon, 19 Nov 2018 18:40:55 -0400
+
 concurrent-output (1.10.8) unstable; urgency=medium
 
   * Fix bug in waitDisplayChange that could result in an STM deadlock
diff --git a/System/Console/Regions.hs b/System/Console/Regions.hs
--- a/System/Console/Regions.hs
+++ b/System/Console/Regions.hs
@@ -462,23 +462,27 @@
 displayChangeBarrier = unsafePerformIO $ newTVarIO 0
 
 -- | Runs a STM action, and waits for the display to be fully updated
--- before returning.
+-- with any changes that action makes to the displayed regions.
 waitDisplayChange :: STM a -> IO a
 waitDisplayChange a = do
-	r <- atomically a
 	c <- atomically $ dupTChan displayUpdateNotifier
-	b <- atomically $ do
+	bv <- newEmptyTMVarIO
+	setbarrier bv `concurrently` waitchange c bv
+	snd <$> atomically (readTMVar bv)
+  where
+	setbarrier bv = atomically $ do
 		!b <- succ <$> readTVar displayChangeBarrier
+		r <- a
 		writeTVar displayChangeBarrier b
-		return b
-	atomically $ waitchange c b
-	return r
-  where
-	waitchange c b = do
-		change <- readTChan c
+		putTMVar bv (b, r)
+	waitchange c bv = do
+		change <- atomically $ readTChan c
+		-- this blocks until the STM action has run, and the
+		-- barrier is set.
+		b <- fst <$> atomically (readTMVar bv)
 		case change of
 			DisplayChangeBarrier b' | b' >= b -> return ()
-			_ -> waitchange c b
+			_ -> waitchange c bv
 
 displayThread :: Bool -> TSem -> IO ()
 displayThread isterm endsignal = do
diff --git a/concurrent-output.cabal b/concurrent-output.cabal
--- a/concurrent-output.cabal
+++ b/concurrent-output.cabal
@@ -1,5 +1,5 @@
 Name: concurrent-output
-Version: 1.10.8
+Version: 1.10.9
 Cabal-Version: >= 1.8
 License: BSD2
 Maintainer: Joey Hess <id@joeyh.name>
diff --git a/stmdemo.hs b/stmdemo.hs
--- a/stmdemo.hs
+++ b/stmdemo.hs
@@ -15,9 +15,7 @@
 	ir <- infoRegion
 	cr <- clockRegion
 	rr <- rulerRegion
-	growingDots
-	runBash
-	growingDots
+	growingDots `concurrently` runBash
 	mapM_ closeConsoleRegion [ir, cr]
 
 titleRegion :: IO ConsoleRegion
@@ -83,6 +81,8 @@
 
 runBash :: IO ()
 runBash = do
+	-- Wait for growingDots to display some.
+	threadDelay 1000000
 	-- Temporarily clear whatever console regions are open.
 	rs <- waitDisplayChange $ swapTMVar regionList []
 	putStrLn "We interrupt this demo to run a shell prompt. exit to continue!"
