about summary refs log tree commit diff
path: root/nixpkgs/nixos/modules/services/x11/desktop-managers
diff options
context:
space:
mode:
Diffstat (limited to 'nixpkgs/nixos/modules/services/x11/desktop-managers')
-rw-r--r--nixpkgs/nixos/modules/services/x11/desktop-managers/default.nix113
-rw-r--r--nixpkgs/nixos/modules/services/x11/desktop-managers/enlightenment.nix104
-rw-r--r--nixpkgs/nixos/modules/services/x11/desktop-managers/gnome3.nix325
-rw-r--r--nixpkgs/nixos/modules/services/x11/desktop-managers/kodi.nix30
-rw-r--r--nixpkgs/nixos/modules/services/x11/desktop-managers/lumina.nix45
-rw-r--r--nixpkgs/nixos/modules/services/x11/desktop-managers/lxqt.nix67
-rw-r--r--nixpkgs/nixos/modules/services/x11/desktop-managers/mate.nix113
-rw-r--r--nixpkgs/nixos/modules/services/x11/desktop-managers/maxx.nix31
-rw-r--r--nixpkgs/nixos/modules/services/x11/desktop-managers/none.nix7
-rw-r--r--nixpkgs/nixos/modules/services/x11/desktop-managers/pantheon.nix214
-rw-r--r--nixpkgs/nixos/modules/services/x11/desktop-managers/plasma5.nix266
-rw-r--r--nixpkgs/nixos/modules/services/x11/desktop-managers/surf-display.nix127
-rw-r--r--nixpkgs/nixos/modules/services/x11/desktop-managers/xfce.nix129
-rw-r--r--nixpkgs/nixos/modules/services/x11/desktop-managers/xfce4-14.nix157
-rw-r--r--nixpkgs/nixos/modules/services/x11/desktop-managers/xterm.nix38
15 files changed, 1766 insertions, 0 deletions
diff --git a/nixpkgs/nixos/modules/services/x11/desktop-managers/default.nix b/nixpkgs/nixos/modules/services/x11/desktop-managers/default.nix
new file mode 100644
index 000000000000..dfb84113e130
--- /dev/null
+++ b/nixpkgs/nixos/modules/services/x11/desktop-managers/default.nix
@@ -0,0 +1,113 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+
+  xcfg = config.services.xserver;
+  cfg = xcfg.desktopManager;
+
+  # If desktop manager `d' isn't capable of setting a background and
+  # the xserver is enabled, `feh' or `xsetroot' are used as a fallback.
+  needBGCond = d: ! (d ? bgSupport && d.bgSupport) && xcfg.enable;
+
+in
+
+{
+  # Note: the order in which desktop manager modules are imported here
+  # determines the default: later modules (if enabled) are preferred.
+  # E.g., if Plasma 5 is enabled, it supersedes xterm.
+  imports = [
+    ./none.nix ./xterm.nix ./xfce.nix ./xfce4-14.nix ./plasma5.nix ./lumina.nix
+    ./lxqt.nix ./enlightenment.nix ./gnome3.nix ./kodi.nix ./maxx.nix
+    ./mate.nix ./pantheon.nix ./surf-display.nix
+  ];
+
+  options = {
+
+    services.xserver.desktopManager = {
+
+      wallpaper = {
+        mode = mkOption {
+          type = types.enum [ "center" "fill" "max" "scale" "tile" ];
+          default = "scale";
+          example = "fill";
+          description = ''
+            The file <filename>~/.background-image</filename> is used as a background image.
+            This option specifies the placement of this image onto your desktop.
+
+            Possible values:
+            <literal>center</literal>: Center the image on the background. If it is too small, it will be surrounded by a black border.
+            <literal>fill</literal>: Like <literal>scale</literal>, but preserves aspect ratio by zooming the image until it fits. Either a horizontal or a vertical part of the image will be cut off.
+            <literal>max</literal>: Like <literal>fill</literal>, but scale the image to the maximum size that fits the screen with black borders on one side.
+            <literal>scale</literal>: Fit the file into the background without repeating it, cutting off stuff or using borders. But the aspect ratio is not preserved either.
+            <literal>tile</literal>: Tile (repeat) the image in case it is too small for the screen.
+          '';
+        };
+
+        combineScreens = mkOption {
+          type = types.bool;
+          default = false;
+          description = ''
+            When set to <literal>true</literal> the wallpaper will stretch across all screens.
+            When set to <literal>false</literal> the wallpaper is duplicated to all screens.
+          '';
+        };
+      };
+
+      session = mkOption {
+        internal = true;
+        default = [];
+        example = singleton
+          { name = "kde";
+            bgSupport = true;
+            start = "...";
+          };
+        description = ''
+          Internal option used to add some common line to desktop manager
+          scripts before forwarding the value to the
+          <varname>displayManager</varname>.
+        '';
+        apply = list: {
+          list = map (d: d // {
+            manage = "desktop";
+            start = d.start
+            + optionalString (needBGCond d) ''
+              if [ -e $HOME/.background-image ]; then
+                ${pkgs.feh}/bin/feh --bg-${cfg.wallpaper.mode} ${optionalString cfg.wallpaper.combineScreens "--no-xinerama"} $HOME/.background-image
+              else
+                # Use a solid black background as fallback
+                ${pkgs.xorg.xsetroot}/bin/xsetroot -solid black
+              fi
+            '';
+          }) list;
+          needBGPackages = [] != filter needBGCond list;
+        };
+      };
+
+      default = mkOption {
+        type = types.str;
+        default = "";
+        example = "none";
+        description = "Default desktop manager loaded if none have been chosen.";
+        apply = defaultDM:
+          if defaultDM == "" && cfg.session.list != [] then
+            (head cfg.session.list).name
+          else if any (w: w.name == defaultDM) cfg.session.list then
+            defaultDM
+          else
+            builtins.trace ''
+              Default desktop manager (${defaultDM}) not found at evaluation time.
+              These are the known valid session names:
+                ${concatMapStringsSep "\n  " (w: "services.xserver.desktopManager.default = \"${w.name}\";") cfg.session.list}
+              It's also possible the default can be found in one of these packages:
+                ${concatMapStringsSep "\n  " (p: p.name) config.services.xserver.displayManager.extraSessionFilePackages}
+            '' defaultDM;
+      };
+
+    };
+
+  };
+
+  config.services.xserver.displayManager.session = cfg.session.list;
+}
diff --git a/nixpkgs/nixos/modules/services/x11/desktop-managers/enlightenment.nix b/nixpkgs/nixos/modules/services/x11/desktop-managers/enlightenment.nix
new file mode 100644
index 000000000000..527e4b18045b
--- /dev/null
+++ b/nixpkgs/nixos/modules/services/x11/desktop-managers/enlightenment.nix
@@ -0,0 +1,104 @@
+{ config, pkgs, lib, ... }:
+
+with lib;
+
+let
+
+  e = pkgs.enlightenment;
+  xcfg = config.services.xserver;
+  cfg = xcfg.desktopManager.enlightenment;
+  GST_PLUGIN_PATH = lib.makeSearchPathOutput "lib" "lib/gstreamer-1.0" [
+    pkgs.gst_all_1.gst-plugins-base
+    pkgs.gst_all_1.gst-plugins-good
+    pkgs.gst_all_1.gst-plugins-bad
+    pkgs.gst_all_1.gst-libav ];
+
+in
+
+{
+  options = {
+
+    services.xserver.desktopManager.enlightenment.enable = mkOption {
+      default = false;
+      description = "Enable the Enlightenment desktop environment.";
+    };
+
+  };
+
+  config = mkIf cfg.enable {
+
+    environment.systemPackages = [
+      e.efl e.enlightenment
+      e.terminology e.econnman
+      pkgs.xorg.xauth # used by kdesu
+      pkgs.gtk2 # To get GTK+'s themes.
+      pkgs.tango-icon-theme
+
+      pkgs.gnome2.gnome_icon_theme
+      pkgs.xorg.xcursorthemes
+    ];
+
+    environment.pathsToLink = [
+      "/etc/enlightenment"
+      "/share/enlightenment"
+      "/share/elementary"
+      "/share/locale"
+    ];
+
+    services.xserver.desktopManager.session = [
+    { name = "Enlightenment";
+      start = ''
+        # Set GTK_DATA_PREFIX so that GTK+ can find the themes
+        export GTK_DATA_PREFIX=${config.system.path}
+        # find theme engines
+        export GTK_PATH=${config.system.path}/lib/gtk-3.0:${config.system.path}/lib/gtk-2.0
+        export XDG_MENU_PREFIX=e-
+
+        export GST_PLUGIN_PATH="${GST_PLUGIN_PATH}"
+
+        # make available for D-BUS user services
+        #export XDG_DATA_DIRS=$XDG_DATA_DIRS''${XDG_DATA_DIRS:+:}:${config.system.path}/share:${e.efl}/share
+
+        # Update user dirs as described in http://freedesktop.org/wiki/Software/xdg-user-dirs/
+        ${pkgs.xdg-user-dirs}/bin/xdg-user-dirs-update
+
+        exec ${e.enlightenment}/bin/enlightenment_start
+      '';
+    }];
+
+    security.wrappers = (import "${e.enlightenment}/e-wrappers.nix").security.wrappers;
+
+    environment.etc = singleton
+      { source = xcfg.xkbDir;
+        target = "X11/xkb";
+      };
+
+    fonts.fonts = [ pkgs.dejavu_fonts pkgs.ubuntu_font_family ];
+
+    services.udisks2.enable = true;
+    services.upower.enable = config.powerManagement.enable;
+
+    services.dbus.packages = [ e.efl ];
+
+    systemd.user.services.efreet =
+      { enable = true;
+        description = "org.enlightenment.Efreet";
+        serviceConfig =
+          { ExecStart = "${e.efl}/bin/efreetd";
+            StandardOutput = "null";
+          };
+      };
+
+    systemd.user.services.ethumb =
+      { enable = true;
+        description = "org.enlightenment.Ethumb";
+        serviceConfig =
+          { ExecStart = "${e.efl}/bin/ethumbd";
+            StandardOutput = "null";
+          };
+      };
+
+
+  };
+
+}
diff --git a/nixpkgs/nixos/modules/services/x11/desktop-managers/gnome3.nix b/nixpkgs/nixos/modules/services/x11/desktop-managers/gnome3.nix
new file mode 100644
index 000000000000..0caa93ad217f
--- /dev/null
+++ b/nixpkgs/nixos/modules/services/x11/desktop-managers/gnome3.nix
@@ -0,0 +1,325 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+
+  cfg = config.services.xserver.desktopManager.gnome3;
+  serviceCfg = config.services.gnome3;
+
+  # Prioritize nautilus by default when opening directories
+  mimeAppsList = pkgs.writeTextFile {
+    name = "gnome-mimeapps";
+    destination = "/share/applications/mimeapps.list";
+    text = ''
+      [Default Applications]
+      inode/directory=nautilus.desktop;org.gnome.Nautilus.desktop
+    '';
+  };
+
+  nixos-gsettings-desktop-schemas = let
+    defaultPackages = with pkgs; [ gsettings-desktop-schemas gnome3.gnome-shell ];
+  in
+  pkgs.runCommand "nixos-gsettings-desktop-schemas" { preferLocalBuild = true; }
+    ''
+     mkdir -p $out/share/gsettings-schemas/nixos-gsettings-overrides/glib-2.0/schemas
+
+     ${concatMapStrings
+        (pkg: "cp -rf ${pkg}/share/gsettings-schemas/*/glib-2.0/schemas/*.xml $out/share/gsettings-schemas/nixos-gsettings-overrides/glib-2.0/schemas\n")
+        (defaultPackages ++ cfg.extraGSettingsOverridePackages)}
+
+     chmod -R a+w $out/share/gsettings-schemas/nixos-gsettings-overrides
+     cat - > $out/share/gsettings-schemas/nixos-gsettings-overrides/glib-2.0/schemas/nixos-defaults.gschema.override <<- EOF
+       [org.gnome.desktop.background]
+       picture-uri='file://${pkgs.nixos-artwork.wallpapers.simple-dark-gray}/share/artwork/gnome/nix-wallpaper-simple-dark-gray.png'
+
+       [org.gnome.desktop.screensaver]
+       picture-uri='file://${pkgs.nixos-artwork.wallpapers.simple-dark-gray-bottom}/share/artwork/gnome/nix-wallpaper-simple-dark-gray_bottom.png'
+
+       [org.gnome.shell]
+       favorite-apps=[ 'org.gnome.Epiphany.desktop', 'evolution.desktop', 'org.gnome.Music.desktop', 'org.gnome.Photos.desktop', 'org.gnome.Nautilus.desktop', 'org.gnome.Software.desktop' ]
+
+       ${cfg.extraGSettingsOverrides}
+     EOF
+
+     ${pkgs.glib.dev}/bin/glib-compile-schemas $out/share/gsettings-schemas/nixos-gsettings-overrides/glib-2.0/schemas/
+    '';
+
+  flashbackEnabled = cfg.flashback.enableMetacity || length cfg.flashback.customSessions > 0;
+
+in
+
+{
+
+  options = {
+
+    services.gnome3 = {
+      core-os-services.enable = mkEnableOption "essential services for GNOME3";
+      core-shell.enable = mkEnableOption "GNOME Shell services";
+      core-utilities.enable = mkEnableOption "GNOME core utilities";
+      games.enable = mkEnableOption "GNOME games";
+    };
+
+    services.xserver.desktopManager.gnome3 = {
+      enable = mkOption {
+        default = false;
+        description = "Enable Gnome 3 desktop manager.";
+      };
+
+      sessionPath = mkOption {
+        default = [];
+        example = literalExample "[ pkgs.gnome3.gpaste ]";
+        description = ''
+          Additional list of packages to be added to the session search path.
+          Useful for GNOME Shell extensions or GSettings-conditional autostart.
+
+          Note that this should be a last resort; patching the package is preferred (see GPaste).
+        '';
+        apply = list: list ++ [ pkgs.gnome3.gnome-shell pkgs.gnome3.gnome-shell-extensions ];
+      };
+
+      extraGSettingsOverrides = mkOption {
+        default = "";
+        type = types.lines;
+        description = "Additional gsettings overrides.";
+      };
+
+      extraGSettingsOverridePackages = mkOption {
+        default = [];
+        type = types.listOf types.path;
+        description = "List of packages for which gsettings are overridden.";
+      };
+
+      debug = mkEnableOption "gnome-session debug messages";
+
+      flashback = {
+        enableMetacity = mkEnableOption "the standard GNOME Flashback session with Metacity";
+
+        customSessions = mkOption {
+          type = types.listOf (types.submodule {
+            options = {
+              wmName = mkOption {
+                type = types.str;
+                description = "The filename-compatible name of the window manager to use.";
+                example = "xmonad";
+              };
+
+              wmLabel = mkOption {
+                type = types.str;
+                description = "The pretty name of the window manager to use.";
+                example = "XMonad";
+              };
+
+              wmCommand = mkOption {
+                type = types.str;
+                description = "The executable of the window manager to use.";
+                example = "\${pkgs.haskellPackages.xmonad}/bin/xmonad";
+              };
+            };
+          });
+          default = [];
+          description = "Other GNOME Flashback sessions to enable.";
+        };
+      };
+    };
+
+    environment.gnome3.excludePackages = mkOption {
+      default = [];
+      example = literalExample "[ pkgs.gnome3.totem ]";
+      type = types.listOf types.package;
+      description = "Which packages gnome should exclude from the default environment";
+    };
+
+  };
+
+  config = mkMerge [
+    (mkIf (cfg.enable || flashbackEnabled) {
+      services.gnome3.core-os-services.enable = true;
+      services.gnome3.core-shell.enable = true;
+      services.gnome3.core-utilities.enable = mkDefault true;
+
+      services.xserver.displayManager.extraSessionFilePackages = [ pkgs.gnome3.gnome-session ];
+
+      environment.extraInit = ''
+        ${concatMapStrings (p: ''
+          if [ -d "${p}/share/gsettings-schemas/${p.name}" ]; then
+            export XDG_DATA_DIRS=$XDG_DATA_DIRS''${XDG_DATA_DIRS:+:}${p}/share/gsettings-schemas/${p.name}
+          fi
+
+          if [ -d "${p}/lib/girepository-1.0" ]; then
+            export GI_TYPELIB_PATH=$GI_TYPELIB_PATH''${GI_TYPELIB_PATH:+:}${p}/lib/girepository-1.0
+            export LD_LIBRARY_PATH=$LD_LIBRARY_PATH''${LD_LIBRARY_PATH:+:}${p}/lib
+          fi
+        '') cfg.sessionPath}
+      '';
+
+      environment.systemPackages = cfg.sessionPath;
+
+      environment.variables.GNOME_SESSION_DEBUG = mkIf cfg.debug "1";
+
+      # Override GSettings schemas
+      environment.variables.NIX_GSETTINGS_OVERRIDES_DIR = "${nixos-gsettings-desktop-schemas}/share/gsettings-schemas/nixos-gsettings-overrides/glib-2.0/schemas";
+
+       # If gnome3 is installed, build vim for gtk3 too.
+      nixpkgs.config.vim.gui = "gtk3";
+    })
+
+    (mkIf flashbackEnabled {
+      services.xserver.displayManager.extraSessionFilePackages =  map
+        (wm: pkgs.gnome3.gnome-flashback.mkSessionForWm {
+          inherit (wm) wmName wmLabel wmCommand;
+        }) (optional cfg.flashback.enableMetacity {
+              wmName = "metacity";
+              wmLabel = "Metacity";
+              wmCommand = "${pkgs.gnome3.metacity}/bin/metacity";
+            } ++ cfg.flashback.customSessions);
+
+      security.pam.services.gnome-screensaver = {
+        enableGnomeKeyring = true;
+      };
+
+      services.dbus.packages = [
+        pkgs.gnome3.gnome-screensaver
+      ];
+    })
+
+    (mkIf serviceCfg.core-os-services.enable {
+      hardware.bluetooth.enable = mkDefault true;
+      hardware.pulseaudio.enable = mkDefault true;
+      programs.dconf.enable = true;
+      security.polkit.enable = true;
+      services.accounts-daemon.enable = true;
+      services.dleyna-renderer.enable = mkDefault true;
+      services.dleyna-server.enable = mkDefault true;
+      services.gnome3.at-spi2-core.enable = true;
+      services.gnome3.evolution-data-server.enable = true;
+      services.gnome3.gnome-keyring.enable = true;
+      services.gnome3.gnome-online-accounts.enable = mkDefault true;
+      services.gnome3.gnome-online-miners.enable = true;
+      services.gnome3.tracker-miners.enable = mkDefault true;
+      services.gnome3.tracker.enable = mkDefault true;
+      services.hardware.bolt.enable = mkDefault true;
+      services.packagekit.enable = mkDefault true;
+      services.udisks2.enable = true;
+      services.upower.enable = config.powerManagement.enable;
+      services.xserver.libinput.enable = mkDefault true; # for controlling touchpad settings via gnome control center
+
+      xdg.portal.enable = true;
+      xdg.portal.extraPortals = [ pkgs.xdg-desktop-portal-gtk ];
+
+      networking.networkmanager.enable = mkDefault true;
+
+      # Use the correct gnome3 packageSet
+      networking.networkmanager.basePackages = {
+        inherit (pkgs) networkmanager modemmanager wpa_supplicant crda;
+        inherit (pkgs.gnome3) networkmanager-openvpn networkmanager-vpnc
+        networkmanager-openconnect networkmanager-fortisslvpn
+        networkmanager-iodine networkmanager-l2tp;
+      };
+
+      services.xserver.updateDbusEnvironment = true;
+
+      # Needed for themes and backgrounds
+      environment.pathsToLink = [
+        "/share" # TODO: https://github.com/NixOS/nixpkgs/issues/47173
+      ];
+    })
+
+    (mkIf serviceCfg.core-shell.enable {
+      services.colord.enable = mkDefault true;
+      services.gnome3.glib-networking.enable = true;
+      services.gnome3.gnome-remote-desktop.enable = mkDefault true;
+      services.gnome3.gnome-settings-daemon.enable = true;
+      services.gnome3.gnome-user-share.enable = mkDefault true;
+      services.gnome3.rygel.enable = mkDefault true;
+      services.gvfs.enable = true;
+      services.telepathy.enable = mkDefault true;
+      systemd.packages = [ pkgs.gnome3.vino ];
+      services.dbus.packages =
+        optional config.services.printing.enable pkgs.system-config-printer;
+
+      services.geoclue2.enable = mkDefault true;
+      services.geoclue2.enableDemoAgent = false; # GNOME has its own geoclue agent
+
+      services.geoclue2.appConfig."gnome-datetime-panel" = {
+        isAllowed = true;
+        isSystem = true;
+      };
+      services.geoclue2.appConfig."gnome-color-panel" = {
+        isAllowed = true;
+        isSystem = true;
+      };
+      services.geoclue2.appConfig."org.gnome.Shell" = {
+        isAllowed = true;
+        isSystem = true;
+      };
+
+      fonts.fonts = with pkgs; [
+        cantarell-fonts
+        dejavu_fonts
+        source-code-pro # Default monospace font in 3.32
+        source-sans-pro
+      ];
+
+      environment.systemPackages = with pkgs.gnome3; [
+        adwaita-icon-theme
+        gnome-backgrounds
+        gnome-bluetooth
+        gnome-control-center
+        gnome-getting-started-docs
+        gnome-shell
+        gnome-shell-extensions
+        gnome-themes-extra
+        gnome-user-docs
+        pkgs.glib # for gsettings
+        pkgs.gnome-menus
+        pkgs.gtk3.out # for gtk-launch
+        pkgs.hicolor-icon-theme
+        pkgs.shared-mime-info # for update-mime-database
+        pkgs.xdg-user-dirs # Update user dirs as described in http://freedesktop.org/wiki/Software/xdg-user-dirs/
+        vino
+      ];
+    })
+
+    (mkIf serviceCfg.core-utilities.enable {
+      environment.systemPackages = (with pkgs.gnome3; removePackagesByName [
+        baobab eog epiphany evince gucharmap nautilus totem yelp gnome-calculator
+        gnome-contacts gnome-font-viewer gnome-screenshot gnome-system-monitor simple-scan
+        gnome-terminal evolution file-roller gedit gnome-clocks gnome-music gnome-tweaks
+        pkgs.gnome-photos nautilus-sendto dconf-editor vinagre gnome-weather gnome-logs
+        gnome-maps gnome-characters gnome-calendar accerciser gnome-nettool gnome-packagekit
+        gnome-software gnome-power-manager gnome-todo pkgs.gnome-usage
+      ] config.environment.gnome3.excludePackages);
+
+      # Enable default programs
+      programs.evince.enable = mkDefault true;
+      programs.file-roller.enable = mkDefault true;
+      programs.gnome-disks.enable = mkDefault true;
+      programs.gnome-documents.enable = mkDefault true;
+      programs.gnome-terminal.enable = mkDefault true;
+      services.gnome3.seahorse.enable = mkDefault true;
+      services.gnome3.sushi.enable = mkDefault true;
+
+      # Let nautilus find extensions
+      # TODO: Create nautilus-with-extensions package
+      environment.variables.NAUTILUS_EXTENSION_DIR = "${config.system.path}/lib/nautilus/extensions-3.0";
+
+      # Override default mimeapps for nautilus
+      environment.variables.XDG_DATA_DIRS = [ "${mimeAppsList}/share" ];
+
+      environment.pathsToLink = [
+        "/share/nautilus-python/extensions"
+      ];
+    })
+
+    (mkIf serviceCfg.games.enable {
+      environment.systemPackages = (with pkgs.gnome3; removePackagesByName [
+        aisleriot atomix five-or-more four-in-a-row gnome-chess gnome-klotski
+        gnome-mahjongg gnome-mines gnome-nibbles gnome-robots gnome-sudoku
+        gnome-taquin gnome-tetravex hitori iagno lightsoff quadrapassel
+        swell-foop tali
+      ] config.environment.gnome3.excludePackages);
+    })
+  ];
+
+}
diff --git a/nixpkgs/nixos/modules/services/x11/desktop-managers/kodi.nix b/nixpkgs/nixos/modules/services/x11/desktop-managers/kodi.nix
new file mode 100644
index 000000000000..65a7b9c628e5
--- /dev/null
+++ b/nixpkgs/nixos/modules/services/x11/desktop-managers/kodi.nix
@@ -0,0 +1,30 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+  cfg = config.services.xserver.desktopManager.kodi;
+in
+
+{
+  options = {
+    services.xserver.desktopManager.kodi = {
+      enable = mkOption {
+        default = false;
+        description = "Enable the kodi multimedia center.";
+      };
+    };
+  };
+
+  config = mkIf cfg.enable {
+    services.xserver.desktopManager.session = [{
+      name = "kodi";
+      start = ''
+        ${pkgs.kodi}/bin/kodi --lircdev /run/lirc/lircd --standalone &
+        waitPID=$!
+      '';
+    }];
+
+    environment.systemPackages = [ pkgs.kodi ];
+  };
+}
diff --git a/nixpkgs/nixos/modules/services/x11/desktop-managers/lumina.nix b/nixpkgs/nixos/modules/services/x11/desktop-managers/lumina.nix
new file mode 100644
index 000000000000..2224bcd5a2a5
--- /dev/null
+++ b/nixpkgs/nixos/modules/services/x11/desktop-managers/lumina.nix
@@ -0,0 +1,45 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+
+  xcfg = config.services.xserver;
+  cfg = xcfg.desktopManager.lumina;
+
+in
+
+{
+  options = {
+
+    services.xserver.desktopManager.lumina.enable = mkOption {
+      type = types.bool;
+      default = false;
+      description = "Enable the Lumina desktop manager";
+    };
+
+  };
+
+
+  config = mkIf cfg.enable {
+
+    services.xserver.desktopManager.session = singleton {
+      name = "lumina";
+      start = ''
+        exec ${pkgs.lumina.lumina}/bin/start-lumina-desktop
+      '';
+    };
+
+    environment.systemPackages =
+      pkgs.lumina.preRequisitePackages ++
+      pkgs.lumina.corePackages;
+
+    # Link some extra directories in /run/current-system/software/share
+    environment.pathsToLink = [
+      "/share/lumina"
+      # FIXME: modules should link subdirs of `/share` rather than relying on this
+      "/share"
+    ];
+
+  };
+}
diff --git a/nixpkgs/nixos/modules/services/x11/desktop-managers/lxqt.nix b/nixpkgs/nixos/modules/services/x11/desktop-managers/lxqt.nix
new file mode 100644
index 000000000000..bf53082b267d
--- /dev/null
+++ b/nixpkgs/nixos/modules/services/x11/desktop-managers/lxqt.nix
@@ -0,0 +1,67 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+  xcfg = config.services.xserver;
+  cfg = xcfg.desktopManager.lxqt;
+
+in
+
+{
+  options = {
+
+    services.xserver.desktopManager.lxqt.enable = mkOption {
+      type = types.bool;
+      default = false;
+      description = "Enable the LXQt desktop manager";
+    };
+
+    environment.lxqt.excludePackages = mkOption {
+      default = [];
+      example = literalExample "[ pkgs.lxqt.qterminal ]";
+      type = types.listOf types.package;
+      description = "Which LXQt packages to exclude from the default environment";
+    };
+
+  };
+
+  config = mkIf cfg.enable {
+
+    services.xserver.desktopManager.session = singleton {
+      name = "lxqt";
+      bgSupport = true;
+      start = ''
+        # Upstream installs default configuration files in
+        # $prefix/share/lxqt instead of $prefix/etc/xdg, (arguably)
+        # giving distributors freedom to ship custom default
+        # configuration files more easily. In order to let the session
+        # manager find them the share subdirectory is added to the
+        # XDG_CONFIG_DIRS environment variable.
+        #
+        # For an explanation see
+        # https://github.com/lxqt/lxqt/issues/1521#issuecomment-405097453
+        #
+        export XDG_CONFIG_DIRS=$XDG_CONFIG_DIRS''${XDG_CONFIG_DIRS:+:}${config.system.path}/share
+
+        exec ${pkgs.lxqt.lxqt-session}/bin/startlxqt
+      '';
+    };
+
+    environment.systemPackages =
+      pkgs.lxqt.preRequisitePackages ++
+      pkgs.lxqt.corePackages ++
+      (pkgs.gnome3.removePackagesByName
+        pkgs.lxqt.optionalPackages
+        config.environment.lxqt.excludePackages);
+
+    # Link some extra directories in /run/current-system/software/share
+    environment.pathsToLink = [ "/share" ];
+
+    services.gvfs.enable = true;
+    services.gvfs.package = pkgs.gvfs;
+
+    services.upower.enable = config.powerManagement.enable;
+  };
+
+}
diff --git a/nixpkgs/nixos/modules/services/x11/desktop-managers/mate.nix b/nixpkgs/nixos/modules/services/x11/desktop-managers/mate.nix
new file mode 100644
index 000000000000..e1084b0053cc
--- /dev/null
+++ b/nixpkgs/nixos/modules/services/x11/desktop-managers/mate.nix
@@ -0,0 +1,113 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+
+  addToXDGDirs = p: ''
+    if [ -d "${p}/share/gsettings-schemas/${p.name}" ]; then
+      export XDG_DATA_DIRS=$XDG_DATA_DIRS''${XDG_DATA_DIRS:+:}${p}/share/gsettings-schemas/${p.name}
+    fi
+
+    if [ -d "${p}/lib/girepository-1.0" ]; then
+      export GI_TYPELIB_PATH=$GI_TYPELIB_PATH''${GI_TYPELIB_PATH:+:}${p}/lib/girepository-1.0
+      export LD_LIBRARY_PATH=$LD_LIBRARY_PATH''${LD_LIBRARY_PATH:+:}${p}/lib
+    fi
+  '';
+
+  xcfg = config.services.xserver;
+  cfg = xcfg.desktopManager.mate;
+
+in
+
+{
+  options = {
+
+    services.xserver.desktopManager.mate = {
+      enable = mkOption {
+        type = types.bool;
+        default = false;
+        description = "Enable the MATE desktop environment";
+      };
+
+      debug = mkEnableOption "mate-session debug messages";
+    };
+
+    environment.mate.excludePackages = mkOption {
+      default = [];
+      example = literalExample "[ pkgs.mate.mate-terminal pkgs.mate.pluma ]";
+      type = types.listOf types.package;
+      description = "Which MATE packages to exclude from the default environment";
+    };
+
+  };
+
+  config = mkIf cfg.enable {
+
+    services.xserver.desktopManager.session = singleton {
+      name = "mate";
+      bgSupport = true;
+      start = ''
+        # Set GTK_DATA_PREFIX so that GTK+ can find the themes
+        export GTK_DATA_PREFIX=${config.system.path}
+
+        # Find theme engines
+        export GTK_PATH=${config.system.path}/lib/gtk-3.0:${config.system.path}/lib/gtk-2.0
+
+        export XDG_MENU_PREFIX=mate-
+
+        # Let caja find extensions
+        export CAJA_EXTENSION_DIRS=$CAJA_EXTENSION_DIRS''${CAJA_EXTENSION_DIRS:+:}${config.system.path}/lib/caja/extensions-2.0
+
+        # Let caja extensions find gsettings schemas
+        ${concatMapStrings (p: ''
+          if [ -d "${p}/lib/caja/extensions-2.0" ]; then
+            ${addToXDGDirs p}
+          fi
+          '')
+          config.environment.systemPackages
+        }
+
+        # Let mate-panel find applets
+        export MATE_PANEL_APPLETS_DIR=$MATE_PANEL_APPLETS_DIR''${MATE_PANEL_APPLETS_DIR:+:}${config.system.path}/share/mate-panel/applets
+        export MATE_PANEL_EXTRA_MODULES=$MATE_PANEL_EXTRA_MODULES''${MATE_PANEL_EXTRA_MODULES:+:}${config.system.path}/lib/mate-panel/applets
+
+        # Add mate-control-center paths to some XDG variables because its schemas are needed by mate-settings-daemon, and mate-settings-daemon is a dependency for mate-control-center (that is, they are mutually recursive)
+        ${addToXDGDirs pkgs.mate.mate-control-center}
+
+        ${pkgs.mate.mate-session-manager}/bin/mate-session ${optionalString cfg.debug "--debug"} &
+        waitPID=$!
+      '';
+    };
+
+    environment.systemPackages =
+      pkgs.mate.basePackages ++
+      (pkgs.gnome3.removePackagesByName
+        pkgs.mate.extraPackages
+        config.environment.mate.excludePackages) ++
+      [
+        pkgs.desktop-file-utils
+        pkgs.glib
+        pkgs.gtk3.out
+        pkgs.shared-mime-info
+        pkgs.xdg-user-dirs # Update user dirs as described in https://freedesktop.org/wiki/Software/xdg-user-dirs/
+      ];
+
+    programs.dconf.enable = true;
+    # Shell integration for VTE terminals
+    programs.bash.vteIntegration = mkDefault true;
+    programs.zsh.vteIntegration = mkDefault true;
+
+    services.gnome3.at-spi2-core.enable = true;
+    services.gnome3.gnome-keyring.enable = true;
+    services.gnome3.gnome-settings-daemon.enable = true;
+    services.gnome3.gnome-settings-daemon.package = pkgs.mate.mate-settings-daemon;
+    services.gvfs.enable = true;
+    services.upower.enable = config.powerManagement.enable;
+
+    security.pam.services."mate-screensaver".unixAuth = true;
+
+    environment.pathsToLink = [ "/share" ];
+  };
+
+}
diff --git a/nixpkgs/nixos/modules/services/x11/desktop-managers/maxx.nix b/nixpkgs/nixos/modules/services/x11/desktop-managers/maxx.nix
new file mode 100644
index 000000000000..1c04104df41e
--- /dev/null
+++ b/nixpkgs/nixos/modules/services/x11/desktop-managers/maxx.nix
@@ -0,0 +1,31 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+  xcfg = config.services.xserver;
+  cfg = xcfg.desktopManager.maxx;
+in {
+  options.services.xserver.desktopManager.maxx = {
+    enable = mkEnableOption "MaXX desktop environment";
+  };
+
+  config = mkIf cfg.enable {
+    environment.systemPackages = [ pkgs.maxx ];
+
+    # there is hardcoded path in binaries
+    system.activationScripts.setup-maxx = ''
+      mkdir -p /opt
+      ln -sfn ${pkgs.maxx}/opt/MaXX /opt
+    '';
+
+    services.xserver.desktopManager.session = [
+    { name = "MaXX";
+      start = ''
+        exec ${pkgs.maxx}/opt/MaXX/etc/skel/Xsession.dt
+      '';
+    }];
+  };
+
+  meta.maintainers = [ maintainers.gnidorah ];
+}
diff --git a/nixpkgs/nixos/modules/services/x11/desktop-managers/none.nix b/nixpkgs/nixos/modules/services/x11/desktop-managers/none.nix
new file mode 100644
index 000000000000..af7a376ae029
--- /dev/null
+++ b/nixpkgs/nixos/modules/services/x11/desktop-managers/none.nix
@@ -0,0 +1,7 @@
+{
+  services.xserver.desktopManager.session =
+    [ { name = "none";
+        start = "";
+      }
+    ];
+}
diff --git a/nixpkgs/nixos/modules/services/x11/desktop-managers/pantheon.nix b/nixpkgs/nixos/modules/services/x11/desktop-managers/pantheon.nix
new file mode 100644
index 000000000000..ae23015d2005
--- /dev/null
+++ b/nixpkgs/nixos/modules/services/x11/desktop-managers/pantheon.nix
@@ -0,0 +1,214 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+
+  cfg = config.services.xserver.desktopManager.pantheon;
+
+  nixos-gsettings-desktop-schemas = pkgs.pantheon.elementary-gsettings-schemas.override {
+    extraGSettingsOverridePackages = cfg.extraGSettingsOverridePackages;
+    extraGSettingsOverrides = cfg.extraGSettingsOverrides;
+  };
+
+in
+
+{
+
+  meta.maintainers = pkgs.pantheon.maintainers;
+
+  options = {
+
+    services.xserver.desktopManager.pantheon = {
+      enable = mkOption {
+        type = types.bool;
+        default = false;
+        description = "Enable the pantheon desktop manager";
+      };
+
+      sessionPath = mkOption {
+        default = [];
+        example = literalExample "[ pkgs.gnome3.gpaste ]";
+        description = ''
+          Additional list of packages to be added to the session search path.
+          Useful for GSettings-conditional autostart.
+
+          Note that this should be a last resort; patching the package is preferred (see GPaste).
+        '';
+        apply = list: list ++
+        [
+          pkgs.pantheon.pantheon-agent-geoclue2
+        ];
+      };
+
+      extraGSettingsOverrides = mkOption {
+        default = "";
+        type = types.lines;
+        description = "Additional gsettings overrides.";
+      };
+
+      extraGSettingsOverridePackages = mkOption {
+        default = [];
+        type = types.listOf types.path;
+        description = "List of packages for which gsettings are overridden.";
+      };
+
+      debug = mkEnableOption "gnome-session debug messages";
+
+    };
+
+    environment.pantheon.excludePackages = mkOption {
+      default = [];
+      example = literalExample "[ pkgs.pantheon.elementary-camera ]";
+      type = types.listOf types.package;
+      description = "Which packages pantheon should exclude from the default environment";
+    };
+
+  };
+
+
+  config = mkIf cfg.enable {
+
+    services.xserver.displayManager.extraSessionFilePackages = [ pkgs.pantheon.elementary-session-settings ];
+
+    # Ensure lightdm is used when Pantheon is enabled
+    # Without it screen locking will be nonfunctional because of the use of lightlocker
+
+    warnings = optional (config.services.xserver.displayManager.lightdm.enable != true)
+      ''
+        Using Pantheon without LightDM as a displayManager will break screenlocking from the UI.
+      '';
+
+    services.xserver.displayManager.lightdm.enable = mkDefault true;
+    services.xserver.displayManager.lightdm.greeters.gtk.enable = mkDefault true;
+
+    # If not set manually Pantheon session cannot be started
+    # Known issue of https://github.com/NixOS/nixpkgs/pull/43992
+    services.xserver.desktopManager.default = mkForce "pantheon";
+
+    services.xserver.displayManager.sessionCommands = ''
+      if test "$XDG_CURRENT_DESKTOP" = "Pantheon"; then
+          ${concatMapStrings (p: ''
+            if [ -d "${p}/share/gsettings-schemas/${p.name}" ]; then
+              export XDG_DATA_DIRS=$XDG_DATA_DIRS''${XDG_DATA_DIRS:+:}${p}/share/gsettings-schemas/${p.name}
+            fi
+
+            if [ -d "${p}/lib/girepository-1.0" ]; then
+              export GI_TYPELIB_PATH=$GI_TYPELIB_PATH''${GI_TYPELIB_PATH:+:}${p}/lib/girepository-1.0
+              export LD_LIBRARY_PATH=$LD_LIBRARY_PATH''${LD_LIBRARY_PATH:+:}${p}/lib
+            fi
+          '') cfg.sessionPath}
+
+          # Settings from elementary-default-settings
+          export GTK_CSD=1
+          export GTK_MODULES=$GTK_MODULES:pantheon-filechooser-module
+      fi
+    '';
+
+    hardware.bluetooth.enable = mkDefault true;
+    hardware.pulseaudio.enable = mkDefault true;
+    security.polkit.enable = true;
+    services.accounts-daemon.enable = true;
+    services.bamf.enable = true;
+    services.colord.enable = mkDefault true;
+    services.pantheon.files.enable = mkDefault true;
+    services.tumbler.enable = mkDefault true;
+    services.dbus.packages = mkMerge [
+      ([ pkgs.pantheon.switchboard-plug-power ])
+      (mkIf config.services.printing.enable  ([pkgs.system-config-printer]) )
+    ];
+    services.pantheon.contractor.enable = mkDefault true;
+    services.gnome3.at-spi2-core.enable = true;
+    services.gnome3.evolution-data-server.enable = true;
+    services.gnome3.glib-networking.enable = true;
+    # TODO: gnome-keyring's xdg autostarts will still be in the environment (from elementary-session-settings) if disabled forcefully
+    services.gnome3.gnome-keyring.enable = true;
+    services.gnome3.gnome-settings-daemon.enable = true;
+    services.gnome3.gnome-settings-daemon.package = pkgs.pantheon.elementary-settings-daemon;
+    services.gvfs.enable = true;
+    services.gnome3.rygel.enable = mkDefault true;
+    services.gsignond.enable = mkDefault true;
+    services.gsignond.plugins = with pkgs.gsignondPlugins; [ lastfm mail oauth ];
+    services.udisks2.enable = true;
+    services.upower.enable = config.powerManagement.enable;
+    services.xserver.libinput.enable = mkDefault true;
+    services.xserver.updateDbusEnvironment = true;
+    services.zeitgeist.enable = mkDefault true;
+    services.geoclue2.enable = mkDefault true;
+    # pantheon has pantheon-agent-geoclue2
+    services.geoclue2.enableDemoAgent = false;
+    services.geoclue2.appConfig."io.elementary.desktop.agent-geoclue2" = {
+      isAllowed = true;
+      isSystem = true;
+    };
+
+    programs.dconf.enable = true;
+    programs.evince.enable = mkDefault true;
+    programs.file-roller.enable = mkDefault true;
+
+    # Shell integration for VTE terminals
+    programs.bash.vteIntegration = mkDefault true;
+    programs.zsh.vteIntegration = mkDefault true;
+
+    # Harmonize Qt5 applications under Pantheon
+    qt5.enable = true;
+    qt5.platformTheme = "gnome";
+    qt5.style = "adwaita";
+
+    networking.networkmanager.enable = mkDefault true;
+    networking.networkmanager.basePackages =
+      { inherit (pkgs) networkmanager modemmanager wpa_supplicant crda;
+        inherit (pkgs.gnome3) networkmanager-openvpn networkmanager-vpnc
+                              networkmanager-openconnect networkmanager-fortisslvpn
+                              networkmanager-iodine networkmanager-l2tp; };
+
+    # Override GSettings schemas
+    environment.variables.NIX_GSETTINGS_OVERRIDES_DIR = "${nixos-gsettings-desktop-schemas}/share/gsettings-schemas/nixos-gsettings-overrides/glib-2.0/schemas";
+
+    environment.variables.GNOME_SESSION_DEBUG = optionalString cfg.debug "1";
+
+    environment.pathsToLink = [
+      # FIXME: modules should link subdirs of `/share` rather than relying on this
+      "/share"
+    ];
+
+    environment.systemPackages =
+      pkgs.pantheon.artwork ++ pkgs.pantheon.desktop ++ pkgs.pantheon.services ++ cfg.sessionPath
+      ++ (with pkgs; gnome3.removePackagesByName
+      ([
+        gnome3.geary
+        gnome3.epiphany
+        gnome3.gnome-font-viewer
+      ] ++ pantheon.apps) config.environment.pantheon.excludePackages)
+      ++ (with pkgs;
+      [
+        adwaita-qt
+        desktop-file-utils
+        glib
+        glib-networking
+        gnome-menus
+        gnome3.adwaita-icon-theme
+        gtk3.out
+        hicolor-icon-theme
+        lightlocker
+        plank
+        qgnomeplatform
+        shared-mime-info
+        sound-theme-freedesktop
+        xdg-user-dirs
+      ]);
+
+    fonts.fonts = with pkgs; [
+      open-sans
+      roboto-mono
+      pantheon.elementary-redacted-script # needed by screenshot-tool
+    ];
+
+    fonts.fontconfig.defaultFonts = {
+      monospace = [ "Roboto Mono" ];
+      sansSerif = [ "Open Sans" ];
+    };
+
+  };
+
+}
diff --git a/nixpkgs/nixos/modules/services/x11/desktop-managers/plasma5.nix b/nixpkgs/nixos/modules/services/x11/desktop-managers/plasma5.nix
new file mode 100644
index 000000000000..94a307ae1007
--- /dev/null
+++ b/nixpkgs/nixos/modules/services/x11/desktop-managers/plasma5.nix
@@ -0,0 +1,266 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+
+  xcfg = config.services.xserver;
+  cfg = xcfg.desktopManager.plasma5;
+
+  inherit (pkgs) kdeApplications plasma5 libsForQt5 qt5;
+
+in
+
+{
+  options = {
+
+    services.xserver.desktopManager.plasma5 = {
+      enable = mkOption {
+        type = types.bool;
+        default = false;
+        description = "Enable the Plasma 5 (KDE 5) desktop environment.";
+      };
+
+      phononBackend = mkOption {
+        type = types.enum [ "gstreamer" "vlc" ];
+        default = "gstreamer";
+        example = "vlc";
+        description = "Phonon audio backend to install.";
+      };
+
+      enableQt4Support = mkOption {
+        type = types.bool;
+        default = true;
+        description = ''
+          Enable support for Qt 4-based applications. Particularly, install a
+          default backend for Phonon.
+        '';
+      };
+
+    };
+
+  };
+
+
+  config = mkMerge [
+    (mkIf cfg.enable {
+      services.xserver.desktopManager.session = singleton {
+        name = "plasma5";
+        bgSupport = true;
+        start = ''
+          # Load PulseAudio module for routing support.
+          # See http://colin.guthr.ie/2009/10/so-how-does-the-kde-pulseaudio-support-work-anyway/
+          ${optionalString config.hardware.pulseaudio.enable ''
+            ${getBin config.hardware.pulseaudio.package}/bin/pactl load-module module-device-manager "do_routing=1"
+          ''}
+
+          if [ -f "$HOME/.config/kdeglobals" ]
+          then
+              # Remove extraneous font style names.
+              # See also: https://phabricator.kde.org/D9070
+              ${getBin pkgs.gnused}/bin/sed -i "$HOME/.config/kdeglobals" \
+                  -e '/^fixed=/ s/,Regular$//' \
+                  -e '/^font=/ s/,Regular$//' \
+                  -e '/^menuFont=/ s/,Regular$//' \
+                  -e '/^smallestReadableFont=/ s/,Regular$//' \
+                  -e '/^toolBarFont=/ s/,Regular$//'
+          fi
+
+          exec "${getBin plasma5.plasma-workspace}/bin/startkde"
+        '';
+      };
+
+      security.wrappers = {
+        kcheckpass.source = "${lib.getBin plasma5.kscreenlocker}/libexec/kcheckpass";
+        "start_kdeinit".source = "${lib.getBin pkgs.kinit}/libexec/kf5/start_kdeinit";
+        kwin_wayland = {
+          source = "${lib.getBin plasma5.kwin}/bin/kwin_wayland";
+          capabilities = "cap_sys_nice+ep";
+        };
+      };
+
+      environment.systemPackages = with pkgs; with qt5; with libsForQt5; with plasma5; with kdeApplications;
+        [
+          frameworkintegration
+          kactivities
+          kauth
+          kcmutils
+          kconfig
+          kconfigwidgets
+          kcoreaddons
+          kdoctools
+          kdbusaddons
+          kdeclarative
+          kded
+          kdesu
+          kdnssd
+          kemoticons
+          kfilemetadata
+          kglobalaccel
+          kguiaddons
+          kiconthemes
+          kidletime
+          kimageformats
+          kinit
+          kio
+          kjobwidgets
+          knewstuff
+          knotifications
+          knotifyconfig
+          kpackage
+          kparts
+          kpeople
+          krunner
+          kservice
+          ktextwidgets
+          kwallet
+          kwallet-pam
+          kwalletmanager
+          kwayland
+          kwidgetsaddons
+          kxmlgui
+          kxmlrpcclient
+          plasma-framework
+          solid
+          sonnet
+          threadweaver
+
+          breeze-qt5
+          kactivitymanagerd
+          kde-cli-tools
+          kdecoration
+          kdeplasma-addons
+          kgamma5
+          khotkeys
+          kinfocenter
+          kmenuedit
+          kscreen
+          kscreenlocker
+          ksysguard
+          kwayland
+          kwin
+          kwrited
+          libkscreen
+          libksysguard
+          milou
+          plasma-integration
+          polkit-kde-agent
+          systemsettings
+
+          plasma-desktop
+          plasma-workspace
+          plasma-workspace-wallpapers
+
+          dolphin
+          dolphin-plugins
+          ffmpegthumbs
+          kdegraphics-thumbnailers
+          khelpcenter
+          kio-extras
+          konsole
+          oxygen
+          print-manager
+
+          breeze-icons
+          pkgs.hicolor-icon-theme
+
+          kde-gtk-config breeze-gtk
+
+          qtvirtualkeyboard
+
+          xdg-user-dirs # Update user dirs as described in https://freedesktop.org/wiki/Software/xdg-user-dirs/
+        ]
+
+        # Phonon audio backend
+        ++ lib.optional (cfg.phononBackend == "gstreamer") libsForQt5.phonon-backend-gstreamer
+        ++ lib.optional (cfg.phononBackend == "gstreamer" && cfg.enableQt4Support) pkgs.phonon-backend-gstreamer
+        ++ lib.optional (cfg.phononBackend == "vlc") libsForQt5.phonon-backend-vlc
+        ++ lib.optional (cfg.phononBackend == "vlc" && cfg.enableQt4Support) pkgs.phonon-backend-vlc
+
+        # Optional hardware support features
+        ++ lib.optionals config.hardware.bluetooth.enable [ bluedevil bluez-qt ]
+        ++ lib.optional config.networking.networkmanager.enable plasma-nm
+        ++ lib.optional config.hardware.pulseaudio.enable plasma-pa
+        ++ lib.optional config.powerManagement.enable powerdevil
+        ++ lib.optional config.services.colord.enable colord-kde
+        ++ lib.optionals config.services.samba.enable [ kdenetwork-filesharing pkgs.samba ];
+
+      environment.pathsToLink = [
+        # FIXME: modules should link subdirs of `/share` rather than relying on this
+        "/share"
+      ];
+
+      environment.etc = singleton {
+        source = xcfg.xkbDir;
+        target = "X11/xkb";
+      };
+
+      # Enable GTK applications to load SVG icons
+      services.xserver.gdk-pixbuf.modulePackages = [ pkgs.librsvg ];
+
+      fonts.fonts = with pkgs; [ noto-fonts hack-font ];
+      fonts.fontconfig.defaultFonts = {
+        monospace = [ "Hack" "Noto Mono" ];
+        sansSerif = [ "Noto Sans" ];
+        serif = [ "Noto Serif" ];
+      };
+
+      programs.ssh.askPassword = mkDefault "${plasma5.ksshaskpass.out}/bin/ksshaskpass";
+
+      # Enable helpful DBus services.
+      services.udisks2.enable = true;
+      services.upower.enable = config.powerManagement.enable;
+      services.dbus.packages =
+        mkIf config.services.printing.enable [ pkgs.system-config-printer ];
+
+      # Extra UDEV rules used by Solid
+      services.udev.packages = [
+        pkgs.libmtp
+        pkgs.media-player-info
+      ];
+
+      services.xserver.displayManager.sddm = {
+        theme = mkDefault "breeze";
+      };
+
+      security.pam.services.kde = { allowNullPassword = true; };
+
+      # Doing these one by one seems silly, but we currently lack a better
+      # construct for handling common pam configs.
+      security.pam.services.gdm.enableKwallet = true;
+      security.pam.services.kdm.enableKwallet = true;
+      security.pam.services.lightdm.enableKwallet = true;
+      security.pam.services.sddm.enableKwallet = true;
+      security.pam.services.slim.enableKwallet = true;
+
+      xdg.portal.enable = true;
+      xdg.portal.extraPortals = [ pkgs.xdg-desktop-portal-kde ];
+
+      # Update the start menu for each user that is currently logged in
+      system.userActivationScripts.plasmaSetup = ''
+        # The KDE icon cache is supposed to update itself
+        # automatically, but it uses the timestamp on the icon
+        # theme directory as a trigger.  Since in Nix the
+        # timestamp is always the same, this doesn't work.  So as
+        # a workaround, nuke the icon cache on login.  This isn't
+        # perfect, since it may require logging out after
+        # installing new applications to update the cache.
+        # See http://lists-archives.org/kde-devel/26175-what-when-will-icon-cache-refresh.html
+        rm -fv $HOME/.cache/icon-cache.kcache
+
+        # xdg-desktop-settings generates this empty file but
+        # it makes kbuildsyscoca5 fail silently. To fix this
+        # remove that menu if it exists.
+        rm -fv $HOME/.config/menus/applications-merged/xdg-desktop-menu-dummy.menu
+
+        # Remove the kbuildsyscoca5 cache. It will be regenerated
+        # immediately after. This is necessary for kbuildsyscoca5 to
+        # recognize that software that has been removed.
+        rm -fv $HOME/.cache/ksycoca*
+
+        ${pkgs.libsForQt5.kservice}/bin/kbuildsycoca5
+      '';
+    })
+  ];
+
+}
diff --git a/nixpkgs/nixos/modules/services/x11/desktop-managers/surf-display.nix b/nixpkgs/nixos/modules/services/x11/desktop-managers/surf-display.nix
new file mode 100644
index 000000000000..232bbf5c55d4
--- /dev/null
+++ b/nixpkgs/nixos/modules/services/x11/desktop-managers/surf-display.nix
@@ -0,0 +1,127 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+  cfg = config.services.xserver.desktopManager.surf-display;
+
+  surfDisplayConf = ''
+    # Surf Kiosk Display: Wrap around surf browser and turn your
+    # system into a browser screen in KIOSK-mode.
+
+    # default download URI for all display screens if not configured individually
+    DEFAULT_WWW_URI="${cfg.defaultWwwUri}"
+
+    # Enforce fixed resolution for all displays (default: not set):
+    #DEFAULT_RESOLUTION="1920x1080"
+
+    # HTTP proxy URL, if needed (default: not set).
+    #HTTP_PROXY_URL="http://webcache:3128"
+
+    # Setting for internal inactivity timer to restart surf-display
+    # if the user goes inactive/idle.
+    INACTIVITY_INTERVAL="${builtins.toString cfg.inactivityInterval}"
+
+    # log to syslog instead of .xsession-errors
+    LOG_TO_SYSLOG="yes"
+
+    # Launch pulseaudio daemon if not already running.
+    WITH_PULSEAUDIO="yes"
+
+    # screensaver settings, see "man 1 xset" for possible options
+    SCREENSAVER_SETTINGS="${cfg.screensaverSettings}"
+
+    # disable right and middle pointer device click in browser sessions while keeping
+    # scrolling wheels' functionality intact... (consider "pointer" subcommand on
+    # xmodmap man page for details).
+    POINTER_BUTTON_MAP="${cfg.pointerButtonMap}"
+
+    # Hide idle mouse pointer.
+    HIDE_IDLE_POINTER="${cfg.hideIdlePointer}"
+
+    ${cfg.extraConfig}
+  '';
+
+in {
+  options = {
+    services.xserver.desktopManager.surf-display = {
+      enable = mkEnableOption "surf-display as a kiosk browser session";
+
+      defaultWwwUri = mkOption {
+        type = types.string;
+        default = "${pkgs.surf-display}/share/surf-display/empty-page.html";
+        example = "https://www.example.com/";
+        description = "Default URI to display.";
+      };
+
+      inactivityInterval = mkOption {
+        type = types.int;
+        default = 300;
+        example = "0";
+        description = ''
+          Setting for internal inactivity timer to restart surf-display if the
+          user goes inactive/idle to get a fresh session for the next user of
+          the kiosk.
+
+          If this value is set to zero, the whole feature of restarting due to
+          inactivity is disabled.
+        '';
+      };
+
+      screensaverSettings = mkOption {
+        type = types.string;
+        default = "";
+        description = ''
+          Screensaver settings, see <literal>man 1 xset</literal> for possible options.
+        '';
+      };
+
+      pointerButtonMap = mkOption {
+        type = types.string;
+        default = "1 0 0 4 5 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0";
+        description = ''
+          Disable right and middle pointer device click in browser sessions
+          while keeping scrolling wheels' functionality intact. See pointer
+          subcommand on <literal>man xmodmap</literal> for details.
+        '';
+      };
+
+      hideIdlePointer = mkOption {
+        type = types.string;
+        default = "yes";
+        example = "no";
+        description = "Hide idle mouse pointer.";
+      };
+
+      extraConfig = mkOption {
+        type = types.string;
+        default = "";
+        example = ''
+          # Enforce fixed resolution for all displays (default: not set):
+          DEFAULT_RESOLUTION="1920x1080"
+
+          # HTTP proxy URL, if needed (default: not set).
+          HTTP_PROXY_URL="http://webcache:3128"
+
+          # Configure individual display screens with host specific parameters:
+          DISPLAYS['display-host-0']="www_uri=https://www.displayserver.comany.net/display-1/index.html"
+          DISPLAYS['display-host-1']="www_uri=https://www.displayserver.comany.net/display-2/index.html"
+          DISPLAYS['display-host-2']="www_uri=https://www.displayserver.comany.net/display-3/index.html|res=1920x1280"
+          DISPLAYS['display-host-3']="www_uri=https://www.displayserver.comany.net/display-4/index.html"|res=1280x1024"
+          DISPLAYS['display-host-local-file']="www_uri=file:///usr/share/doc/surf-display/empty-page.html"
+        '';
+        description = ''
+          Extra configuration options to append to <literal>/etc/default/surf-display</literal>.
+        '';
+      };
+    };
+  };
+
+  config = mkIf cfg.enable {
+    services.xserver.displayManager.extraSessionFilePackages = [
+      pkgs.surf-display
+    ];
+
+    environment.etc."default/surf-display".text = surfDisplayConf;
+  };
+}
diff --git a/nixpkgs/nixos/modules/services/x11/desktop-managers/xfce.nix b/nixpkgs/nixos/modules/services/x11/desktop-managers/xfce.nix
new file mode 100644
index 000000000000..1102f73d1ac3
--- /dev/null
+++ b/nixpkgs/nixos/modules/services/x11/desktop-managers/xfce.nix
@@ -0,0 +1,129 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+  cfg = config.services.xserver.desktopManager.xfce;
+in
+
+{
+  options = {
+    services.xserver.desktopManager.xfce = {
+      enable = mkOption {
+        type = types.bool;
+        default = false;
+        description = "Enable the Xfce desktop environment.";
+      };
+
+      thunarPlugins = mkOption {
+        default = [];
+        type = types.listOf types.package;
+        example = literalExample "[ pkgs.xfce.thunar-archive-plugin ]";
+        description = ''
+          A list of plugin that should be installed with Thunar.
+        '';
+      };
+
+      noDesktop = mkOption {
+        type = types.bool;
+        default = false;
+        description = "Don't install XFCE desktop components (xfdesktop, panel and notification daemon).";
+      };
+
+      extraSessionCommands = mkOption {
+        default = "";
+        type = types.lines;
+        description = ''
+          Shell commands executed just before XFCE is started.
+        '';
+      };
+
+      enableXfwm = mkOption {
+        type = types.bool;
+        default = true;
+        description = "Enable the XFWM (default) window manager.";
+      };
+    };
+  };
+
+  config = mkIf cfg.enable {
+    environment.systemPackages = with pkgs.xfce // pkgs; [
+      # Get GTK+ themes and gtk-update-icon-cache
+      gtk2.out
+
+      # Supplies some abstract icons such as:
+      # utilities-terminal, accessories-text-editor
+      gnome3.adwaita-icon-theme
+
+      hicolor-icon-theme
+      tango-icon-theme
+      xfce4-icon-theme
+
+      # Needed by Xfce's xinitrc script
+      # TODO: replace with command -v
+      which
+
+      exo
+      garcon
+      gtk-xfce-engine
+      libxfce4ui
+      tumbler
+      xfconf
+
+      mousepad
+      ristretto
+      xfce4-appfinder
+      xfce4-screenshooter
+      xfce4-session
+      xfce4-settings
+      xfce4-terminal
+
+      (thunar.override { thunarPlugins = cfg.thunarPlugins; })
+      thunar-volman # TODO: drop
+    ] ++ (if config.hardware.pulseaudio.enable
+          then [ xfce4-mixer-pulse xfce4-volumed-pulse ]
+          else [ xfce4-mixer xfce4-volumed ])
+      # TODO: NetworkManager doesn't belong here
+      ++ optionals config.networking.networkmanager.enable [ networkmanagerapplet ]
+      ++ optionals config.powerManagement.enable [ xfce4-power-manager ]
+      ++ optionals cfg.enableXfwm [ xfwm4 ]
+      ++ optionals (!cfg.noDesktop) [
+        xfce4-panel
+        xfce4-notifyd
+        xfdesktop
+      ];
+
+    environment.pathsToLink = [
+      "/share/xfce4"
+      "/share/themes"
+      "/share/gtksourceview-2.0"
+    ];
+
+    services.xserver.gdk-pixbuf.modulePackages = [ pkgs.librsvg ];
+
+    services.xserver.desktopManager.session = [{
+      name = "xfce";
+      bgSupport = true;
+      start = ''
+        ${cfg.extraSessionCommands}
+
+        # Set GTK_PATH so that GTK+ can find the theme engines.
+        export GTK_PATH="${config.system.path}/lib/gtk-2.0:${config.system.path}/lib/gtk-3.0"
+
+        # Set GTK_DATA_PREFIX so that GTK+ can find the Xfce themes.
+        export GTK_DATA_PREFIX=${config.system.path}
+
+        ${pkgs.runtimeShell} ${pkgs.xfce.xinitrc} &
+        waitPID=$!
+      '';
+    }];
+
+    services.xserver.updateDbusEnvironment = true;
+
+    # Enable helpful DBus services.
+    services.udisks2.enable = true;
+    services.upower.enable = config.powerManagement.enable;
+    services.gvfs.enable = true;
+    services.gvfs.package = pkgs.xfce.gvfs;
+  };
+}
diff --git a/nixpkgs/nixos/modules/services/x11/desktop-managers/xfce4-14.nix b/nixpkgs/nixos/modules/services/x11/desktop-managers/xfce4-14.nix
new file mode 100644
index 000000000000..16329c093f98
--- /dev/null
+++ b/nixpkgs/nixos/modules/services/x11/desktop-managers/xfce4-14.nix
@@ -0,0 +1,157 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+  cfg = config.services.xserver.desktopManager.xfce4-14;
+in
+
+{
+  # added 2019-08-18
+  # needed to preserve some semblance of UI familarity
+  # with original XFCE module
+  imports = [
+    (mkRenamedOptionModule
+      [ "services" "xserver" "desktopManager" "xfce4-14" "extraSessionCommands" ]
+      [ "services" "xserver" "displayManager" "sessionCommands" ])
+  ];
+
+  options = {
+    services.xserver.desktopManager.xfce4-14 = {
+      enable = mkOption {
+        type = types.bool;
+        default = false;
+        description = "Enable the Xfce desktop environment.";
+      };
+
+    # TODO: support thunar plugins
+    #   thunarPlugins = mkOption {
+    #     default = [];
+    #     type = types.listOf types.package;
+    #     example = literalExample "[ pkgs.xfce4-14.thunar-archive-plugin ]";
+    #     description = ''
+    #       A list of plugin that should be installed with Thunar.
+    #     '';
+    #  };
+
+      noDesktop = mkOption {
+        type = types.bool;
+        default = false;
+        description = "Don't install XFCE desktop components (xfdesktop, panel and notification daemon).";
+      };
+
+      enableXfwm = mkOption {
+        type = types.bool;
+        default = true;
+        description = "Enable the XFWM (default) window manager.";
+      };
+    };
+  };
+
+  config = mkIf cfg.enable {
+    environment.systemPackages = with pkgs.xfce4-14 // pkgs; [
+      glib # for gsettings
+      gtk3.out # gtk-update-icon-cache
+
+      gnome3.adwaita-icon-theme
+      hicolor-icon-theme
+      tango-icon-theme
+      xfce4-icon-theme
+
+      desktop-file-utils
+      shared-mime-info # for update-mime-database
+
+      # For a polkit authentication agent
+      polkit_gnome
+
+      # Needed by Xfce's xinitrc script
+      xdg-user-dirs # Update user dirs as described in https://freedesktop.org/wiki/Software/xdg-user-dirs/
+
+      exo
+      garcon
+      gtk-xfce-engine
+      libxfce4ui
+      xfconf
+
+      mousepad
+      ristretto
+      xfce4-appfinder
+      xfce4-screenshooter
+      xfce4-session
+      xfce4-settings
+      xfce4-terminal
+
+      # TODO: resync patch for plugins
+      #(thunar.override { thunarPlugins = cfg.thunarPlugins; })
+      thunar
+    ] # TODO: NetworkManager doesn't belong here
+      ++ optional config.networking.networkmanager.enable networkmanagerapplet
+      ++ optional config.hardware.pulseaudio.enable xfce4-pulseaudio-plugin
+      ++ optional config.powerManagement.enable xfce4-power-manager
+      ++ optional cfg.enableXfwm xfwm4
+      ++ optionals (!cfg.noDesktop) [
+        xfce4-panel
+        xfce4-notifyd
+        xfdesktop
+      ];
+
+    environment.pathsToLink = [
+      "/share/xfce4"
+      "/lib/xfce4"
+      "/share/gtksourceview-3.0"
+      "/share/gtksourceview-4.0"
+    ];
+
+    # Use the correct gnome3 packageSet
+    networking.networkmanager.basePackages = mkIf config.networking.networkmanager.enable {
+      inherit (pkgs) networkmanager modemmanager wpa_supplicant crda;
+      inherit (pkgs.gnome3) networkmanager-openvpn networkmanager-vpnc
+      networkmanager-openconnect networkmanager-fortisslvpn
+      networkmanager-iodine networkmanager-l2tp;
+    };
+
+    services.xserver.desktopManager.session = [{
+      name = "xfce4-14";
+      bgSupport = true;
+      start = ''
+        # Set GTK_PATH so that GTK+ can find the theme engines.
+        export GTK_PATH="${config.system.path}/lib/gtk-2.0:${config.system.path}/lib/gtk-3.0"
+
+        # Set GTK_DATA_PREFIX so that GTK+ can find the Xfce themes.
+        export GTK_DATA_PREFIX=${config.system.path}
+
+        ${pkgs.runtimeShell} ${pkgs.xfce4-14.xinitrc} &
+        waitPID=$!
+      '';
+    }];
+
+    services.xserver.updateDbusEnvironment = true;
+    services.xserver.gdk-pixbuf.modulePackages = [ pkgs.librsvg ];
+
+    # Enable helpful DBus services.
+    services.udisks2.enable = true;
+    security.polkit.enable = true;
+    services.accounts-daemon.enable = true;
+    services.upower.enable = config.powerManagement.enable;
+    services.gnome3.glib-networking.enable = true;
+    services.gvfs.enable = true;
+    services.gvfs.package = pkgs.xfce.gvfs;
+    services.tumbler.enable = true;
+    services.dbus.packages =
+      optional config.services.printing.enable pkgs.system-config-printer;
+    services.xserver.libinput.enable = mkDefault true; # used in xfce4-settings-manager
+
+    # Enable default programs
+    programs.dconf.enable = true;
+
+    # Shell integration for VTE terminals
+    programs.bash.vteIntegration = mkDefault true;
+    programs.zsh.vteIntegration = mkDefault true;
+
+    # Systemd services
+    systemd.packages = with pkgs.xfce4-14; [
+      thunar
+    ] ++ optional (!cfg.noDesktop) xfce4-notifyd;
+
+  };
+}
diff --git a/nixpkgs/nixos/modules/services/x11/desktop-managers/xterm.nix b/nixpkgs/nixos/modules/services/x11/desktop-managers/xterm.nix
new file mode 100644
index 000000000000..ea441fbbe715
--- /dev/null
+++ b/nixpkgs/nixos/modules/services/x11/desktop-managers/xterm.nix
@@ -0,0 +1,38 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+
+  cfg = config.services.xserver.desktopManager.xterm;
+  xserverEnabled = config.services.xserver.enable;
+
+in
+
+{
+  options = {
+
+    services.xserver.desktopManager.xterm.enable = mkOption {
+      type = types.bool;
+      default = xserverEnabled;
+      defaultText = "config.services.xserver.enable";
+      description = "Enable a xterm terminal as a desktop manager.";
+    };
+
+  };
+
+  config = mkIf cfg.enable {
+
+    services.xserver.desktopManager.session = singleton
+      { name = "xterm";
+        start = ''
+          ${pkgs.xterm}/bin/xterm -ls &
+          waitPID=$!
+        '';
+      };
+
+    environment.systemPackages = [ pkgs.xterm ];
+
+  };
+
+}