summaryrefslogtreecommitdiffstats
path: root/lib/Phi/X11.hs
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Phi/X11.hs')
-rw-r--r--lib/Phi/X11.hs47
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