summaryrefslogtreecommitdiffstats
path: root/XMonad
diff options
context:
space:
mode:
authortv <tv@krebsco.de>2018-11-29 17:32:25 +0100
committertv <tv@krebsco.de>2018-11-29 17:32:25 +0100
commitb1032b849d72b246d7098b5940bbe61e8ac719c6 (patch)
tree01b7caff88fa0b62a9f53c6cc27d1b3eb4316668 /XMonad
parent97c4b6c5a2db1591a6bf181f787e109b827684ab (diff)
shutdown: wait for process to exit
Diffstat (limited to 'XMonad')
-rw-r--r--XMonad/Stockholm/Shutdown.hs75
1 files changed, 58 insertions, 17 deletions
diff --git a/XMonad/Stockholm/Shutdown.hs b/XMonad/Stockholm/Shutdown.hs
index 6786c7c..373214e 100644
--- a/XMonad/Stockholm/Shutdown.hs
+++ b/XMonad/Stockholm/Shutdown.hs
@@ -1,17 +1,40 @@
{-# LANGUAGE LambdaCase #-}
module XMonad.Stockholm.Shutdown
- ( sendShutdownEvent
- , handleShutdownEvent
+ ( newShutdownEventHandler
, shutdown
)
where
-import Control.Monad
-import Data.Monoid
+import Control.Concurrent (threadDelay)
+import Control.Monad (forever, when)
+import Data.Monoid (All(All))
import System.Exit (exitSuccess)
+import System.FilePath ((</>))
+import System.IO.Error (isDoesNotExistError, tryIOError)
+import System.IO (hPutStrLn, stderr)
+import System.Posix.Process (getProcessID)
+import System.Posix.Signals (nullSignal, signalProcess)
+import System.Posix.Types (ProcessID)
import XMonad
+newShutdownEventHandler :: IO (Event -> X All)
+newShutdownEventHandler = do
+ writeProcessIDToFile
+ return handleShutdownEvent
+
+handleShutdownEvent :: Event -> X All
+handleShutdownEvent = \case
+ ClientMessageEvent { ev_message_type = mt } -> do
+ isShutdownEvent <- (mt ==) <$> getAtom "XMONAD_SHUTDOWN"
+ when isShutdownEvent $ do
+ broadcastMessage ReleaseResources
+ writeStateToFile
+ io exitSuccess >> return ()
+ return (All (not isShutdownEvent))
+ _ ->
+ return (All True)
+
sendShutdownEvent :: IO ()
sendShutdownEvent = do
dpy <- openDisplay ""
@@ -23,17 +46,35 @@ sendShutdownEvent = do
sendEvent dpy rw False structureNotifyMask e
sync dpy False
-handleShutdownEvent :: Event -> X All
-handleShutdownEvent = \case
- ClientMessageEvent { ev_message_type = mt } -> do
- c <- (mt ==) <$> getAtom "XMONAD_SHUTDOWN"
- when c shutdown
- return (All c)
- _ ->
- return (All True)
-
-shutdown :: X ()
+shutdown :: IO ()
shutdown = do
- broadcastMessage ReleaseResources
- writeStateToFile
- io exitSuccess >> return ()
+ pid <- readProcessIDFromFile
+ sendShutdownEvent
+ hPutStrLn stderr ("waiting for: " <> show pid)
+ result <- tryIOError (waitProcess pid)
+ if isSuccess result
+ then hPutStrLn stderr ("result: " <> show result <> " [AKA success^_^]")
+ else hPutStrLn stderr ("result: " <> show result)
+ where
+ isSuccess = either isDoesNotExistError (const False)
+
+waitProcess :: ProcessID -> IO ()
+waitProcess pid = forever (signalProcess nullSignal pid >> threadDelay 10000)
+
+--
+-- PID file stuff
+--
+
+getProcessIDFileName :: (Functor m, MonadIO m) => m FilePath
+getProcessIDFileName = (</> "xmonad.pid") <$> getXMonadDataDir
+
+writeProcessIDToFile :: IO ()
+writeProcessIDToFile = do
+ pidFileName <- getProcessIDFileName
+ pid <- getProcessID
+ writeFile pidFileName (show pid)
+
+readProcessIDFromFile :: IO ProcessID
+readProcessIDFromFile = do
+ pidFileName <- getProcessIDFileName
+ read <$> readFile pidFileName