summary refs log tree commit diff
path: root/nixos/modules/services/x11/window-managers
diff options
context:
space:
mode:
Diffstat (limited to 'nixos/modules/services/x11/window-managers')
-rw-r--r--nixos/modules/services/x11/window-managers/2bwm.nix37
-rw-r--r--nixos/modules/services/x11/window-managers/afterstep.nix25
-rw-r--r--nixos/modules/services/x11/window-managers/awesome.nix66
-rw-r--r--nixos/modules/services/x11/window-managers/berry.nix25
-rw-r--r--nixos/modules/services/x11/window-managers/bspwm.nix77
-rw-r--r--nixos/modules/services/x11/window-managers/clfswm.nix34
-rw-r--r--nixos/modules/services/x11/window-managers/cwm.nix23
-rw-r--r--nixos/modules/services/x11/window-managers/default.nix88
-rw-r--r--nixos/modules/services/x11/window-managers/dwm.nix37
-rw-r--r--nixos/modules/services/x11/window-managers/e16.nix26
-rw-r--r--nixos/modules/services/x11/window-managers/evilwm.nix25
-rw-r--r--nixos/modules/services/x11/window-managers/exwm.nix69
-rw-r--r--nixos/modules/services/x11/window-managers/fluxbox.nix25
-rw-r--r--nixos/modules/services/x11/window-managers/fvwm.nix41
-rw-r--r--nixos/modules/services/x11/window-managers/herbstluftwm.nix47
-rw-r--r--nixos/modules/services/x11/window-managers/i3.nix78
-rw-r--r--nixos/modules/services/x11/window-managers/icewm.nix27
-rw-r--r--nixos/modules/services/x11/window-managers/jwm.nix25
-rw-r--r--nixos/modules/services/x11/window-managers/leftwm.nix25
-rw-r--r--nixos/modules/services/x11/window-managers/lwm.nix25
-rw-r--r--nixos/modules/services/x11/window-managers/metacity.nix30
-rw-r--r--nixos/modules/services/x11/window-managers/mlvwm.nix41
-rw-r--r--nixos/modules/services/x11/window-managers/mwm.nix25
-rw-r--r--nixos/modules/services/x11/window-managers/none.nix12
-rw-r--r--nixos/modules/services/x11/window-managers/notion.nix26
-rw-r--r--nixos/modules/services/x11/window-managers/openbox.nix24
-rw-r--r--nixos/modules/services/x11/window-managers/oroborus.nix25
-rw-r--r--nixos/modules/services/x11/window-managers/pekwm.nix25
-rw-r--r--nixos/modules/services/x11/window-managers/qtile.nix25
-rw-r--r--nixos/modules/services/x11/window-managers/ratpoison.nix25
-rw-r--r--nixos/modules/services/x11/window-managers/sawfish.nix25
-rw-r--r--nixos/modules/services/x11/window-managers/smallwm.nix25
-rw-r--r--nixos/modules/services/x11/window-managers/spectrwm.nix27
-rw-r--r--nixos/modules/services/x11/window-managers/stumpwm.nix24
-rw-r--r--nixos/modules/services/x11/window-managers/tinywm.nix25
-rw-r--r--nixos/modules/services/x11/window-managers/twm.nix37
-rw-r--r--nixos/modules/services/x11/window-managers/windowlab.nix22
-rw-r--r--nixos/modules/services/x11/window-managers/windowmaker.nix25
-rw-r--r--nixos/modules/services/x11/window-managers/wmderland.nix61
-rw-r--r--nixos/modules/services/x11/window-managers/wmii.nix39
-rw-r--r--nixos/modules/services/x11/window-managers/xmonad.nix203
-rw-r--r--nixos/modules/services/x11/window-managers/yeahwm.nix25
42 files changed, 1621 insertions, 0 deletions
diff --git a/nixos/modules/services/x11/window-managers/2bwm.nix b/nixos/modules/services/x11/window-managers/2bwm.nix
new file mode 100644
index 00000000000..fdbdf35b0f5
--- /dev/null
+++ b/nixos/modules/services/x11/window-managers/2bwm.nix
@@ -0,0 +1,37 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+
+  cfg = config.services.xserver.windowManager."2bwm";
+
+in
+
+{
+
+  ###### interface
+
+  options = {
+    services.xserver.windowManager."2bwm".enable = mkEnableOption "2bwm";
+  };
+
+
+  ###### implementation
+
+  config = mkIf cfg.enable {
+
+    services.xserver.windowManager.session = singleton
+      { name = "2bwm";
+        start =
+          ''
+            ${pkgs._2bwm}/bin/2bwm &
+            waitPID=$!
+          '';
+      };
+
+    environment.systemPackages = [ pkgs._2bwm ];
+
+  };
+
+}
diff --git a/nixos/modules/services/x11/window-managers/afterstep.nix b/nixos/modules/services/x11/window-managers/afterstep.nix
new file mode 100644
index 00000000000..ba88a64c702
--- /dev/null
+++ b/nixos/modules/services/x11/window-managers/afterstep.nix
@@ -0,0 +1,25 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+  cfg = config.services.xserver.windowManager.afterstep;
+in
+{
+  ###### interface
+  options = {
+    services.xserver.windowManager.afterstep.enable = mkEnableOption "afterstep";
+  };
+
+  ###### implementation
+  config = mkIf cfg.enable {
+    services.xserver.windowManager.session = singleton {
+      name = "afterstep";
+      start = ''
+        ${pkgs.afterstep}/bin/afterstep &
+        waitPID=$!
+      '';
+    };
+    environment.systemPackages = [ pkgs.afterstep ];
+  };
+}
diff --git a/nixos/modules/services/x11/window-managers/awesome.nix b/nixos/modules/services/x11/window-managers/awesome.nix
new file mode 100644
index 00000000000..c6c0c934f9a
--- /dev/null
+++ b/nixos/modules/services/x11/window-managers/awesome.nix
@@ -0,0 +1,66 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+
+  cfg = config.services.xserver.windowManager.awesome;
+  awesome = cfg.package;
+  getLuaPath = lib : dir : "${lib}/${dir}/lua/${pkgs.luaPackages.lua.luaversion}";
+  makeSearchPath = lib.concatMapStrings (path:
+    " --search " + (getLuaPath path "share") +
+    " --search " + (getLuaPath path "lib")
+  );
+in
+
+{
+
+  ###### interface
+
+  options = {
+
+    services.xserver.windowManager.awesome = {
+
+      enable = mkEnableOption "Awesome window manager";
+
+      luaModules = mkOption {
+        default = [];
+        type = types.listOf types.package;
+        description = "List of lua packages available for being used in the Awesome configuration.";
+        example = literalExpression "[ pkgs.luaPackages.vicious ]";
+      };
+
+      package = mkOption {
+        default = null;
+        type = types.nullOr types.package;
+        description = "Package to use for running the Awesome WM.";
+        apply = pkg: if pkg == null then pkgs.awesome else pkg;
+      };
+
+      noArgb = mkOption {
+        default = false;
+        type = types.bool;
+        description = "Disable client transparency support, which can be greatly detrimental to performance in some setups";
+      };
+    };
+
+  };
+
+
+  ###### implementation
+
+  config = mkIf cfg.enable {
+
+    services.xserver.windowManager.session = singleton
+      { name = "awesome";
+        start =
+          ''
+            ${awesome}/bin/awesome ${lib.optionalString cfg.noArgb "--no-argb"} ${makeSearchPath cfg.luaModules} &
+            waitPID=$!
+          '';
+      };
+
+    environment.systemPackages = [ awesome ];
+
+  };
+}
diff --git a/nixos/modules/services/x11/window-managers/berry.nix b/nixos/modules/services/x11/window-managers/berry.nix
new file mode 100644
index 00000000000..0d2285e7a60
--- /dev/null
+++ b/nixos/modules/services/x11/window-managers/berry.nix
@@ -0,0 +1,25 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+  cfg = config.services.xserver.windowManager.berry;
+in
+{
+  ###### interface
+  options = {
+    services.xserver.windowManager.berry.enable = mkEnableOption "berry";
+  };
+
+  ###### implementation
+  config = mkIf cfg.enable {
+    services.xserver.windowManager.session = singleton {
+      name = "berry";
+      start = ''
+        ${pkgs.berry}/bin/berry &
+        waitPID=$!
+      '';
+    };
+    environment.systemPackages = [ pkgs.berry ];
+  };
+}
diff --git a/nixos/modules/services/x11/window-managers/bspwm.nix b/nixos/modules/services/x11/window-managers/bspwm.nix
new file mode 100644
index 00000000000..ade24061a06
--- /dev/null
+++ b/nixos/modules/services/x11/window-managers/bspwm.nix
@@ -0,0 +1,77 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+  cfg = config.services.xserver.windowManager.bspwm;
+in
+
+{
+  options = {
+    services.xserver.windowManager.bspwm = {
+      enable = mkEnableOption "bspwm";
+
+      package = mkOption {
+        type        = types.package;
+        default     = pkgs.bspwm;
+        defaultText = literalExpression "pkgs.bspwm";
+        example     = literalExpression "pkgs.bspwm-unstable";
+        description = ''
+          bspwm package to use.
+        '';
+      };
+      configFile = mkOption {
+        type        = with types; nullOr path;
+        example     = literalExpression ''"''${pkgs.bspwm}/share/doc/bspwm/examples/bspwmrc"'';
+        default     = null;
+        description = ''
+          Path to the bspwm configuration file.
+          If null, $HOME/.config/bspwm/bspwmrc will be used.
+        '';
+      };
+
+      sxhkd = {
+        package = mkOption {
+          type        = types.package;
+          default     = pkgs.sxhkd;
+          defaultText = literalExpression "pkgs.sxhkd";
+          example     = literalExpression "pkgs.sxhkd-unstable";
+          description = ''
+            sxhkd package to use.
+          '';
+        };
+        configFile = mkOption {
+          type        = with types; nullOr path;
+          example     = literalExpression ''"''${pkgs.bspwm}/share/doc/bspwm/examples/sxhkdrc"'';
+          default     = null;
+          description = ''
+            Path to the sxhkd configuration file.
+            If null, $HOME/.config/sxhkd/sxhkdrc will be used.
+          '';
+        };
+      };
+    };
+  };
+
+  config = mkIf cfg.enable {
+    services.xserver.windowManager.session = singleton {
+      name  = "bspwm";
+      start = ''
+        export _JAVA_AWT_WM_NONREPARENTING=1
+        SXHKD_SHELL=/bin/sh ${cfg.sxhkd.package}/bin/sxhkd ${optionalString (cfg.sxhkd.configFile != null) "-c \"${cfg.sxhkd.configFile}\""} &
+        ${cfg.package}/bin/bspwm ${optionalString (cfg.configFile != null) "-c \"${cfg.configFile}\""} &
+        waitPID=$!
+      '';
+    };
+    environment.systemPackages = [ cfg.package ];
+  };
+
+  imports = [
+   (mkRemovedOptionModule [ "services" "xserver" "windowManager" "bspwm-unstable" "enable" ]
+     "Use services.xserver.windowManager.bspwm.enable and set services.xserver.windowManager.bspwm.package to pkgs.bspwm-unstable to use the unstable version of bspwm.")
+   (mkRemovedOptionModule [ "services" "xserver" "windowManager" "bspwm" "startThroughSession" ]
+     "bspwm package does not provide bspwm-session anymore.")
+   (mkRemovedOptionModule [ "services" "xserver" "windowManager" "bspwm" "sessionScript" ]
+     "bspwm package does not provide bspwm-session anymore.")
+  ];
+}
diff --git a/nixos/modules/services/x11/window-managers/clfswm.nix b/nixos/modules/services/x11/window-managers/clfswm.nix
new file mode 100644
index 00000000000..78772c79974
--- /dev/null
+++ b/nixos/modules/services/x11/window-managers/clfswm.nix
@@ -0,0 +1,34 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+  cfg = config.services.xserver.windowManager.clfswm;
+in
+
+{
+  options = {
+    services.xserver.windowManager.clfswm = {
+      enable = mkEnableOption "clfswm";
+      package = mkOption {
+        type        = types.package;
+        default     = pkgs.lispPackages.clfswm;
+        defaultText = literalExpression "pkgs.lispPackages.clfswm";
+        description = ''
+          clfswm package to use.
+        '';
+      };
+    };
+  };
+
+  config = mkIf cfg.enable {
+    services.xserver.windowManager.session = singleton {
+      name = "clfswm";
+      start = ''
+        ${cfg.package}/bin/clfswm &
+        waitPID=$!
+      '';
+    };
+    environment.systemPackages = [ cfg.package ];
+  };
+}
diff --git a/nixos/modules/services/x11/window-managers/cwm.nix b/nixos/modules/services/x11/window-managers/cwm.nix
new file mode 100644
index 00000000000..03375a226bb
--- /dev/null
+++ b/nixos/modules/services/x11/window-managers/cwm.nix
@@ -0,0 +1,23 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+  cfg = config.services.xserver.windowManager.cwm;
+in
+{
+  options = {
+    services.xserver.windowManager.cwm.enable = mkEnableOption "cwm";
+  };
+  config = mkIf cfg.enable {
+    services.xserver.windowManager.session = singleton
+      { name = "cwm";
+        start =
+          ''
+            cwm &
+            waitPID=$!
+          '';
+      };
+    environment.systemPackages = [ pkgs.cwm ];
+  };
+}
diff --git a/nixos/modules/services/x11/window-managers/default.nix b/nixos/modules/services/x11/window-managers/default.nix
new file mode 100644
index 00000000000..d71738ea633
--- /dev/null
+++ b/nixos/modules/services/x11/window-managers/default.nix
@@ -0,0 +1,88 @@
+{ config, lib, ... }:
+
+with lib;
+
+let
+  cfg = config.services.xserver.windowManager;
+in
+
+{
+  imports = [
+    ./2bwm.nix
+    ./afterstep.nix
+    ./berry.nix
+    ./bspwm.nix
+    ./cwm.nix
+    ./clfswm.nix
+    ./dwm.nix
+    ./e16.nix
+    ./evilwm.nix
+    ./exwm.nix
+    ./fluxbox.nix
+    ./fvwm.nix
+    ./herbstluftwm.nix
+    ./i3.nix
+    ./jwm.nix
+    ./leftwm.nix
+    ./lwm.nix
+    ./metacity.nix
+    ./mlvwm.nix
+    ./mwm.nix
+    ./openbox.nix
+    ./pekwm.nix
+    ./notion.nix
+    ./ratpoison.nix
+    ./sawfish.nix
+    ./smallwm.nix
+    ./stumpwm.nix
+    ./spectrwm.nix
+    ./tinywm.nix
+    ./twm.nix
+    ./windowmaker.nix
+    ./wmderland.nix
+    ./wmii.nix
+    ./xmonad.nix
+    ./yeahwm.nix
+    ./qtile.nix
+    ./none.nix ];
+
+  options = {
+
+    services.xserver.windowManager = {
+
+      session = mkOption {
+        internal = true;
+        default = [];
+        example = [{
+          name = "wmii";
+          start = "...";
+        }];
+        description = ''
+          Internal option used to add some common line to window manager
+          scripts before forwarding the value to the
+          <varname>displayManager</varname>.
+        '';
+        apply = map (d: d // {
+          manage = "window";
+        });
+      };
+
+      default = mkOption {
+        type = types.nullOr types.str;
+        default = null;
+        example = "wmii";
+        description = ''
+          <emphasis role="strong">Deprecated</emphasis>, please use <xref linkend="opt-services.xserver.displayManager.defaultSession"/> instead.
+
+          Default window manager loaded if none have been chosen.
+        '';
+      };
+
+    };
+
+  };
+
+  config = {
+    services.xserver.displayManager.session = cfg.session;
+  };
+}
diff --git a/nixos/modules/services/x11/window-managers/dwm.nix b/nixos/modules/services/x11/window-managers/dwm.nix
new file mode 100644
index 00000000000..7777913ce1e
--- /dev/null
+++ b/nixos/modules/services/x11/window-managers/dwm.nix
@@ -0,0 +1,37 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+
+  cfg = config.services.xserver.windowManager.dwm;
+
+in
+
+{
+
+  ###### interface
+
+  options = {
+    services.xserver.windowManager.dwm.enable = mkEnableOption "dwm";
+  };
+
+
+  ###### implementation
+
+  config = mkIf cfg.enable {
+
+    services.xserver.windowManager.session = singleton
+      { name = "dwm";
+        start =
+          ''
+            dwm &
+            waitPID=$!
+          '';
+      };
+
+    environment.systemPackages = [ pkgs.dwm ];
+
+  };
+
+}
diff --git a/nixos/modules/services/x11/window-managers/e16.nix b/nixos/modules/services/x11/window-managers/e16.nix
new file mode 100644
index 00000000000..3e1a22c4dab
--- /dev/null
+++ b/nixos/modules/services/x11/window-managers/e16.nix
@@ -0,0 +1,26 @@
+{ config , lib , pkgs , ... }:
+
+with lib;
+
+let
+  cfg = config.services.xserver.windowManager.e16;
+in
+{
+  ###### interface
+  options = {
+    services.xserver.windowManager.e16.enable = mkEnableOption "e16";
+  };
+
+  ###### implementation
+  config = mkIf cfg.enable {
+    services.xserver.windowManager.session = singleton {
+      name = "E16";
+      start = ''
+        ${pkgs.e16}/bin/e16 &
+        waitPID=$!
+      '';
+    };
+
+    environment.systemPackages = [ pkgs.e16 ];
+  };
+}
diff --git a/nixos/modules/services/x11/window-managers/evilwm.nix b/nixos/modules/services/x11/window-managers/evilwm.nix
new file mode 100644
index 00000000000..6f1db2110f8
--- /dev/null
+++ b/nixos/modules/services/x11/window-managers/evilwm.nix
@@ -0,0 +1,25 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+  cfg = config.services.xserver.windowManager.evilwm;
+in
+{
+  ###### interface
+  options = {
+    services.xserver.windowManager.evilwm.enable = mkEnableOption "evilwm";
+  };
+
+  ###### implementation
+  config = mkIf cfg.enable {
+    services.xserver.windowManager.session = singleton {
+      name = "evilwm";
+      start = ''
+        ${pkgs.evilwm}/bin/evilwm &
+        waitPID=$!
+      '';
+    };
+    environment.systemPackages = [ pkgs.evilwm ];
+  };
+}
diff --git a/nixos/modules/services/x11/window-managers/exwm.nix b/nixos/modules/services/x11/window-managers/exwm.nix
new file mode 100644
index 00000000000..b505f720f04
--- /dev/null
+++ b/nixos/modules/services/x11/window-managers/exwm.nix
@@ -0,0 +1,69 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+  cfg = config.services.xserver.windowManager.exwm;
+  loadScript = pkgs.writeText "emacs-exwm-load" ''
+    ${cfg.loadScript}
+    ${optionalString cfg.enableDefaultConfig ''
+      (require 'exwm-config)
+      (exwm-config-default)
+    ''}
+  '';
+  packages = epkgs: cfg.extraPackages epkgs ++ [ epkgs.exwm ];
+  exwm-emacs = pkgs.emacsWithPackages packages;
+in
+
+{
+  options = {
+    services.xserver.windowManager.exwm = {
+      enable = mkEnableOption "exwm";
+      loadScript = mkOption {
+        default = "(require 'exwm)";
+        type = types.lines;
+        example = ''
+          (require 'exwm)
+          (exwm-enable)
+        '';
+        description = ''
+          Emacs lisp code to be run after loading the user's init
+          file. If enableDefaultConfig is true, this will be run
+          before loading the default config.
+        '';
+      };
+      enableDefaultConfig = mkOption {
+        default = true;
+        type = lib.types.bool;
+        description = "Enable an uncustomised exwm configuration.";
+      };
+      extraPackages = mkOption {
+        type = types.functionTo (types.listOf types.package);
+        default = epkgs: [];
+        defaultText = literalExpression "epkgs: []";
+        example = literalExpression ''
+          epkgs: [
+            epkgs.emms
+            epkgs.magit
+            epkgs.proofgeneral
+          ]
+        '';
+        description = ''
+          Extra packages available to Emacs. The value must be a
+          function which receives the attrset defined in
+          <varname>emacs.pkgs</varname> as the sole argument.
+        '';
+      };
+    };
+  };
+
+  config = mkIf cfg.enable {
+    services.xserver.windowManager.session = singleton {
+      name = "exwm";
+      start = ''
+        ${exwm-emacs}/bin/emacs -l ${loadScript}
+      '';
+    };
+    environment.systemPackages = [ exwm-emacs ];
+  };
+}
diff --git a/nixos/modules/services/x11/window-managers/fluxbox.nix b/nixos/modules/services/x11/window-managers/fluxbox.nix
new file mode 100644
index 00000000000..b409335702a
--- /dev/null
+++ b/nixos/modules/services/x11/window-managers/fluxbox.nix
@@ -0,0 +1,25 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+  cfg = config.services.xserver.windowManager.fluxbox;
+in
+{
+  ###### interface
+  options = {
+    services.xserver.windowManager.fluxbox.enable = mkEnableOption "fluxbox";
+  };
+
+  ###### implementation
+  config = mkIf cfg.enable {
+    services.xserver.windowManager.session = singleton {
+      name = "fluxbox";
+      start = ''
+        ${pkgs.fluxbox}/bin/startfluxbox &
+        waitPID=$!
+      '';
+    };
+    environment.systemPackages = [ pkgs.fluxbox ];
+  };
+}
diff --git a/nixos/modules/services/x11/window-managers/fvwm.nix b/nixos/modules/services/x11/window-managers/fvwm.nix
new file mode 100644
index 00000000000..e283886ecc4
--- /dev/null
+++ b/nixos/modules/services/x11/window-managers/fvwm.nix
@@ -0,0 +1,41 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+  cfg = config.services.xserver.windowManager.fvwm;
+  fvwm = pkgs.fvwm.override { enableGestures = cfg.gestures; };
+in
+
+{
+
+  ###### interface
+
+  options = {
+    services.xserver.windowManager.fvwm = {
+      enable = mkEnableOption "Fvwm window manager";
+
+      gestures = mkOption {
+        default = false;
+        type = types.bool;
+        description = "Whether or not to enable libstroke for gesture support";
+      };
+    };
+  };
+
+
+  ###### implementation
+
+  config = mkIf cfg.enable {
+    services.xserver.windowManager.session = singleton
+      { name = "fvwm";
+        start =
+          ''
+            ${fvwm}/bin/fvwm &
+            waitPID=$!
+          '';
+      };
+
+    environment.systemPackages = [ fvwm ];
+  };
+}
diff --git a/nixos/modules/services/x11/window-managers/herbstluftwm.nix b/nixos/modules/services/x11/window-managers/herbstluftwm.nix
new file mode 100644
index 00000000000..354d70c695c
--- /dev/null
+++ b/nixos/modules/services/x11/window-managers/herbstluftwm.nix
@@ -0,0 +1,47 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+  cfg = config.services.xserver.windowManager.herbstluftwm;
+in
+
+{
+  options = {
+    services.xserver.windowManager.herbstluftwm = {
+      enable = mkEnableOption "herbstluftwm";
+
+      package = mkOption {
+        type = types.package;
+        default = pkgs.herbstluftwm;
+        defaultText = literalExpression "pkgs.herbstluftwm";
+        description = ''
+          Herbstluftwm package to use.
+        '';
+      };
+
+      configFile = mkOption {
+        default     = null;
+        type        = with types; nullOr path;
+        description = ''
+          Path to the herbstluftwm configuration file.  If left at the
+          default value, $XDG_CONFIG_HOME/herbstluftwm/autostart will
+          be used.
+        '';
+      };
+    };
+  };
+
+  config = mkIf cfg.enable {
+    services.xserver.windowManager.session = singleton {
+      name = "herbstluftwm";
+      start =
+        let configFileClause = optionalString
+            (cfg.configFile != null)
+            ''-c "${cfg.configFile}"''
+            ;
+        in "${cfg.package}/bin/herbstluftwm ${configFileClause}";
+    };
+    environment.systemPackages = [ cfg.package ];
+  };
+}
diff --git a/nixos/modules/services/x11/window-managers/i3.nix b/nixos/modules/services/x11/window-managers/i3.nix
new file mode 100644
index 00000000000..99f9997024f
--- /dev/null
+++ b/nixos/modules/services/x11/window-managers/i3.nix
@@ -0,0 +1,78 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+  cfg = config.services.xserver.windowManager.i3;
+in
+
+{
+  options.services.xserver.windowManager.i3 = {
+    enable = mkEnableOption "i3 window manager";
+
+    configFile = mkOption {
+      default     = null;
+      type        = with types; nullOr path;
+      description = ''
+        Path to the i3 configuration file.
+        If left at the default value, $HOME/.i3/config will be used.
+      '';
+    };
+
+    extraSessionCommands = mkOption {
+      default     = "";
+      type        = types.lines;
+      description = ''
+        Shell commands executed just before i3 is started.
+      '';
+    };
+
+    package = mkOption {
+      type        = types.package;
+      default     = pkgs.i3;
+      defaultText = literalExpression "pkgs.i3";
+      example     = literalExpression "pkgs.i3-gaps";
+      description = ''
+        i3 package to use.
+      '';
+    };
+
+    extraPackages = mkOption {
+      type = with types; listOf package;
+      default = with pkgs; [ dmenu i3status i3lock ];
+      defaultText = literalExpression ''
+        with pkgs; [
+          dmenu
+          i3status
+          i3lock
+        ]
+      '';
+      description = ''
+        Extra packages to be installed system wide.
+      '';
+    };
+  };
+
+  config = mkIf cfg.enable {
+    services.xserver.windowManager.session = [{
+      name  = "i3";
+      start = ''
+        ${cfg.extraSessionCommands}
+
+        ${cfg.package}/bin/i3 ${optionalString (cfg.configFile != null)
+          "-c /etc/i3/config"
+        } &
+        waitPID=$!
+      '';
+    }];
+    environment.systemPackages = [ cfg.package ] ++ cfg.extraPackages;
+    environment.etc."i3/config" = mkIf (cfg.configFile != null) {
+      source = cfg.configFile;
+    };
+  };
+
+  imports = [
+    (mkRemovedOptionModule [ "services" "xserver" "windowManager" "i3-gaps" "enable" ]
+      "Use services.xserver.windowManager.i3.enable and set services.xserver.windowManager.i3.package to pkgs.i3-gaps to use i3-gaps.")
+  ];
+}
diff --git a/nixos/modules/services/x11/window-managers/icewm.nix b/nixos/modules/services/x11/window-managers/icewm.nix
new file mode 100644
index 00000000000..f4ae9222df6
--- /dev/null
+++ b/nixos/modules/services/x11/window-managers/icewm.nix
@@ -0,0 +1,27 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+  cfg = config.services.xserver.windowManager.icewm;
+in
+{
+  ###### interface
+  options = {
+    services.xserver.windowManager.icewm.enable = mkEnableOption "icewm";
+  };
+
+  ###### implementation
+  config = mkIf cfg.enable {
+    services.xserver.windowManager.session = singleton
+      { name = "icewm";
+        start =
+          ''
+            ${pkgs.icewm}/bin/icewm &
+            waitPID=$!
+          '';
+      };
+
+    environment.systemPackages = [ pkgs.icewm ];
+  };
+}
diff --git a/nixos/modules/services/x11/window-managers/jwm.nix b/nixos/modules/services/x11/window-managers/jwm.nix
new file mode 100644
index 00000000000..0e8dab2e922
--- /dev/null
+++ b/nixos/modules/services/x11/window-managers/jwm.nix
@@ -0,0 +1,25 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+  cfg = config.services.xserver.windowManager.jwm;
+in
+{
+  ###### interface
+  options = {
+    services.xserver.windowManager.jwm.enable = mkEnableOption "jwm";
+  };
+
+  ###### implementation
+  config = mkIf cfg.enable {
+    services.xserver.windowManager.session = singleton {
+      name = "jwm";
+      start = ''
+        ${pkgs.jwm}/bin/jwm &
+        waitPID=$!
+      '';
+    };
+    environment.systemPackages = [ pkgs.jwm ];
+  };
+}
diff --git a/nixos/modules/services/x11/window-managers/leftwm.nix b/nixos/modules/services/x11/window-managers/leftwm.nix
new file mode 100644
index 00000000000..3ef40df95df
--- /dev/null
+++ b/nixos/modules/services/x11/window-managers/leftwm.nix
@@ -0,0 +1,25 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+  cfg = config.services.xserver.windowManager.leftwm;
+in
+{
+  ###### interface
+  options = {
+    services.xserver.windowManager.leftwm.enable = mkEnableOption "leftwm";
+  };
+
+  ###### implementation
+  config = mkIf cfg.enable {
+    services.xserver.windowManager.session = singleton {
+      name = "leftwm";
+      start = ''
+        ${pkgs.leftwm}/bin/leftwm &
+        waitPID=$!
+      '';
+    };
+    environment.systemPackages = [ pkgs.leftwm ];
+  };
+}
diff --git a/nixos/modules/services/x11/window-managers/lwm.nix b/nixos/modules/services/x11/window-managers/lwm.nix
new file mode 100644
index 00000000000..e2aa062fd13
--- /dev/null
+++ b/nixos/modules/services/x11/window-managers/lwm.nix
@@ -0,0 +1,25 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+  cfg = config.services.xserver.windowManager.lwm;
+in
+{
+  ###### interface
+  options = {
+    services.xserver.windowManager.lwm.enable = mkEnableOption "lwm";
+  };
+
+  ###### implementation
+  config = mkIf cfg.enable {
+    services.xserver.windowManager.session = singleton {
+      name = "lwm";
+      start = ''
+        ${pkgs.lwm}/bin/lwm &
+        waitPID=$!
+      '';
+    };
+    environment.systemPackages = [ pkgs.lwm ];
+  };
+}
diff --git a/nixos/modules/services/x11/window-managers/metacity.nix b/nixos/modules/services/x11/window-managers/metacity.nix
new file mode 100644
index 00000000000..600afe759b2
--- /dev/null
+++ b/nixos/modules/services/x11/window-managers/metacity.nix
@@ -0,0 +1,30 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+
+  cfg = config.services.xserver.windowManager.metacity;
+  inherit (pkgs) gnome;
+in
+
+{
+  options = {
+    services.xserver.windowManager.metacity.enable = mkEnableOption "metacity";
+  };
+
+  config = mkIf cfg.enable {
+
+    services.xserver.windowManager.session = singleton
+      { name = "metacity";
+        start = ''
+          ${gnome.metacity}/bin/metacity &
+          waitPID=$!
+        '';
+      };
+
+    environment.systemPackages = [ gnome.metacity ];
+
+  };
+
+}
diff --git a/nixos/modules/services/x11/window-managers/mlvwm.nix b/nixos/modules/services/x11/window-managers/mlvwm.nix
new file mode 100644
index 00000000000..08dd0402029
--- /dev/null
+++ b/nixos/modules/services/x11/window-managers/mlvwm.nix
@@ -0,0 +1,41 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let cfg = config.services.xserver.windowManager.mlvwm;
+
+in
+{
+
+  options.services.xserver.windowManager.mlvwm = {
+    enable = mkEnableOption "Macintosh-like Virtual Window Manager";
+
+    configFile = mkOption {
+      default = null;
+      type = with types; nullOr path;
+      description = ''
+        Path to the mlvwm configuration file.
+        If left at the default value, $HOME/.mlvwmrc will be used.
+      '';
+    };
+  };
+
+  config = mkIf cfg.enable {
+
+    services.xserver.windowManager.session = [{
+      name = "mlvwm";
+      start = ''
+        ${pkgs.mlvwm}/bin/mlvwm ${optionalString (cfg.configFile != null)
+          "-f /etc/mlvwm/mlvwmrc"
+        } &
+        waitPID=$!
+      '';
+    }];
+
+    environment.etc."mlvwm/mlvwmrc" = mkIf (cfg.configFile != null) {
+      source = cfg.configFile;
+    };
+
+    environment.systemPackages = [ pkgs.mlvwm ];
+  };
+}
diff --git a/nixos/modules/services/x11/window-managers/mwm.nix b/nixos/modules/services/x11/window-managers/mwm.nix
new file mode 100644
index 00000000000..31f7b725f74
--- /dev/null
+++ b/nixos/modules/services/x11/window-managers/mwm.nix
@@ -0,0 +1,25 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+  cfg = config.services.xserver.windowManager.mwm;
+in
+{
+  ###### interface
+  options = {
+    services.xserver.windowManager.mwm.enable = mkEnableOption "mwm";
+  };
+
+  ###### implementation
+  config = mkIf cfg.enable {
+    services.xserver.windowManager.session = singleton {
+      name = "mwm";
+      start = ''
+        ${pkgs.motif}/bin/mwm &
+        waitPID=$!
+      '';
+    };
+    environment.systemPackages = [ pkgs.motif ];
+  };
+}
diff --git a/nixos/modules/services/x11/window-managers/none.nix b/nixos/modules/services/x11/window-managers/none.nix
new file mode 100644
index 00000000000..84cf1d77077
--- /dev/null
+++ b/nixos/modules/services/x11/window-managers/none.nix
@@ -0,0 +1,12 @@
+{
+  services = {
+    xserver = {
+      windowManager = {
+        session = [{
+          name = "none";
+          start = "";
+        }];
+      };
+    };
+  };
+}
diff --git a/nixos/modules/services/x11/window-managers/notion.nix b/nixos/modules/services/x11/window-managers/notion.nix
new file mode 100644
index 00000000000..4ece0d241c9
--- /dev/null
+++ b/nixos/modules/services/x11/window-managers/notion.nix
@@ -0,0 +1,26 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+  cfg = config.services.xserver.windowManager.notion;
+in
+
+{
+  options = {
+    services.xserver.windowManager.notion.enable = mkEnableOption "notion";
+  };
+
+  config = mkIf cfg.enable {
+    services.xserver.windowManager = {
+      session = [{
+        name = "notion";
+        start = ''
+          ${pkgs.notion}/bin/notion &
+          waitPID=$!
+        '';
+      }];
+    };
+    environment.systemPackages = [ pkgs.notion ];
+  };
+}
diff --git a/nixos/modules/services/x11/window-managers/openbox.nix b/nixos/modules/services/x11/window-managers/openbox.nix
new file mode 100644
index 00000000000..165772d1aa0
--- /dev/null
+++ b/nixos/modules/services/x11/window-managers/openbox.nix
@@ -0,0 +1,24 @@
+{lib, pkgs, config, ...}:
+
+with lib;
+let
+  cfg = config.services.xserver.windowManager.openbox;
+in
+
+{
+  options = {
+    services.xserver.windowManager.openbox.enable = mkEnableOption "openbox";
+  };
+
+  config = mkIf cfg.enable {
+    services.xserver.windowManager = {
+      session = [{
+        name = "openbox";
+        start = "
+          ${pkgs.openbox}/bin/openbox-session
+        ";
+      }];
+    };
+    environment.systemPackages = [ pkgs.openbox ];
+  };
+}
diff --git a/nixos/modules/services/x11/window-managers/oroborus.nix b/nixos/modules/services/x11/window-managers/oroborus.nix
new file mode 100644
index 00000000000..bd7e3396864
--- /dev/null
+++ b/nixos/modules/services/x11/window-managers/oroborus.nix
@@ -0,0 +1,25 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+  cfg = config.services.xserver.windowManager.oroborus;
+in
+{
+  ###### interface
+  options = {
+    services.xserver.windowManager.oroborus.enable = mkEnableOption "oroborus";
+  };
+
+  ###### implementation
+  config = mkIf cfg.enable {
+    services.xserver.windowManager.session = singleton {
+      name = "oroborus";
+      start = ''
+        ${pkgs.oroborus}/bin/oroborus &
+        waitPID=$!
+      '';
+    };
+    environment.systemPackages = [ pkgs.oroborus ];
+  };
+}
diff --git a/nixos/modules/services/x11/window-managers/pekwm.nix b/nixos/modules/services/x11/window-managers/pekwm.nix
new file mode 100644
index 00000000000..850335ce7dd
--- /dev/null
+++ b/nixos/modules/services/x11/window-managers/pekwm.nix
@@ -0,0 +1,25 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+  cfg = config.services.xserver.windowManager.pekwm;
+in
+{
+  ###### interface
+  options = {
+    services.xserver.windowManager.pekwm.enable = mkEnableOption "pekwm";
+  };
+
+  ###### implementation
+  config = mkIf cfg.enable {
+    services.xserver.windowManager.session = singleton {
+      name = "pekwm";
+      start = ''
+        ${pkgs.pekwm}/bin/pekwm &
+        waitPID=$!
+      '';
+    };
+    environment.systemPackages = [ pkgs.pekwm ];
+  };
+}
diff --git a/nixos/modules/services/x11/window-managers/qtile.nix b/nixos/modules/services/x11/window-managers/qtile.nix
new file mode 100644
index 00000000000..835b41d4ada
--- /dev/null
+++ b/nixos/modules/services/x11/window-managers/qtile.nix
@@ -0,0 +1,25 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+  cfg = config.services.xserver.windowManager.qtile;
+in
+
+{
+  options = {
+    services.xserver.windowManager.qtile.enable = mkEnableOption "qtile";
+  };
+
+  config = mkIf cfg.enable {
+    services.xserver.windowManager.session = [{
+      name = "qtile";
+      start = ''
+        ${pkgs.qtile}/bin/qtile start &
+        waitPID=$!
+      '';
+    }];
+
+    environment.systemPackages = [ pkgs.qtile ];
+  };
+}
diff --git a/nixos/modules/services/x11/window-managers/ratpoison.nix b/nixos/modules/services/x11/window-managers/ratpoison.nix
new file mode 100644
index 00000000000..0d58481d457
--- /dev/null
+++ b/nixos/modules/services/x11/window-managers/ratpoison.nix
@@ -0,0 +1,25 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+  cfg = config.services.xserver.windowManager.ratpoison;
+in
+{
+  ###### interface
+  options = {
+    services.xserver.windowManager.ratpoison.enable = mkEnableOption "ratpoison";
+  };
+
+  ###### implementation
+  config = mkIf cfg.enable {
+    services.xserver.windowManager.session = singleton {
+      name = "ratpoison";
+      start = ''
+        ${pkgs.ratpoison}/bin/ratpoison &
+        waitPID=$!
+      '';
+    };
+    environment.systemPackages = [ pkgs.ratpoison ];
+  };
+}
diff --git a/nixos/modules/services/x11/window-managers/sawfish.nix b/nixos/modules/services/x11/window-managers/sawfish.nix
new file mode 100644
index 00000000000..b988b5e1829
--- /dev/null
+++ b/nixos/modules/services/x11/window-managers/sawfish.nix
@@ -0,0 +1,25 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+  cfg = config.services.xserver.windowManager.sawfish;
+in
+{
+  ###### interface
+  options = {
+    services.xserver.windowManager.sawfish.enable = mkEnableOption "sawfish";
+  };
+
+  ###### implementation
+  config = mkIf cfg.enable {
+    services.xserver.windowManager.session = singleton {
+      name = "sawfish";
+      start = ''
+        ${pkgs.sawfish}/bin/sawfish &
+        waitPID=$!
+      '';
+    };
+    environment.systemPackages = [ pkgs.sawfish ];
+  };
+}
diff --git a/nixos/modules/services/x11/window-managers/smallwm.nix b/nixos/modules/services/x11/window-managers/smallwm.nix
new file mode 100644
index 00000000000..091ba4f92b9
--- /dev/null
+++ b/nixos/modules/services/x11/window-managers/smallwm.nix
@@ -0,0 +1,25 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+  cfg = config.services.xserver.windowManager.smallwm;
+in
+{
+  ###### interface
+  options = {
+    services.xserver.windowManager.smallwm.enable = mkEnableOption "smallwm";
+  };
+
+  ###### implementation
+  config = mkIf cfg.enable {
+    services.xserver.windowManager.session = singleton {
+      name = "smallwm";
+      start = ''
+        ${pkgs.smallwm}/bin/smallwm &
+        waitPID=$!
+      '';
+    };
+    environment.systemPackages = [ pkgs.smallwm ];
+  };
+}
diff --git a/nixos/modules/services/x11/window-managers/spectrwm.nix b/nixos/modules/services/x11/window-managers/spectrwm.nix
new file mode 100644
index 00000000000..a1dc298d242
--- /dev/null
+++ b/nixos/modules/services/x11/window-managers/spectrwm.nix
@@ -0,0 +1,27 @@
+
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+  cfg = config.services.xserver.windowManager.spectrwm;
+in
+
+{
+  options = {
+    services.xserver.windowManager.spectrwm.enable = mkEnableOption "spectrwm";
+  };
+
+  config = mkIf cfg.enable {
+    services.xserver.windowManager = {
+      session = [{
+        name = "spectrwm";
+        start = ''
+          ${pkgs.spectrwm}/bin/spectrwm &
+          waitPID=$!
+        '';
+      }];
+    };
+    environment.systemPackages = [ pkgs.spectrwm ];
+  };
+}
diff --git a/nixos/modules/services/x11/window-managers/stumpwm.nix b/nixos/modules/services/x11/window-managers/stumpwm.nix
new file mode 100644
index 00000000000..27a17178476
--- /dev/null
+++ b/nixos/modules/services/x11/window-managers/stumpwm.nix
@@ -0,0 +1,24 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+  cfg = config.services.xserver.windowManager.stumpwm;
+in
+
+{
+  options = {
+    services.xserver.windowManager.stumpwm.enable = mkEnableOption "stumpwm";
+  };
+
+  config = mkIf cfg.enable {
+    services.xserver.windowManager.session = singleton {
+      name = "stumpwm";
+      start = ''
+        ${pkgs.lispPackages.stumpwm}/bin/stumpwm &
+        waitPID=$!
+      '';
+    };
+    environment.systemPackages = [ pkgs.lispPackages.stumpwm ];
+  };
+}
diff --git a/nixos/modules/services/x11/window-managers/tinywm.nix b/nixos/modules/services/x11/window-managers/tinywm.nix
new file mode 100644
index 00000000000..8e5d9b9170c
--- /dev/null
+++ b/nixos/modules/services/x11/window-managers/tinywm.nix
@@ -0,0 +1,25 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+  cfg = config.services.xserver.windowManager.tinywm;
+in
+{
+  ###### interface
+  options = {
+    services.xserver.windowManager.tinywm.enable = mkEnableOption "tinywm";
+  };
+
+  ###### implementation
+  config = mkIf cfg.enable {
+    services.xserver.windowManager.session = singleton {
+      name = "tinywm";
+      start = ''
+        ${pkgs.tinywm}/bin/tinywm &
+        waitPID=$!
+      '';
+    };
+    environment.systemPackages = [ pkgs.tinywm ];
+  };
+}
diff --git a/nixos/modules/services/x11/window-managers/twm.nix b/nixos/modules/services/x11/window-managers/twm.nix
new file mode 100644
index 00000000000..fc09901aae3
--- /dev/null
+++ b/nixos/modules/services/x11/window-managers/twm.nix
@@ -0,0 +1,37 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+
+  cfg = config.services.xserver.windowManager.twm;
+
+in
+
+{
+
+  ###### interface
+
+  options = {
+    services.xserver.windowManager.twm.enable = mkEnableOption "twm";
+  };
+
+
+  ###### implementation
+
+  config = mkIf cfg.enable {
+
+    services.xserver.windowManager.session = singleton
+      { name = "twm";
+        start =
+          ''
+            ${pkgs.xorg.twm}/bin/twm &
+            waitPID=$!
+          '';
+      };
+
+    environment.systemPackages = [ pkgs.xorg.twm ];
+
+  };
+
+}
diff --git a/nixos/modules/services/x11/window-managers/windowlab.nix b/nixos/modules/services/x11/window-managers/windowlab.nix
new file mode 100644
index 00000000000..fb891a39fa4
--- /dev/null
+++ b/nixos/modules/services/x11/window-managers/windowlab.nix
@@ -0,0 +1,22 @@
+{lib, pkgs, config, ...}:
+
+let
+  cfg = config.services.xserver.windowManager.windowlab;
+in
+
+{
+  options = {
+    services.xserver.windowManager.windowlab.enable =
+      lib.mkEnableOption "windowlab";
+  };
+
+  config = lib.mkIf cfg.enable {
+    services.xserver.windowManager = {
+      session =
+        [{ name  = "windowlab";
+           start = "${pkgs.windowlab}/bin/windowlab";
+        }];
+    };
+    environment.systemPackages = [ pkgs.windowlab ];
+  };
+}
diff --git a/nixos/modules/services/x11/window-managers/windowmaker.nix b/nixos/modules/services/x11/window-managers/windowmaker.nix
new file mode 100644
index 00000000000..b6272375805
--- /dev/null
+++ b/nixos/modules/services/x11/window-managers/windowmaker.nix
@@ -0,0 +1,25 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+  cfg = config.services.xserver.windowManager.windowmaker;
+in
+{
+  ###### interface
+  options = {
+    services.xserver.windowManager.windowmaker.enable = mkEnableOption "windowmaker";
+  };
+
+  ###### implementation
+  config = mkIf cfg.enable {
+    services.xserver.windowManager.session = singleton {
+      name = "windowmaker";
+      start = ''
+        ${pkgs.windowmaker}/bin/wmaker &
+        waitPID=$!
+      '';
+    };
+    environment.systemPackages = [ pkgs.windowmaker ];
+  };
+}
diff --git a/nixos/modules/services/x11/window-managers/wmderland.nix b/nixos/modules/services/x11/window-managers/wmderland.nix
new file mode 100644
index 00000000000..56b69220965
--- /dev/null
+++ b/nixos/modules/services/x11/window-managers/wmderland.nix
@@ -0,0 +1,61 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+  cfg = config.services.xserver.windowManager.wmderland;
+in
+
+{
+  options.services.xserver.windowManager.wmderland = {
+    enable = mkEnableOption "wmderland";
+
+    extraSessionCommands = mkOption {
+      default = "";
+      type = types.lines;
+      description = ''
+        Shell commands executed just before wmderland is started.
+      '';
+    };
+
+    extraPackages = mkOption {
+      type = with types; listOf package;
+      default = with pkgs; [
+        rofi
+        dunst
+        light
+        hsetroot
+        feh
+        rxvt-unicode
+      ];
+      defaultText = literalExpression ''
+        with pkgs; [
+          rofi
+          dunst
+          light
+          hsetroot
+          feh
+          rxvt-unicode
+        ]
+      '';
+      description = ''
+        Extra packages to be installed system wide.
+      '';
+    };
+  };
+
+  config = mkIf cfg.enable {
+    services.xserver.windowManager.session = singleton {
+      name = "wmderland";
+      start = ''
+        ${cfg.extraSessionCommands}
+
+        ${pkgs.wmderland}/bin/wmderland &
+        waitPID=$!
+      '';
+    };
+    environment.systemPackages = [
+      pkgs.wmderland pkgs.wmderlandc
+    ] ++ cfg.extraPackages;
+  };
+}
diff --git a/nixos/modules/services/x11/window-managers/wmii.nix b/nixos/modules/services/x11/window-managers/wmii.nix
new file mode 100644
index 00000000000..9b50a99bf23
--- /dev/null
+++ b/nixos/modules/services/x11/window-managers/wmii.nix
@@ -0,0 +1,39 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+let
+  cfg = config.services.xserver.windowManager.wmii;
+  wmii = pkgs.wmii_hg;
+in
+{
+  options = {
+    services.xserver.windowManager.wmii.enable = mkEnableOption "wmii";
+  };
+
+  config = mkIf cfg.enable {
+    services.xserver.windowManager.session = singleton
+      # stop wmii by
+      #   $wmiir xwrite /ctl quit
+      # this will cause wmii exiting with exit code 0
+      # (or "mod+a quit", which is bound to do the same thing in wmiirc
+      # by default)
+      #
+      # why this loop?
+      # wmii crashes once a month here. That doesn't matter that much
+      # wmii can recover very well. However without loop the X session
+      # terminates and then your workspace setup is lost and all
+      # applications running on X will terminate.
+      # Another use case is kill -9 wmii; after rotating screen.
+      # Note: we don't like kill for that purpose. But it works (->
+      # subject "wmii and xrandr" on mailinglist)
+      { name = "wmii";
+        start = ''
+          while :; do
+            ${wmii}/bin/wmii && break
+          done
+        '';
+      };
+
+    environment.systemPackages = [ wmii ];
+  };
+}
diff --git a/nixos/modules/services/x11/window-managers/xmonad.nix b/nixos/modules/services/x11/window-managers/xmonad.nix
new file mode 100644
index 00000000000..68f97c2f504
--- /dev/null
+++ b/nixos/modules/services/x11/window-managers/xmonad.nix
@@ -0,0 +1,203 @@
+{pkgs, lib, config, ...}:
+
+with lib;
+let
+  inherit (lib) mkOption mkIf optionals literalExpression optionalString;
+  cfg = config.services.xserver.windowManager.xmonad;
+
+  ghcWithPackages = cfg.haskellPackages.ghcWithPackages;
+  packages = self: cfg.extraPackages self ++
+                   optionals cfg.enableContribAndExtras
+                   [ self.xmonad-contrib self.xmonad-extras ];
+
+  xmonad-vanilla = pkgs.xmonad-with-packages.override {
+    inherit ghcWithPackages packages;
+  };
+
+  xmonad-config =
+    let
+      xmonadAndPackages = self: [ self.xmonad ] ++ packages self;
+      xmonadEnv = ghcWithPackages xmonadAndPackages;
+      configured = pkgs.writers.writeHaskellBin "xmonad" {
+        ghc = cfg.haskellPackages.ghc;
+        libraries = xmonadAndPackages cfg.haskellPackages;
+        inherit (cfg) ghcArgs;
+      } cfg.config;
+    in
+      pkgs.runCommandLocal "xmonad" {
+        nativeBuildInputs = [ pkgs.makeWrapper ];
+      } (''
+        install -D ${xmonadEnv}/share/man/man1/xmonad.1.gz $out/share/man/man1/xmonad.1.gz
+        makeWrapper ${configured}/bin/xmonad $out/bin/xmonad \
+      '' + optionalString cfg.enableConfiguredRecompile ''
+          --set NIX_GHC "${xmonadEnv}/bin/ghc" \
+      '' + ''
+          --set XMONAD_XMESSAGE "${pkgs.xorg.xmessage}/bin/xmessage"
+      '');
+
+  xmonad = if (cfg.config != null) then xmonad-config else xmonad-vanilla;
+in {
+  meta.maintainers = with maintainers; [ lassulus xaverdh ivanbrennan ];
+
+  options = {
+    services.xserver.windowManager.xmonad = {
+      enable = mkEnableOption "xmonad";
+
+      haskellPackages = mkOption {
+        default = pkgs.haskellPackages;
+        defaultText = literalExpression "pkgs.haskellPackages";
+        example = literalExpression "pkgs.haskell.packages.ghc784";
+        type = types.attrs;
+        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
+          <varname>extraPackages</varname>.
+        '';
+      };
+
+      extraPackages = mkOption {
+        type = types.functionTo (types.listOf types.package);
+        default = self: [];
+        defaultText = literalExpression "self: []";
+        example = literalExpression ''
+          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 attrset defined
+          in <varname>haskellPackages</varname> as the sole argument.
+        '';
+      };
+
+      enableContribAndExtras = mkOption {
+        default = false;
+        type = lib.types.bool;
+        description = "Enable xmonad-{contrib,extras} in Xmonad.";
+      };
+
+      config = mkOption {
+        default = null;
+        type = with lib.types; nullOr (either path str);
+        description = ''
+          Configuration from which XMonad gets compiled. If no value is
+          specified, a vanilla xmonad binary is put in PATH, which will
+          attempt to recompile and exec your xmonad config from $HOME/.xmonad.
+          This setup is then analogous to other (non-NixOS) linux distributions.
+
+          If you do set this option, you likely want to use "launch" as your
+          entry point for xmonad (as in the example), to avoid xmonad's
+          recompilation logic on startup. Doing so will render the default
+          "mod+q" restart key binding dysfunctional though, because that attempts
+          to call your binary with the "--restart" command line option, unless
+          you implement that yourself. You way mant to bind "mod+q" to
+          <literal>(restart "xmonad" True)</literal> instead, which will just restart
+          xmonad from PATH. This allows e.g. switching to the new xmonad binary
+          after rebuilding your system with nixos-rebuild.
+          For the same reason, ghc is not added to the environment when this
+          option is set, unless <option>enableConfiguredRecompile</option> is
+          set to <literal>true</literal>.
+
+          If you actually want to run xmonad with a config specified here, but
+          also be able to recompile and restart it from a copy of that source in
+          $HOME/.xmonad on the fly, set <option>enableConfiguredRecompile</option>
+          to <literal>true</literal> and implement something like "compileRestart"
+          from the example.
+          This should allow you to switch at will between the local xmonad and
+          the one NixOS puts in your PATH.
+        '';
+        example = ''
+          import XMonad
+          import XMonad.Util.EZConfig (additionalKeys)
+          import Control.Monad (when)
+          import Text.Printf (printf)
+          import System.Posix.Process (executeFile)
+          import System.Info (arch,os)
+          import System.Environment (getArgs)
+          import System.FilePath ((</>))
+
+          compiledConfig = printf "xmonad-%s-%s" arch os
+
+          myConfig = defaultConfig
+            { modMask = mod4Mask -- Use Super instead of Alt
+            , terminal = "urxvt" }
+            `additionalKeys`
+            [ ( (mod4Mask,xK_r), compileRestart True)
+            , ( (mod4Mask,xK_q), restart "xmonad" True ) ]
+
+          --------------------------------------------
+          {- version 0.17.0 -}
+          --------------------------------------------
+          -- compileRestart resume =
+          --   dirs <- io getDirectories
+          --   whenX (recompile dirs True) $
+          --     when resume writeStateToFile
+          --       *> catchIO
+          --         ( do
+          --             args <- getArgs
+          --             executeFile (cacheDir dirs </> compiledConfig) False args Nothing
+          --         )
+          --
+          -- main = getDirectories >>= launch myConfig
+          --------------------------------------------
+
+          compileRestart resume =
+            whenX (recompile True) $
+              when resume writeStateToFile
+                *> catchIO
+                  ( do
+                      dir <- getXMonadDataDir
+                      args <- getArgs
+                      executeFile (dir </> compiledConfig) False args Nothing
+                  )
+
+          main = launch myConfig
+        '';
+      };
+
+      enableConfiguredRecompile = mkOption {
+        default = false;
+        type = lib.types.bool;
+        description = ''
+          Enable recompilation even if <option>config</option> is set to a
+          non-null value. This adds the necessary Haskell dependencies (GHC with
+          packages) to the xmonad binary's environment.
+        '';
+      };
+
+      xmonadCliArgs = mkOption {
+        default = [];
+        type = with lib.types; listOf str;
+        description = ''
+          Command line arguments passed to the xmonad binary.
+        '';
+      };
+
+      ghcArgs = mkOption {
+        default = [];
+        type = with lib.types; listOf str;
+        description = ''
+          Command line arguments passed to the compiler (ghc)
+          invocation when xmonad.config is set.
+        '';
+      };
+
+    };
+  };
+  config = mkIf cfg.enable {
+    services.xserver.windowManager = {
+      session = [{
+        name = "xmonad";
+        start = ''
+           systemd-cat -t xmonad -- ${xmonad}/bin/xmonad ${lib.escapeShellArgs cfg.xmonadCliArgs} &
+           waitPID=$!
+        '';
+      }];
+    };
+
+    environment.systemPackages = [ xmonad ];
+  };
+}
diff --git a/nixos/modules/services/x11/window-managers/yeahwm.nix b/nixos/modules/services/x11/window-managers/yeahwm.nix
new file mode 100644
index 00000000000..351bd7dfe48
--- /dev/null
+++ b/nixos/modules/services/x11/window-managers/yeahwm.nix
@@ -0,0 +1,25 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+  cfg = config.services.xserver.windowManager.yeahwm;
+in
+{
+  ###### interface
+  options = {
+    services.xserver.windowManager.yeahwm.enable = mkEnableOption "yeahwm";
+  };
+
+  ###### implementation
+  config = mkIf cfg.enable {
+    services.xserver.windowManager.session = singleton {
+      name = "yeahwm";
+      start = ''
+        ${pkgs.yeahwm}/bin/yeahwm &
+        waitPID=$!
+      '';
+    };
+    environment.systemPackages = [ pkgs.yeahwm ];
+  };
+}