mirror of
https://github.com/xmonad/xmonad-contrib.git
synced 2025-05-19 11:30:22 -07:00
New module: XMonad.Util.WindowState
Save almost arbitary data per window
This commit is contained in:
parent
0f6bed2ff7
commit
ca9961c1ca
92
XMonad/Util/WindowState.hs
Normal file
92
XMonad/Util/WindowState.hs
Normal file
@ -0,0 +1,92 @@
|
|||||||
|
{-#
|
||||||
|
LANGUAGE ScopedTypeVariables, GeneralizedNewtypeDeriving,
|
||||||
|
FlexibleInstances, MultiParamTypeClasses
|
||||||
|
#-}
|
||||||
|
-----------------------------------------------------------------------------
|
||||||
|
-- |
|
||||||
|
-- Module : XMonad.Util.WindowState
|
||||||
|
-- Copyright : (c) Dmitry Bogatov <KAction@gnu.org>
|
||||||
|
-- License : BSD
|
||||||
|
--
|
||||||
|
-- Maintainer : Dmitry Bogatov <KAction@gnu.org>
|
||||||
|
-- Stability : unstable
|
||||||
|
-- Portability : unportable
|
||||||
|
--
|
||||||
|
-- Functions for saving per-window data.
|
||||||
|
-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
module XMonad.Util.WindowState ( -- * Usage
|
||||||
|
-- $usage
|
||||||
|
get,
|
||||||
|
put,
|
||||||
|
StateQuery(..),
|
||||||
|
runStateQuery,
|
||||||
|
getQuery ) where
|
||||||
|
import XMonad hiding (get, put, modify)
|
||||||
|
import Control.Monad.Reader(ReaderT(..))
|
||||||
|
import Control.Monad.State.Class
|
||||||
|
import Control.Monad.State(StateT(..), evalStateT)
|
||||||
|
import Control.Monad.Trans(MonadTrans, lift)
|
||||||
|
import Data.Typeable (Typeable, typeOf)
|
||||||
|
import Control.Applicative((<$>))
|
||||||
|
-- $usage
|
||||||
|
--
|
||||||
|
-- This module allow to store state data with some 'Window'.
|
||||||
|
-- It is implemented with XProperties, so resources will be freed when
|
||||||
|
-- 'Window' is destoyed.
|
||||||
|
--
|
||||||
|
-- This module have advantage over "XMonad.Actions.TagWindows" in that it
|
||||||
|
-- hides from you implementation details and provides simple type-safe
|
||||||
|
-- interface. Main datatype is "StateQuery", which is simple wrapper around
|
||||||
|
-- "Query", which is instance of MonadState, with 'put' and 'get' are
|
||||||
|
-- functions to acess data, stored in "Window".
|
||||||
|
--
|
||||||
|
-- To save some data in window you probably want to do following:
|
||||||
|
-- > (runStateQuery (put $ Just value) win) :: X ()
|
||||||
|
-- To retrive it, you can use
|
||||||
|
-- > (runStateQuery get win) :: X (Maybe YourValueType)
|
||||||
|
-- "Query" can be promoted to "StateQuery" simply by constructor,
|
||||||
|
-- and reverse is 'getQuery'.
|
||||||
|
--
|
||||||
|
-- For example, I use it to have all X applications @russian@ or @dvorak@
|
||||||
|
-- layout, but emacs have only @us@, to not screw keybindings. Use your
|
||||||
|
-- imagination!
|
||||||
|
|
||||||
|
-- | Wrapper around "Query" with phanom type @s@, representing state, saved in
|
||||||
|
-- window.
|
||||||
|
newtype StateQuery s a = StateQuery {
|
||||||
|
getQuery :: Query a
|
||||||
|
} deriving (Monad, MonadIO, Functor)
|
||||||
|
|
||||||
|
packIntoQuery :: (Window -> X a) -> Query a
|
||||||
|
packIntoQuery = Query . ReaderT
|
||||||
|
|
||||||
|
-- | Apply "StateQuery" to "Window".
|
||||||
|
runStateQuery :: StateQuery s a -> Window -> X a
|
||||||
|
runStateQuery = runQuery . getQuery
|
||||||
|
|
||||||
|
-- | Lifted to "Query" version of 'catchX'
|
||||||
|
catchQuery :: Query a -> Query (Maybe a)
|
||||||
|
catchQuery q = packIntoQuery $ \win -> userCode $ runQuery q win
|
||||||
|
|
||||||
|
-- | Instance of MonadState for StateQuery.
|
||||||
|
instance (Show s, Read s, Typeable s) => MonadState (Maybe s) (StateQuery s) where
|
||||||
|
get = StateQuery $ read' <$> get' undefined where
|
||||||
|
get' :: (Maybe s) -> Query String
|
||||||
|
get' x = stringProperty (typePropertyName x)
|
||||||
|
read' :: (Read s) => String -> Maybe s
|
||||||
|
read' "" = Nothing
|
||||||
|
read' s = Just $ read s
|
||||||
|
put = StateQuery . packIntoQuery <$> setWindowProperty' where
|
||||||
|
setWindowProperty' val = setWindowProperty prop strValue where
|
||||||
|
prop = typePropertyName val
|
||||||
|
strValue = maybe "" show val
|
||||||
|
|
||||||
|
typePropertyName :: (Typeable a) => a -> String
|
||||||
|
typePropertyName x = "_XMONAD_WINSTATE__" ++ show (typeOf x)
|
||||||
|
|
||||||
|
type PropertyName = String
|
||||||
|
setWindowProperty :: PropertyName -> String -> Window -> X ()
|
||||||
|
setWindowProperty prop val win = withDisplay $ \d -> io $
|
||||||
|
internAtom d prop False >>=
|
||||||
|
setTextProperty d win val
|
@ -317,6 +317,7 @@ library
|
|||||||
XMonad.Util.Timer
|
XMonad.Util.Timer
|
||||||
XMonad.Util.Types
|
XMonad.Util.Types
|
||||||
XMonad.Util.WindowProperties
|
XMonad.Util.WindowProperties
|
||||||
|
XMonad.Util.WindowState
|
||||||
XMonad.Util.WorkspaceCompare
|
XMonad.Util.WorkspaceCompare
|
||||||
XMonad.Util.XSelection
|
XMonad.Util.XSelection
|
||||||
XMonad.Util.XUtils
|
XMonad.Util.XUtils
|
||||||
|
Loading…
x
Reference in New Issue
Block a user