tv xmonad service: save state on shutdown

This commit is contained in:
tv 2015-10-25 02:06:37 +01:00
parent a4d7f920bf
commit 2cf33f24be
3 changed files with 92 additions and 18 deletions

View File

@ -44,11 +44,14 @@ let
systemd.services.display-manager = mkForce {}; systemd.services.display-manager = mkForce {};
services.xserver.enable = true; services.xserver.enable = true;
systemd.services.xmonad = { systemd.services.xmonad = {
wantedBy = [ "multi-user.target" ]; wantedBy = [ "multi-user.target" ];
requires = [ "xserver.service" ]; requires = [ "xserver.service" ];
environment = xmonad-environment;
serviceConfig = { serviceConfig = {
ExecStart = "${xmonad}/bin/xmonad"; ExecStart = "${xmonad-start}/bin/xmonad";
ExecStop = "${xmonad-stop}/bin/xmonad-stop";
User = user.name; User = user.name;
WorkingDirectory = user.home; WorkingDirectory = user.home;
}; };
@ -69,15 +72,19 @@ let
}; };
}; };
xmonad = let xmonad-pkg = pkgs.haskellPackages.callPackage xmonad-src {};
pkg = pkgs.haskellPackages.callPackage src {}; xmonad-src = pkgs.runCommand "xmonad-package" {} ''
src = pkgs.runCommand "xmonad-package" {} '' ${pkgs.cabal2nix}/bin/cabal2nix ${./xmonad} > $out
${pkgs.cabal2nix}/bin/cabal2nix ${./xmonad} > $out '';
'';
in pkgs.writeScriptBin "xmonad" '' xmonad-environment = {
#! /bin/sh DISPLAY = ":${toString config.services.xserver.display}";
XMONAD_STATE = "/tmp/xmonad.state";
};
xmonad-start = pkgs.writeScriptBin "xmonad" ''
#! ${pkgs.bash}/bin/bash
set -efu set -efu
export DISPLAY; DISPLAY=:${toString config.services.xserver.display}
export PATH; PATH=${makeSearchPath "bin" [ export PATH; PATH=${makeSearchPath "bin" [
pkgs.rxvt_unicode pkgs.rxvt_unicode
]}:/var/setuid-wrappers ]}:/var/setuid-wrappers
@ -93,7 +100,17 @@ let
settle ${pkgs.xorg.xhost}/bin/xhost +LOCAL: settle ${pkgs.xorg.xhost}/bin/xhost +LOCAL:
settle ${pkgs.xorg.xrdb}/bin/xrdb -merge ${import ./Xresources.nix args} settle ${pkgs.xorg.xrdb}/bin/xrdb -merge ${import ./Xresources.nix args}
settle ${pkgs.xorg.xsetroot}/bin/xsetroot -solid '#1c1c1c' settle ${pkgs.xorg.xsetroot}/bin/xsetroot -solid '#1c1c1c'
exec ${pkg}/bin/xmonad if test -e "$XMONAD_STATE"; then
IFS=''$'\n'
exec ${xmonad-pkg}/bin/xmonad --resume $(< "$XMONAD_STATE")
else
exec ${xmonad-pkg}/bin/xmonad
fi
'';
xmonad-stop = pkgs.writeScriptBin "xmonad-stop" ''
#! /bin/sh
exec ${xmonad-pkg}/bin/xmonad --shutdown
''; '';
xserver-environment = { xserver-environment = {
@ -103,7 +120,7 @@ let
[ "${pkgs.xorg.libX11}/lib" "${pkgs.xorg.libXext}/lib" ] [ "${pkgs.xorg.libX11}/lib" "${pkgs.xorg.libXext}/lib" ]
++ concatLists (catAttrs "libPath" config.services.xserver.drivers)); ++ concatLists (catAttrs "libPath" config.services.xserver.drivers));
}; };
xserver = pkgs.writeScriptBin "xserver" '' xserver = pkgs.writeScriptBin "xserver" ''
#! /bin/sh #! /bin/sh
set -efu set -efu

View File

@ -1,9 +1,11 @@
{-# LANGUAGE DeriveDataTypeable #-} -- for XS {-# LANGUAGE DeriveDataTypeable #-} -- for XS
{-# LANGUAGE LambdaCase #-}
module Main where module Main where
import XMonad import XMonad
import System.Environment (getArgs)
import XMonad.Prompt (defaultXPConfig) import XMonad.Prompt (defaultXPConfig)
import XMonad.Actions.DynamicWorkspaces ( addWorkspacePrompt, renameWorkspace import XMonad.Actions.DynamicWorkspaces ( addWorkspacePrompt, renameWorkspace
, removeEmptyWorkspace) , removeEmptyWorkspace)
@ -30,6 +32,7 @@ import XMonad.Layout.PerWorkspace (onWorkspace)
import Util.Pager import Util.Pager
import Util.Rhombus import Util.Rhombus
import Util.Debunk import Util.Debunk
import Util.Shutdown
--data MyState = MyState deriving Typeable --data MyState = MyState deriving Typeable
@ -48,11 +51,12 @@ myFont :: String
myFont = "-schumacher-*-*-*-*-*-*-*-*-*-*-*-iso10646-*" myFont = "-schumacher-*-*-*-*-*-*-*-*-*-*-*-iso10646-*"
main :: IO () main :: IO ()
main = do main = getArgs >>= \case
-- TODO exec (shlex "xrdb -merge" ++ [HOME ++ "/.Xresources"]) ["--shutdown"] -> sendShutdownEvent
-- TODO exec (shlex "xsetroot -solid '#1c1c1c'") _ -> mainNoArgs
--spawn "xrdb -merge \"$HOME/.Xresources\""
--spawn "xsetroot -solid '#1c1c1c'" mainNoArgs :: IO ()
mainNoArgs = do
xmonad xmonad
-- $ withUrgencyHookC dzenUrgencyHook { args = ["-bg", "magenta", "-fg", "magenta", "-h", "2"], duration = 500000 } -- $ withUrgencyHookC dzenUrgencyHook { args = ["-bg", "magenta", "-fg", "magenta", "-h", "2"], duration = 500000 }
-- urgencyConfig { remindWhen = Every 1 } -- urgencyConfig { remindWhen = Every 1 }
@ -80,6 +84,7 @@ main = do
, startupHook = spawn "echo emit XMonadStartup" , startupHook = spawn "echo emit XMonadStartup"
, normalBorderColor = "#1c1c1c" , normalBorderColor = "#1c1c1c"
, focusedBorderColor = "#f000b0" , focusedBorderColor = "#f000b0"
, handleEventHook = handleShutdownEvent
} }
where where
myLayout = myLayout =
@ -118,8 +123,7 @@ spawnTermAt _ = spawn myTerm
myKeys :: XConfig Layout -> Map (KeyMask, KeySym) (X ()) myKeys :: XConfig Layout -> Map (KeyMask, KeySym) (X ())
myKeys conf = Map.fromList $ myKeys conf = Map.fromList $
[ ((_4C , xK_Delete ), spawn "make -C $HOME/.xmonad reload") [ ((_4 , xK_Escape ), spawn "/var/setuid-wrappers/slock")
, ((_4 , xK_Escape ), spawn "/var/setuid-wrappers/slock")
, ((_4S , xK_c ), kill) , ((_4S , xK_c ), kill)
, ((_4 , xK_x ), chooseAction spawnTermAt) , ((_4 , xK_x ), chooseAction spawnTermAt)

View File

@ -0,0 +1,53 @@
{-# LANGUAGE LambdaCase #-}
module Util.Shutdown
( sendShutdownEvent
, handleShutdownEvent
, shutdown
)
where
import Control.Monad
import Data.Monoid
import Data.Maybe (catMaybes)
import qualified Data.Map as Map
import System.Environment (getEnv)
import System.Exit (exitSuccess)
import XMonad
import qualified XMonad.StackSet as W
sendShutdownEvent :: IO ()
sendShutdownEvent = do
dpy <- openDisplay ""
rw <- rootWindow dpy $ defaultScreen dpy
a <- internAtom dpy "XMONAD_SHUTDOWN" False
allocaXEvent $ \e -> do
setEventType e clientMessage
setClientMessageEvent e rw a 32 0 currentTime
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 = do
broadcastMessage ReleaseResources
io . flush =<< asks display
let wsData = show . W.mapLayout show . windowset
maybeShow (t, Right (PersistentExtension ext)) = Just (t, show ext)
maybeShow (t, Left str) = Just (t, str)
maybeShow _ = Nothing
extState =
return . show . catMaybes . map maybeShow . Map.toList . extensibleState
s <- gets (\s -> (wsData s : extState s))
_ <- io $ do
path <- getEnv "XMONAD_STATE"
writeFile path (concatMap (++"\n") s)
exitSuccess
return ()