{-# LANGUAGE DeriveDataTypeable #-}

-----------------------------------------------------------------------------
-- |
-- Module      :  XMonad.Util.SessionStart
-- Copyright   :  (c) Markus Ongyerth 2017
-- License     :  BSD3-style (see LICENSE)
--
-- Maintainer  :  markus@ongy.net
-- Stability   :  unstable
-- Portability :  not portable
--
-- A module for detectiong session startup.  Useful to start
-- status bars, compositors and session initialization.
-- This is a more general approach than spawnOnce and allows spawnOn etc.
-----------------------------------------------------------------------------

module XMonad.Util.SessionStart
    ( doOnce
    , isSessionStart
    , setSessionStarted
    )
where

import Control.Monad (when)
import Control.Applicative ((<$>))

import XMonad
import qualified XMonad.Util.ExtensibleState as XS

-- ---------------------------------------------------------------------
-- $usage
--
-- Add 'setSessionStarted' at the end of the 'startupHook' to set the
-- flag.
--
-- To do something only when the session is started up, use 
-- 'isSessionStart' to query or wrap it in 'doOnce' to only do it when
-- the flag isn't set.
-- ---------------------------------------------------------------------

data SessionStart = SessionStart { unSessionStart :: Bool }
    deriving (Read, Show, Typeable)

instance ExtensionClass SessionStart where
    initialValue = SessionStart True
    extensionType = PersistentExtension

-- | Use this to only do a part of your hook on session start
doOnce :: X () -> X ()
doOnce act = do
    startup <- isSessionStart
    when startup act

-- | Query if the current startup is the session start
isSessionStart :: X Bool
isSessionStart = unSessionStart <$> XS.get

-- This should become a noop/be deprecated when merged into master, and
-- the flag should be set when the state file is loaded.
-- | This currently has to be added to the end of the startup hook to
-- set the flag.
setSessionStarted :: X ()
setSessionStarted = XS.put $ SessionStart False