@@ -33,6 +33,7 @@
3333module Graphics.Vty
3434 ( Vty(..)
3535 , mkVty
36+ , setWindowTitle
3637 , Mode(..)
3738 , module Graphics.Vty.Config
3839 , module Graphics.Vty.Input
@@ -54,6 +55,9 @@ import Graphics.Vty.Attributes
5455import Graphics.Vty.UnicodeWidthTable.IO
5556import Graphics.Vty.UnicodeWidthTable.Install
5657
58+import Data.Char (isPrint, showLitChar)
59+import qualified Data.ByteString.Char8 as BS8
60+
5761import qualified Control.Exception as E
5862import Control.Monad (when)
5963import Control.Concurrent.STM
@@ -224,3 +228,24 @@ internalMkVty input out = do
224228 , shutdown = shutdownIo
225229 , isShutdown = shutdownStatus
226230 }
231+
232+-- | Set the terminal window title string.
233+--
234+-- This function emits an Xterm-compatible escape sequence that we
235+-- anticipate will work for essentially all modern terminal emulators.
236+-- Ideally we'd use a terminal capability for this, but there does not
237+-- seem to exist a termcap for setting window titles. If you find that
238+-- this function does not work for a given terminal emulator, please
239+-- report the issue.
240+--
241+-- For details, see:
242+--
243+-- https://tldp.org/HOWTO/Xterm-Title-3.html
244+setWindowTitle :: Vty -> String -> IO ()
245+setWindowTitle vty title = do
246+ let sanitize :: String -> String
247+ sanitize = concatMap sanitizeChar
248+ sanitizeChar c | not (isPrint c) = showLitChar c ""
249+ | otherwise = [c]
250+ let buf = BS8.pack $ "\ESC]2;" <> sanitize title <> "\007"
251+ outputByteBuffer (outputIface vty) buf