53 lines
1.8 KiB
Haskell
53 lines
1.8 KiB
Haskell
-- | Send a special event as a signal to the window manager
|
|
-- Specifically, this is meant to be run after applications exit which
|
|
-- will allow xmonad to react to processes closing. It takes two
|
|
-- arguments: a string called the "magic string" up to 5 characters
|
|
-- and a string up to 15 characters called the "tag." These will be
|
|
-- concatenated and sent to xmonad in a ClientRequest event of type
|
|
-- BITMAP (which hopefully will never do anything) to the root window.
|
|
-- Operationally, the magic string is meant to be used to
|
|
-- differentiate this event and the tag is meant to be a signal to be
|
|
-- read by xmonad.
|
|
|
|
import Graphics.X11.Types
|
|
import Graphics.X11.Xlib.Atom
|
|
import Graphics.X11.Xlib.Display
|
|
import Graphics.X11.Xlib.Event
|
|
import Graphics.X11.Xlib.Extras
|
|
|
|
import System.Environment
|
|
import System.Exit
|
|
|
|
main :: IO ()
|
|
main = getArgs >>= parse
|
|
|
|
parse :: [String] -> IO ()
|
|
parse [magic, tag] = send magic tag >> exitSuccess
|
|
parse _ = exitFailure
|
|
|
|
send :: String -> String -> IO ()
|
|
send magic tag = do
|
|
dpy <- openDisplay ""
|
|
root <- rootWindow dpy $ defaultScreen dpy
|
|
allocaXEvent $ \e -> do
|
|
setEventType e clientMessage
|
|
-- NOTE: This function is written such that the penultimate
|
|
-- argument represents the first 40 bits of the 160 bit data
|
|
-- field, and it also only takes a decimal digit, which means the
|
|
-- string to be stored in the data field needs to be converted to
|
|
-- its decimal equivalent. The penultimate argument will be used
|
|
-- for the magic string and the last will be used for the tag.
|
|
setClientMessageEvent e root bITMAP 8 m t
|
|
sendEvent dpy root False substructureNotifyMask e
|
|
flush dpy
|
|
where
|
|
m = str2digit magic
|
|
t = str2digit tag
|
|
|
|
str2digit :: (Num a) => String -> a
|
|
str2digit = fromIntegral
|
|
. sum
|
|
. map (\(p, n) -> n * 256 ^ p)
|
|
. zip [0 :: Int ..]
|
|
. map fromEnum
|