X.U.Hacks: Add "Stacking trays (trayer) above panels (xmobar)"

This commit is contained in:
Tomas Janousek
2021-03-22 10:30:18 +00:00
parent b6bd6f6d9d
commit 6d42c540a5

View File

@@ -27,12 +27,17 @@ module XMonad.Util.Hacks (
-- * Java Hack
-- $java
javaHack,
-- * Stacking trays (trayer) above panels (xmobar)
-- $raiseTrayer
trayerAboveXmobarEventHook,
trayAbovePanelEventHook,
) where
import XMonad
import Data.Monoid (All(All))
import Control.Monad (when)
import Control.Monad (when, filterM)
import System.Posix.Env (putEnv)
@@ -93,3 +98,49 @@ javaHack conf = conf
{ startupHook = startupHook conf
*> io (putEnv "_JAVA_AWT_WM_NONREPARENTING=1")
}
-- $raiseTrayer
-- Placing @trayer@ on top of @xmobar@ is somewhat tricky:
--
-- - they both should be lowered to the bottom of the stacking order to avoid
-- overlapping fullscreen windows
--
-- - the tray needs to be stacked on top of the panel regardless of which
-- happens to start first
--
-- 'trayerAboveXmobarEventHook' (and the more generic
-- 'trayAbovePanelEventHook') is an event hook that ensures the latter:
-- whenever the tray lowers itself to the bottom of the stack, it checks
-- whether there are any panels above it and lowers these again.
--
-- To ensure the former, that is having both @trayer@ and @xmobar@ lower
-- themselves, which is a necessary prerequisite for this event hook to
-- trigger:
--
-- - set @lowerOnStart = True@ and @overrideRedirect = True@ in @~/.xmobarrc@
-- - pass @-l@ to @trayer@
--
-- Usage:
--
-- > handleEventHook = … <> Hacks.trayerAboveXmobarEventHook
-- | 'trayAbovePanelEventHook' for trayer/xmobar
trayerAboveXmobarEventHook :: Event -> X All
trayerAboveXmobarEventHook = trayAbovePanelEventHook (className =? "trayer") (appName =? "xmobar")
-- | Whenever a tray window lowers itself to the bottom of the stack, look for
-- any panels above it and lower these.
trayAbovePanelEventHook
:: Query Bool -- ^ tray
-> Query Bool -- ^ panel
-> (Event -> X All) -- ^ event hook
trayAbovePanelEventHook trayQ panelQ ConfigureEvent{ev_window = w, ev_above = a} | a == none = do
whenX (runQuery trayQ w) $ withDisplay $ \dpy -> do
rootw <- asks theRoot
(_, _, ws) <- io $ queryTree dpy rootw
let aboveTrayWs = dropWhile (w /=) ws
panelWs <- filterM (runQuery panelQ) aboveTrayWs
mapM_ (io . lowerWindow dpy) panelWs
mempty
trayAbovePanelEventHook _ _ _ = mempty