----------------------------------------------------------------------------- -- | -- Module : XMonad.Hooks.ServerMode -- Copyright : (c) Andrea Rossato and David Roundy 2007 -- License : BSD-style (see xmonad/LICENSE) -- -- Maintainer : andrea.rossato@unibz.it -- Stability : unstable -- Portability : unportable -- -- This is an 'EventHook' that will receive commands from an external -- client. -- -- This is the example of a client: -- -- > import Graphics.X11.Xlib -- > import Graphics.X11.Xlib.Extras -- > import System.Environment -- > import Data.Char -- > -- > usage :: String -> String -- > usage n = "Usage: " ++ n ++ " command number\nSend a command number to a running instance of XMonad" -- > -- > main :: IO () -- > main = do -- > args <- getArgs -- > pn <- getProgName -- > let com = case args of -- > [] -> error $ usage pn -- > w -> (w !! 0) -- > sendCommand com -- > -- > sendCommand :: String -> IO () -- > sendCommand s = do -- > d <- openDisplay "" -- > rw <- rootWindow d $ defaultScreen d -- > a <- internAtom d "XMONAD_COMMAND" False -- > allocaXEvent $ \e -> do -- > setEventType e clientMessage -- > setClientMessageEvent e rw a 32 (fromIntegral (read s)) currentTime -- > sendEvent d rw False structureNotifyMask e -- > sync d False -- -- compile with: @ghc --make sendCommand.hs@ -- -- run with -- -- > sendCommand command number -- -- For instance: -- -- > sendCommand 0 -- -- will ask to xmonad to print the list of command numbers in -- stderr (so you can read it in @~\/.xsession-errors@). ----------------------------------------------------------------------------- module XMonad.Hooks.ServerMode ( -- * Usage -- $usage ServerMode (..) , eventHook ) where import Control.Monad (when) import Data.List import System.IO import XMonad import XMonad.Actions.Commands import XMonad.Hooks.EventHook -- $usage -- You can use this module with the following in your -- @~\/.xmonad\/xmonad.hs@: -- -- > import XMonad.Hooks.ServerMode -- -- Then edit your @layoutHook@ by adding the 'eventHook': -- -- > layoutHook = eventHook ServerMode $ avoidStruts $ simpleTabbed ||| Full ||| etc.. -- -- and then: -- -- > main = xmonad defaultConfig { layoutHook = myLayouts } -- -- For more detailed instructions on editing the layoutHook see: -- -- "XMonad.Doc.Extending#Editing_the_layout_hook" data ServerMode = ServerMode deriving ( Show, Read ) instance EventHook ServerMode where handleEvent _ (ClientMessageEvent {ev_message_type = mt, ev_data = dt}) = do d <- asks display a <- io $ internAtom d "XMONAD_COMMAND" False when (mt == a && dt /= []) $ do cl <- defaultCommands let listOfCommands = map (uncurry (++)) . zip (map show ([1..] :: [Int])) . map ((++) " - " . fst) case lookup (fromIntegral (head dt) :: Int) (zip [1..] cl) of Just (c,_) -> runCommand' c Nothing -> mapM_ (io . hPutStrLn stderr) . listOfCommands $ cl handleEvent _ _ = return ()