diff options
Diffstat (limited to 'lib/Phi')
-rw-r--r-- | lib/Phi/Border.hs | 8 | ||||
-rw-r--r-- | lib/Phi/Widget.hs | 86 | ||||
-rw-r--r-- | lib/Phi/Widgets/AlphaBox.hs | 8 | ||||
-rw-r--r-- | lib/Phi/Widgets/Clock.hs | 8 | ||||
-rw-r--r-- | lib/Phi/Widgets/X11/Systray.hs (renamed from lib/Phi/Widgets/Systray.hs) | 4 | ||||
-rw-r--r-- | lib/Phi/Widgets/X11/Taskbar.hs (renamed from lib/Phi/Widgets/Taskbar.hs) | 156 | ||||
-rw-r--r-- | lib/Phi/X11.hs | 308 | ||||
-rw-r--r-- | lib/Phi/X11/AtomList.hs | 2 |
8 files changed, 305 insertions, 275 deletions
diff --git a/lib/Phi/Border.hs b/lib/Phi/Border.hs index ca5e515..2e1e008 100644 --- a/lib/Phi/Border.hs +++ b/lib/Phi/Border.hs @@ -56,11 +56,11 @@ defaultBorderConfig = BorderConfig { margin = simpleBorderWidth 0 , borderWeight = 1 } -data Border w s c = (Widget w s c) => Border !BorderConfig !w +data Border w s c d = (Widget w s c d) => Border !BorderConfig !w -data BorderCache w s c = (Widget w s c) => BorderCache !c +data BorderCache w s c d = (Widget w s c d) => BorderCache !c -instance Eq s => Widget (Border w s c) s (BorderCache w s c) where +instance (Eq s, Display d) => Widget (Border w s c d) s (BorderCache w s c d) d where initWidget (Border _ w) = initWidget w initCache (Border _ w) = BorderCache $ initCache w @@ -165,5 +165,5 @@ roundRectangle x y width height radius = do arc (x + radius) (y + radius) radius pi (pi*3/2) closePath -border :: (Widget w s c) => BorderConfig -> w -> Border w s c +border :: (Widget w s c d) => BorderConfig -> w -> Border w s c d border = Border diff --git a/lib/Phi/Widget.hs b/lib/Phi/Widget.hs index a598887..3687630 100644 --- a/lib/Phi/Widget.hs +++ b/lib/Phi/Widget.hs @@ -1,10 +1,7 @@ -{-# LANGUAGE ExistentialQuantification, StandaloneDeriving, DeriveDataTypeable, MultiParamTypeClasses, FunctionalDependencies, TypeSynonymInstances, FlexibleInstances #-} +{-# LANGUAGE ExistentialQuantification, StandaloneDeriving, MultiParamTypeClasses, FunctionalDependencies, TypeSynonymInstances, FlexibleInstances, TypeFamilies #-} -module Phi.Widget ( XEvent(..) +module Phi.Widget ( Rectangle(..) , Display(..) - , withDisplay - , getAtoms - , XMessage(..) , unionArea , SurfaceSlice(..) , Widget(..) @@ -23,7 +20,6 @@ module Phi.Widget ( XEvent(..) import Control.Arrow import Control.Arrow.Transformer import Control.CacheArrow -import Control.Concurrent.MVar import Control.Monad import Control.Monad.State.Strict hiding (lift) import Control.Monad.IO.Class @@ -31,67 +27,57 @@ import Control.Monad.IO.Class import Data.Maybe import Data.Typeable -import Graphics.XHB import Graphics.Rendering.Cairo import Phi.Phi import Phi.X11.Atoms -data Display = Display !Connection !Atoms +data Rectangle = Rectangle { rect_x :: !Int + , rect_y :: !Int + , rect_width :: !Int + , rect_height :: !Int + } deriving (Show, Eq) -newtype XEvent = XEvent SomeEvent deriving Typeable +class Display d where + type Window d :: * -instance Show XEvent where - show _ = "XEvent (..)" - -withDisplay :: MonadIO m => Display -> (Connection -> m a) -> m a -withDisplay (Display conn _) f = f conn - -getAtoms :: Display -> Atoms -getAtoms (Display _ atoms) = atoms - -data XMessage = UpdateScreens [(RECTANGLE, WINDOW)] deriving (Show, Typeable) - - -unionArea :: RECTANGLE -> RECTANGLE -> Int +unionArea :: Rectangle -> Rectangle -> Int unionArea a b = uw*uh where - uw = max 0 $ (min ax2 bx2) - fromIntegral (max ax1 bx1) - uh = max 0 $ (min ay2 by2) - fromIntegral (max ay1 by1) + uw = max 0 $ (min ax2 bx2) - (max ax1 bx1) + uh = max 0 $ (min ay2 by2) - (max ay1 by1) - MkRECTANGLE ax1 ay1 aw ah = a - MkRECTANGLE bx1 by1 bw bh = b + Rectangle ax1 ay1 aw ah = a + Rectangle bx1 by1 bw bh = b - ax2 = fromIntegral ax1 + fromIntegral aw - ay2 = fromIntegral ay1 + fromIntegral ah + ax2 = ax1 + aw + ay2 = ay1 + ah - bx2 = fromIntegral bx1 + fromIntegral bw - by2 = fromIntegral by1 + fromIntegral bh + bx2 = bx1 + bw + by2 = by1 + bh data SurfaceSlice = SurfaceSlice !Int !Surface -class Eq s => Widget w s c | w -> s, w -> c where - initWidget :: w -> Phi -> Display -> [(RECTANGLE, WINDOW)] -> IO s +class (Eq s, Display d) => Widget w s c d | w -> s, w -> c, w -> d where + initWidget :: w -> Phi -> d -> [(Rectangle, Window d)] -> IO s initCache :: w -> c - minSize :: w -> s -> Int -> RECTANGLE -> Int + minSize :: w -> s -> Int -> Rectangle -> Int weight :: w -> Float weight _ = 0 - render :: w -> s -> Int -> Int -> Int -> Int -> RECTANGLE -> StateT c IO [(Bool, SurfaceSlice)] + render :: w -> s -> Int -> Int -> Int -> Int -> Rectangle -> StateT c IO [(Bool, SurfaceSlice)] handleMessage :: w -> s -> Message -> s handleMessage _ priv _ = priv -deriving instance Eq RECTANGLE - type IOCache = CacheArrow (Kleisli IO) -type RenderCache s = IOCache (s, Int, Int, Int, Int, RECTANGLE) Surface +type RenderCache s = IOCache (s, Int, Int, Int, Int, Rectangle) Surface createIOCache :: Eq a => (a -> IO b) -> IOCache a b createIOCache = lift . Kleisli @@ -103,8 +89,8 @@ runIOCache a = do put cache' return b -createRenderCache :: (s -> Int -> Int -> Int -> Int -> RECTANGLE -> Render ()) - -> CacheArrow (Kleisli IO) (s, Int, Int, Int, Int, RECTANGLE) Surface +createRenderCache :: (s -> Int -> Int -> Int -> Int -> Rectangle -> Render ()) + -> CacheArrow (Kleisli IO) (s, Int, Int, Int, Int, Rectangle) Surface createRenderCache f = lift . Kleisli $ \(state, x, y, w, h, screen) -> do surface <- createImageSurface FormatARGB32 w h renderWith surface $ do @@ -114,22 +100,22 @@ createRenderCache f = lift . Kleisli $ \(state, x, y, w, h, screen) -> do f state x y w h screen return surface -renderCached :: Eq s => s -> Int -> Int -> Int -> Int -> RECTANGLE -> StateT (RenderCache s) IO [(Bool, SurfaceSlice)] +renderCached :: Eq s => s -> Int -> Int -> Int -> Int -> Rectangle -> StateT (RenderCache s) IO [(Bool, SurfaceSlice)] renderCached state x y w h screen = do cache <- get (surf, updated, cache') <- liftIO $ runKleisli (runCache' cache) (state, x, y, w, h, screen) put cache' return [(updated, SurfaceSlice 0 surf)] -data CompoundWidget a sa ca b sb cb = (Widget a sa ca, Widget b sb cb) => CompoundWidget !a !b +data CompoundWidget a sa ca b sb cb d = (Widget a sa ca d, Widget b sb cb d) => CompoundWidget !a !b -data CompoundState a sa ca b sb cb = (Widget a sa ca, Widget b sb cb) => CompoundState !sa !sb -deriving instance Eq (CompoundState a sa ca b sb cb) +data CompoundState a sa ca b sb cb d = (Widget a sa ca d, Widget b sb cb d) => CompoundState !sa !sb +deriving instance Eq (CompoundState a sa ca b sb cb d) -data CompoundCache a sa ca b sb cb = (Widget a sa ca, Widget b sb cb) => CompoundCache !ca !cb +data CompoundCache a sa ca b sb cb d = (Widget a sa ca d, Widget b sb cb d) => CompoundCache !ca !cb -instance Widget (CompoundWidget a sa ca b sb cb) (CompoundState a sa ca b sb cb) (CompoundCache a sa ca b sb cb) where +instance Display d => Widget (CompoundWidget a sa ca b sb cb d) (CompoundState a sa ca b sb cb d) (CompoundCache a sa ca b sb cb d) d where initWidget (CompoundWidget a b) phi disp screens = liftM2 CompoundState (initWidget a phi disp screens) (initWidget b phi disp screens) initCache (CompoundWidget a b) = CompoundCache (initCache a) (initCache b) @@ -154,15 +140,15 @@ instance Widget (CompoundWidget a sa ca b sb cb) (CompoundState a sa ca b sb cb) handleMessage (CompoundWidget a b) (CompoundState sa sb) message = CompoundState (handleMessage a sa message) (handleMessage b sb message) -weight' :: (Widget a sa ca) => a -> Float +weight' :: (Widget a sa ca d) => a -> Float weight' = max 0 . weight -(<~>) :: (Widget a sa ca, Widget b sb cb) => a -> b -> CompoundWidget a sa ca b sb cb +(<~>) :: (Widget a sa ca d, Widget b sb cb d) => a -> b -> CompoundWidget a sa ca b sb cb d a <~> b = CompoundWidget a b -data Separator = Separator !Int !Float deriving (Show, Eq) +data Separator d = Separator !Int !Float deriving (Show, Eq) -instance Widget Separator () (RenderCache ()) where +instance Display d => Widget (Separator d) () (RenderCache ()) d where initWidget _ _ _ _ = return () initCache _ = createRenderCache $ \_ _ _ _ _ _ -> do setOperator OperatorClear @@ -173,5 +159,5 @@ instance Widget Separator () (RenderCache ()) where render _ = renderCached -separator :: Int -> Float -> Separator +separator :: Int -> Float -> Separator d separator = Separator diff --git a/lib/Phi/Widgets/AlphaBox.hs b/lib/Phi/Widgets/AlphaBox.hs index 6f989ea..59f8aea 100644 --- a/lib/Phi/Widgets/AlphaBox.hs +++ b/lib/Phi/Widgets/AlphaBox.hs @@ -13,11 +13,11 @@ import Control.Monad.State.Strict import Graphics.Rendering.Cairo -data AlphaBox w s c = (Widget w s c) => AlphaBox !Double !w +data AlphaBox w s c d = (Widget w s c d) => AlphaBox !Double !w -data AlphaBoxCache w s c = (Widget w s c) => AlphaBoxCache !c +data AlphaBoxCache w s c d = (Widget w s c d) => AlphaBoxCache !c -instance Eq s => Widget (AlphaBox w s c) s (AlphaBoxCache w s c) where +instance (Eq s, Display d) => Widget (AlphaBox w s c d) s (AlphaBoxCache w s c d) d where initWidget (AlphaBox _ w) = initWidget w initCache (AlphaBox _ w) = AlphaBoxCache $ initCache w @@ -47,6 +47,6 @@ instance Eq s => Widget (AlphaBox w s c) s (AlphaBoxCache w s c) where handleMessage (AlphaBox _ w) = handleMessage w -alphaBox :: (Widget w s c) => Double -> w -> AlphaBox w s c +alphaBox :: (Widget w s c d) => Double -> w -> AlphaBox w s c d alphaBox = AlphaBox diff --git a/lib/Phi/Widgets/Clock.hs b/lib/Phi/Widgets/Clock.hs index 9282432..26b777f 100644 --- a/lib/Phi/Widgets/Clock.hs +++ b/lib/Phi/Widgets/Clock.hs @@ -34,7 +34,7 @@ data ClockConfig = ClockConfig { clockFormat :: !String defaultClockConfig :: ClockConfig defaultClockConfig = ClockConfig "%R" (0, 0, 0, 1) 0 50 -data Clock = Clock !ClockConfig deriving (Show, Eq) +data Clock d = Clock !ClockConfig deriving (Show, Eq) deriving instance Eq ZonedTime @@ -42,7 +42,7 @@ data ClockState = ClockState !ZonedTime deriving (Show, Eq) data ClockMessage = UpdateTime !ZonedTime deriving (Show, Typeable) -instance Widget Clock ClockState (RenderCache ClockState) where +instance Display d => Widget (Clock d) ClockState (RenderCache ClockState) d where initWidget (Clock _) phi _ _ = do forkIO $ forever $ do time <- getZonedTime @@ -85,6 +85,6 @@ instance Widget Clock ClockState (RenderCache ClockState) where _ -> priv -clock :: ClockConfig -> Clock +clock :: ClockConfig -> Clock d clock config = do - Clock config
\ No newline at end of file + Clock config diff --git a/lib/Phi/Widgets/Systray.hs b/lib/Phi/Widgets/X11/Systray.hs index 27a5e34..fffb181 100644 --- a/lib/Phi/Widgets/Systray.hs +++ b/lib/Phi/Widgets/X11/Systray.hs @@ -1,7 +1,7 @@ {-# LANGUAGE MultiParamTypeClasses, DeriveDataTypeable, TypeSynonymInstances, FlexibleInstances #-} -module Phi.Widgets.Systray ( systray - ) where +module Phi.Widgets.X11.Systray ( systray + ) where import Control.Concurrent import Control.Monad diff --git a/lib/Phi/Widgets/Taskbar.hs b/lib/Phi/Widgets/X11/Taskbar.hs index f0a8196..07a7292 100644 --- a/lib/Phi/Widgets/Taskbar.hs +++ b/lib/Phi/Widgets/X11/Taskbar.hs @@ -1,15 +1,15 @@ {-# LANGUAGE MultiParamTypeClasses, DeriveDataTypeable, TypeSynonymInstances, FlexibleInstances #-} -module Phi.Widgets.Taskbar ( IconStyle - , idIconStyle - , desaturateIconStyle - , TaskStyle(..) - , DesktopStyle(..) - , TaskbarConfig(..) - , defaultTaskbarConfig - , Taskbar - , taskbar - ) where +module Phi.Widgets.X11.Taskbar ( IconStyle + , idIconStyle + , desaturateIconStyle + , TaskStyle(..) + , DesktopStyle(..) + , TaskbarConfig(..) + , defaultTaskbarConfig + , Taskbar + , taskbar + ) where import Control.Arrow import Control.Concurrent @@ -48,6 +48,7 @@ import Phi.Phi import Phi.Types import Phi.Border import Phi.Widget +import Phi.X11 import Phi.X11.Atoms import Phi.X11.Util @@ -138,7 +139,7 @@ defaultTaskbarConfig = TaskbarConfig { taskMaxSize = 200 data Taskbar = Taskbar TaskbarConfig -data TaskbarState = TaskbarState { taskbarScreens :: ![RECTANGLE] +data TaskbarState = TaskbarState { taskbarScreens :: ![Rectangle] , taskbarActiveWindow :: !WINDOW , taskbarDesktopCount :: !Int , taskbarCurrentDesktop :: !Int @@ -161,7 +162,7 @@ data WindowState = WindowState { windowTitle :: !String , windowDesktop :: !Int , windowVisible :: !Bool , windowIcons :: ![Icon] - , windowGeometry :: !RECTANGLE + , windowGeometry :: !Rectangle } deriving (Eq, Show) data WindowCache = WindowCache { createScaledIconCached :: !(IOCache ([Icon], Int) (Maybe Icon)) @@ -208,7 +209,7 @@ data TaskbarMessage = WindowListUpdate ![WINDOW] !(M.Map WINDOW WindowState) | ActiveWindowUpdate !WINDOW deriving (Typeable, Show) -instance Widget Taskbar TaskbarState (M.Map WINDOW WindowCache) where +instance Widget Taskbar TaskbarState (M.Map WINDOW WindowCache) X11 where initWidget (Taskbar _) phi dispvar screens = do phi' <- dupPhi phi forkIO $ taskbarRunner phi' dispvar @@ -398,14 +399,14 @@ windowOnDesktop :: Int -> WindowState -> Bool windowOnDesktop desktop state = (windowVisible state) && (desktop == windowDesktop state) -taskbarRunner :: Phi -> Display -> IO () -taskbarRunner phi dispvar = do - (windows, states) <- liftIO $ withDisplay dispvar $ \disp -> do - (windows, states) <- getWindowStates disp (getAtoms dispvar) M.empty - desktopCount <- getDesktopCount disp (getAtoms dispvar) - current <- getCurrentDesktop disp (getAtoms dispvar) - names <- getDesktopNames disp (getAtoms dispvar) - activeWindow <- getActiveWindow disp (getAtoms dispvar) +taskbarRunner :: Phi -> X11 -> IO () +taskbarRunner phi x11 = do + (windows, states) <- liftIO $ do + (windows, states) <- getWindowStates x11 M.empty + desktopCount <- getDesktopCount x11 + current <- getCurrentDesktop x11 + names <- getDesktopNames x11 + activeWindow <- getActiveWindow x11 sendMessage phi $ WindowListUpdate windows states sendMessage phi $ DesktopCountUpdate desktopCount sendMessage phi $ CurrentDesktopUpdate current @@ -418,23 +419,24 @@ taskbarRunner phi dispvar = do m <- receiveMessage phi case (fromMessage m) of Just (XEvent event) -> - handleEvent phi dispvar event + handleEvent phi x11 event _ -> return () -handleEvent :: Phi -> Display -> SomeEvent -> StateT ([WINDOW], M.Map WINDOW WindowState) IO () -handleEvent phi dispvar event = +handleEvent :: Phi -> X11 -> SomeEvent -> StateT ([WINDOW], M.Map WINDOW WindowState) IO () +handleEvent phi x11 event = case (fromEvent event) of - Just e -> handlePropertyNotifyEvent phi dispvar e + Just e -> handlePropertyNotifyEvent phi x11 e Nothing -> case (fromEvent event) of - Just e -> handleConfigureNotifyEvent phi dispvar e + Just e -> handleConfigureNotifyEvent phi x11 e Nothing -> return () -handlePropertyNotifyEvent :: Phi -> Display -> PropertyNotifyEvent -> StateT ([WINDOW], M.Map WINDOW WindowState) IO () -handlePropertyNotifyEvent phi dispvar MkPropertyNotifyEvent {atom_PropertyNotifyEvent = atom, window_PropertyNotifyEvent = window} = do - let atoms = getAtoms dispvar - +handlePropertyNotifyEvent :: Phi -> X11 -> PropertyNotifyEvent -> StateT ([WINDOW], M.Map WINDOW WindowState) IO () +handlePropertyNotifyEvent phi x11 MkPropertyNotifyEvent {atom_PropertyNotifyEvent = atom, window_PropertyNotifyEvent = window} = do + let atoms = x11Atoms x11 + rootwin = root_SCREEN . x11Screen $ x11 + when (elem atom $ map ($ atoms) [ atom_NET_ACTIVE_WINDOW , atom_NET_NUMBER_OF_DESKTOPS , atom_NET_CURRENT_DESKTOP @@ -445,29 +447,28 @@ handlePropertyNotifyEvent phi dispvar MkPropertyNotifyEvent {atom_PropertyNotify , atom_NET_WM_NAME , atom_NET_WM_DESKTOP , atom_NET_WM_STATE - ]) $ withDisplay dispvar $ \conn -> do - let rootwin = getRoot conn + ]) $ do if (window == rootwin) then do when (atom == atom_NET_ACTIVE_WINDOW atoms) $ do - activeWindow <- liftIO $ getActiveWindow conn atoms + activeWindow <- liftIO $ getActiveWindow x11 sendMessage phi $ ActiveWindowUpdate activeWindow sendMessage phi Repaint when (atom == atom_NET_NUMBER_OF_DESKTOPS atoms) $ do - desktopCount <- liftIO $ getDesktopCount conn atoms + desktopCount <- liftIO $ getDesktopCount x11 sendMessage phi $ DesktopCountUpdate desktopCount sendMessage phi Repaint when (atom == atom_NET_CURRENT_DESKTOP atoms) $ do - current <- liftIO $ getCurrentDesktop conn atoms + current <- liftIO $ getCurrentDesktop x11 sendMessage phi $ CurrentDesktopUpdate current sendMessage phi Repaint when (atom == atom_NET_DESKTOP_NAMES atoms) $ do - names <- liftIO $ getDesktopNames conn atoms + names <- liftIO $ getDesktopNames x11 sendMessage phi $ DesktopNamesUpdate names sendMessage phi Repaint when (atom == atom_NET_CLIENT_LIST atoms) $ do (windows, windowStates) <- get - (windows', windowStates') <- liftIO $ getWindowStates conn atoms windowStates + (windows', windowStates') <- liftIO $ getWindowStates x11 windowStates when (windows /= windows') $ do sendMessage phi $ WindowListUpdate windows' windowStates' @@ -479,14 +480,14 @@ handlePropertyNotifyEvent phi dispvar MkPropertyNotifyEvent {atom_PropertyNotify when (elem window windows) $ do case () of _ | (atom == atom_NET_WM_ICON atoms) -> do - icons <- liftIO $ getWindowIcons conn atoms window + icons <- liftIO $ getWindowIcons x11 window let windowStates' = M.update (\state -> Just state {windowIcons = icons}) window windowStates sendMessage phi $ WindowListUpdate windows windowStates' sendMessage phi Repaint put (windows, windowStates') | otherwise -> do - (name, desktop, visible) <- liftIO $ getWindowInfo conn atoms window + (name, desktop, visible) <- liftIO $ getWindowInfo x11 window let mwindowState = M.lookup window windowStates case mwindowState of Just windowState -> do @@ -501,12 +502,13 @@ handlePropertyNotifyEvent phi dispvar MkPropertyNotifyEvent {atom_PropertyNotify return () -handleConfigureNotifyEvent :: Phi -> Display -> ConfigureNotifyEvent -> StateT ([WINDOW], M.Map WINDOW WindowState) IO () -handleConfigureNotifyEvent phi dispvar MkConfigureNotifyEvent {window_ConfigureNotifyEvent = window} = do +handleConfigureNotifyEvent :: Phi -> X11 -> ConfigureNotifyEvent -> StateT ([WINDOW], M.Map WINDOW WindowState) IO () +handleConfigureNotifyEvent phi x11 MkConfigureNotifyEvent {window_ConfigureNotifyEvent = window} = do + let conn = x11Connection x11 (windows, windowStates) <- get - when (elem window windows) $ withDisplay dispvar $ \conn -> do + when (elem window windows) $ do let geom = fmap windowGeometry . M.lookup window $ windowStates - geom' <- liftIO $ getWindowGeometry conn window + geom' <- liftIO $ getWindowGeometry x11 window when (geom /= (Just geom')) $ do let windowStates' = M.update (\state -> Just state {windowGeometry = geom'}) window windowStates sendMessage phi $ WindowListUpdate windows windowStates' @@ -514,30 +516,30 @@ handleConfigureNotifyEvent phi dispvar MkConfigureNotifyEvent {window_ConfigureN put (windows, windowStates') -getDesktopCount :: Connection -> Atoms -> IO Int -getDesktopCount conn atoms = - liftM (fromIntegral . fromMaybe 0 . join . fmap listToMaybe) $ getProperty32 conn (getRoot conn) (atom_NET_NUMBER_OF_DESKTOPS atoms) +getDesktopCount :: X11 -> IO Int +getDesktopCount x11 = + liftM (fromIntegral . fromMaybe 0 . join . fmap listToMaybe) $ getProperty32 (x11Connection x11) (root_SCREEN . x11Screen $ x11) (atom_NET_NUMBER_OF_DESKTOPS . x11Atoms $ x11) -getCurrentDesktop :: Connection -> Atoms -> IO Int -getCurrentDesktop conn atoms = - liftM (fromIntegral . fromMaybe (-1) . join . fmap listToMaybe) $ getProperty32 conn (getRoot conn) (atom_NET_CURRENT_DESKTOP atoms) +getCurrentDesktop :: X11 -> IO Int +getCurrentDesktop x11 = + liftM (fromIntegral . fromMaybe (-1) . join . fmap listToMaybe) $ getProperty32 (x11Connection x11) (root_SCREEN . x11Screen $ x11) (atom_NET_CURRENT_DESKTOP . x11Atoms $ x11) -getDesktopNames :: Connection -> Atoms -> IO [String] -getDesktopNames conn atoms = - liftM (map (decode . map fromIntegral) . break' . fromMaybe []) $ getProperty8 conn (getRoot conn) (atom_NET_DESKTOP_NAMES atoms) +getDesktopNames :: X11 -> IO [String] +getDesktopNames x11 = + liftM (map (decode . map fromIntegral) . break' . fromMaybe []) $ getProperty8 (x11Connection x11) (root_SCREEN . x11Screen $ x11) (atom_NET_DESKTOP_NAMES . x11Atoms $ x11) where break' l = case dropWhile (== 0) l of [] -> [] l' -> w : break' l'' where (w, l'') = break (== 0) l' -getActiveWindow :: Connection -> Atoms -> IO WINDOW -getActiveWindow conn atoms = - liftM (fromXid . toXid . fromMaybe 0 . join . fmap listToMaybe) $ getProperty32 conn (getRoot conn) (atom_NET_ACTIVE_WINDOW atoms) +getActiveWindow :: X11 -> IO WINDOW +getActiveWindow x11 = + liftM (fromXid . toXid . fromMaybe 0 . join . fmap listToMaybe) $ getProperty32 (x11Connection x11) (root_SCREEN . x11Screen $ x11) (atom_NET_ACTIVE_WINDOW . x11Atoms $ x11) -getWindowStates :: Connection -> Atoms -> M.Map WINDOW WindowState -> IO ([WINDOW], M.Map WINDOW WindowState) -getWindowStates conn atoms windowStates = do - windows <- getWindowList conn atoms +getWindowStates :: X11 -> M.Map WINDOW WindowState -> IO ([WINDOW], M.Map WINDOW WindowState) +getWindowStates x11 windowStates = do + windows <- getWindowList x11 let windowStates' = map (\w -> (w, M.lookup w windowStates)) windows @@ -547,15 +549,15 @@ getWindowStates conn atoms windowStates = do where getWindowState' (window, Just windowState) = return (window, windowState) getWindowState' (window, Nothing) = do - changeWindowAttributes conn window $ toValueParam [(CWEventMask, toMask [EventMaskPropertyChange, EventMaskStructureNotify])] - windowState <- getWindowState conn atoms window + changeWindowAttributes (x11Connection x11) window $ toValueParam [(CWEventMask, toMask [EventMaskPropertyChange, EventMaskStructureNotify])] + windowState <- getWindowState x11 window return (window, windowState) -getWindowState :: Connection -> Atoms -> WINDOW -> IO WindowState -getWindowState conn atoms window = do - (name, workspace, visible) <- getWindowInfo conn atoms window - icons <- getWindowIcons conn atoms window - geom <- getWindowGeometry conn window +getWindowState :: X11 -> WINDOW -> IO WindowState +getWindowState x11 window = do + (name, workspace, visible) <- getWindowInfo x11 window + icons <- getWindowIcons x11 window + geom <- getWindowGeometry x11 window return $ WindowState { windowTitle = name , windowDesktop = workspace @@ -564,8 +566,10 @@ getWindowState conn atoms window = do , windowGeometry = geom } -getWindowInfo :: Connection -> Atoms -> WINDOW -> IO (String, Int, Bool) -getWindowInfo conn atoms window = do +getWindowInfo :: X11 -> WINDOW -> IO (String, Int, Bool) +getWindowInfo x11 window = do + let conn = x11Connection x11 + atoms = x11Atoms x11 netwmname <- liftM (fmap (decode . map fromIntegral)) $ getProperty8 conn window (atom_NET_WM_NAME atoms) wmname <- case netwmname of Just name -> return name @@ -578,8 +582,8 @@ getWindowInfo conn atoms window = do where unsignedChr = chr . fromIntegral -getWindowIcons :: Connection -> Atoms -> WINDOW -> IO [Icon] -getWindowIcons conn atoms window = getProperty32 conn window (atom_NET_WM_ICON atoms) >>= readIcons . fromMaybe [] +getWindowIcons :: X11 -> WINDOW -> IO [Icon] +getWindowIcons x11 window = getProperty32 (x11Connection x11) window (atom_NET_WM_ICON . x11Atoms $ x11) >>= readIcons . fromMaybe [] readIcons :: [Word32] -> IO [Icon] @@ -612,9 +616,13 @@ premultiply c = a .|. r .|. g .|. b b = pm bmask -getWindowGeometry :: Connection -> WINDOW -> IO RECTANGLE -getWindowGeometry conn window = - getGeometry conn (fromXid . toXid $ window) >>= getReply >>= return . ((const $ MkRECTANGLE 0 0 0 0) ||| (\(MkGetGeometryReply _ _ x y width height _) -> MkRECTANGLE x y width height)) +getWindowGeometry :: X11 -> WINDOW -> IO Rectangle +getWindowGeometry x11 window = + getGeometry (x11Connection x11) (fromXid . toXid $ window) >>= getReply >>= + return . ((const $ Rectangle 0 0 0 0) ||| (\(MkGetGeometryReply _ _ x y width height _) -> Rectangle (fi x) (fi y) (fi width) (fi height))) + where + fi :: (Integral a, Num b) => a -> b + fi = fromIntegral showWindow :: Connection -> Atoms -> WINDOW -> IO Bool showWindow conn atoms window = do @@ -634,8 +642,8 @@ showWindow conn atoms window = do ] -getWindowList :: Connection -> Atoms -> IO [WINDOW] -getWindowList conn atoms = liftM (map (fromXid . toXid) . join . maybeToList) $ getProperty32 conn (getRoot conn) (atom_NET_CLIENT_LIST atoms) +getWindowList :: X11 -> IO [WINDOW] +getWindowList x11 = liftM (map (fromXid . toXid) . join . maybeToList) $ getProperty32 (x11Connection x11) (root_SCREEN . x11Screen $ x11) (atom_NET_CLIENT_LIST . x11Atoms $ x11) taskbar :: TaskbarConfig -> Taskbar taskbar = Taskbar diff --git a/lib/Phi/X11.hs b/lib/Phi/X11.hs index 7e0bfff..713b162 100644 --- a/lib/Phi/X11.hs +++ b/lib/Phi/X11.hs @@ -1,13 +1,17 @@ -{-# LANGUAGE GeneralizedNewtypeDeriving, ExistentialQuantification #-} +{-# LANGUAGE GeneralizedNewtypeDeriving, ExistentialQuantification, TypeFamilies, FlexibleContexts, DeriveDataTypeable #-} -module Phi.X11 ( XConfig(..) +module Phi.X11 ( X11(..) + , XEvent(..) + , XMessage(..) + , XConfig(..) , defaultXConfig , runPhi ) where -import Graphics.XHB +import Graphics.XHB hiding (Window) +import qualified Graphics.XHB.Connection.Open as CO import Graphics.XHB.Gen.Xinerama -import Graphics.XHB.Gen.Xproto +import Graphics.XHB.Gen.Xproto hiding (Window) import Graphics.Rendering.Cairo @@ -36,33 +40,51 @@ import Phi.Phi import Phi.X11.Util import qualified Phi.Types as Phi import qualified Phi.Panel as Panel -import qualified Phi.Widget as Widget -import Phi.Widget hiding (Display, handleMessage) +import qualified Phi.Widget as Widget (handleMessage) +import Phi.Widget hiding (handleMessage) import Phi.X11.Atoms -data XConfig = XConfig { phiXScreenInfo :: !(Connection -> IO [RECTANGLE]) +data X11 = X11 { x11Connection :: !Connection + , x11Atoms :: !Atoms + , x11Screen :: !SCREEN + } + +instance Display X11 where + type Window X11 = WINDOW + + +newtype XEvent = XEvent SomeEvent deriving Typeable + +instance Show XEvent where + show _ = "XEvent (..)" + +data XMessage = UpdateScreens [(Rectangle, WINDOW)] deriving (Show, Typeable) + + +data XConfig = XConfig { phiXScreenInfo :: !(X11 -> IO [Rectangle]) } -data PhiState w s c = (Widget.Widget w s c) => PhiState { phiRootImage :: !Surface - , phiPanels :: ![PanelState w s c] - , phiRepaint :: !Bool - , phiShutdown :: !Bool - , phiShutdownHold :: !Int - , phiWidgetState :: !s - } - -data PanelState w s c = (Widget.Widget w s c) => PanelState { panelWindow :: !WINDOW - , panelPixmap :: !PIXMAP - , panelArea :: !RECTANGLE - , panelScreenArea :: !RECTANGLE - , panelWidgetCache :: !c - } +data PhiState w s c = (Widget w s c X11) => PhiState { phiRootImage :: !Surface + , phiPanels :: ![PanelState w s c] + , phiRepaint :: !Bool + , phiShutdown :: !Bool + , phiShutdownHold :: !Int + , phiWidgetState :: !s + } + +data PanelState w s c = (Widget w s c X11) => PanelState { panelWindow :: !WINDOW + , panelPixmap :: !PIXMAP + , panelArea :: !Rectangle + , panelScreenArea :: !Rectangle + , panelWidgetCache :: !c + } data PhiConfig w s c = PhiConfig { phiPhi :: !Phi , phiPanelConfig :: !Panel.PanelConfig , phiXConfig :: !XConfig - , phiAtoms :: !Atoms + , phiX11 :: !X11 + , phiXCB :: !XCB.Connection , phiWidget :: !w } @@ -81,17 +103,22 @@ runPhiX config st (PhiX a) = runPhiReader config $ runStateT a st defaultXConfig = XConfig { phiXScreenInfo = getScreenInfo } -getScreenInfo :: Connection -> IO [RECTANGLE] -getScreenInfo conn = do +getScreenInfo :: X11 -> IO [Rectangle] +getScreenInfo x11 = do + let conn = x11Connection x11 + screen = x11Screen x11 exs <- queryScreens conn >>= getReply case exs of Right xs -> return . map screenInfoToRect $ screen_info_QueryScreensReply xs - Left _ -> getGeometry conn (fromXid . toXid $ getRoot conn) >>= getReply' "getScreenInfo: getGeometry failed" >>= - return . (\(MkGetGeometryReply _ _ x y w h _) -> [MkRECTANGLE x y w h]) + Left _ -> getGeometry conn (fromXid . toXid $ root_SCREEN screen) >>= getReply' "getScreenInfo: getGeometry failed" >>= + return . (\(MkGetGeometryReply _ _ x y w h _) -> [Rectangle (fi x) (fi y) (fi w) (fi h)]) where - screenInfoToRect (MkScreenInfo x y w h) = MkRECTANGLE x y w h + screenInfoToRect (MkScreenInfo x y w h) = Rectangle (fi x) (fi y) (fi w) (fi h) + + fi :: (Integral a, Num b) => a -> b + fi = fromIntegral -runPhi :: (Widget.Widget w s c) => XConfig -> Panel.PanelConfig -> w -> IO () +runPhi :: (Widget w s c X11) => XConfig -> Panel.PanelConfig -> w -> IO () runPhi xconfig config widget = do phi <- initPhi @@ -102,24 +129,30 @@ runPhi xconfig config widget = do conn <- liftM fromJust connect xcb <- XCB.connect + let dispname = displayInfo conn + screen = (roots_Setup . connectionSetup $ conn) !! CO.screen dispname + atoms <- initAtoms conn - changeWindowAttributes conn (getRoot conn) $ toValueParam [(CWEventMask, toMask [EventMaskPropertyChange, EventMaskStructureNotify])] + changeWindowAttributes conn (root_SCREEN screen) $ toValueParam [(CWEventMask, toMask [EventMaskPropertyChange, EventMaskStructureNotify])] bg <- createImageSurface FormatRGB24 1 1 - screens <- liftIO $ phiXScreenInfo xconfig conn - panelWindows <- mapM (createPanelWindow conn config) screens - let dispvar = Widget.Display conn atoms - widget' = widget <~> separator 0 (if weight widget > 0 then 0 else 1) + let x11 = X11 conn atoms screen + + screens <- liftIO $ phiXScreenInfo xconfig x11 + panelWindows <- mapM (createPanelWindow conn screen config) screens + + let widget' = widget <~> separator 0 (if weight widget > 0 then 0 else 1) screenPanels = zip screens panelWindows - initialState <- Widget.initWidget widget' phi dispvar screenPanels + initialState <- initWidget widget' phi x11 screenPanels runPhiX PhiConfig { phiPhi = phi , phiXConfig = xconfig , phiPanelConfig = config - , phiAtoms = atoms + , phiX11 = x11 + , phiXCB = xcb , phiWidget = widget' } PhiState { phiRootImage = bg @@ -129,15 +162,15 @@ runPhi xconfig config widget = do , phiShutdownHold = 0 , phiWidgetState = initialState } $ do - updateRootImage conn xcb + updateRootImage - panels <- mapM (\(screen, window) -> createPanel conn window screen) screenPanels + panels <- mapM (\(screen, window) -> createPanel window screen) screenPanels - forM_ panels $ setPanelProperties conn + forM_ panels setPanelProperties modify $ \state -> state { phiPanels = panels } - updatePanels conn xcb + updatePanels forM_ panels $ liftIO . mapWindow conn . panelWindow @@ -150,11 +183,11 @@ runPhi xconfig config widget = do available <- messageAvailable phi when (not available && repaint) $ do - updatePanels conn xcb + updatePanels modify $ \state -> state {phiRepaint = False} message <- receiveMessage phi - handleMessage conn xcb message + handleMessage message case (fromMessage message) of Just Shutdown -> @@ -179,8 +212,8 @@ termHandler :: Phi -> Handler termHandler phi = Catch $ sendMessage phi Shutdown -handleMessage :: (Widget w s c) => Connection -> XCB.Connection -> Message -> PhiX w s c () -handleMessage conn xcb m = do +handleMessage :: (Widget w s c X11) => Message -> PhiX w s c () +handleMessage m = do w <- asks phiWidget modify $ \state -> state {phiWidgetState = Widget.handleMessage w (phiWidgetState state) m} @@ -190,81 +223,86 @@ handleMessage conn xcb m = do _ -> case (fromMessage m) of Just (XEvent event) -> - handleEvent conn xcb event + handleEvent event _ -> return () -handleEvent :: (Widget w s c) => Connection -> XCB.Connection -> SomeEvent -> PhiX w s c () -handleEvent conn xcb event = +handleEvent :: (Widget w s c X11) => SomeEvent -> PhiX w s c () +handleEvent event = case (fromEvent event) of - Just e -> handlePropertyNotifyEvent conn xcb e + Just e -> handlePropertyNotifyEvent e Nothing -> case (fromEvent event) of - Just e -> handleConfigureNotifyEvent conn e + Just e -> handleConfigureNotifyEvent e Nothing -> return () -handlePropertyNotifyEvent :: (Widget w s c) => Connection -> XCB.Connection -> PropertyNotifyEvent -> PhiX w s c () -handlePropertyNotifyEvent conn xcb MkPropertyNotifyEvent { atom_PropertyNotifyEvent = atom } = do +handlePropertyNotifyEvent :: (Widget w s c X11) => PropertyNotifyEvent -> PhiX w s c () +handlePropertyNotifyEvent MkPropertyNotifyEvent { atom_PropertyNotifyEvent = atom } = do phi <- asks phiPhi - atoms <- asks phiAtoms + atoms <- asks (x11Atoms . phiX11) panels <- gets phiPanels when (atom == atom_XROOTPMAP_ID atoms || atom == atom_XROOTMAP_ID atoms) $ do - updateRootImage conn xcb + updateRootImage sendMessage phi ResetBackground sendMessage phi Repaint -handleConfigureNotifyEvent :: (Widget w s c) => Connection -> ConfigureNotifyEvent -> PhiX w s c () -handleConfigureNotifyEvent conn MkConfigureNotifyEvent { window_ConfigureNotifyEvent = window } | window == getRoot conn = do - phi <- asks phiPhi - xconfig <- asks phiXConfig - config <- asks phiPanelConfig - panels <- gets phiPanels - let screens = map panelScreenArea panels - screens' <- liftIO $ phiXScreenInfo xconfig conn - - when (screens /= screens') $ do - liftIO $ do - mapM_ (freePixmap conn . panelPixmap) panels - mapM_ (destroyWindow conn . panelWindow) $ drop (length screens') panels - - let panelsScreens = zip screens' $ map Just panels ++ repeat Nothing - - panels' <- forM panelsScreens $ \(screen, mpanel) -> - case mpanel of - Just panel -> do - let rect = panelBounds config screen - win = panelWindow panel - - liftIO $ configureWindow conn win $ toValueParam [ (ConfigWindowX, fromIntegral $ x_RECTANGLE rect) - , (ConfigWindowY, fromIntegral $ y_RECTANGLE rect) - , (ConfigWindowWidth, fromIntegral $ width_RECTANGLE rect) - , (ConfigWindowHeight, fromIntegral $ height_RECTANGLE rect) - ] - - panel' <- createPanel conn win screen - setPanelProperties conn panel' - - return panel' - Nothing -> do - win <- liftIO $ createPanelWindow conn config screen - panel <- createPanel conn win screen - setPanelProperties conn panel - liftIO $ mapWindow conn $ panelWindow panel - return panel - - modify $ \state -> state { phiPanels = panels' } +handleConfigureNotifyEvent :: (Widget w s c X11) => ConfigureNotifyEvent -> PhiX w s c () +handleConfigureNotifyEvent MkConfigureNotifyEvent { window_ConfigureNotifyEvent = window } = do + x11 <- asks phiX11 + let conn = x11Connection x11 + screen = x11Screen x11 + rootWindow = root_SCREEN screen + when (window == rootWindow) $ do + phi <- asks phiPhi + xconfig <- asks phiXConfig + config <- asks phiPanelConfig + panels <- gets phiPanels + let screens = map panelScreenArea panels + screens' <- liftIO $ phiXScreenInfo xconfig x11 - sendMessage phi $ UpdateScreens $ map (panelScreenArea &&& panelWindow) panels' - sendMessage phi Repaint - -handleConfigureNotifyEvent _ _ = return () + when (screens /= screens') $ do + liftIO $ do + mapM_ (freePixmap conn . panelPixmap) panels + mapM_ (destroyWindow conn . panelWindow) $ drop (length screens') panels + + let panelsScreens = zip screens' $ map Just panels ++ repeat Nothing + + panels' <- forM panelsScreens $ \(screenarea, mpanel) -> + case mpanel of + Just panel -> do + let rect = panelBounds config screenarea + win = panelWindow panel + + liftIO $ configureWindow conn win $ toValueParam [ (ConfigWindowX, fromIntegral $ rect_x rect) + , (ConfigWindowY, fromIntegral $ rect_y rect) + , (ConfigWindowWidth, fromIntegral $ rect_width rect) + , (ConfigWindowHeight, fromIntegral $ rect_height rect) + ] + + panel' <- createPanel win screenarea + setPanelProperties panel' + + return panel' + Nothing -> do + win <- liftIO $ createPanelWindow conn screen config screenarea + panel <- createPanel win screenarea + setPanelProperties panel + liftIO $ mapWindow conn $ panelWindow panel + return panel + + modify $ \state -> state { phiPanels = panels' } + + sendMessage phi $ UpdateScreens $ map (panelScreenArea &&& panelWindow) panels' + sendMessage phi Repaint receiveEvents :: Phi -> Connection -> IO () receiveEvents phi conn = do forever $ waitForEvent conn >>= sendMessage phi . XEvent -updatePanels :: (Widget w s c) => Connection -> XCB.Connection -> PhiX w s c () -updatePanels conn xcb = do +updatePanels :: (Widget w s c X11) => PhiX w s c () +updatePanels = do + X11 conn _ screen <- asks phiX11 + xcb <- asks phiXCB w <- asks phiWidget s <- gets phiWidgetState rootImage <- gets phiRootImage @@ -275,17 +313,16 @@ updatePanels conn xcb = do area = panelArea panel (panelSurfaces, cache') <- liftIO $ flip runStateT (panelWidgetCache panel) $ - (withDimension area $ Widget.render w s 0 0) (panelScreenArea panel) + (withDimension area $ render w s 0 0) (panelScreenArea panel) - let screen = head . roots_Setup . connectionSetup $ conn - visualtype = fromJust $ findVisualtype screen (root_visual_SCREEN screen) + let visualtype = fromJust $ findVisualtype screen (root_visual_SCREEN screen) xbuffer <- liftIO $ withDimension area $ XCB.createXCBSurface xcb (fromXid . toXid $ pixmap) visualtype liftIO $ (withDimension area $ withSimilarSurface xbuffer ContentColor) $ \buffer -> do renderWith buffer $ do save - translate (-(fromIntegral $ x_RECTANGLE area)) (-(fromIntegral $ y_RECTANGLE area)) + translate (-(fromIntegral $ rect_x area)) (-(fromIntegral $ rect_y area)) withPatternForSurface rootImage $ \pattern -> do patternSetExtend pattern ExtendRepeat setSource pattern @@ -313,12 +350,12 @@ updatePanels conn xcb = do modify $ \state -> state { phiPanels = panels' } -updateRootImage :: Connection -> XCB.Connection -> PhiX w s c () -updateRootImage conn xcb = do - atoms <- asks phiAtoms +updateRootImage :: PhiX w s c () +updateRootImage = do + X11 conn atoms screen <- asks phiX11 + xcb <- asks phiXCB - let screen = head . roots_Setup . connectionSetup $ conn - visualtype = fromJust $ findVisualtype screen (root_visual_SCREEN screen) + let visualtype = fromJust $ findVisualtype screen (root_visual_SCREEN screen) rootwin = root_SCREEN screen pixmap <- liftM (fromXid . toXid . fromMaybe 0 . listToMaybe . join . catMaybes) $ forM [atom_XROOTPMAP_ID atoms, atom_XROOTMAP_ID atoms] $ @@ -355,12 +392,12 @@ updateRootImage conn xcb = do return () -createPanel :: (Widget w s c) => Connection -> WINDOW -> RECTANGLE -> PhiX w s c (PanelState w s c) -createPanel conn win screenRect = do +createPanel :: (Widget w s c X11) => WINDOW -> Rectangle -> PhiX w s c (PanelState w s c) +createPanel win screenRect = do + (conn, screen) <- asks $ (x11Connection &&& x11Screen) . phiX11 config <- asks phiPanelConfig w <- asks phiWidget let rect = panelBounds config screenRect - screen = head . roots_Setup . connectionSetup $ conn depth = root_depth_SCREEN screen pixmap <- liftIO $ newResource conn @@ -374,10 +411,9 @@ createPanel conn win screenRect = do , panelWidgetCache = initCache w } -createPanelWindow :: Connection -> Panel.PanelConfig -> RECTANGLE -> IO WINDOW -createPanelWindow conn config screenRect = do +createPanelWindow :: Connection -> SCREEN -> Panel.PanelConfig -> Rectangle -> IO WINDOW +createPanelWindow conn screen config screenRect = do let rect = panelBounds config screenRect - screen = head . roots_Setup . connectionSetup $ conn depth = root_depth_SCREEN screen rootwin = root_SCREEN screen visual = root_visual_SCREEN screen @@ -387,9 +423,9 @@ createPanelWindow conn config screenRect = do return win -setPanelProperties :: Connection -> PanelState w s c -> PhiX w s c () -setPanelProperties conn panel = do - atoms <- asks phiAtoms +setPanelProperties :: PanelState w s c -> PhiX w s c () +setPanelProperties panel = do + (conn, atoms) <- asks $ (x11Connection &&& x11Atoms) . phiX11 liftIO $ do let name = map (fromIntegral . ord) "Phi" changeProperty8 conn PropModeReplace (panelWindow panel) (atomWM_NAME atoms) (atomSTRING atoms) name @@ -408,28 +444,28 @@ setPanelProperties conn panel = do changeProperty8 conn PropModeReplace (panelWindow panel) (atomWM_CLASS atoms) (atomSTRING atoms) $ map (fromIntegral . ord) "phi\0Phi" - setStruts conn panel + setStruts panel -setStruts :: Connection -> PanelState w s c -> PhiX w s c () -setStruts conn panel = do - atoms <- asks phiAtoms +setStruts :: PanelState w s c -> PhiX w s c () +setStruts panel = do + X11 conn atoms screen <- asks phiX11 config <- asks phiPanelConfig - let rootwin = getRoot conn + let rootwin = root_SCREEN screen position = Panel.panelPosition config area = panelArea panel rootHeight <- liftIO $ getGeometry conn (fromXid . toXid $ rootwin) >>= getReply' "setStruts: getGeometry failed" >>= return . height_GetGeometryReply let struts = [makeStruts i | i <- [0..11]] where - makeTopStruts 2 = (fromIntegral $ y_RECTANGLE area) + (fromIntegral $ height_RECTANGLE area) - makeTopStruts 8 = (fromIntegral $ x_RECTANGLE area) - makeTopStruts 9 = (fromIntegral $ x_RECTANGLE area) + (fromIntegral $ width_RECTANGLE area) - 1 + makeTopStruts 2 = (fromIntegral $ rect_y area) + (fromIntegral $ rect_height area) + makeTopStruts 8 = (fromIntegral $ rect_x area) + makeTopStruts 9 = (fromIntegral $ rect_x area) + (fromIntegral $ rect_width area) - 1 makeTopStruts _ = 0 - makeBottomStruts 3 = (fromIntegral rootHeight) - (fromIntegral $ y_RECTANGLE area) - makeBottomStruts 10 = (fromIntegral $ x_RECTANGLE area) - makeBottomStruts 11 = (fromIntegral $ x_RECTANGLE area) + (fromIntegral $ width_RECTANGLE area) - 1 + makeBottomStruts 3 = (fromIntegral rootHeight) - (fromIntegral $ rect_y area) + makeBottomStruts 10 = (fromIntegral $ rect_x area) + makeBottomStruts 11 = (fromIntegral $ rect_x area) + (fromIntegral $ rect_width area) - 1 makeBottomStruts _ = 0 makeStruts = case position of @@ -441,17 +477,17 @@ setStruts conn panel = do changeProperty32 conn PropModeReplace (panelWindow panel) (atom_NET_WM_STRUT_PARTIAL atoms) (atomCARDINAL atoms) struts -panelBounds :: Panel.PanelConfig -> RECTANGLE -> RECTANGLE +panelBounds :: Panel.PanelConfig -> Rectangle -> Rectangle panelBounds config screenBounds = case Panel.panelPosition config of - Phi.Top -> screenBounds { height_RECTANGLE = fromIntegral $ Panel.panelSize config } - Phi.Bottom -> screenBounds { height_RECTANGLE = fromIntegral $ Panel.panelSize config, - y_RECTANGLE = (y_RECTANGLE screenBounds) + (fromIntegral $ height_RECTANGLE screenBounds) - (fromIntegral $ Panel.panelSize config) } + Phi.Top -> screenBounds { rect_height = Panel.panelSize config } + Phi.Bottom -> screenBounds { rect_height = Panel.panelSize config, + rect_y = rect_y screenBounds + rect_height screenBounds - Panel.panelSize config } -withRectangle :: (Num x, Num y, Num w, Num h) => RECTANGLE -> (x -> y -> w -> h -> a) -> a +withRectangle :: (Num x, Num y, Num w, Num h) => Rectangle -> (x -> y -> w -> h -> a) -> a withRectangle r = withDimension r . withPosition r -withPosition :: (Num x, Num y) => RECTANGLE -> (x -> y -> a) -> a -withPosition r f = f (fromIntegral $ x_RECTANGLE r) (fromIntegral $ y_RECTANGLE r) +withPosition :: (Num x, Num y) => Rectangle -> (x -> y -> a) -> a +withPosition r f = f (fromIntegral $ rect_x r) (fromIntegral $ rect_y r) -withDimension :: (Num w, Num h) => RECTANGLE -> (w -> h -> a) -> a -withDimension r f = f (fromIntegral $ width_RECTANGLE r) (fromIntegral $ height_RECTANGLE r) +withDimension :: (Num w, Num h) => Rectangle -> (w -> h -> a) -> a +withDimension r f = f (fromIntegral $ rect_width r) (fromIntegral $ rect_height r) diff --git a/lib/Phi/X11/AtomList.hs b/lib/Phi/X11/AtomList.hs index 5fbd98c..31a029a 100644 --- a/lib/Phi/X11/AtomList.hs +++ b/lib/Phi/X11/AtomList.hs @@ -53,4 +53,4 @@ atoms = [ "ATOM" -- the expression must have the type (Connection -> String) specialAtoms :: [(String, Q Exp)] specialAtoms = [ ("_NET_SYSTEM_TRAY_SCREEN", [|("_NET_SYSTEM_TRAY_S" ++) . show . screen . displayInfo|]) - ]
\ No newline at end of file + ] |