diff options
Diffstat (limited to 'lib/Phi/X11.hs')
-rw-r--r-- | lib/Phi/X11.hs | 47 |
1 files changed, 43 insertions, 4 deletions
diff --git a/lib/Phi/X11.hs b/lib/Phi/X11.hs index 0da8594..9bd5cd4 100644 --- a/lib/Phi/X11.hs +++ b/lib/Phi/X11.hs @@ -22,6 +22,8 @@ import Control.Monad.State import Control.Monad.Reader import Control.Monad.Trans +import System.Exit +import System.Posix.Signals import System.Posix.Types import Phi.Phi @@ -35,9 +37,11 @@ import qualified Phi.Bindings.Util as Util data XConfig = XConfig { phiXScreenInfo :: !(Display -> IO [Rectangle]) } -data PhiState = PhiState { phiRootImage :: !Surface - , phiPanels :: ![PanelState] - , phiRepaint :: !Bool +data PhiState = PhiState { phiRootImage :: !Surface + , phiPanels :: ![PanelState] + , phiRepaint :: !Bool + , phiShutdown :: !Bool + , phiShutdownHold :: !Int } data PanelState = PanelState { panelWindow :: !Window @@ -74,13 +78,27 @@ runPhi xconfig config widgets = do xSetErrorHandler phi <- initPhi + + installHandler sigTERM (termHandler phi) Nothing + installHandler sigINT (termHandler phi) Nothing + installHandler sigQUIT (termHandler phi) Nothing + disp <- openDisplay [] atoms <- initAtoms disp selectInput disp (defaultRootWindow disp) $ propertyChangeMask.|.structureNotifyMask bg <- createImageSurface FormatRGB24 1 1 - runPhiX PhiConfig { phiPhi = phi, phiXConfig = xconfig, phiPanelConfig = config, phiAtoms = atoms } PhiState { phiRootImage = bg, phiPanels = [], phiRepaint = True } $ do + runPhiX PhiConfig { phiPhi = phi + , phiXConfig = xconfig + , phiPanelConfig = config + , phiAtoms = atoms + } PhiState { phiRootImage = bg + , phiPanels = [] + , phiRepaint = True + , phiShutdown = False + , phiShutdownHold = 0 + } $ do updateRootImage disp screens <- liftIO $ phiXScreenInfo xconfig disp @@ -113,9 +131,30 @@ runPhi xconfig config widgets = do message <- receiveMessage phi handleMessage dispvar message + + case (fromMessage message) of + Just Shutdown -> + modify $ \state -> state { phiShutdown = True } + Just HoldShutdown -> + modify $ \state -> state { phiShutdownHold = phiShutdownHold state + 1 } + Just ReleaseShutdown -> + modify $ \state -> state { phiShutdownHold = phiShutdownHold state - 1 } + _ -> + return () + + shutdown <- gets phiShutdown + shutdownHold <- gets phiShutdownHold + + when (shutdown && (shutdownHold == 0)) $ + liftIO $ exitSuccess + return () +termHandler :: Phi -> Handler +termHandler phi = Catch $ sendMessage phi Shutdown + + handlePanel :: Message -> PanelState -> PanelState handlePanel message panel@PanelState {panelWidgetStates = widgets} = panel {panelWidgetStates = widgets'} where |