From 5890215501972ae6805f3adba46f003dd48ce647 Mon Sep 17 00:00:00 2001 From: Moritz Ulrich Date: Thu, 12 Dec 2013 22:33:51 +0100 Subject: [PATCH] windowManager.xmonad: Make it configurable and extensible. PR #1366 The previous windowManager.xmonad option only starts xmonad and doesn't make ghc available. This assumes that the user has GHC with access to the xmonad package in his PATH when using xmonad. Xmonad in Nix is now patched to accept the XMONAD_{GHC,XMESSAGE} environment variables which define the path to either ghc or xmessage. These are set automatically when using xmonad through windowManager.xmonad. My (or specific: @aristidb and my) changes make it possible to use Xmonad without adding GHC to any profile. This is useful if you want to add a different GHC to your profile. This commit introduces some options: - xmonad.haskellPackages: Controls which Haskell package set & GHC set is used to (re)build Xmonad - xmonad.extraPackages: Function returning a list of additional packages to make available to GHC when rebuilding Xmonad - xmonad.enableContribExtras: Boolean option to build xmonadContrib and xmonadExtras. Signed-off-by: Moritz Ulrich --- .../services/x11/window-managers/xmonad.nix | 55 ++++++++++++++++--- .../window-managers/xmonad/default.nix | 6 ++ .../xmonad/xmonad_ghc_var_0.11.patch | 44 +++++++++++++++ 3 files changed, 97 insertions(+), 8 deletions(-) create mode 100644 pkgs/applications/window-managers/xmonad/xmonad_ghc_var_0.11.patch diff --git a/nixos/modules/services/x11/window-managers/xmonad.nix b/nixos/modules/services/x11/window-managers/xmonad.nix index 2cbb5002d6cf..87eff38a028a 100644 --- a/nixos/modules/services/x11/window-managers/xmonad.nix +++ b/nixos/modules/services/x11/window-managers/xmonad.nix @@ -1,10 +1,14 @@ {pkgs, config, ...}: let - inherit (pkgs.lib) mkOption mkIf; + inherit (pkgs.lib) mkOption mkIf optionals literalExample; cfg = config.services.xserver.windowManager.xmonad; + xmonadEnv = cfg.haskellPackages.ghcWithPackages(self: [ + self.xmonad + ] ++ optionals cfg.enableContribAndExtras [ self.xmonadContrib self.xmonadExtras] + ++ optionals (cfg.extraPackages != null) (cfg.extraPackages self)); + xmessage = pkgs.xlibs.xmessage; in - { options = { services.xserver.windowManager.xmonad = { @@ -13,18 +17,53 @@ in example = true; description = "Enable the xmonad window manager."; }; + + haskellPackages = mkOption { + default = pkgs.haskellPackages; + defaultText = "pkgs.haskellPackages"; + example = literalExample "pkgs.haskellPackages_ghc701"; + description = '' + haskellPackages used to build Xmonad and other packages. + This can be used to change the GHC version used to build + Xmonad and the packages listed in + extraPackages. + ''; + }; + + extraPackages = mkOption { + default = null; + example = literalExample '' + haskellPackages: [ + haskellPackages.xmonadContrib + haskellPackages.monadLogger + ] + ''; + description = '' + Extra packages available to ghc when rebuilding Xmonad. The + value must be a function which receives the attrset defined + in haskellpackages as the sole argument. + ''; + }; + + enableContribAndExtras = mkOption { + default = false; + example = true; + type = pkgs.lib.types.bool; + description = "Enable xmonad-{contrib,extras} in Xmonad."; + }; }; }; - - config = { + config = mkIf cfg.enable { services.xserver.windowManager = { - session = mkIf cfg.enable [{ + session = [{ name = "xmonad"; - start = " - ${pkgs.haskellPackages.xmonad}/bin/xmonad & + start = '' + XMONAD_GHC=${xmonadEnv}/bin/ghc XMONAD_XMESSAGE=${xmessage}/bin/xmessage xmonad & waitPID=$! - "; + ''; }]; }; + + environment.systemPackages = [ cfg.haskellPackages.xmonad ]; }; } diff --git a/pkgs/applications/window-managers/xmonad/default.nix b/pkgs/applications/window-managers/xmonad/default.nix index 0b8b71db7e92..54ef0b274aa8 100644 --- a/pkgs/applications/window-managers/xmonad/default.nix +++ b/pkgs/applications/window-managers/xmonad/default.nix @@ -13,6 +13,12 @@ cabal.mkDerivation (self: { mkdir -p $out/share/man/man1 mv $out/share/xmonad-*/man/*.1 $out/share/man/man1/ ''; + + patches = [ + # Patch to make xmonad use XMONAD_{GHC,XMESSAGE} (if available). + ./xmonad_ghc_var_0.11.patch + ]; + meta = { homepage = "http://xmonad.org"; description = "A tiling window manager"; diff --git a/pkgs/applications/window-managers/xmonad/xmonad_ghc_var_0.11.patch b/pkgs/applications/window-managers/xmonad/xmonad_ghc_var_0.11.patch new file mode 100644 index 000000000000..f0785773cc14 --- /dev/null +++ b/pkgs/applications/window-managers/xmonad/xmonad_ghc_var_0.11.patch @@ -0,0 +1,44 @@ +--- xmonad-0.11/XMonad/Core.hs 2013-01-01 01:31:47.000000000 +0000 ++++ new-xmonad/XMonad/Core.hs 2013-12-23 17:36:40.862146910 +0000 +@@ -47,6 +47,7 @@ + import System.Process + import System.Directory + import System.Exit ++import System.Environment (lookupEnv) + import Graphics.X11.Xlib + import Graphics.X11.Xlib.Extras (Event) + import Data.Typeable +@@ -452,6 +453,7 @@ + err = base ++ ".errors" + src = base ++ ".hs" + lib = dir "lib" ++ ghc <- fromMaybe "ghc" <$> liftIO (lookupEnv "XMONAD_GHC") + libTs <- mapM getModTime . Prelude.filter isSource =<< allFiles lib + srcT <- getModTime src + binT <- getModTime bin +@@ -460,7 +462,7 @@ + -- temporarily disable SIGCHLD ignoring: + uninstallSignalHandlers + status <- bracket (openFile err WriteMode) hClose $ \h -> +- waitForProcess =<< runProcess "ghc" ["--make", "xmonad.hs", "-i", "-ilib", "-fforce-recomp", "-v0", "-o",binn] (Just dir) ++ waitForProcess =<< runProcess ghc ["--make", "xmonad.hs", "-i", "-ilib", "-fforce-recomp", "-v0", "-o",binn] (Just dir) + Nothing Nothing Nothing (Just h) + + -- re-enable SIGCHLD: +@@ -469,6 +471,7 @@ + -- now, if it fails, run xmessage to let the user know: + when (status /= ExitSuccess) $ do + ghcErr <- readFile err ++ xmessage <- fromMaybe "xmessage" <$> liftIO (lookupEnv "XMONAD_XMESSAGE") + let msg = unlines $ + ["Error detected while loading xmonad configuration file: " ++ src] + ++ lines (if null ghcErr then show status else ghcErr) +@@ -476,7 +479,7 @@ + -- nb, the ordering of printing, then forking, is crucial due to + -- lazy evaluation + hPutStrLn stderr msg +- forkProcess $ executeFile "xmessage" True ["-default", "okay", msg] Nothing ++ forkProcess $ executeFile xmessage True ["-default", "okay", msg] Nothing + return () + return (status == ExitSuccess) + else return True