{-# LANGUAGE MultiWayIf #-}
module XMonad.Util.Timer
(
startTimer
, handleTimer
, TimerId
) where
import Control.Concurrent
import Data.Unique
import XMonad
import XMonad.Prelude (listToMaybe)
type TimerId = Int
startTimer :: Rational -> X TimerId
startTimer :: Rational -> X Int
startTimer Rational
s = IO Int -> X Int
forall (m :: * -> *) a. MonadIO m => IO a -> m a
io (IO Int -> X Int) -> IO Int -> X Int
forall a b. (a -> b) -> a -> b
$ do
Int
u <- Unique -> Int
hashUnique (Unique -> Int) -> IO Unique -> IO Int
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> IO Unique
newUnique
IO () -> IO ProcessID
forall (m :: * -> *). MonadIO m => IO () -> m ProcessID
xfork (IO () -> IO ProcessID) -> IO () -> IO ProcessID
forall a b. (a -> b) -> a -> b
$ do
Display
d <- String -> IO Display
openDisplay String
""
Atom
rw <- Display -> ScreenNumber -> IO Atom
rootWindow Display
d (ScreenNumber -> IO Atom) -> ScreenNumber -> IO Atom
forall a b. (a -> b) -> a -> b
$ Display -> ScreenNumber
defaultScreen Display
d
Int -> IO ()
threadDelay (Rational -> Int
forall a. Enum a => a -> Int
fromEnum (Rational -> Int) -> Rational -> Int
forall a b. (a -> b) -> a -> b
$ Rational
s Rational -> Rational -> Rational
forall a. Num a => a -> a -> a
* Rational
1000000)
Atom
a <- Display -> String -> Bool -> IO Atom
internAtom Display
d String
"XMONAD_TIMER" Bool
False
(XEventPtr -> IO ()) -> IO ()
forall a. (XEventPtr -> IO a) -> IO a
allocaXEvent ((XEventPtr -> IO ()) -> IO ()) -> (XEventPtr -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ \XEventPtr
e -> do
XEventPtr -> ScreenNumber -> IO ()
setEventType XEventPtr
e ScreenNumber
clientMessage
XEventPtr -> Atom -> Atom -> CInt -> Atom -> Atom -> IO ()
setClientMessageEvent XEventPtr
e Atom
rw Atom
a CInt
32 (Int -> Atom
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
u) Atom
0
Display -> Atom -> Bool -> Atom -> XEventPtr -> IO ()
sendEvent Display
d Atom
rw Bool
False Atom
structureNotifyMask XEventPtr
e
Display -> Bool -> IO ()
sync Display
d Bool
False
Int -> IO Int
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return Int
u
handleTimer :: TimerId -> Event -> X (Maybe a) -> X (Maybe a)
handleTimer :: forall a. Int -> Event -> X (Maybe a) -> X (Maybe a)
handleTimer Int
ti ClientMessageEvent{ev_message_type :: Event -> Atom
ev_message_type = Atom
mt, ev_data :: Event -> [CInt]
ev_data = [CInt]
dt} X (Maybe a)
action = do
Display
d <- (XConf -> Display) -> X Display
forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
asks XConf -> Display
display
Atom
a <- IO Atom -> X Atom
forall (m :: * -> *) a. MonadIO m => IO a -> m a
io (IO Atom -> X Atom) -> IO Atom -> X Atom
forall a b. (a -> b) -> a -> b
$ Display -> String -> Bool -> IO Atom
internAtom Display
d String
"XMONAD_TIMER" Bool
False
if | Atom
mt Atom -> Atom -> Bool
forall a. Eq a => a -> a -> Bool
== Atom
a, Just CInt
dth <- [CInt] -> Maybe CInt
forall a. [a] -> Maybe a
listToMaybe [CInt]
dt, CInt -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral CInt
dth Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
ti -> X (Maybe a)
action
| Bool
otherwise -> Maybe a -> X (Maybe a)
forall a. a -> X a
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe a
forall a. Maybe a
Nothing
handleTimer Int
_ Event
_ X (Maybe a)
_ = Maybe a -> X (Maybe a)
forall a. a -> X a
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe a
forall a. Maybe a
Nothing