diff options
| -rw-r--r-- | changelog.md | 1 | ||||
| -rw-r--r-- | src/Xmobar/X11/XRender.hsc | 38 |
2 files changed, 23 insertions, 16 deletions
diff --git a/changelog.md b/changelog.md index aeb07e3..bc56e1d 100644 --- a/changelog.md +++ b/changelog.md @@ -1,5 +1,6 @@ ## Version 0.51 (unrelease) +- Fix BadDrawable crash when wallpaper setters free the root pixmap while alpha is 255 - base dependency relaxed to 4.21 ## Version 0.50 (June, 2025) diff --git a/src/Xmobar/X11/XRender.hsc b/src/Xmobar/X11/XRender.hsc index 5ad0391..4e4d448 100644 --- a/src/Xmobar/X11/XRender.hsc +++ b/src/Xmobar/X11/XRender.hsc @@ -91,22 +91,28 @@ drawBackground d p bgc alpha (Rectangle x y wid ht) = do withRenderFill d (XRenderColor 0 0 0 (257 * alpha)) (render pictOpSrc bgfill pic) - -- Handle transparency - internAtom d "_XROOTPMAP_ID" False >>= \xid -> - let xroot = defaultRootWindow d in - alloca $ \x1 -> - alloca $ \x2 -> - alloca $ \x3 -> - alloca $ \x4 -> - alloca $ \pprop -> do - xGetWindowProperty d xroot xid 0 1 False 20 x1 x2 x3 x4 pprop - prop <- peek pprop - when (prop /= nullPtr) $ do - rootbg <- peek (castPtr prop) :: IO Pixmap - xFree prop - withRenderPicture d rootbg $ \bgpic -> - withRenderFill d (XRenderColor 0 0 0 (0xFFFF - 257 * alpha)) - (render pictOpAdd bgpic pic) + -- Handle pseudo-transparency by compositing the root pixmap. + -- Skip entirely when alpha == 255 (fully opaque) since the blend + -- factor would be zero, making this a no-op. More importantly, + -- the root pixmap (_XROOTPMAP_ID) can be freed at any time by + -- wallpaper setters like feh (via XKillClient), causing a + -- BadDrawable crash in XRenderCreatePicture if we touch it. + when (alpha < 255) $ + internAtom d "_XROOTPMAP_ID" False >>= \xid -> + let xroot = defaultRootWindow d in + alloca $ \x1 -> + alloca $ \x2 -> + alloca $ \x3 -> + alloca $ \x4 -> + alloca $ \pprop -> do + xGetWindowProperty d xroot xid 0 1 False 20 x1 x2 x3 x4 pprop + prop <- peek pprop + when (prop /= nullPtr) $ do + rootbg <- peek (castPtr prop) :: IO Pixmap + xFree prop + withRenderPicture d rootbg $ \bgpic -> + withRenderFill d (XRenderColor 0 0 0 (0xFFFF - 257 * alpha)) + (render pictOpAdd bgpic pic) -- | Parses color into XRender color (allocation not necessary!) parseRenderColor :: Display -> String -> IO XRenderColor |
