module System.Taffybar.Information.X11DesktopInfo
( X11Context(..)
, X11Property
, X11Window
, doLowerWindow
, eventLoop
, fetch
, getAtom
, getDefaultCtx
, getDisplay
, getPrimaryOutputNumber
, getVisibleTags
, isWindowUrgent
, postX11RequestSyncProp
, readAsInt
, readAsListOfInt
, readAsListOfString
, readAsListOfWindow
, readAsString
, sendCommandEvent
, sendWindowEvent
, withDefaultCtx
) where
import Data.List
import Data.Maybe
import Codec.Binary.UTF8.String as UTF8
import qualified Control.Concurrent.MVar as MV
import Control.Monad
import Control.Monad.IO.Class
import Control.Monad.Trans.Class
import Control.Monad.Trans.Reader
import Data.Bits (testBit, (.|.))
import Data.List.Split (endBy)
import Graphics.X11.Xlib
import Graphics.X11.Xlib.Extras
hiding (getWindowProperty8, getWindowProperty32, getWMHints)
import Graphics.X11.Xrandr
import Safe
import System.Taffybar.Information.SafeX11
import Prelude
data X11Context = X11Context
{ X11Context -> Display
contextDisplay :: Display
, X11Context -> RRCrtc
_contextRoot :: Window
, X11Context -> MVar [(String, RRCrtc)]
atomCache :: MV.MVar [(String, Atom)]
}
type X11Property a = ReaderT X11Context IO a
type X11Window = Window
type PropertyFetcher a = Display -> Atom -> Window -> IO (Maybe [a])
withDefaultCtx :: X11Property a -> IO a
withDefaultCtx :: forall a. X11Property a -> IO a
withDefaultCtx X11Property a
fun = do
X11Context
ctx <- IO X11Context
getDefaultCtx
a
res <- X11Property a -> X11Context -> IO a
forall r (m :: * -> *) a. ReaderT r m a -> r -> m a
runReaderT X11Property a
fun X11Context
ctx
Display -> IO ()
closeDisplay (X11Context -> Display
contextDisplay X11Context
ctx)
a -> IO a
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return a
res
getDisplay :: X11Property Display
getDisplay :: X11Property Display
getDisplay = X11Context -> Display
contextDisplay (X11Context -> Display)
-> ReaderT X11Context IO X11Context -> X11Property Display
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ReaderT X11Context IO X11Context
forall (m :: * -> *) r. Monad m => ReaderT r m r
ask
doRead :: Integral a => b -> ([a] -> b)
-> PropertyFetcher a
-> Maybe X11Window
-> String
-> X11Property b
doRead :: forall a b.
Integral a =>
b
-> ([a] -> b)
-> PropertyFetcher a
-> Maybe RRCrtc
-> String
-> X11Property b
doRead b
def [a] -> b
transform PropertyFetcher a
windowPropFn Maybe RRCrtc
window String
name =
(b -> Maybe b -> b
forall a. a -> Maybe a -> a
fromMaybe b
def) (Maybe b -> b) -> (Maybe [a] -> Maybe b) -> Maybe [a] -> b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (([a] -> b) -> Maybe [a] -> Maybe b
forall a b. (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap [a] -> b
transform) (Maybe [a] -> b)
-> ReaderT X11Context IO (Maybe [a]) -> ReaderT X11Context IO b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> PropertyFetcher a
-> Maybe RRCrtc -> String -> ReaderT X11Context IO (Maybe [a])
forall a.
Integral a =>
PropertyFetcher a
-> Maybe RRCrtc -> String -> X11Property (Maybe [a])
fetch PropertyFetcher a
windowPropFn Maybe RRCrtc
window String
name
readAsInt :: Maybe X11Window
-> String
-> X11Property Int
readAsInt :: Maybe RRCrtc -> String -> X11Property Int
readAsInt = Int
-> ([CLong] -> Int)
-> PropertyFetcher CLong
-> Maybe RRCrtc
-> String
-> X11Property Int
forall a b.
Integral a =>
b
-> ([a] -> b)
-> PropertyFetcher a
-> Maybe RRCrtc
-> String
-> X11Property b
doRead (-Int
1) (Int -> (CLong -> Int) -> Maybe CLong -> Int
forall b a. b -> (a -> b) -> Maybe a -> b
maybe (-Int
1) CLong -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Maybe CLong -> Int) -> ([CLong] -> Maybe CLong) -> [CLong] -> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [CLong] -> Maybe CLong
forall a. [a] -> Maybe a
headMay) PropertyFetcher CLong
getWindowProperty32
readAsListOfInt :: Maybe X11Window
-> String
-> X11Property [Int]
readAsListOfInt :: Maybe RRCrtc -> String -> X11Property [Int]
readAsListOfInt = [Int]
-> ([CLong] -> [Int])
-> PropertyFetcher CLong
-> Maybe RRCrtc
-> String
-> X11Property [Int]
forall a b.
Integral a =>
b
-> ([a] -> b)
-> PropertyFetcher a
-> Maybe RRCrtc
-> String
-> X11Property b
doRead [] ((CLong -> Int) -> [CLong] -> [Int]
forall a b. (a -> b) -> [a] -> [b]
map CLong -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral) PropertyFetcher CLong
getWindowProperty32
readAsString :: Maybe X11Window
-> String
-> X11Property String
readAsString :: Maybe RRCrtc -> String -> X11Property String
readAsString = String
-> ([CChar] -> String)
-> PropertyFetcher CChar
-> Maybe RRCrtc
-> String
-> X11Property String
forall a b.
Integral a =>
b
-> ([a] -> b)
-> PropertyFetcher a
-> Maybe RRCrtc
-> String
-> X11Property b
doRead String
"" ([Word8] -> String
UTF8.decode ([Word8] -> String) -> ([CChar] -> [Word8]) -> [CChar] -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (CChar -> Word8) -> [CChar] -> [Word8]
forall a b. (a -> b) -> [a] -> [b]
map CChar -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral) PropertyFetcher CChar
getWindowProperty8
readAsListOfString :: Maybe X11Window
-> String
-> X11Property [String]
readAsListOfString :: Maybe RRCrtc -> String -> X11Property [String]
readAsListOfString = [String]
-> ([CChar] -> [String])
-> PropertyFetcher CChar
-> Maybe RRCrtc
-> String
-> X11Property [String]
forall a b.
Integral a =>
b
-> ([a] -> b)
-> PropertyFetcher a
-> Maybe RRCrtc
-> String
-> X11Property b
doRead [] [CChar] -> [String]
parse PropertyFetcher CChar
getWindowProperty8
where parse :: [CChar] -> [String]
parse = String -> String -> [String]
forall a. Eq a => [a] -> [a] -> [[a]]
endBy String
"\0" (String -> [String]) -> ([CChar] -> String) -> [CChar] -> [String]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Word8] -> String
UTF8.decode ([Word8] -> String) -> ([CChar] -> [Word8]) -> [CChar] -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (CChar -> Word8) -> [CChar] -> [Word8]
forall a b. (a -> b) -> [a] -> [b]
map CChar -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral
readAsListOfWindow :: Maybe X11Window
-> String
-> X11Property [X11Window]
readAsListOfWindow :: Maybe RRCrtc -> String -> X11Property [RRCrtc]
readAsListOfWindow = [RRCrtc]
-> ([CLong] -> [RRCrtc])
-> PropertyFetcher CLong
-> Maybe RRCrtc
-> String
-> X11Property [RRCrtc]
forall a b.
Integral a =>
b
-> ([a] -> b)
-> PropertyFetcher a
-> Maybe RRCrtc
-> String
-> X11Property b
doRead [] ((CLong -> RRCrtc) -> [CLong] -> [RRCrtc]
forall a b. (a -> b) -> [a] -> [b]
map CLong -> RRCrtc
forall a b. (Integral a, Num b) => a -> b
fromIntegral) PropertyFetcher CLong
getWindowProperty32
isWindowUrgent :: X11Window -> X11Property Bool
isWindowUrgent :: RRCrtc -> X11Property Bool
isWindowUrgent RRCrtc
window = do
WMHints
hints <- RRCrtc -> X11Property WMHints
fetchWindowHints RRCrtc
window
Bool -> X11Property Bool
forall a. a -> ReaderT X11Context IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (Bool -> X11Property Bool) -> Bool -> X11Property Bool
forall a b. (a -> b) -> a -> b
$ CLong -> Int -> Bool
forall a. Bits a => a -> Int -> Bool
testBit (WMHints -> CLong
wmh_flags WMHints
hints) Int
urgencyHintBit
getVisibleTags :: X11Property [String]
getVisibleTags :: X11Property [String]
getVisibleTags = Maybe RRCrtc -> String -> X11Property [String]
readAsListOfString Maybe RRCrtc
forall a. Maybe a
Nothing String
"_XMONAD_VISIBLE_WORKSPACES"
getAtom :: String -> X11Property Atom
getAtom :: String -> X11Property RRCrtc
getAtom String
s = do
(X11Context Display
d RRCrtc
_ MVar [(String, RRCrtc)]
cacheVar) <- ReaderT X11Context IO X11Context
forall (m :: * -> *) r. Monad m => ReaderT r m r
ask
Maybe RRCrtc
a <- IO (Maybe RRCrtc) -> ReaderT X11Context IO (Maybe RRCrtc)
forall (m :: * -> *) a. Monad m => m a -> ReaderT X11Context m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (IO (Maybe RRCrtc) -> ReaderT X11Context IO (Maybe RRCrtc))
-> IO (Maybe RRCrtc) -> ReaderT X11Context IO (Maybe RRCrtc)
forall a b. (a -> b) -> a -> b
$ String -> [(String, RRCrtc)] -> Maybe RRCrtc
forall a b. Eq a => a -> [(a, b)] -> Maybe b
lookup String
s ([(String, RRCrtc)] -> Maybe RRCrtc)
-> IO [(String, RRCrtc)] -> IO (Maybe RRCrtc)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> MVar [(String, RRCrtc)] -> IO [(String, RRCrtc)]
forall a. MVar a -> IO a
MV.readMVar MVar [(String, RRCrtc)]
cacheVar
let updateCacheAction :: X11Property RRCrtc
updateCacheAction = IO RRCrtc -> X11Property RRCrtc
forall (m :: * -> *) a. Monad m => m a -> ReaderT X11Context m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (IO RRCrtc -> X11Property RRCrtc)
-> IO RRCrtc -> X11Property RRCrtc
forall a b. (a -> b) -> a -> b
$ MVar [(String, RRCrtc)]
-> ([(String, RRCrtc)] -> IO ([(String, RRCrtc)], RRCrtc))
-> IO RRCrtc
forall a b. MVar a -> (a -> IO (a, b)) -> IO b
MV.modifyMVar MVar [(String, RRCrtc)]
cacheVar [(String, RRCrtc)] -> IO ([(String, RRCrtc)], RRCrtc)
updateCache
updateCache :: [(String, RRCrtc)] -> IO ([(String, RRCrtc)], RRCrtc)
updateCache [(String, RRCrtc)]
currentCache =
do
RRCrtc
atom <- Display -> String -> Bool -> IO RRCrtc
internAtom Display
d String
s Bool
False
([(String, RRCrtc)], RRCrtc) -> IO ([(String, RRCrtc)], RRCrtc)
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return ((String
s, RRCrtc
atom)(String, RRCrtc) -> [(String, RRCrtc)] -> [(String, RRCrtc)]
forall a. a -> [a] -> [a]
:[(String, RRCrtc)]
currentCache, RRCrtc
atom)
X11Property RRCrtc
-> (RRCrtc -> X11Property RRCrtc)
-> Maybe RRCrtc
-> X11Property RRCrtc
forall b a. b -> (a -> b) -> Maybe a -> b
maybe X11Property RRCrtc
updateCacheAction RRCrtc -> X11Property RRCrtc
forall a. a -> ReaderT X11Context IO a
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe RRCrtc
a
eventLoop :: (Event -> IO ()) -> X11Property ()
eventLoop :: (Event -> IO ()) -> X11Property ()
eventLoop Event -> IO ()
dispatch = do
(X11Context Display
d RRCrtc
w MVar [(String, RRCrtc)]
_) <- ReaderT X11Context IO X11Context
forall (m :: * -> *) r. Monad m => ReaderT r m r
ask
IO () -> X11Property ()
forall a. IO a -> ReaderT X11Context IO a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> X11Property ()) -> IO () -> X11Property ()
forall a b. (a -> b) -> a -> b
$ do
Display -> RRCrtc -> RRCrtc -> IO ()
selectInput Display
d RRCrtc
w (RRCrtc -> IO ()) -> RRCrtc -> IO ()
forall a b. (a -> b) -> a -> b
$ RRCrtc
propertyChangeMask RRCrtc -> RRCrtc -> RRCrtc
forall a. Bits a => a -> a -> a
.|. RRCrtc
substructureNotifyMask
(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 -> IO () -> IO ()
forall (f :: * -> *) a b. Applicative f => f a -> f b
forever (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$ do
Event
event <- Display -> XEventPtr -> IO ()
nextEvent Display
d XEventPtr
e IO () -> IO Event -> IO Event
forall a b. IO a -> IO b -> IO b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> XEventPtr -> IO Event
getEvent XEventPtr
e
case Event
event of
MapNotifyEvent { ev_window :: Event -> RRCrtc
ev_window = RRCrtc
window } ->
Display -> RRCrtc -> RRCrtc -> IO ()
selectInput Display
d RRCrtc
window RRCrtc
propertyChangeMask
Event
_ -> () -> IO ()
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return ()
Event -> IO ()
dispatch Event
event
sendCommandEvent :: Atom -> Atom -> X11Property ()
sendCommandEvent :: RRCrtc -> RRCrtc -> X11Property ()
sendCommandEvent RRCrtc
cmd RRCrtc
arg = do
(X11Context Display
dpy RRCrtc
root MVar [(String, RRCrtc)]
_) <- ReaderT X11Context IO X11Context
forall (m :: * -> *) r. Monad m => ReaderT r m r
ask
Display -> RRCrtc -> RRCrtc -> RRCrtc -> RRCrtc -> X11Property ()
sendCustomEvent Display
dpy RRCrtc
cmd RRCrtc
arg RRCrtc
root RRCrtc
root
sendWindowEvent :: Atom -> X11Window -> X11Property ()
sendWindowEvent :: RRCrtc -> RRCrtc -> X11Property ()
sendWindowEvent RRCrtc
cmd RRCrtc
win = do
(X11Context Display
dpy RRCrtc
root MVar [(String, RRCrtc)]
_) <- ReaderT X11Context IO X11Context
forall (m :: * -> *) r. Monad m => ReaderT r m r
ask
Display -> RRCrtc -> RRCrtc -> RRCrtc -> RRCrtc -> X11Property ()
sendCustomEvent Display
dpy RRCrtc
cmd RRCrtc
cmd RRCrtc
root RRCrtc
win
getDefaultCtx :: IO X11Context
getDefaultCtx :: IO X11Context
getDefaultCtx = do
Display
d <- String -> IO Display
openDisplay String
""
RRCrtc
w <- Display -> ScreenNumber -> IO RRCrtc
rootWindow Display
d (ScreenNumber -> IO RRCrtc) -> ScreenNumber -> IO RRCrtc
forall a b. (a -> b) -> a -> b
$ Display -> ScreenNumber
defaultScreen Display
d
MVar [(String, RRCrtc)]
cache <- [(String, RRCrtc)] -> IO (MVar [(String, RRCrtc)])
forall a. a -> IO (MVar a)
MV.newMVar []
X11Context -> IO X11Context
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (X11Context -> IO X11Context) -> X11Context -> IO X11Context
forall a b. (a -> b) -> a -> b
$ Display -> RRCrtc -> MVar [(String, RRCrtc)] -> X11Context
X11Context Display
d RRCrtc
w MVar [(String, RRCrtc)]
cache
fetch :: (Integral a)
=> PropertyFetcher a
-> Maybe X11Window
-> String
-> X11Property (Maybe [a])
fetch :: forall a.
Integral a =>
PropertyFetcher a
-> Maybe RRCrtc -> String -> X11Property (Maybe [a])
fetch PropertyFetcher a
fetcher Maybe RRCrtc
window String
name = do
(X11Context Display
dpy RRCrtc
root MVar [(String, RRCrtc)]
_) <- ReaderT X11Context IO X11Context
forall (m :: * -> *) r. Monad m => ReaderT r m r
ask
RRCrtc
atom <- String -> X11Property RRCrtc
getAtom String
name
IO (Maybe [a]) -> X11Property (Maybe [a])
forall a. IO a -> ReaderT X11Context IO a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO (Maybe [a]) -> X11Property (Maybe [a]))
-> IO (Maybe [a]) -> X11Property (Maybe [a])
forall a b. (a -> b) -> a -> b
$ PropertyFetcher a
fetcher Display
dpy RRCrtc
atom (RRCrtc -> Maybe RRCrtc -> RRCrtc
forall a. a -> Maybe a -> a
fromMaybe RRCrtc
root Maybe RRCrtc
window)
fetchWindowHints :: X11Window -> X11Property WMHints
fetchWindowHints :: RRCrtc -> X11Property WMHints
fetchWindowHints RRCrtc
window = do
(X11Context Display
d RRCrtc
_ MVar [(String, RRCrtc)]
_) <- ReaderT X11Context IO X11Context
forall (m :: * -> *) r. Monad m => ReaderT r m r
ask
IO WMHints -> X11Property WMHints
forall a. IO a -> ReaderT X11Context IO a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO WMHints -> X11Property WMHints)
-> IO WMHints -> X11Property WMHints
forall a b. (a -> b) -> a -> b
$ Display -> RRCrtc -> IO WMHints
getWMHints Display
d RRCrtc
window
sendCustomEvent :: Display
-> Atom
-> Atom
-> X11Window
-> X11Window
-> X11Property ()
sendCustomEvent :: Display -> RRCrtc -> RRCrtc -> RRCrtc -> RRCrtc -> X11Property ()
sendCustomEvent Display
dpy RRCrtc
cmd RRCrtc
arg RRCrtc
root RRCrtc
win =
IO () -> X11Property ()
forall a. IO a -> ReaderT X11Context IO a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> X11Property ()) -> IO () -> X11Property ()
forall a b. (a -> b) -> a -> b
$ (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 -> RRCrtc -> RRCrtc -> CInt -> RRCrtc -> RRCrtc -> IO ()
setClientMessageEvent XEventPtr
e RRCrtc
win RRCrtc
cmd CInt
32 RRCrtc
arg RRCrtc
currentTime
Display -> RRCrtc -> Bool -> RRCrtc -> XEventPtr -> IO ()
sendEvent Display
dpy RRCrtc
root Bool
False RRCrtc
structureNotifyMask XEventPtr
e
Display -> Bool -> IO ()
sync Display
dpy Bool
False
postX11RequestSyncProp :: X11Property a -> a -> X11Property a
postX11RequestSyncProp :: forall a. X11Property a -> a -> X11Property a
postX11RequestSyncProp X11Property a
prop a
def = do
X11Context
c <- ReaderT X11Context IO X11Context
forall (m :: * -> *) r. Monad m => ReaderT r m r
ask
let action :: IO a
action = X11Property a -> X11Context -> IO a
forall r (m :: * -> *) a. ReaderT r m a -> r -> m a
runReaderT X11Property a
prop X11Context
c
IO a -> X11Property a
forall (m :: * -> *) a. Monad m => m a -> ReaderT X11Context m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (IO a -> X11Property a) -> IO a -> X11Property a
forall a b. (a -> b) -> a -> b
$ a -> IO a -> IO a
forall a. a -> IO a -> IO a
postX11RequestSyncDef a
def IO a
action
isActiveOutput :: XRRScreenResources -> RROutput -> X11Property Bool
isActiveOutput :: XRRScreenResources -> RRCrtc -> X11Property Bool
isActiveOutput XRRScreenResources
sres RRCrtc
output = do
(X11Context Display
display RRCrtc
_ MVar [(String, RRCrtc)]
_) <- ReaderT X11Context IO X11Context
forall (m :: * -> *) r. Monad m => ReaderT r m r
ask
Maybe XRROutputInfo
maybeOutputInfo <- IO (Maybe XRROutputInfo)
-> ReaderT X11Context IO (Maybe XRROutputInfo)
forall a. IO a -> ReaderT X11Context IO a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO (Maybe XRROutputInfo)
-> ReaderT X11Context IO (Maybe XRROutputInfo))
-> IO (Maybe XRROutputInfo)
-> ReaderT X11Context IO (Maybe XRROutputInfo)
forall a b. (a -> b) -> a -> b
$ Display -> XRRScreenResources -> RRCrtc -> IO (Maybe XRROutputInfo)
xrrGetOutputInfo Display
display XRRScreenResources
sres RRCrtc
output
Bool -> X11Property Bool
forall a. a -> ReaderT X11Context IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (Bool -> X11Property Bool) -> Bool -> X11Property Bool
forall a b. (a -> b) -> a -> b
$ RRCrtc
-> (XRROutputInfo -> RRCrtc) -> Maybe XRROutputInfo -> RRCrtc
forall b a. b -> (a -> b) -> Maybe a -> b
maybe RRCrtc
0 XRROutputInfo -> RRCrtc
xrr_oi_crtc Maybe XRROutputInfo
maybeOutputInfo RRCrtc -> RRCrtc -> Bool
forall a. Eq a => a -> a -> Bool
/= RRCrtc
0
getActiveOutputs :: X11Property [RROutput]
getActiveOutputs :: X11Property [RRCrtc]
getActiveOutputs = do
(X11Context Display
display RRCrtc
rootw MVar [(String, RRCrtc)]
_) <- ReaderT X11Context IO X11Context
forall (m :: * -> *) r. Monad m => ReaderT r m r
ask
Maybe XRRScreenResources
maybeSres <- IO (Maybe XRRScreenResources)
-> ReaderT X11Context IO (Maybe XRRScreenResources)
forall a. IO a -> ReaderT X11Context IO a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO (Maybe XRRScreenResources)
-> ReaderT X11Context IO (Maybe XRRScreenResources))
-> IO (Maybe XRRScreenResources)
-> ReaderT X11Context IO (Maybe XRRScreenResources)
forall a b. (a -> b) -> a -> b
$ Display -> RRCrtc -> IO (Maybe XRRScreenResources)
xrrGetScreenResources Display
display RRCrtc
rootw
X11Property [RRCrtc]
-> (XRRScreenResources -> X11Property [RRCrtc])
-> Maybe XRRScreenResources
-> X11Property [RRCrtc]
forall b a. b -> (a -> b) -> Maybe a -> b
maybe ([RRCrtc] -> X11Property [RRCrtc]
forall a. a -> ReaderT X11Context IO a
forall (m :: * -> *) a. Monad m => a -> m a
return []) (\XRRScreenResources
sres -> (RRCrtc -> X11Property Bool) -> [RRCrtc] -> X11Property [RRCrtc]
forall (m :: * -> *) a.
Applicative m =>
(a -> m Bool) -> [a] -> m [a]
filterM (XRRScreenResources -> RRCrtc -> X11Property Bool
isActiveOutput XRRScreenResources
sres) ([RRCrtc] -> X11Property [RRCrtc])
-> [RRCrtc] -> X11Property [RRCrtc]
forall a b. (a -> b) -> a -> b
$ XRRScreenResources -> [RRCrtc]
xrr_sr_outputs XRRScreenResources
sres)
Maybe XRRScreenResources
maybeSres
getPrimaryOutputNumber :: X11Property (Maybe Int)
getPrimaryOutputNumber :: X11Property (Maybe Int)
getPrimaryOutputNumber = do
(X11Context Display
display RRCrtc
rootw MVar [(String, RRCrtc)]
_) <- ReaderT X11Context IO X11Context
forall (m :: * -> *) r. Monad m => ReaderT r m r
ask
RRCrtc
primary <- IO RRCrtc -> X11Property RRCrtc
forall a. IO a -> ReaderT X11Context IO a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO RRCrtc -> X11Property RRCrtc)
-> IO RRCrtc -> X11Property RRCrtc
forall a b. (a -> b) -> a -> b
$ Display -> RRCrtc -> IO RRCrtc
xrrGetOutputPrimary Display
display RRCrtc
rootw
[RRCrtc]
outputs <- X11Property [RRCrtc]
getActiveOutputs
Maybe Int -> X11Property (Maybe Int)
forall a. a -> ReaderT X11Context IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe Int -> X11Property (Maybe Int))
-> Maybe Int -> X11Property (Maybe Int)
forall a b. (a -> b) -> a -> b
$ RRCrtc
primary RRCrtc -> [RRCrtc] -> Maybe Int
forall a. Eq a => a -> [a] -> Maybe Int
`elemIndex` [RRCrtc]
outputs
doLowerWindow :: X11Window -> X11Property ()
doLowerWindow :: RRCrtc -> X11Property ()
doLowerWindow RRCrtc
window =
(X11Context -> Display) -> X11Property Display
forall (m :: * -> *) r a. Monad m => (r -> a) -> ReaderT r m a
asks X11Context -> Display
contextDisplay X11Property Display
-> (Display -> X11Property ()) -> X11Property ()
forall a b.
ReaderT X11Context IO a
-> (a -> ReaderT X11Context IO b) -> ReaderT X11Context IO b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= IO () -> X11Property ()
forall (m :: * -> *) a. Monad m => m a -> ReaderT X11Context m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (IO () -> X11Property ())
-> (Display -> IO ()) -> Display -> X11Property ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Display -> RRCrtc -> IO ()) -> RRCrtc -> Display -> IO ()
forall a b c. (a -> b -> c) -> b -> a -> c
flip Display -> RRCrtc -> IO ()
lowerWindow RRCrtc
window