dynamicLogString forces its result and recovers

Originally, `dynamicLogString` could have a bottom hidden in it and
thereby crash the `logHook`. Under some circumstances (see #801)
this could cause xmonad to get stuck. We now force the result, and
`dynamicLogString` catches the exception and substitutes a
message (currently "_|_"). Use `dynamicLogString'` for the old behavior.
This commit is contained in:
brandon s allbery kf8nh 2023-02-20 15:40:30 -05:00
parent 29f0e03256
commit 4a97716d59
No known key found for this signature in database
GPG Key ID: 227EE1942B0BDB95
2 changed files with 17 additions and 2 deletions

View File

@ -100,6 +100,12 @@
### Bug Fixes and Minor Changes
* `XMonad.Hooks.StatusBar.PP`
- `dynamicLogString` now forces its result and produces an error string if
it throws an exception. Use `dynamicLogString'` if for some reason you
need the old behavior.
* `XMonad.Util.EZConfig`
- Added `remapKeysP`, which remaps keybindings from one binding to

View File

@ -32,6 +32,7 @@ module XMonad.Hooks.StatusBar.PP (
-- * Build your own formatter
PP(..), def,
dynamicLogString,
dynamicLogString',
dynamicLogWithPP,
-- * Predicates and formatters
@ -55,6 +56,7 @@ module XMonad.Hooks.StatusBar.PP (
) where
import Control.Monad.Reader
import Control.DeepSeq
import XMonad
import XMonad.Prelude
@ -181,7 +183,14 @@ dynamicLogWithPP pp = dynamicLogString pp >>= io . ppOutput pp
-- allow for further processing, or use in some application other than
-- a status bar.
dynamicLogString :: PP -> X String
dynamicLogString pp = do
dynamicLogString pp = userCodeDef "_|_" (dynamicLogString' pp)
-- | The guts of 'dynamicLogString'. Forces the result, so it may throw
-- an exception (most commonly because 'ppOrder' is non-total). Use
-- 'dynamicLogString' for a version that catches the exception and
-- produces an error string.
dynamicLogString' :: PP -> X String
dynamicLogString' pp = do
winset <- gets windowset
urgents <- readUrgents
@ -199,7 +208,7 @@ dynamicLogString pp = do
-- window title
wt <- maybe (pure "") (fmap show . getName) . S.peek $ winset
return $ sepBy (ppSep pp) . ppOrder pp $
return $! force $ sepBy (ppSep pp) . ppOrder pp $
[ ws
, ppLayout pp ld
, ppTitle pp $ ppTitleSanitize pp wt