------------------------------------------------------------------------------
-- |
-- Module      :  ScratchpadPrime 
-- Copyright   :  (c) Mads N Noe 2009
-- Maintainer  :  mntnoe (@) gmail.com
-- License     :  as-is
-- 
-- A modified scatchpad which uses GNU Screen to detach the window rather than
-- putting it on a hidden workspace.  This makes cycling between workspaces
-- easy, as there is no need for a dummy workspace to store the terminal when
-- hidden.
-- 
------------------------------------------------------------------------------

module ScratchpadPrime (
    scratchpad'
  ) where

-- Haskell modules
import Control.Monad

-- XMonad modules
import XMonad
import qualified XMonad.StackSet as W

-- | A modified scatchpad which uses GNU Screen to detach the
--   window rather than putting it on a hidden workspace.
scratchpad' :: Query Bool -> String -> X ()
scratchpad' q cmd = withWindowSet $ \s -> do
  filterCurrent <- filterM (runQuery $ q) 
                     $ (maybe [] W.integrate 
                        . W.stack 
                        . W.workspace 
                        . W.current) s
  case filterCurrent of
    (x:_) -> kill' x
    []    -> do
      filterAll <- filterM (runQuery $ q) $ W.allWindows s
      case filterAll of
        (x:_) -> windows (W.shiftWin (W.currentTag s) x)
        -- no need to 'sleep 0.2' here, as window isn't resized
        []    -> spawn cmd

-- | As 'kill', but kill a given window (rather than killing the focused window).
kill' :: Window ->X ()
kill' w = withDisplay $ \d -> do
    wmdelt <- atom_WM_DELETE_WINDOW  ;  wmprot <- atom_WM_PROTOCOLS

    protocols <- io $ getWMProtocols d w
    io $ if wmdelt `elem` protocols
        then allocaXEvent $ \ev -> do
                setEventType ev clientMessage
                setClientMessageEvent ev w wmprot 32 wmdelt 0
                sendEvent d w False noEventMask ev
        else killClient d w >> return ()

