{-# LANGUAGE DeriveDataTypeable, FlexibleContexts, MultiParamTypeClasses, TypeSynonymInstances, PatternGuards #-}
----------------------------------------------------------------------------
-- |
-- Module : XMonad.Layout.Hidden
-- Copyright : (c) Peter Jones 2015
-- License : BSD3-style (see LICENSE)
--
-- Maintainer : pjones@devalot.com
-- Stability : unstable
-- Portability : not portable
--
-- Similar to "XMonad.Layout.Minimize" but completely removes windows
-- from the window set so "XMonad.Layout.BoringWindows" isn't
-- necessary. Perfect companion to
-- "XMonad.Layout.BinarySpacePartition" since it can be used to move
-- windows to another part of the BSP tree.
--
-----------------------------------------------------------------------------
module XMonad.Layout.Hidden
( -- * Usage
-- $usage
HiddenMsg (..)
, hiddenWindows
, hideWindow
, popOldestHiddenWindow
, popNewestHiddenWindow
) where
--------------------------------------------------------------------------------
import XMonad
import XMonad.Layout.LayoutModifier
import qualified XMonad.StackSet as W
--------------------------------------------------------------------------------
-- $usage
-- You can use this module with the following in your @~\/.xmonad\/xmonad.hs@:
--
-- > import XMonad.Layout.Hidden
--
-- Then edit your @layoutHook@ by adding the @HiddenWindows@ layout modifier:
--
-- > myLayout = hiddenWindows (Tall 1 (3/100) (1/2)) ||| Full ||| etc..
-- > main = xmonad def { layoutHook = myLayout }
--
-- For more detailed instructions on editing the layoutHook see:
--
-- "XMonad.Doc.Extending#Editing_the_layout_hook"
--
-- In the key bindings, do something like:
--
-- > , ((modMask, xK_backslash), withFocused hideWindow)
-- > , ((modMask .|. shiftMask, xK_backslash), popOldestHiddenWindow)
-- > ...
--
-- For detailed instruction on editing the key bindings see:
--
-- "XMonad.Doc.Extending#Editing_key_bindings".
--------------------------------------------------------------------------------
data HiddenWindows a = HiddenWindows [Window] deriving (Show, Read)
--------------------------------------------------------------------------------
-- | Messages for the @HiddenWindows@ layout modifier.
data HiddenMsg = HideWindow Window -- ^ Hide a window.
| PopNewestHiddenWindow -- ^ Restore window (FILO).
| PopOldestHiddenWindow -- ^ Restore window (FIFO).
deriving (Typeable, Eq)
instance Message HiddenMsg
--------------------------------------------------------------------------------
instance LayoutModifier HiddenWindows Window where
handleMess h@(HiddenWindows hidden) mess
| Just (HideWindow win) <- fromMessage mess = hideWindowMsg h win
| Just (PopNewestHiddenWindow) <- fromMessage mess = popNewestMsg h
| Just (PopOldestHiddenWindow) <- fromMessage mess = popOldestMsg h
| Just ReleaseResources <- fromMessage mess = doUnhook
| otherwise = return Nothing
where doUnhook = do mapM_ restoreWindow hidden
return Nothing
modifierDescription _ = "Hidden"
--------------------------------------------------------------------------------
-- | Apply the @HiddenWindows@ layout modifier.
hiddenWindows :: LayoutClass l Window => l Window -> ModifiedLayout HiddenWindows l Window
hiddenWindows = ModifiedLayout $ HiddenWindows []
--------------------------------------------------------------------------------
-- | Remove the given window from the current layout. It is placed in
-- list of hidden windows so it can be restored later.
hideWindow :: Window -> X ()
hideWindow = sendMessage . HideWindow
--------------------------------------------------------------------------------
-- | Restore a previously hidden window. Using this function will
-- treat the list of hidden windows as a FIFO queue. That is, the
-- first window hidden will be restored.
popOldestHiddenWindow :: X ()
popOldestHiddenWindow = sendMessage PopOldestHiddenWindow
--------------------------------------------------------------------------------
-- | Restore a previously hidden window. Using this function will
-- treat the list of hidden windows as a FILO queue. That is, the
-- most recently hidden window will be restored.
popNewestHiddenWindow :: X ()
popNewestHiddenWindow = sendMessage PopNewestHiddenWindow
--------------------------------------------------------------------------------
hideWindowMsg :: HiddenWindows a -> Window -> X (Maybe (HiddenWindows a))
hideWindowMsg (HiddenWindows hidden) win = do
windows (W.delete' win)
return . Just . HiddenWindows $ hidden ++ [win]
--------------------------------------------------------------------------------
popNewestMsg :: HiddenWindows a -> X (Maybe (HiddenWindows a))
popNewestMsg (HiddenWindows []) = return Nothing
popNewestMsg (HiddenWindows hidden) = do
let (win, rest) = (last hidden, init hidden)
restoreWindow win
return . Just . HiddenWindows $ rest
--------------------------------------------------------------------------------
popOldestMsg :: HiddenWindows a -> X (Maybe (HiddenWindows a))
popOldestMsg (HiddenWindows []) = return Nothing
popOldestMsg (HiddenWindows (win:rest)) = do
restoreWindow win
return . Just . HiddenWindows $ rest
--------------------------------------------------------------------------------
restoreWindow :: Window -> X ()
restoreWindow = windows . W.insertUp