{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE RecordWildCards #-}
module System.Taffybar.Information.X11DesktopInfo
(
X11Context
, DisplayName(..)
, getX11Context
, withX11Context
, X11Property
, X11PropertyT
, eventLoop
, getDisplay
, getAtom
, X11Window
, PropertyFetcher
, fetch
, readAsInt
, readAsListOfInt
, readAsListOfString
, readAsListOfWindow
, readAsString
, isWindowUrgent
, getPrimaryOutputNumber
, getVisibleTags
, doLowerWindow
, postX11RequestSyncProp
, sendCommandEvent
, sendWindowEvent
) where
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.Default (Default(..))
import Data.List (elemIndex)
import Data.List.Split (endBy)
import Data.Maybe (fromMaybe, listToMaybe)
import GHC.Generics (Generic)
import Graphics.X11.Xrandr (XRRScreenResources(..), XRROutputInfo(..), xrrGetOutputInfo, xrrGetScreenResources, xrrGetOutputPrimary)
import System.Taffybar.Information.SafeX11 hiding (displayName)
data X11Context = X11Context
{ X11Context -> DisplayName
ctxDisplayName :: DisplayName
, X11Context -> Display
ctxDisplay :: Display
, X11Context -> EventMask
ctxRoot :: Window
, X11Context -> MVar [(String, EventMask)]
ctxAtomCache :: MV.MVar [(String, Atom)]
}
data DisplayName = DefaultDisplay
| DisplayName String
deriving (Int -> DisplayName -> ShowS
[DisplayName] -> ShowS
DisplayName -> String
(Int -> DisplayName -> ShowS)
-> (DisplayName -> String)
-> ([DisplayName] -> ShowS)
-> Show DisplayName
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> DisplayName -> ShowS
showsPrec :: Int -> DisplayName -> ShowS
$cshow :: DisplayName -> String
show :: DisplayName -> String
$cshowList :: [DisplayName] -> ShowS
showList :: [DisplayName] -> ShowS
Show, ReadPrec [DisplayName]
ReadPrec DisplayName
Int -> ReadS DisplayName
ReadS [DisplayName]
(Int -> ReadS DisplayName)
-> ReadS [DisplayName]
-> ReadPrec DisplayName
-> ReadPrec [DisplayName]
-> Read DisplayName
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
$creadsPrec :: Int -> ReadS DisplayName
readsPrec :: Int -> ReadS DisplayName
$creadList :: ReadS [DisplayName]
readList :: ReadS [DisplayName]
$creadPrec :: ReadPrec DisplayName
readPrec :: ReadPrec DisplayName
$creadListPrec :: ReadPrec [DisplayName]
readListPrec :: ReadPrec [DisplayName]
Read, DisplayName -> DisplayName -> Bool
(DisplayName -> DisplayName -> Bool)
-> (DisplayName -> DisplayName -> Bool) -> Eq DisplayName
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: DisplayName -> DisplayName -> Bool
== :: DisplayName -> DisplayName -> Bool
$c/= :: DisplayName -> DisplayName -> Bool
/= :: DisplayName -> DisplayName -> Bool
Eq, Eq DisplayName
Eq DisplayName =>
(DisplayName -> DisplayName -> Ordering)
-> (DisplayName -> DisplayName -> Bool)
-> (DisplayName -> DisplayName -> Bool)
-> (DisplayName -> DisplayName -> Bool)
-> (DisplayName -> DisplayName -> Bool)
-> (DisplayName -> DisplayName -> DisplayName)
-> (DisplayName -> DisplayName -> DisplayName)
-> Ord DisplayName
DisplayName -> DisplayName -> Bool
DisplayName -> DisplayName -> Ordering
DisplayName -> DisplayName -> DisplayName
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: DisplayName -> DisplayName -> Ordering
compare :: DisplayName -> DisplayName -> Ordering
$c< :: DisplayName -> DisplayName -> Bool
< :: DisplayName -> DisplayName -> Bool
$c<= :: DisplayName -> DisplayName -> Bool
<= :: DisplayName -> DisplayName -> Bool
$c> :: DisplayName -> DisplayName -> Bool
> :: DisplayName -> DisplayName -> Bool
$c>= :: DisplayName -> DisplayName -> Bool
>= :: DisplayName -> DisplayName -> Bool
$cmax :: DisplayName -> DisplayName -> DisplayName
max :: DisplayName -> DisplayName -> DisplayName
$cmin :: DisplayName -> DisplayName -> DisplayName
min :: DisplayName -> DisplayName -> DisplayName
Ord, (forall x. DisplayName -> Rep DisplayName x)
-> (forall x. Rep DisplayName x -> DisplayName)
-> Generic DisplayName
forall x. Rep DisplayName x -> DisplayName
forall x. DisplayName -> Rep DisplayName x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. DisplayName -> Rep DisplayName x
from :: forall x. DisplayName -> Rep DisplayName x
$cto :: forall x. Rep DisplayName x -> DisplayName
to :: forall x. Rep DisplayName x -> DisplayName
Generic)
instance Default DisplayName where
def :: DisplayName
def = DisplayName
DefaultDisplay
fromDisplayName :: DisplayName -> String
fromDisplayName :: DisplayName -> String
fromDisplayName DisplayName
DefaultDisplay = String
""
fromDisplayName (DisplayName String
displayName) = String
displayName
type X11PropertyT m a = ReaderT X11Context m a
type X11Property a = X11PropertyT IO a
type X11Window = Window
type PropertyFetcher a = Display -> Atom -> X11Window -> IO (Maybe [a])
withX11Context :: DisplayName -> X11Property a -> IO a
withX11Context :: forall a. DisplayName -> X11Property a -> IO a
withX11Context DisplayName
dn X11Property a
fun = do
X11Context
ctx <- DisplayName -> IO X11Context
getX11Context DisplayName
dn
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
ctxDisplay 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
ctxDisplay (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 EventMask
-> String
-> X11Property b
doRead b
b [a] -> b
transform PropertyFetcher a
windowPropFn Maybe EventMask
window String
name =
b -> ([a] -> b) -> Maybe [a] -> b
forall b a. b -> (a -> b) -> Maybe a -> b
maybe b
b [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 EventMask -> String -> ReaderT X11Context IO (Maybe [a])
forall a.
Integral a =>
PropertyFetcher a
-> Maybe EventMask -> String -> X11Property (Maybe [a])
fetch PropertyFetcher a
windowPropFn Maybe EventMask
window String
name
readAsInt :: Maybe X11Window
-> String
-> X11Property Int
readAsInt :: Maybe EventMask -> String -> X11Property Int
readAsInt = Int
-> ([CLong] -> Int)
-> PropertyFetcher CLong
-> Maybe EventMask
-> String
-> X11Property Int
forall a b.
Integral a =>
b
-> ([a] -> b)
-> PropertyFetcher a
-> Maybe EventMask
-> 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
listToMaybe) PropertyFetcher CLong
getWindowProperty32
readAsListOfInt :: Maybe X11Window
-> String
-> X11Property [Int]
readAsListOfInt :: Maybe EventMask -> String -> X11Property [Int]
readAsListOfInt = [Int]
-> ([CLong] -> [Int])
-> PropertyFetcher CLong
-> Maybe EventMask
-> String
-> X11Property [Int]
forall a b.
Integral a =>
b
-> ([a] -> b)
-> PropertyFetcher a
-> Maybe EventMask
-> 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 EventMask -> String -> X11Property String
readAsString = String
-> ([CChar] -> String)
-> PropertyFetcher CChar
-> Maybe EventMask
-> String
-> X11Property String
forall a b.
Integral a =>
b
-> ([a] -> b)
-> PropertyFetcher a
-> Maybe EventMask
-> 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 EventMask -> String -> X11Property [String]
readAsListOfString = [String]
-> ([CChar] -> [String])
-> PropertyFetcher CChar
-> Maybe EventMask
-> String
-> X11Property [String]
forall a b.
Integral a =>
b
-> ([a] -> b)
-> PropertyFetcher a
-> Maybe EventMask
-> 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 EventMask -> String -> X11Property [EventMask]
readAsListOfWindow = [EventMask]
-> ([CLong] -> [EventMask])
-> PropertyFetcher CLong
-> Maybe EventMask
-> String
-> X11Property [EventMask]
forall a b.
Integral a =>
b
-> ([a] -> b)
-> PropertyFetcher a
-> Maybe EventMask
-> String
-> X11Property b
doRead [] ((CLong -> EventMask) -> [CLong] -> [EventMask]
forall a b. (a -> b) -> [a] -> [b]
map CLong -> EventMask
forall a b. (Integral a, Num b) => a -> b
fromIntegral) PropertyFetcher CLong
getWindowProperty32
isWindowUrgent :: X11Window -> X11Property Bool
isWindowUrgent :: EventMask -> X11Property Bool
isWindowUrgent EventMask
window = do
WMHints
hints <- EventMask -> X11Property WMHints
fetchWindowHints EventMask
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 EventMask -> String -> X11Property [String]
readAsListOfString Maybe EventMask
forall a. Maybe a
Nothing String
"_XMONAD_VISIBLE_WORKSPACES"
getAtom :: String -> X11Property Atom
getAtom :: String -> X11Property EventMask
getAtom String
s = do
Display
d <- (X11Context -> Display) -> X11Property Display
forall (m :: * -> *) r a. Monad m => (r -> a) -> ReaderT r m a
asks X11Context -> Display
ctxDisplay
MVar [(String, EventMask)]
cacheVar <- (X11Context -> MVar [(String, EventMask)])
-> ReaderT X11Context IO (MVar [(String, EventMask)])
forall (m :: * -> *) r a. Monad m => (r -> a) -> ReaderT r m a
asks X11Context -> MVar [(String, EventMask)]
ctxAtomCache
Maybe EventMask
a <- IO (Maybe EventMask) -> ReaderT X11Context IO (Maybe EventMask)
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 EventMask) -> ReaderT X11Context IO (Maybe EventMask))
-> IO (Maybe EventMask) -> ReaderT X11Context IO (Maybe EventMask)
forall a b. (a -> b) -> a -> b
$ String -> [(String, EventMask)] -> Maybe EventMask
forall a b. Eq a => a -> [(a, b)] -> Maybe b
lookup String
s ([(String, EventMask)] -> Maybe EventMask)
-> IO [(String, EventMask)] -> IO (Maybe EventMask)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> MVar [(String, EventMask)] -> IO [(String, EventMask)]
forall a. MVar a -> IO a
MV.readMVar MVar [(String, EventMask)]
cacheVar
let updateCacheAction :: X11Property EventMask
updateCacheAction = IO EventMask -> X11Property EventMask
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 EventMask -> X11Property EventMask)
-> IO EventMask -> X11Property EventMask
forall a b. (a -> b) -> a -> b
$ MVar [(String, EventMask)]
-> ([(String, EventMask)] -> IO ([(String, EventMask)], EventMask))
-> IO EventMask
forall a b. MVar a -> (a -> IO (a, b)) -> IO b
MV.modifyMVar MVar [(String, EventMask)]
cacheVar [(String, EventMask)] -> IO ([(String, EventMask)], EventMask)
updateCache
updateCache :: [(String, EventMask)] -> IO ([(String, EventMask)], EventMask)
updateCache [(String, EventMask)]
currentCache =
do
EventMask
atom <- Display -> String -> Bool -> IO EventMask
internAtom Display
d String
s Bool
False
([(String, EventMask)], EventMask)
-> IO ([(String, EventMask)], EventMask)
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return ((String
s, EventMask
atom)(String, EventMask)
-> [(String, EventMask)] -> [(String, EventMask)]
forall a. a -> [a] -> [a]
:[(String, EventMask)]
currentCache, EventMask
atom)
X11Property EventMask
-> (EventMask -> X11Property EventMask)
-> Maybe EventMask
-> X11Property EventMask
forall b a. b -> (a -> b) -> Maybe a -> b
maybe X11Property EventMask
updateCacheAction EventMask -> X11Property EventMask
forall a. a -> ReaderT X11Context IO a
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe EventMask
a
eventLoop :: (Event -> IO ()) -> X11Property ()
eventLoop :: (Event -> IO ()) -> X11Property ()
eventLoop Event -> IO ()
dispatch = do
Display
d <- (X11Context -> Display) -> X11Property Display
forall (m :: * -> *) r a. Monad m => (r -> a) -> ReaderT r m a
asks X11Context -> Display
ctxDisplay
EventMask
w <- (X11Context -> EventMask) -> X11Property EventMask
forall (m :: * -> *) r a. Monad m => (r -> a) -> ReaderT r m a
asks X11Context -> EventMask
ctxRoot
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 -> EventMask -> EventMask -> IO ()
selectInput Display
d EventMask
w (EventMask -> IO ()) -> EventMask -> IO ()
forall a b. (a -> b) -> a -> b
$ EventMask
propertyChangeMask EventMask -> EventMask -> EventMask
forall a. Bits a => a -> a -> a
.|. EventMask
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 -> EventMask
ev_window = EventMask
window } ->
Display -> EventMask -> EventMask -> IO ()
selectInput Display
d EventMask
window EventMask
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 :: EventMask -> EventMask -> X11Property ()
sendCommandEvent EventMask
cmd EventMask
arg = EventMask -> EventMask -> Maybe EventMask -> X11Property ()
sendCustomEvent EventMask
cmd EventMask
arg Maybe EventMask
forall a. Maybe a
Nothing
sendWindowEvent :: Atom -> X11Window -> X11Property ()
sendWindowEvent :: EventMask -> EventMask -> X11Property ()
sendWindowEvent EventMask
cmd EventMask
win = EventMask -> EventMask -> Maybe EventMask -> X11Property ()
sendCustomEvent EventMask
cmd EventMask
cmd (EventMask -> Maybe EventMask
forall a. a -> Maybe a
Just EventMask
win)
getX11Context :: DisplayName -> IO X11Context
getX11Context :: DisplayName -> IO X11Context
getX11Context DisplayName
ctxDisplayName = do
Display
d <- String -> IO Display
openDisplay (String -> IO Display) -> String -> IO Display
forall a b. (a -> b) -> a -> b
$ DisplayName -> String
fromDisplayName DisplayName
ctxDisplayName
EventMask
ctxRoot <- Display -> ScreenNumber -> IO EventMask
rootWindow Display
d (ScreenNumber -> IO EventMask) -> ScreenNumber -> IO EventMask
forall a b. (a -> b) -> a -> b
$ Display -> ScreenNumber
defaultScreen Display
d
MVar [(String, EventMask)]
ctxAtomCache <- [(String, EventMask)] -> IO (MVar [(String, EventMask)])
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
$ X11Context{ctxDisplay :: Display
ctxDisplay=Display
d,EventMask
MVar [(String, EventMask)]
DisplayName
ctxDisplayName :: DisplayName
ctxRoot :: EventMask
ctxAtomCache :: MVar [(String, EventMask)]
ctxDisplayName :: DisplayName
ctxRoot :: EventMask
ctxAtomCache :: MVar [(String, EventMask)]
..}
fetch :: (Integral a)
=> PropertyFetcher a
-> Maybe X11Window
-> String
-> X11Property (Maybe [a])
fetch :: forall a.
Integral a =>
PropertyFetcher a
-> Maybe EventMask -> String -> X11Property (Maybe [a])
fetch PropertyFetcher a
fetcher Maybe EventMask
window String
name = do
X11Context{EventMask
MVar [(String, EventMask)]
Display
DisplayName
ctxDisplayName :: X11Context -> DisplayName
ctxDisplay :: X11Context -> Display
ctxRoot :: X11Context -> EventMask
ctxAtomCache :: X11Context -> MVar [(String, EventMask)]
ctxDisplayName :: DisplayName
ctxDisplay :: Display
ctxRoot :: EventMask
ctxAtomCache :: MVar [(String, EventMask)]
..} <- ReaderT X11Context IO X11Context
forall (m :: * -> *) r. Monad m => ReaderT r m r
ask
EventMask
atom <- String -> X11Property EventMask
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
ctxDisplay EventMask
atom (EventMask -> Maybe EventMask -> EventMask
forall a. a -> Maybe a -> a
fromMaybe EventMask
ctxRoot Maybe EventMask
window)
fetchWindowHints :: X11Window -> X11Property WMHints
fetchWindowHints :: EventMask -> X11Property WMHints
fetchWindowHints EventMask
window = do
Display
d <- X11Property Display
getDisplay
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 -> EventMask -> IO WMHints
getWMHints Display
d EventMask
window
sendCustomEvent :: Atom
-> Atom
-> Maybe X11Window
-> X11Property ()
sendCustomEvent :: EventMask -> EventMask -> Maybe EventMask -> X11Property ()
sendCustomEvent EventMask
cmd EventMask
arg Maybe EventMask
win = do
X11Context{EventMask
MVar [(String, EventMask)]
Display
DisplayName
ctxDisplayName :: X11Context -> DisplayName
ctxDisplay :: X11Context -> Display
ctxRoot :: X11Context -> EventMask
ctxAtomCache :: X11Context -> MVar [(String, EventMask)]
ctxDisplayName :: DisplayName
ctxDisplay :: Display
ctxRoot :: EventMask
ctxAtomCache :: MVar [(String, EventMask)]
..} <- ReaderT X11Context IO X11Context
forall (m :: * -> *) r. Monad m => ReaderT r m r
ask
let win' :: EventMask
win' = EventMask -> Maybe EventMask -> EventMask
forall a. a -> Maybe a -> a
fromMaybe EventMask
ctxRoot Maybe EventMask
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
-> EventMask
-> EventMask
-> CInt
-> EventMask
-> EventMask
-> IO ()
setClientMessageEvent XEventPtr
e EventMask
win' EventMask
cmd CInt
32 EventMask
arg EventMask
currentTime
Display -> EventMask -> Bool -> EventMask -> XEventPtr -> IO ()
sendEvent Display
ctxDisplay EventMask
ctxRoot Bool
False EventMask
structureNotifyMask XEventPtr
e
Display -> Bool -> IO ()
sync Display
ctxDisplay Bool
False
postX11RequestSyncProp :: X11Property a -> a -> X11Property a
postX11RequestSyncProp :: forall a. X11Property a -> a -> X11Property a
postX11RequestSyncProp X11Property a
prop a
a = 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
a IO a
action
isActiveOutput :: XRRScreenResources -> RROutput -> X11Property Bool
isActiveOutput :: XRRScreenResources -> EventMask -> X11Property Bool
isActiveOutput XRRScreenResources
sres EventMask
output = do
Display
display <- X11Property Display
getDisplay
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 -> EventMask -> IO (Maybe XRROutputInfo)
xrrGetOutputInfo Display
display XRRScreenResources
sres EventMask
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
$ EventMask
-> (XRROutputInfo -> EventMask) -> Maybe XRROutputInfo -> EventMask
forall b a. b -> (a -> b) -> Maybe a -> b
maybe EventMask
0 XRROutputInfo -> EventMask
xrr_oi_crtc Maybe XRROutputInfo
maybeOutputInfo EventMask -> EventMask -> Bool
forall a. Eq a => a -> a -> Bool
/= EventMask
0
getActiveOutputs :: X11Property [RROutput]
getActiveOutputs :: X11Property [EventMask]
getActiveOutputs = do
X11Context{EventMask
MVar [(String, EventMask)]
Display
DisplayName
ctxDisplayName :: X11Context -> DisplayName
ctxDisplay :: X11Context -> Display
ctxRoot :: X11Context -> EventMask
ctxAtomCache :: X11Context -> MVar [(String, EventMask)]
ctxDisplayName :: DisplayName
ctxDisplay :: Display
ctxRoot :: EventMask
ctxAtomCache :: MVar [(String, EventMask)]
..} <- ReaderT X11Context IO X11Context
forall (m :: * -> *) r. Monad m => ReaderT r m r
ask
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 (Display -> EventMask -> IO (Maybe XRRScreenResources)
xrrGetScreenResources Display
ctxDisplay EventMask
ctxRoot) ReaderT X11Context IO (Maybe XRRScreenResources)
-> (Maybe XRRScreenResources -> X11Property [EventMask])
-> X11Property [EventMask]
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
>>= \case
Just XRRScreenResources
sres -> (EventMask -> X11Property Bool)
-> [EventMask] -> X11Property [EventMask]
forall (m :: * -> *) a.
Applicative m =>
(a -> m Bool) -> [a] -> m [a]
filterM (XRRScreenResources -> EventMask -> X11Property Bool
isActiveOutput XRRScreenResources
sres) (XRRScreenResources -> [EventMask]
xrr_sr_outputs XRRScreenResources
sres)
Maybe XRRScreenResources
Nothing -> [EventMask] -> X11Property [EventMask]
forall a. a -> ReaderT X11Context IO a
forall (m :: * -> *) a. Monad m => a -> m a
return []
getPrimaryOutputNumber :: X11Property (Maybe Int)
getPrimaryOutputNumber :: X11Property (Maybe Int)
getPrimaryOutputNumber = do
X11Context{EventMask
MVar [(String, EventMask)]
Display
DisplayName
ctxDisplayName :: X11Context -> DisplayName
ctxDisplay :: X11Context -> Display
ctxRoot :: X11Context -> EventMask
ctxAtomCache :: X11Context -> MVar [(String, EventMask)]
ctxDisplayName :: DisplayName
ctxDisplay :: Display
ctxRoot :: EventMask
ctxAtomCache :: MVar [(String, EventMask)]
..} <- ReaderT X11Context IO X11Context
forall (m :: * -> *) r. Monad m => ReaderT r m r
ask
EventMask
primary <- IO EventMask -> X11Property EventMask
forall a. IO a -> ReaderT X11Context IO a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO EventMask -> X11Property EventMask)
-> IO EventMask -> X11Property EventMask
forall a b. (a -> b) -> a -> b
$ Display -> EventMask -> IO EventMask
xrrGetOutputPrimary Display
ctxDisplay EventMask
ctxRoot
[EventMask]
outputs <- X11Property [EventMask]
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
$ EventMask
primary EventMask -> [EventMask] -> Maybe Int
forall a. Eq a => a -> [a] -> Maybe Int
`elemIndex` [EventMask]
outputs
doLowerWindow :: X11Window -> X11Property ()
doLowerWindow :: EventMask -> X11Property ()
doLowerWindow EventMask
window =
(X11Context -> Display) -> X11Property Display
forall (m :: * -> *) r a. Monad m => (r -> a) -> ReaderT r m a
asks X11Context -> Display
ctxDisplay 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 -> EventMask -> IO ()) -> EventMask -> Display -> IO ()
forall a b c. (a -> b -> c) -> b -> a -> c
flip Display -> EventMask -> IO ()
lowerWindow EventMask
window