-----------------------------------------------------------------------------
-- |
-- Module      :  Window
-- Copyright   :  (c) 2011-18, 2020-22 Jose A. Ortega Ruiz
--             :  (c) 2012 Jochen Keil
-- License     :  BSD-style (see LICENSE)
--
-- Maintainer  :  Jose A. Ortega Ruiz <jao@gnu.org>
-- Stability   :  unstable
-- Portability :  unportable
--
-- Window manipulation functions
--
-----------------------------------------------------------------------------

module Xmobar.X11.Window where

import qualified Control.Monad as CM

import qualified Data.Function as DF
import qualified Data.List as DL
import qualified Data.Maybe as DM

import qualified Graphics.X11.Xlib as X
import qualified Graphics.X11.Xlib.Extras as Xx

import qualified Graphics.X11.Xinerama as Xi
import qualified Foreign.C.Types as C

import qualified System.Posix.Process as PP

import qualified Xmobar.Config.Types as T
import qualified Xmobar.X11.Text as Txt

-- $window

-- | Creates a window with the attribute override_redirect set to True.
-- Windows Managers should not touch this kind of windows.
newWindow ::
  X.Display -> X.Screen -> X.Window -> X.Rectangle -> Bool -> IO X.Window
newWindow :: Display -> Screen -> Atom -> Rectangle -> Bool -> IO Atom
newWindow Display
dpy Screen
scr Atom
rw (X.Rectangle Position
x Position
y Dimension
w Dimension
h) Bool
o = do
  let visual :: Visual
visual = Screen -> Visual
X.defaultVisualOfScreen Screen
scr
      attrmask :: Atom
attrmask = if Bool
o then Atom
X.cWOverrideRedirect else Atom
0
  (Ptr SetWindowAttributes -> IO Atom) -> IO Atom
forall a. (Ptr SetWindowAttributes -> IO a) -> IO a
X.allocaSetWindowAttributes ((Ptr SetWindowAttributes -> IO Atom) -> IO Atom)
-> (Ptr SetWindowAttributes -> IO Atom) -> IO Atom
forall a b. (a -> b) -> a -> b
$
         \Ptr SetWindowAttributes
attributes -> do
           Ptr SetWindowAttributes -> Bool -> IO ()
X.set_override_redirect Ptr SetWindowAttributes
attributes Bool
o
           Display
-> Atom
-> Position
-> Position
-> Dimension
-> Dimension
-> CInt
-> CInt
-> CInt
-> Visual
-> Atom
-> Ptr SetWindowAttributes
-> IO Atom
X.createWindow Display
dpy Atom
rw Position
x Position
y Dimension
w Dimension
h CInt
0 (Screen -> CInt
X.defaultDepthOfScreen Screen
scr)
                        CInt
X.inputOutput Visual
visual Atom
attrmask Ptr SetWindowAttributes
attributes

-- | The function to create the initial window
createWin :: X.Display -> Txt.XFont -> T.Config -> IO (X.Rectangle, X.Window)
createWin :: Display -> XFont -> Config -> IO (Rectangle, Atom)
createWin Display
d XFont
fs Config
c = do
  let dflt :: Dimension
dflt = Display -> Dimension
X.defaultScreen Display
d
  srs <- Display -> IO [Rectangle]
Xi.getScreenInfo Display
d
  rootw <- X.rootWindow d dflt
  (as,ds) <- Txt.textExtents fs "0"
  let ht = Position
as Position -> Position -> Position
forall a. Num a => a -> a -> a
+ Position
ds Position -> Position -> Position
forall a. Num a => a -> a -> a
+ Position
4
      r = Config -> XPosition -> [Rectangle] -> Dimension -> Rectangle
setPosition Config
c (Config -> XPosition
T.position Config
c) [Rectangle]
srs (Position -> Dimension
forall a b. (Integral a, Num b) => a -> b
fromIntegral Position
ht)
  win <- newWindow  d (X.defaultScreenOfDisplay d) rootw r (T.overrideRedirect c)
  setProperties c d win
  setStruts r c d win srs
  CM.when (T.lowerOnStart c) $ X.lowerWindow d win
  CM.unless (T.hideOnStart c) $ showWindow r c d win
  return (r,win)

-- | Updates the size and position of the window
repositionWin :: X.Display -> X.Window -> Txt.XFont -> T.Config -> IO X.Rectangle
repositionWin :: Display -> Atom -> XFont -> Config -> IO Rectangle
repositionWin Display
d Atom
win XFont
fs Config
c = do
  srs <- Display -> IO [Rectangle]
Xi.getScreenInfo Display
d
  (as,ds) <- Txt.textExtents fs "0"
  let ht = Position
as Position -> Position -> Position
forall a. Num a => a -> a -> a
+ Position
ds Position -> Position -> Position
forall a. Num a => a -> a -> a
+ Position
4
      r = Config -> XPosition -> [Rectangle] -> Dimension -> Rectangle
setPosition Config
c (Config -> XPosition
T.position Config
c) [Rectangle]
srs (Position -> Dimension
forall a b. (Integral a, Num b) => a -> b
fromIntegral Position
ht)
  X.moveResizeWindow d win
    (X.rect_x r) (X.rect_y r) (X.rect_width r) (X.rect_height r)
  setStruts r c d win srs
  X.sync d False
  return r

fi :: (Integral a, Num b) => a -> b
fi :: forall a b. (Integral a, Num b) => a -> b
fi = a -> b
forall a b. (Integral a, Num b) => a -> b
fromIntegral

setPosition ::
  T.Config -> T.XPosition -> [X.Rectangle] -> X.Dimension -> X.Rectangle
setPosition :: Config -> XPosition -> [Rectangle] -> Dimension -> Rectangle
setPosition Config
c XPosition
p [Rectangle]
rs Dimension
ht =
  case XPosition
p' of
    XPosition
T.Top -> Position -> Position -> Dimension -> Dimension -> Rectangle
X.Rectangle Position
rx Position
ry Dimension
rw Dimension
h
    T.TopP Int
l Int
r -> Position -> Position -> Dimension -> Dimension -> Rectangle
X.Rectangle (Position
rx Position -> Position -> Position
forall a. Num a => a -> a -> a
+ Int -> Position
forall a b. (Integral a, Num b) => a -> b
fi Int
l) Position
ry (Dimension
rw Dimension -> Dimension -> Dimension
forall a. Num a => a -> a -> a
- Int -> Dimension
forall a b. (Integral a, Num b) => a -> b
fi Int
l Dimension -> Dimension -> Dimension
forall a. Num a => a -> a -> a
- Int -> Dimension
forall a b. (Integral a, Num b) => a -> b
fi Int
r) Dimension
h
    T.TopH Int
ch -> Position -> Position -> Dimension -> Dimension -> Rectangle
X.Rectangle Position
rx Position
ry Dimension
rw (Int -> Dimension
forall {a}. Integral a => a -> Dimension
mh Int
ch)
    T.TopHM Int
ch Int
l Int
r Int
t Int
_ ->
      Position -> Position -> Dimension -> Dimension -> Rectangle
X.Rectangle (Position
rx Position -> Position -> Position
forall a. Num a => a -> a -> a
+ Int -> Position
forall a b. (Integral a, Num b) => a -> b
fi Int
l) (Position
ry Position -> Position -> Position
forall a. Num a => a -> a -> a
+ Int -> Position
forall a b. (Integral a, Num b) => a -> b
fi Int
t) (Dimension
rw Dimension -> Dimension -> Dimension
forall a. Num a => a -> a -> a
- Int -> Dimension
forall a b. (Integral a, Num b) => a -> b
fi Int
l Dimension -> Dimension -> Dimension
forall a. Num a => a -> a -> a
- Int -> Dimension
forall a b. (Integral a, Num b) => a -> b
fi Int
r) (Int -> Dimension
forall {a}. Integral a => a -> Dimension
mh Int
ch)
    T.TopW Align
a Int
i -> Position -> Position -> Dimension -> Dimension -> Rectangle
X.Rectangle (Align -> Int -> Position
forall {b}. Integral b => Align -> b -> Position
ax Align
a Int
i) Position
ry (Int -> Dimension
nw Int
i) Dimension
h
    T.TopSize Align
a Int
i Int
ch -> Position -> Position -> Dimension -> Dimension -> Rectangle
X.Rectangle (Align -> Int -> Position
forall {b}. Integral b => Align -> b -> Position
ax Align
a Int
i) Position
ry (Int -> Dimension
nw Int
i) (Int -> Dimension
forall {a}. Integral a => a -> Dimension
mh Int
ch)
    XPosition
T.Bottom -> Position -> Position -> Dimension -> Dimension -> Rectangle
X.Rectangle Position
rx Position
ny Dimension
rw Dimension
h
    T.BottomH Int
ch -> Position -> Position -> Dimension -> Dimension -> Rectangle
X.Rectangle Position
rx (Int -> Position
forall {a}. Integral a => a -> Position
ny' Int
ch) Dimension
rw (Int -> Dimension
forall {a}. Integral a => a -> Dimension
mh Int
ch)
    T.BottomHM Int
ch Int
l Int
r Int
_ Int
b ->
      Position -> Position -> Dimension -> Dimension -> Rectangle
X.Rectangle (Position
rx Position -> Position -> Position
forall a. Num a => a -> a -> a
+ Int -> Position
forall a b. (Integral a, Num b) => a -> b
fi Int
l) (Position
ry Position -> Position -> Position
forall a. Num a => a -> a -> a
+ Dimension -> Position
forall a b. (Integral a, Num b) => a -> b
fi Dimension
rh Position -> Position -> Position
forall a. Num a => a -> a -> a
- Int -> Position
forall a b. (Integral a, Num b) => a -> b
fi Int
b Position -> Position -> Position
forall a. Num a => a -> a -> a
- Dimension -> Position
forall a b. (Integral a, Num b) => a -> b
fi (Int -> Dimension
forall {a}. Integral a => a -> Dimension
mh Int
ch)) (Dimension
rw Dimension -> Dimension -> Dimension
forall a. Num a => a -> a -> a
- Int -> Dimension
forall a b. (Integral a, Num b) => a -> b
fi Int
l Dimension -> Dimension -> Dimension
forall a. Num a => a -> a -> a
- Int -> Dimension
forall a b. (Integral a, Num b) => a -> b
fi Int
r) (Int -> Dimension
forall {a}. Integral a => a -> Dimension
mh Int
ch)
    T.BottomW Align
a Int
i -> Position -> Position -> Dimension -> Dimension -> Rectangle
X.Rectangle (Align -> Int -> Position
forall {b}. Integral b => Align -> b -> Position
ax Align
a Int
i) Position
ny (Int -> Dimension
nw Int
i) Dimension
h
    T.BottomP Int
l Int
r -> Position -> Position -> Dimension -> Dimension -> Rectangle
X.Rectangle (Position
rx Position -> Position -> Position
forall a. Num a => a -> a -> a
+ Int -> Position
forall a b. (Integral a, Num b) => a -> b
fi Int
l) Position
ny (Dimension
rw Dimension -> Dimension -> Dimension
forall a. Num a => a -> a -> a
- Int -> Dimension
forall a b. (Integral a, Num b) => a -> b
fi Int
l Dimension -> Dimension -> Dimension
forall a. Num a => a -> a -> a
- Int -> Dimension
forall a b. (Integral a, Num b) => a -> b
fi Int
r) Dimension
h
    T.BottomSize Align
a Int
i Int
ch  -> Position -> Position -> Dimension -> Dimension -> Rectangle
X.Rectangle (Align -> Int -> Position
forall {b}. Integral b => Align -> b -> Position
ax Align
a Int
i) (Int -> Position
forall {a}. Integral a => a -> Position
ny' Int
ch) (Int -> Dimension
nw Int
i) (Int -> Dimension
forall {a}. Integral a => a -> Dimension
mh Int
ch)
    T.Static Int
cx Int
cy Int
cw Int
ch -> Position -> Position -> Dimension -> Dimension -> Rectangle
X.Rectangle (Int -> Position
forall a b. (Integral a, Num b) => a -> b
fi Int
cx) (Int -> Position
forall a b. (Integral a, Num b) => a -> b
fi Int
cy) (Int -> Dimension
forall a b. (Integral a, Num b) => a -> b
fi Int
cw) (Int -> Dimension
forall a b. (Integral a, Num b) => a -> b
fi Int
ch)
    T.OnScreen Int
_ XPosition
p'' -> Config -> XPosition -> [Rectangle] -> Dimension -> Rectangle
setPosition Config
c XPosition
p'' [Rectangle
scr] Dimension
ht
  where
    (scr :: Rectangle
scr@(X.Rectangle Position
rx Position
ry Dimension
rw Dimension
rh), XPosition
p') =
      case XPosition
p of T.OnScreen Int
i XPosition
x -> (Rectangle -> Maybe Rectangle -> Rectangle
forall a. a -> Maybe a -> a
DM.fromMaybe ([Rectangle] -> Rectangle
picker [Rectangle]
rs) (Maybe Rectangle -> Rectangle) -> Maybe Rectangle -> Rectangle
forall a b. (a -> b) -> a -> b
$ Int -> [Rectangle] -> Maybe Rectangle
forall {a} {b}. (Eq a, Num a, Enum a) => a -> [b] -> Maybe b
safeIndex Int
i [Rectangle]
rs, XPosition
x)
                XPosition
_ -> ([Rectangle] -> Rectangle
picker [Rectangle]
rs, XPosition
p)
    ny :: Position
ny = Position
ry Position -> Position -> Position
forall a. Num a => a -> a -> a
+ Dimension -> Position
forall a b. (Integral a, Num b) => a -> b
fi (Dimension
rh Dimension -> Dimension -> Dimension
forall a. Num a => a -> a -> a
- Dimension
ht)
    center :: a -> Position
center a
i = Position
rx Position -> Position -> Position
forall a. Num a => a -> a -> a
+ Dimension -> Position
forall a b. (Integral a, Num b) => a -> b
fi (Dimension -> Dimension -> Dimension
forall a. Integral a => a -> a -> a
div (a -> Dimension
forall {a}. Integral a => a -> Dimension
remwid a
i) Dimension
2)
    right :: a -> Position
right  a
i = Position
rx Position -> Position -> Position
forall a. Num a => a -> a -> a
+ Dimension -> Position
forall a b. (Integral a, Num b) => a -> b
fi (a -> Dimension
forall {a}. Integral a => a -> Dimension
remwid a
i)
    remwid :: a -> Dimension
remwid a
i = Dimension
rw Dimension -> Dimension -> Dimension
forall a. Num a => a -> a -> a
- Dimension -> Dimension
pw (a -> Dimension
forall a b. (Integral a, Num b) => a -> b
fi a
i)
    ax :: Align -> b -> Position
ax Align
T.L = Position -> b -> Position
forall a b. a -> b -> a
const Position
rx
    ax Align
T.R = b -> Position
forall {a}. Integral a => a -> Position
right
    ax Align
T.C = b -> Position
forall {a}. Integral a => a -> Position
center
    pw :: Dimension -> Dimension
pw Dimension
i = Dimension
rw Dimension -> Dimension -> Dimension
forall a. Num a => a -> a -> a
* Dimension -> Dimension -> Dimension
forall a. Ord a => a -> a -> a
min Dimension
100 Dimension
i Dimension -> Dimension -> Dimension
forall a. Integral a => a -> a -> a
`div` Dimension
100
    nw :: Int -> Dimension
nw = Dimension -> Dimension
forall a b. (Integral a, Num b) => a -> b
fi (Dimension -> Dimension) -> (Int -> Dimension) -> Int -> Dimension
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Dimension -> Dimension
pw (Dimension -> Dimension) -> (Int -> Dimension) -> Int -> Dimension
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> Dimension
forall a b. (Integral a, Num b) => a -> b
fi
    h :: Dimension
h = Dimension -> Dimension
forall a b. (Integral a, Num b) => a -> b
fi Dimension
ht
    mh :: a -> Dimension
mh a
h' = Dimension -> Dimension -> Dimension
forall a. Ord a => a -> a -> a
max (a -> Dimension
forall a b. (Integral a, Num b) => a -> b
fi a
h') Dimension
h
    ny' :: a -> Position
ny' a
h' = Position
ry Position -> Position -> Position
forall a. Num a => a -> a -> a
+ Dimension -> Position
forall a b. (Integral a, Num b) => a -> b
fi (Dimension
rh Dimension -> Dimension -> Dimension
forall a. Num a => a -> a -> a
- a -> Dimension
forall {a}. Integral a => a -> Dimension
mh a
h')
    safeIndex :: a -> [b] -> Maybe b
safeIndex a
i = a -> [(a, b)] -> Maybe b
forall a b. Eq a => a -> [(a, b)] -> Maybe b
lookup a
i ([(a, b)] -> Maybe b) -> ([b] -> [(a, b)]) -> [b] -> Maybe b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [a] -> [b] -> [(a, b)]
forall a b. [a] -> [b] -> [(a, b)]
zip [a
0..]
    picker :: [Rectangle] -> Rectangle
picker = if Config -> Bool
T.pickBroadest Config
c
             then (Rectangle -> Rectangle -> Ordering) -> [Rectangle] -> Rectangle
forall (t :: * -> *) a.
Foldable t =>
(a -> a -> Ordering) -> t a -> a
DL.maximumBy (Dimension -> Dimension -> Ordering
forall a. Ord a => a -> a -> Ordering
compare (Dimension -> Dimension -> Ordering)
-> (Rectangle -> Dimension) -> Rectangle -> Rectangle -> Ordering
forall b c a. (b -> b -> c) -> (a -> b) -> a -> a -> c
`DF.on` Rectangle -> Dimension
X.rect_width)
             else [Rectangle] -> Rectangle
forall a. HasCallStack => [a] -> a
head

setProperties :: T.Config -> X.Display -> X.Window -> IO ()
setProperties :: Config -> Display -> Atom -> IO ()
setProperties Config
c Display
d Atom
w = do
  let mkatom :: String -> IO Atom
mkatom String
n = Display -> String -> Bool -> IO Atom
X.internAtom Display
d String
n Bool
False
  card <- String -> IO Atom
mkatom String
"CARDINAL"
  atom <- mkatom "ATOM"

  X.setTextProperty d w (T.wmClass c) X.wM_CLASS
  X.setTextProperty d w (T.wmName c) X.wM_NAME

  wtype <- mkatom "_NET_WM_WINDOW_TYPE"
  dock <- mkatom "_NET_WM_WINDOW_TYPE_DOCK"
  Xx.changeProperty32 d w wtype atom Xx.propModeReplace [fi dock]

  CM.when (T.allDesktops c) $ do
    desktop <- mkatom "_NET_WM_DESKTOP"
    Xx.changeProperty32 d w desktop card Xx.propModeReplace [0xffffffff]

  pid  <- mkatom "_NET_WM_PID"
  PP.getProcessID >>=
    Xx.changeProperty32 d w pid card Xx.propModeReplace . return . fi

setStruts' :: X.Display -> X.Window -> [C.CLong] -> IO ()
setStruts' :: Display -> Atom -> [CLong] -> IO ()
setStruts' Display
d Atom
w [CLong]
svs = do
  let mkatom :: String -> IO Atom
mkatom String
n = Display -> String -> Bool -> IO Atom
X.internAtom Display
d String
n Bool
False
  card <- String -> IO Atom
mkatom String
"CARDINAL"
  pstrut <- mkatom "_NET_WM_STRUT_PARTIAL"
  strut <- mkatom "_NET_WM_STRUT"
  Xx.changeProperty32 d w pstrut card Xx.propModeReplace svs
  Xx.changeProperty32 d w strut card Xx.propModeReplace (take 4 svs)

setStruts ::
  X.Rectangle -> T.Config -> X.Display -> X.Window -> [X.Rectangle] -> IO ()
setStruts :: Rectangle -> Config -> Display -> Atom -> [Rectangle] -> IO ()
setStruts Rectangle
r Config
c Display
d Atom
w [Rectangle]
rs = do
  let svs :: [CLong]
svs = (Int -> CLong) -> [Int] -> [CLong]
forall a b. (a -> b) -> [a] -> [b]
map Int -> CLong
forall a b. (Integral a, Num b) => a -> b
fi ([Int] -> [CLong]) -> [Int] -> [CLong]
forall a b. (a -> b) -> a -> b
$ Rectangle -> XPosition -> Int -> [Int]
getStrutValues Rectangle
r (Config -> XPosition
T.position Config
c) ([Rectangle] -> Int
getRootWindowHeight [Rectangle]
rs)
  Display -> Atom -> [CLong] -> IO ()
setStruts' Display
d Atom
w [CLong]
svs

getRootWindowHeight :: [X.Rectangle] -> Int
getRootWindowHeight :: [Rectangle] -> Int
getRootWindowHeight [Rectangle]
srs = [Int] -> Int
forall a. Ord a => [a] -> a
forall (t :: * -> *) a. (Foldable t, Ord a) => t a -> a
maximum ((Rectangle -> Int) -> [Rectangle] -> [Int]
forall a b. (a -> b) -> [a] -> [b]
map Rectangle -> Int
forall {a}. Num a => Rectangle -> a
getMaxScreenYCoord [Rectangle]
srs)
  where
    getMaxScreenYCoord :: Rectangle -> a
getMaxScreenYCoord Rectangle
sr = Position -> a
forall a b. (Integral a, Num b) => a -> b
fi (Rectangle -> Position
X.rect_y Rectangle
sr) a -> a -> a
forall a. Num a => a -> a -> a
+ Dimension -> a
forall a b. (Integral a, Num b) => a -> b
fi (Rectangle -> Dimension
X.rect_height Rectangle
sr)

getStrutValues :: X.Rectangle -> T.XPosition -> Int -> [Int]
getStrutValues :: Rectangle -> XPosition -> Int -> [Int]
getStrutValues r :: Rectangle
r@(X.Rectangle Position
x Position
y Dimension
w Dimension
h) XPosition
p Int
rwh =
  case XPosition
p of
    T.OnScreen Int
_ XPosition
p'      -> Rectangle -> XPosition -> Int -> [Int]
getStrutValues Rectangle
r XPosition
p' Int
rwh
    XPosition
T.Top                -> [Int
0, Int
0, Int
st  , Int
0   , Int
0, Int
0, Int
0, Int
0, Int
nx, Int
nw, Int
0 , Int
0 ]
    T.TopH    Int
_          -> [Int
0, Int
0, Int
st  , Int
0   , Int
0, Int
0, Int
0, Int
0, Int
nx, Int
nw, Int
0 , Int
0 ]
    T.TopHM Int
_ Int
_ Int
_ Int
_ Int
b    -> [Int
0, Int
0, Int
stInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
b, Int
0   , Int
0, Int
0, Int
0, Int
0, Int
nx, Int
nw, Int
0 , Int
0 ]
    T.TopP    Int
_ Int
_        -> [Int
0, Int
0, Int
st  , Int
0   , Int
0, Int
0, Int
0, Int
0, Int
nx, Int
nw, Int
0 , Int
0 ]
    T.TopW    Align
_ Int
_        -> [Int
0, Int
0, Int
st  , Int
0   , Int
0, Int
0, Int
0, Int
0, Int
nx, Int
nw, Int
0 , Int
0 ]
    T.TopSize      {}    -> [Int
0, Int
0, Int
st  , Int
0   , Int
0, Int
0, Int
0, Int
0, Int
nx, Int
nw, Int
0 , Int
0 ]
    XPosition
T.Bottom             -> [Int
0, Int
0, Int
0   , Int
sb  , Int
0, Int
0, Int
0, Int
0, Int
0 , Int
0 , Int
nx, Int
nw]
    T.BottomH Int
_          -> [Int
0, Int
0, Int
0   , Int
sb  , Int
0, Int
0, Int
0, Int
0, Int
0 , Int
0 , Int
nx, Int
nw]
    T.BottomHM Int
_ Int
_ Int
_ Int
t Int
_ -> [Int
0, Int
0, Int
0   , Int
sbInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
t, Int
0, Int
0, Int
0, Int
0, Int
0 , Int
0 , Int
nx, Int
nw]
    T.BottomP Int
_ Int
_        -> [Int
0, Int
0, Int
0   , Int
sb  , Int
0, Int
0, Int
0, Int
0, Int
0 , Int
0 , Int
nx, Int
nw]
    T.BottomW Align
_ Int
_        -> [Int
0, Int
0, Int
0   , Int
sb  , Int
0, Int
0, Int
0, Int
0, Int
0 , Int
0 , Int
nx, Int
nw]
    T.BottomSize   {}    -> [Int
0, Int
0, Int
0   , Int
sb  , Int
0, Int
0, Int
0, Int
0, Int
0 , Int
0 , Int
nx, Int
nw]
    T.Static       {}    -> XPosition -> Int -> [Int]
getStaticStrutValues XPosition
p Int
rwh
  where st :: Int
st = Position -> Int
forall a b. (Integral a, Num b) => a -> b
fi Position
y Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Dimension -> Int
forall a b. (Integral a, Num b) => a -> b
fi Dimension
h
        sb :: Int
sb = Int
rwh Int -> Int -> Int
forall a. Num a => a -> a -> a
- Position -> Int
forall a b. (Integral a, Num b) => a -> b
fi Position
y
        nx :: Int
nx = Position -> Int
forall a b. (Integral a, Num b) => a -> b
fi Position
x
        nw :: Int
nw = Position -> Int
forall a b. (Integral a, Num b) => a -> b
fi (Position
x Position -> Position -> Position
forall a. Num a => a -> a -> a
+ Dimension -> Position
forall a b. (Integral a, Num b) => a -> b
fi Dimension
w Position -> Position -> Position
forall a. Num a => a -> a -> a
- Position
1)

-- get some reaonable strut values for static placement.
getStaticStrutValues :: T.XPosition -> Int -> [Int]
getStaticStrutValues :: XPosition -> Int -> [Int]
getStaticStrutValues (T.Static Int
cx Int
cy Int
cw Int
ch) Int
rwh
    -- if the yPos is in the top half of the screen, then assume a Top
    -- placement, otherwise, it's a Bottom placement
    | Int
cy Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< (Int
rwh Int -> Int -> Int
forall a. Integral a => a -> a -> a
`div` Int
2) = [Int
0, Int
0, Int
st,  Int
0, Int
0, Int
0, Int
0, Int
0, Int
xs, Int
xe,  Int
0,  Int
0]
    | Bool
otherwise = [Int
0, Int
0,  Int
0, Int
sb, Int
0, Int
0, Int
0, Int
0,  Int
0,  Int
0, Int
xs, Int
xe]
    where st :: Int
st = Int
cy Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
ch
          sb :: Int
sb = Int
rwh Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
cy
          xs :: Int
xs = Int
cx -- a simple calculation for horizontal (x) placement
          xe :: Int
xe = Int
xs Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
cw Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1
getStaticStrutValues XPosition
_ Int
_ = [Int
0, Int
0, Int
0, Int
0, Int
0, Int
0, Int
0, Int
0, Int
0, Int
0, Int
0, Int
0]

hideWindow :: X.Display -> X.Window -> IO ()
hideWindow :: Display -> Atom -> IO ()
hideWindow Display
d Atom
w = do
    Display -> Atom -> [CLong] -> IO ()
setStruts' Display
d Atom
w (Int -> CLong -> [CLong]
forall a. Int -> a -> [a]
replicate Int
12 CLong
0)
    Display -> Atom -> IO ()
Xx.unmapWindow Display
d Atom
w IO () -> IO () -> IO ()
forall a b. IO a -> IO b -> IO b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Display -> Bool -> IO ()
X.sync Display
d Bool
False

showWindow :: X.Rectangle -> T.Config -> X.Display -> X.Window -> IO ()
showWindow :: Rectangle -> Config -> Display -> Atom -> IO ()
showWindow Rectangle
r Config
c Display
d Atom
w = do
    Display -> Atom -> IO ()
X.mapWindow Display
d Atom
w
    Display -> IO [Rectangle]
Xi.getScreenInfo Display
d IO [Rectangle] -> ([Rectangle] -> IO ()) -> IO ()
forall a b. IO a -> (a -> IO b) -> IO b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Rectangle -> Config -> Display -> Atom -> [Rectangle] -> IO ()
setStruts Rectangle
r Config
c Display
d Atom
w
    Display -> Bool -> IO ()
X.sync Display
d Bool
False

isMapped :: X.Display -> X.Window -> IO Bool
isMapped :: Display -> Atom -> IO Bool
isMapped Display
d Atom
w = WindowAttributes -> Bool
ism (WindowAttributes -> Bool) -> IO WindowAttributes -> IO Bool
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Display -> Atom -> IO WindowAttributes
Xx.getWindowAttributes Display
d Atom
w
    where ism :: WindowAttributes -> Bool
ism Xx.WindowAttributes { wa_map_state :: WindowAttributes -> CInt
Xx.wa_map_state = CInt
wms } = CInt
wms CInt -> CInt -> Bool
forall a. Eq a => a -> a -> Bool
/= CInt
Xx.waIsUnmapped