diff options
author | Jan Vornberger <jan.vornberger@informatik.uni-oldenburg.de> | 2009-11-15 19:48:33 +0100 |
---|---|---|
committer | Jan Vornberger <jan.vornberger@informatik.uni-oldenburg.de> | 2009-11-15 19:48:33 +0100 |
commit | a64225bbe26df7d9873ac1d4c8143e3146045b7a (patch) | |
tree | 03ca9312a6fa32bd143562645d6373b8c75e88f2 /XMonad/Hooks | |
parent | 77bfd730a1a6f970a22c4c06cce0506101470ffd (diff) | |
download | XMonadContrib-a64225bbe26df7d9873ac1d4c8143e3146045b7a.tar.gz XMonadContrib-a64225bbe26df7d9873ac1d4c8143e3146045b7a.tar.xz XMonadContrib-a64225bbe26df7d9873ac1d4c8143e3146045b7a.zip |
PositionStoreFloat - a floating layout with support hooks
Ignore-this: 8b1d0fcef1465356d72cb5f1f32413b6
darcs-hash:20091115184833-594c5-9534e1ec9be959d18713bfdd1edbc1f5995cc4a8.gz
Diffstat (limited to 'XMonad/Hooks')
-rw-r--r-- | XMonad/Hooks/PositionStoreHooks.hs | 98 |
1 files changed, 98 insertions, 0 deletions
diff --git a/XMonad/Hooks/PositionStoreHooks.hs b/XMonad/Hooks/PositionStoreHooks.hs new file mode 100644 index 0000000..92ad0ae --- /dev/null +++ b/XMonad/Hooks/PositionStoreHooks.hs @@ -0,0 +1,98 @@ +{-# LANGUAGE PatternSignatures #-} + +---------------------------------------------------------------------------- +-- | +-- Module : XMonad.Hooks.PositionStoreHooks +-- Copyright : (c) Jan Vornberger 2009 +-- License : BSD3-style (see LICENSE) +-- +-- Maintainer : jan.vornberger@informatik.uni-oldenburg.de +-- Stability : unstable +-- Portability : not portable +-- +-- This module contains two hooks for the +-- PositionStore (see "XMonad.Util.PositionStore") - a ManageHook and +-- an EventHook. +-- +-- The ManageHook can be used to fill the PositionStore with position and size +-- information about new windows. The advantage of using this hook is, that the +-- information is recorded independent of the currently active layout. So the +-- floating shape of the window can later be restored even if it was opened in a +-- tiled layout initially. +-- +-- For windows, that do not request a particular position, a random position will +-- be assigned. This prevents windows from piling up exactly on top of each other. +-- +-- The EventHook makes sure that windows are deleted from the PositionStore +-- when they are closed. +-- +----------------------------------------------------------------------------- + +module XMonad.Hooks.PositionStoreHooks ( + -- * Usage + -- $usage + positionStoreManageHook, + positionStoreEventHook + ) where + +import XMonad +import qualified XMonad.StackSet as W +import XMonad.Util.PositionStore + +import System.Random(randomRIO) +import Control.Applicative((<$>)) +import Control.Monad(when) +import Data.Maybe +import Data.Monoid + +-- $usage +-- You can use this module with the following in your @~\/.xmonad\/xmonad.hs@: +-- +-- > import XMonad.Hooks.PositionStoreHooks +-- +-- and adding 'positionStoreManageHook' to your 'ManageHook' as well +-- as 'positionStoreEventHook' to your event hooks: +-- +-- > myManageHook = positionStoreManageHook <+> manageHook defaultConfig +-- > myHandleEventHook = positionStoreEventHook +-- > +-- > main = xmonad defaultConfig { manageHook = myManageHook +-- > , handleEventHook = myHandleEventHook +-- > } +-- + +positionStoreManageHook :: ManageHook +positionStoreManageHook = ask >>= liftX . positionStoreInit >> idHook + +positionStoreInit :: Window -> X () +positionStoreInit w = withDisplay $ \d -> do + wa <- io $ getWindowAttributes d w + ws <- gets windowset + arbitraryOffsetX <- randomIntOffset + arbitraryOffsetY <- randomIntOffset + if (wa_x wa == 0) && (wa_y wa == 0) + then do + let sr@(Rectangle srX srY _ _) = screenRect . W.screenDetail . W.current $ ws + modifyPosStore (\ps -> posStoreInsert ps w + (Rectangle (srX + fi arbitraryOffsetX) + (srY + fi arbitraryOffsetY) + (fi $ wa_width wa) + (fi $ wa_height wa)) sr ) + else do + sc <- fromMaybe (W.current ws) <$> pointScreen (fi $ wa_x wa) (fi $ wa_y wa) + let sr = screenRect . W.screenDetail $ sc + modifyPosStore (\ps -> posStoreInsert ps w + (Rectangle (fi $ wa_x wa) (fi $ wa_y wa) + (fi $ wa_width wa) (fi $ wa_height wa)) sr ) + where + fi :: (Integral a, Num b) => a -> b + fi = fromIntegral + randomIntOffset :: X (Int) + randomIntOffset = io $ randomRIO (42, 242) + +positionStoreEventHook :: Event -> X All +positionStoreEventHook (DestroyWindowEvent {ev_window = w, ev_event_type = et}) = do + when (et == destroyNotify) $ do + modifyPosStore (\ps -> posStoreRemove ps w) + return (All True) +positionStoreEventHook _ = return (All True) |