سؤال

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.

هل كانت مفيدة؟

المحلول

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

نصائح أخرى

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.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top