mirror of
https://github.com/xmonad/xmonad-contrib.git
synced 2025-05-19 11:30:22 -07:00
Use extensible state instead of IORef
This commit is contained in:
parent
203e63b055
commit
f6f925c823
@ -26,7 +26,6 @@ module XMonad.Hooks.EwmhDesktops (
|
||||
|
||||
import Codec.Binary.UTF8.String (encode)
|
||||
import Control.Applicative((<$>))
|
||||
import Data.IORef
|
||||
import Data.List
|
||||
import Data.Maybe
|
||||
import Data.Monoid
|
||||
@ -38,6 +37,7 @@ import Control.Monad
|
||||
import qualified XMonad.StackSet as W
|
||||
|
||||
import XMonad.Hooks.SetWMName
|
||||
import qualified XMonad.Util.ExtensibleState as E
|
||||
import XMonad.Util.XUtils (fi)
|
||||
import XMonad.Util.WorkspaceCompare
|
||||
import XMonad.Util.WindowProperties (getProp32)
|
||||
@ -74,17 +74,26 @@ ewmhDesktopsStartup = setSupported
|
||||
ewmhDesktopsLogHook :: X ()
|
||||
ewmhDesktopsLogHook = ewmhDesktopsLogHookCustom id
|
||||
|
||||
|
||||
data EwmhState = EwmhState { desktopNames :: [String]
|
||||
-- |
|
||||
-- The values of @_NET_NUMBER_OF_DESKTOPS@, @_NET_CLIENT_LIST@,
|
||||
-- @_NET_CLIENT_LIST_STACKING@, and @_NET_CURRENT_DESKTOP@, cached to avoid
|
||||
-- unnecessary property updates. Another design would be to cache each of these
|
||||
-- independently to allow us to avoid even more updates.
|
||||
data DesktopState
|
||||
= DesktopState { desktopNames :: [String]
|
||||
, clientList :: [Window]
|
||||
, currentDesktop :: Maybe Int
|
||||
, windowDesktops :: M.Map Window Int
|
||||
}
|
||||
deriving (Eq, Show)
|
||||
deriving (Eq)
|
||||
|
||||
toEwmhState :: ([WindowSpace] -> [WindowSpace]) -> WindowSet -> EwmhState
|
||||
toEwmhState f s =
|
||||
EwmhState { desktopNames = map W.tag ws
|
||||
instance ExtensionClass DesktopState where
|
||||
initialValue = DesktopState [] [] Nothing M.empty
|
||||
|
||||
toDesktopState :: ([WindowSpace] -> [WindowSpace]) -> WindowSet -> DesktopState
|
||||
toDesktopState f s =
|
||||
DesktopState
|
||||
{ desktopNames = map W.tag ws
|
||||
, clientList = nub . concatMap (maybe [] (\(W.Stack x l r) -> reverse l ++ r ++ [x]) . W.stack) $ ws
|
||||
, currentDesktop =
|
||||
let maybeCurrent' = W.tag <$> listToMaybe (f [W.workspace $ W.current s])
|
||||
@ -95,11 +104,14 @@ toEwmhState f s =
|
||||
}
|
||||
where ws = f $ W.workspaces s
|
||||
|
||||
-- |
|
||||
-- Cache last property state to avoid needless property changes.
|
||||
cachedState :: IORef (Maybe EwmhState)
|
||||
cachedState = unsafePerformIO $ newIORef Nothing
|
||||
{-# NOINLINE cachedState #-}
|
||||
-- | Compare the given value against the value in the extensible state. Run the
|
||||
-- action if it has changed.
|
||||
whenChanged :: (Eq a, ExtensionClass a) => a -> X () -> X ()
|
||||
whenChanged v action = do
|
||||
v0 <- E.get
|
||||
unless (v == v0) $ do
|
||||
action
|
||||
E.put v
|
||||
|
||||
-- |
|
||||
-- Generalized version of ewmhDesktopsLogHook that allows an arbitrary
|
||||
@ -107,12 +119,8 @@ cachedState = unsafePerformIO $ newIORef Nothing
|
||||
ewmhDesktopsLogHookCustom :: ([WindowSpace] -> [WindowSpace]) -> X ()
|
||||
ewmhDesktopsLogHookCustom f = withWindowSet $ \s -> do
|
||||
sort' <- getSortByIndex
|
||||
let s' = toEwmhState (f . sort') s
|
||||
|
||||
cached <- io $ readIORef cachedState
|
||||
unless (cached == Just s') $ do
|
||||
io $ writeIORef cachedState $ Just s'
|
||||
|
||||
let s' = toDesktopState (f . sort') s
|
||||
whenChanged s' $ do
|
||||
-- Number of Workspaces
|
||||
setNumberOfDesktops (length $ desktopNames s')
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user