diff --git a/modules/misc/news.nix b/modules/misc/news.nix
index 5bbb6fa7..613cc595 100644
--- a/modules/misc/news.nix
+++ b/modules/misc/news.nix
@@ -288,6 +288,13 @@ in
to your Home Manager configuration.
'';
}
+
+ {
+ time = "2017-10-04T18:36:07+00:00";
+ message = ''
+ A new module is available: 'xsession.windowManager.xmonad'.
+ '';
+ }
];
};
}
diff --git a/modules/services/window-managers/xmonad.nix b/modules/services/window-managers/xmonad.nix
new file mode 100644
index 00000000..8105612c
--- /dev/null
+++ b/modules/services/window-managers/xmonad.nix
@@ -0,0 +1,86 @@
+{ pkgs }: { config, lib, ... }:
+
+with lib;
+
+let
+
+ cfg = config.xmonad;
+
+ xmonad = pkgs.xmonad-with-packages.override {
+ ghcWithPackages = cfg.haskellPackages.ghcWithPackages;
+ packages = self:
+ cfg.extraPackages self
+ ++ optionals cfg.enableContribAndExtras [
+ self.xmonad-contrib self.xmonad-extras
+ ];
+ };
+
+in
+
+{
+ options = {
+ xmonad = {
+ enable = mkEnableOption "xmonad window manager";
+
+ haskellPackages = mkOption {
+ default = pkgs.haskellPackages;
+ defaultText = "pkgs.haskellPackages";
+ example = literalExample "pkgs.haskell.packages.ghc784";
+ description = ''
+ The 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 = self: [];
+ defaultText = "self: []";
+ example = literalExample ''
+ haskellPackages: [
+ haskellPackages.xmonad-contrib
+ haskellPackages.monad-logger
+ ]
+ '';
+ description = ''
+ Extra packages available to GHC when rebuilding xmonad. The
+ value must be a function which receives the attribute set
+ defined in haskellPackages as the sole
+ argument.
+ '';
+ };
+
+ enableContribAndExtras = mkOption {
+ default = false;
+ type = types.bool;
+ description = "Enable xmonad-{contrib,extras} in xmonad.";
+ };
+
+ config = mkOption {
+ type = types.nullOr types.path;
+ default = null;
+ example = literalExample ''
+ pkgs.writeText "xmonad.hs" '''
+ import XMonad
+ main = xmonad defaultConfig
+ { terminal = "urxvt"
+ , modMask = mod4Mask
+ , borderWidth = 3
+ }
+ '''
+ '';
+ description = ''
+ The configuration file to be used for xmonad. This must be
+ an absolute path or null in which case
+ ~/.xmonad/xmonad.hs will not be managed
+ by Home Manager.
+ '';
+ };
+ };
+ };
+
+ config = mkIf cfg.enable {
+ command = "${xmonad}/bin/xmonad";
+ };
+}
diff --git a/modules/xsession.nix b/modules/xsession.nix
index 4899ad2e..5c9ee777 100644
--- a/modules/xsession.nix
+++ b/modules/xsession.nix
@@ -1,6 +1,7 @@
{ config, lib, pkgs, ... }:
with lib;
+with import ./lib/dag.nix { inherit lib; };
let
@@ -32,6 +33,10 @@ let
};
};
+ xmonadModule = import ./services/window-managers/xmonad.nix {
+ inherit pkgs;
+ };
+
in
{
@@ -46,7 +51,7 @@ in
types.coercedTo
types.str
(command: { inherit command; usesDeprecated = true; })
- (types.submodule wmBaseModule);
+ (types.submodule [ wmBaseModule xmonadModule ]);
description = ''
Window manager start command. DEPRECATED: Use
xsession.windowManager.command instead.
@@ -69,6 +74,34 @@ in
];
})
+ # Hack to support xsession.windowManager as a string. Once that is
+ # removed this code should go back into the xmonad.nix file.
+ (mkIf (cfg.windowManager.xmonad.enable
+ && cfg.windowManager.xmonad.config != null) {
+ home.file.".xmonad/xmonad.hs".source = cfg.windowManager.xmonad.config;
+
+ home.activation.checkXmonad = dagEntryBefore [ "linkGeneration" ] ''
+ if ! cmp --quiet \
+ "${cfg.windowManager.xmonad.config}" \
+ "$HOME/.xmonad/xmonad.hs"; then
+ xmonadChanged=1
+ fi
+ '';
+
+ home.activation.applyXmonad = dagEntryAfter [ "linkGeneration" ] ''
+ if [[ -v xmonadChanged ]]; then
+ echo "Recompiling xmonad"
+ ${cfg.windowManager.command} --recompile
+
+ # Attempt to restart xmonad if X is running.
+ if [[ -v DISPLAY ]] ; then
+ echo "Restarting xmonad"
+ ${cfg.windowManager.command} --restart
+ fi
+ fi
+ '';
+ })
+
{
systemd.user.services.setxkbmap = {
Unit = {