Question

I would like to configure XMonad so that a certain IO () function is evaluated whenever a window is focused, so that I can change some aspects of the environment depending on which window this was. I can't seem to find anything about this in the docs, but I'm sure it exists so presumably I'm looking for the wrong keyword.

Was it helpful?

Solution

The closest thing is probably logHook :: !(X ()) in the XConfig. You can get the focused window and run your IO action to update the environment, but this hook is described as "The action to perform when the window set is changed", so your updateEnv could be called multiple times in a row with the same window ID (when you swap windows without changing focus, for example).

myLogHook = gets (peek . windowset) >>= liftIO . updateEnv
  where
    updateEnv :: Maybe Window -> IO ()
    updateEnv = undefined

OTHER TIPS

You probably want to customize handleEventHook.

Something like this :

myEventHook e@(CrossingEvent {ev_event_type=t, ev_window=win}) 
        | t == enterNotify = do 
                   something with win
                   return $ All True
        | t == leaveNotify = do 
                   something else
                   return $ All True
        | otherwise = return $ All True

Thanks to the previous options, I built my own. @Leiza, I found how to use clientMask:

import XMonad
-- import Data.Monoid (All(..))
import Control.Monad (when)
...
hook :: Event -> X All
hook (AnyEvent {ev_event_type = et}) = do
  when (et == focusOut) $
    <action>
  return (All True)
hook _ = return (All True)
...
main = do
...
  clientMask = focusChangeMask .|. clientMask def
...

@Leiza was right, for me CrossingEvents not works properly.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top