-----------------------------------------------------------------------------
-- |
-- Module      : XMonad.Util.NoTaskbar
-- Description : Mark a window to be ignored by EWMH taskbars and pagers.
-- Copyright   : (c) ???
-- License     : BSD3-style (see LICENSE)
--
-- Maintainer  : ???
--
-- Function and manageHook to mark a window to be ignored by EWMH
-- taskbars and pagers.
--
-----------------------------------------------------------------------------

module XMonad.Util.NoTaskbar (-- * Usage
                              -- $usage
                              noTaskbar
                             ,markNoTaskbar) where

import XMonad.Core
import XMonad.Prelude (fi)
import XMonad.ManageHook
import Graphics.X11.Xlib (Window)
import Graphics.X11.Xlib.Atom (aTOM)
import Graphics.X11.Xlib.Extras (changeProperty32
                                ,propModePrepend)
import Control.Monad.Reader (ask)

-- $usage
-- Utility functions to hide windows from pagers and taskbars. Mostly useful
-- when EWMH doesn't do what you intend (e.g. for 'NamedScratchpad' windows you
-- probably don't want to be dumped into the 'NSP' workspace).

-- | A 'ManageHook' to mark a window to not be shown in pagers or taskbars.
noTaskbar :: ManageHook
noTaskbar :: Query (Endo WindowSet)
noTaskbar = Query Atom
forall r (m :: * -> *). MonadReader r m => m r
ask Query Atom
-> (Atom -> Query (Endo WindowSet)) -> Query (Endo WindowSet)
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= (Query () -> Query (Endo WindowSet) -> Query (Endo WindowSet)
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Query (Endo WindowSet)
forall m. Monoid m => m
idHook) (Query () -> Query (Endo WindowSet))
-> (Atom -> Query ()) -> Atom -> Query (Endo WindowSet)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. X () -> Query ()
forall a. X a -> Query a
liftX (X () -> Query ()) -> (Atom -> X ()) -> Atom -> Query ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Atom -> X ()
markNoTaskbar

-- | An 'X' action to mark a window to not be shown in pagers or taskbars.
markNoTaskbar :: Window -> X ()
markNoTaskbar :: Atom -> X ()
markNoTaskbar Atom
w = (Display -> X ()) -> X ()
forall a. (Display -> X a) -> X a
withDisplay ((Display -> X ()) -> X ()) -> (Display -> X ()) -> X ()
forall a b. (a -> b) -> a -> b
$ \Display
d -> do
                    Atom
ws <- String -> X Atom
getAtom String
"_NET_WM_STATE"
                    Atom
ntb <- String -> X Atom
getAtom String
"_NET_WM_STATE_SKIP_TASKBAR"
                    Atom
npg <- String -> X Atom
getAtom String
"_NET_WM_STATE_SKIP_PAGER"
                    IO () -> X ()
forall (m :: * -> *) a. MonadIO m => IO a -> m a
io (IO () -> X ()) -> IO () -> X ()
forall a b. (a -> b) -> a -> b
$ Display -> Atom -> Atom -> Atom -> CInt -> [CLong] -> IO ()
changeProperty32 Display
d Atom
w Atom
ws Atom
aTOM CInt
propModePrepend [Atom -> CLong
forall a b. (Integral a, Num b) => a -> b
fi Atom
ntb,Atom -> CLong
forall a b. (Integral a, Num b) => a -> b
fi Atom
npg]