{-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE LambdaCase #-} {-# LANGUAGE DeriveDataTypeable #-} ----------------------------------------------------------------------------- -- | -- Module : XMonad.Hooks.FocusSwitch -- Copyright : (c) Dmitry Bogatov -- License : GNU GPL3+ -- -- Maintainer : Dmitry Bogatov -- Stability : unstable -- Portability : unportable -- -- Log hook, that will be run, when focused 'Window' is changed. ----------------------------------------------------------------------------- module XMonad.Hooks.FocusSwitch (-- * Usage -- $usage focusSwitch) where import XMonad.StackSet import XMonad hiding (focus) import Control.Applicative import qualified XMonad.Util.ExtensibleState as XS import Control.Monad -- $usage -- Provides easy way to specify actions to perform on window focus switch. -- -- > defaultConfig { logHook = focusSwitch myFocusSwitchHandler } -- > -- > myFocusSwitchHandler :: Maybe Window -> X () -- > myFocusSwitchHandler = -- -- > -- > Window is in Maybe, since no window may be focused (i.e empty workspace) newtype FocusedWindow = FocusedWindow { unpackWindow :: Window } deriving (Typeable, Eq) -- Complement to unpackWindow. Newtype instance is too overloaded and -- would require explicit signatures in every touch with ExtensibleState. packWindow :: Window -> FocusedWindow packWindow = FocusedWindow instance ExtensionClass (Maybe FocusedWindow) where initialValue = Nothing prevFocused :: X (Maybe Window) prevFocused = XS.gets (fmap unpackWindow) curFocused :: X (Maybe Window) curFocused = fmap focus . stack . workspace . current . windowset <$> get focusSwitch :: (Maybe Window -> X ()) -> X () focusSwitch f = do prev <- prevFocused cur <- curFocused when (cur /= prev) $ XS.put (packWindow <$> cur) >> f cur