diff options
Diffstat (limited to 'nixpkgs/nixos/modules/services/x11')
81 files changed, 7974 insertions, 0 deletions
diff --git a/nixpkgs/nixos/modules/services/x11/clight.nix b/nixpkgs/nixos/modules/services/x11/clight.nix new file mode 100644 index 00000000000..4daf6d8d9db --- /dev/null +++ b/nixpkgs/nixos/modules/services/x11/clight.nix @@ -0,0 +1,115 @@ +{ config, pkgs, lib, ... }: + +with lib; + +let + cfg = config.services.clight; + + toConf = v: + if builtins.isFloat v then toString v + else if isInt v then toString v + else if isBool v then boolToString v + else if isString v then ''"${escape [''"''] v}"'' + else if isList v then "[ " + concatMapStringsSep ", " toConf v + " ]" + else abort "clight.toConf: unexpected type (v = ${v})"; + + clightConf = pkgs.writeText "clight.conf" + (concatStringsSep "\n" (mapAttrsToList + (name: value: "${toString name} = ${toConf value};") + (filterAttrs + (_: value: value != null) + cfg.settings))); +in { + options.services.clight = { + enable = mkOption { + type = types.bool; + default = false; + description = '' + Whether to enable clight or not. + ''; + }; + + temperature = { + day = mkOption { + type = types.int; + default = 5500; + description = '' + Colour temperature to use during the day, between + <literal>1000</literal> and <literal>25000</literal> K. + ''; + }; + night = mkOption { + type = types.int; + default = 3700; + description = '' + Colour temperature to use at night, between + <literal>1000</literal> and <literal>25000</literal> K. + ''; + }; + }; + + settings = let + validConfigTypes = with types; either int (either str (either bool float)); + in mkOption { + type = with types; attrsOf (nullOr (either validConfigTypes (listOf validConfigTypes))); + default = {}; + example = { captures = 20; gamma_long_transition = true; ac_capture_timeouts = [ 120 300 60 ]; }; + description = '' + Additional configuration to extend clight.conf. See + <link xlink:href="https://github.com/FedeDP/Clight/blob/master/Extra/clight.conf"/> for a + sample configuration file. + ''; + }; + }; + + config = mkIf cfg.enable { + boot.kernelModules = [ "i2c_dev" ]; + environment.systemPackages = with pkgs; [ clight clightd ]; + services.dbus.packages = with pkgs; [ clight clightd ]; + services.upower.enable = true; + + services.clight.settings = { + gamma_temp = with cfg.temperature; mkDefault [ day night ]; + } // (optionalAttrs (config.location.provider == "manual") { + latitude = mkDefault config.location.latitude; + longitude = mkDefault config.location.longitude; + }); + + services.geoclue2.appConfig.clightc = { + isAllowed = true; + isSystem = true; + }; + + systemd.services.clightd = { + requires = [ "polkit.service" ]; + wantedBy = [ "multi-user.target" ]; + + description = "Bus service to manage various screen related properties (gamma, dpms, backlight)"; + serviceConfig = { + Type = "dbus"; + BusName = "org.clightd.clightd"; + Restart = "on-failure"; + RestartSec = 5; + ExecStart = '' + ${pkgs.clightd}/bin/clightd + ''; + }; + }; + + systemd.user.services.clight = { + after = [ "upower.service" "clightd.service" ]; + wants = [ "upower.service" "clightd.service" ]; + partOf = [ "graphical-session.target" ]; + wantedBy = [ "graphical-session.target" ]; + + description = "C daemon to adjust screen brightness to match ambient brightness, as computed capturing frames from webcam"; + serviceConfig = { + Restart = "on-failure"; + RestartSec = 5; + ExecStart = '' + ${pkgs.clight}/bin/clight --conf-file ${clightConf} + ''; + }; + }; + }; +} diff --git a/nixpkgs/nixos/modules/services/x11/colord.nix b/nixpkgs/nixos/modules/services/x11/colord.nix new file mode 100644 index 00000000000..cf113ad2af8 --- /dev/null +++ b/nixpkgs/nixos/modules/services/x11/colord.nix @@ -0,0 +1,41 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + + cfg = config.services.colord; + +in { + + options = { + + services.colord = { + enable = mkEnableOption "colord, the color management daemon"; + }; + + }; + + config = mkIf cfg.enable { + + environment.systemPackages = [ pkgs.colord ]; + + services.dbus.packages = [ pkgs.colord ]; + + services.udev.packages = [ pkgs.colord ]; + + systemd.packages = [ pkgs.colord ]; + + environment.etc."tmpfiles.d/colord.conf".source = "${pkgs.colord}/lib/tmpfiles.d/colord.conf"; + + users.users.colord = { + isSystemUser = true; + home = "/var/lib/colord"; + group = "colord"; + }; + + users.groups.colord = {}; + + }; + +} diff --git a/nixpkgs/nixos/modules/services/x11/compton.nix b/nixpkgs/nixos/modules/services/x11/compton.nix new file mode 100644 index 00000000000..a94a76ff0c0 --- /dev/null +++ b/nixpkgs/nixos/modules/services/x11/compton.nix @@ -0,0 +1,287 @@ +{ config, lib, pkgs, ... }: + +with lib; +with builtins; + +let + + cfg = config.services.compton; + + pairOf = x: with types; addCheck (listOf x) (y: length y == 2); + + floatBetween = a: b: with lib; with types; + addCheck str (x: versionAtLeast x a && versionOlder x b); + + toConf = attrs: concatStringsSep "\n" + (mapAttrsToList + (k: v: let + sep = if isAttrs v then ":" else "="; + # Basically a tinkered lib.generators.mkKeyValueDefault + mkValueString = v: + if isBool v then boolToString v + else if isInt v then toString v + else if isFloat v then toString v + else if isString v then ''"${escape [ ''"'' ] v}"'' + else if isList v then "[ " + + concatMapStringsSep " , " mkValueString v + + " ]" + else if isAttrs v then "{ " + + concatStringsSep " " + (mapAttrsToList + (key: value: "${toString key}=${mkValueString value};") + v) + + " }" + else abort "compton.mkValueString: unexpected type (v = ${v})"; + in "${escape [ sep ] k}${sep}${mkValueString v};") + attrs); + + configFile = pkgs.writeText "compton.conf" (toConf cfg.settings); + +in { + + options.services.compton = { + enable = mkOption { + type = types.bool; + default = false; + description = '' + Whether of not to enable Compton as the X.org composite manager. + ''; + }; + + fade = mkOption { + type = types.bool; + default = false; + description = '' + Fade windows in and out. + ''; + }; + + fadeDelta = mkOption { + type = types.addCheck types.int (x: x > 0); + default = 10; + example = 5; + description = '' + Time between fade animation step (in ms). + ''; + }; + + fadeSteps = mkOption { + type = pairOf (floatBetween "0.01" "1.01"); + default = [ "0.028" "0.03" ]; + example = [ "0.04" "0.04" ]; + description = '' + Opacity change between fade steps (in and out). + (numbers in range 0.01 - 1.0) + ''; + }; + + fadeExclude = mkOption { + type = types.listOf types.str; + default = []; + example = [ + "window_type *= 'menu'" + "name ~= 'Firefox$'" + "focused = 1" + ]; + description = '' + List of conditions of windows that should not be faded. + See <literal>compton(1)</literal> man page for more examples. + ''; + }; + + shadow = mkOption { + type = types.bool; + default = false; + description = '' + Draw window shadows. + ''; + }; + + shadowOffsets = mkOption { + type = pairOf types.int; + default = [ (-15) (-15) ]; + example = [ (-10) (-15) ]; + description = '' + Left and right offset for shadows (in pixels). + ''; + }; + + shadowOpacity = mkOption { + type = floatBetween "0.0" "1.01"; + default = "0.75"; + example = "0.8"; + description = '' + Window shadows opacity (number in range 0.0 - 1.0). + ''; + }; + + shadowExclude = mkOption { + type = types.listOf types.str; + default = []; + example = [ + "window_type *= 'menu'" + "name ~= 'Firefox$'" + "focused = 1" + ]; + description = '' + List of conditions of windows that should have no shadow. + See <literal>compton(1)</literal> man page for more examples. + ''; + }; + + activeOpacity = mkOption { + type = floatBetween "0.0" "1.01"; + default = "1.0"; + example = "0.8"; + description = '' + Opacity of active windows (number in range 0.0 - 1.0). + ''; + }; + + inactiveOpacity = mkOption { + type = floatBetween "0.1" "1.01"; + default = "1.0"; + example = "0.8"; + description = '' + Opacity of inactive windows (number in range 0.1 - 1.0). + ''; + }; + + menuOpacity = mkOption { + type = floatBetween "0.0" "1.01"; + default = "1.0"; + example = "0.8"; + description = '' + Opacity of dropdown and popup menu (number in range 0.0 - 1.0). + ''; + }; + + wintypes = mkOption { + type = types.attrs; + default = { popup_menu = { opacity = cfg.menuOpacity; }; dropdown_menu = { opacity = cfg.menuOpacity; }; }; + example = {}; + description = '' + Rules for specific window types. + ''; + }; + + opacityRules = mkOption { + type = types.listOf types.str; + default = []; + example = [ + "95:class_g = 'URxvt' && !_NET_WM_STATE@:32a" + "0:_NET_WM_STATE@:32a *= '_NET_WM_STATE_HIDDEN'" + ]; + description = '' + Rules that control the opacity of windows, in format PERCENT:PATTERN. + ''; + }; + + backend = mkOption { + type = types.enum [ "glx" "xrender" "xr_glx_hybrid" ]; + default = "xrender"; + description = '' + Backend to use: <literal>glx</literal>, <literal>xrender</literal> or <literal>xr_glx_hybrid</literal>. + ''; + }; + + vSync = mkOption { + type = with types; either bool + (enum [ "none" "drm" "opengl" "opengl-oml" "opengl-swc" "opengl-mswc" ]); + default = false; + apply = x: + let + res = x != "none"; + msg = "The type of services.compton.vSync has changed to bool:" + + " interpreting ${x} as ${boolToString res}"; + in + if isBool x then x + else warn msg res; + + description = '' + Enable vertical synchronization. Chooses the best method + (drm, opengl, opengl-oml, opengl-swc, opengl-mswc) automatically. + The bool value should be used, the others are just for backwards compatibility. + ''; + }; + + refreshRate = mkOption { + type = types.addCheck types.int (x: x >= 0); + default = 0; + example = 60; + description = '' + Screen refresh rate (0 = automatically detect). + ''; + }; + + settings = let + configTypes = with types; oneOf [ bool int float str ]; + # types.loaOf converts lists to sets + loaOf = t: with types; either (listOf t) (attrsOf t); + in mkOption { + type = loaOf (types.either configTypes (loaOf (types.either configTypes (loaOf configTypes)))); + default = {}; + description = '' + Additional Compton configuration. + ''; + }; + }; + + config = mkIf cfg.enable { + services.compton.settings = let + # Hard conversion to float, literally lib.toInt but toFloat + toFloat = str: let + may_be_float = builtins.fromJSON str; + in if builtins.isFloat may_be_float + then may_be_float + else throw "Could not convert ${str} to float."; + in { + # fading + fading = mkDefault cfg.fade; + fade-delta = mkDefault cfg.fadeDelta; + fade-in-step = mkDefault (toFloat (elemAt cfg.fadeSteps 0)); + fade-out-step = mkDefault (toFloat (elemAt cfg.fadeSteps 1)); + fade-exclude = mkDefault cfg.fadeExclude; + + # shadows + shadow = mkDefault cfg.shadow; + shadow-offset-x = mkDefault (elemAt cfg.shadowOffsets 0); + shadow-offset-y = mkDefault (elemAt cfg.shadowOffsets 1); + shadow-opacity = mkDefault (toFloat cfg.shadowOpacity); + shadow-exclude = mkDefault cfg.shadowExclude; + + # opacity + active-opacity = mkDefault (toFloat cfg.activeOpacity); + inactive-opacity = mkDefault (toFloat cfg.inactiveOpacity); + + wintypes = mkDefault cfg.wintypes; + + opacity-rule = mkDefault cfg.opacityRules; + + # other options + backend = mkDefault cfg.backend; + vsync = mkDefault cfg.vSync; + refresh-rate = mkDefault cfg.refreshRate; + }; + + systemd.user.services.compton = { + description = "Compton composite manager"; + wantedBy = [ "graphical-session.target" ]; + partOf = [ "graphical-session.target" ]; + + # Temporarily fixes corrupt colours with Mesa 18 + environment = mkIf (cfg.backend == "glx") { + allow_rgb10_configs = "false"; + }; + + serviceConfig = { + ExecStart = "${pkgs.compton}/bin/compton --config ${configFile}"; + RestartSec = 3; + Restart = "always"; + }; + }; + + environment.systemPackages = [ pkgs.compton ]; + }; + +} 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 00000000000..dfb84113e13 --- /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 00000000000..3745069f6ea --- /dev/null +++ b/nixpkgs/nixos/modules/services/x11/desktop-managers/enlightenment.nix @@ -0,0 +1,100 @@ +{ 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 = '' + 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 00000000000..30c5250221c --- /dev/null +++ b/nixpkgs/nixos/modules/services/x11/desktop-managers/gnome3.nix @@ -0,0 +1,352 @@ +{ 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', 'org.gnome.Geary.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.chrome-gnome-shell.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.system-config-printer.enable = (mkIf config.services.printing.enable (mkDefault true)); + services.telepathy.enable = mkDefault true; + systemd.packages = [ pkgs.gnome3.vino ]; + + services.avahi.enable = mkDefault true; + + xdg.portal.extraPortals = [ pkgs.gnome3.gnome-shell ]; + + 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 + ]; + + # Adapt from https://gitlab.gnome.org/GNOME/gnome-build-meta/blob/gnome-3-32/elements/core/meta-gnome-core-shell.bst + environment.systemPackages = with pkgs.gnome3; [ + adwaita-icon-theme + gnome-backgrounds + gnome-bluetooth + gnome-color-manager + gnome-control-center + gnome-getting-started-docs + gnome-shell + gnome-shell-extensions + gnome-themes-extra + gnome-user-docs + pkgs.orca + 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 + ]; + }) + + # Adapt from https://gitlab.gnome.org/GNOME/gnome-build-meta/blob/gnome-3-32/elements/core/meta-gnome-core-utilities.bst + (mkIf serviceCfg.core-utilities.enable { + environment.systemPackages = (with pkgs.gnome3; removePackagesByName [ + baobab + cheese + eog + epiphany + geary + gedit + gnome-calculator + gnome-calendar + gnome-characters + gnome-clocks + gnome-contacts + gnome-font-viewer + gnome-logs + gnome-maps + gnome-music + gnome-photos + gnome-screenshot + gnome-software + gnome-system-monitor + gnome-weather + nautilus + simple-scan + totem + yelp + # Unsure if sensible for NixOS + /* gnome-boxes */ + ] 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-terminal.enable = mkDefault true; + programs.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 00000000000..65a7b9c628e --- /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 00000000000..2224bcd5a2a --- /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 00000000000..bf53082b267 --- /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 00000000000..4563583e070 --- /dev/null +++ b/nixpkgs/nixos/modules/services/x11/desktop-managers/mate.nix @@ -0,0 +1,110 @@ +{ 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 = '' + 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; + + # Mate uses this for printing + programs.system-config-printer.enable = (mkIf config.services.printing.enable (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 00000000000..1c04104df41 --- /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 00000000000..af7a376ae02 --- /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 00000000000..d80ea9a53e8 --- /dev/null +++ b/nixpkgs/nixos/modules/services/x11/desktop-managers/pantheon.nix @@ -0,0 +1,218 @@ +{ 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.greeters.pantheon.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} + 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.system-config-printer.enable = (mkIf config.services.printing.enable (mkDefault true)); + services.dbus.packages = [ + pkgs.pantheon.switchboard-plug-power + ]; + 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; + # Otherwise you can't store NetworkManager Secrets with + # "Store the password only for this user" + programs.nm-applet.enable = 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.sessionVariables.NIX_GSETTINGS_OVERRIDES_DIR = "${nixos-gsettings-desktop-schemas}/share/gsettings-schemas/nixos-gsettings-overrides/glib-2.0/schemas"; + + environment.sessionVariables.GNOME_SESSION_DEBUG = optionalString cfg.debug "1"; + + # Settings from elementary-default-settings + environment.sessionVariables.GTK_CSD = "1"; + environment.sessionVariables.GTK_MODULES = "pantheon-filechooser-module"; + environment.etc."gtk-3.0/settings.ini".source = "${pkgs.pantheon.elementary-default-settings}/etc/gtk-3.0/settings.ini"; + + 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 + onboard + 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 00000000000..b10755df4dc --- /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.system-config-printer.enable = (mkIf config.services.printing.enable (mkDefault true)); + services.xserver.libinput.enable = mkDefault true; + + # 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 00000000000..140dde828da --- /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.str; + 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.separatedString " "; + default = ""; + description = '' + Screensaver settings, see <literal>man 1 xset</literal> for possible options. + ''; + }; + + pointerButtonMap = mkOption { + type = types.str; + 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.str; + default = "yes"; + example = "no"; + description = "Hide idle mouse pointer."; + }; + + extraConfig = mkOption { + type = types.lines; + 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 00000000000..6965c6d2646 --- /dev/null +++ b/nixpkgs/nixos/modules/services/x11/desktop-managers/xfce.nix @@ -0,0 +1,123 @@ +{ 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} + + ${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 00000000000..130e865a1fb --- /dev/null +++ b/nixpkgs/nixos/modules/services/x11/desktop-managers/xfce4-14.nix @@ -0,0 +1,156 @@ +{ 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.gnome-themes-extra + 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 + libxfce4ui + xfconf + + mousepad + parole + ristretto + xfce4-appfinder + xfce4-screenshooter + xfce4-session + xfce4-settings + xfce4-taskmanager + 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.powerManagement.enable xfce4-power-manager + ++ optionals config.hardware.pulseaudio.enable [ + pavucontrol + xfce4-pulseaudio-plugin + ] ++ optionals cfg.enableXfwm [ + xfwm4 + xfwm4-themes + ] ++ optionals (!cfg.noDesktop) [ + xfce4-notifyd + xfce4-panel + 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 = '' + ${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.system-config-printer.enable = (mkIf config.services.printing.enable (mkDefault true)); + 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 00000000000..f76db278a92 --- /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; + xSessionEnabled = config.services.xserver.enable; + +in + +{ + options = { + + services.xserver.desktopManager.xterm.enable = mkOption { + type = types.bool; + default = (versionOlder config.system.stateVersion "19.09") && xSessionEnabled; + defaultText = if versionOlder config.system.stateVersion "19.09" then "config.services.xserver.enable" else "false"; + 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 ]; + + }; + +} diff --git a/nixpkgs/nixos/modules/services/x11/display-managers/auto.nix b/nixpkgs/nixos/modules/services/x11/display-managers/auto.nix new file mode 100644 index 00000000000..1068a344e0c --- /dev/null +++ b/nixpkgs/nixos/modules/services/x11/display-managers/auto.nix @@ -0,0 +1,68 @@ +{ config, lib, ... }: + +with lib; + +let + + dmcfg = config.services.xserver.displayManager; + cfg = dmcfg.auto; + +in + +{ + + ###### interface + + options = { + + services.xserver.displayManager.auto = { + + enable = mkOption { + default = false; + description = '' + Whether to enable the fake "auto" display manager, which + automatically logs in the user specified in the + <option>user</option> option. This is mostly useful for + automated tests. + ''; + }; + + user = mkOption { + default = "root"; + description = "The user account to login automatically."; + }; + + }; + + }; + + + ###### implementation + + config = mkIf cfg.enable { + + services.xserver.displayManager.lightdm = { + enable = true; + autoLogin = { + enable = true; + user = cfg.user; + }; + }; + + # lightdm by default doesn't allow auto login for root, which is + # required by some nixos tests. Override it here. + security.pam.services.lightdm-autologin.text = lib.mkForce '' + auth requisite pam_nologin.so + auth required pam_succeed_if.so quiet + auth required pam_permit.so + + account include lightdm + + password include lightdm + + session include lightdm + ''; + + }; + +} diff --git a/nixpkgs/nixos/modules/services/x11/display-managers/default.nix b/nixpkgs/nixos/modules/services/x11/display-managers/default.nix new file mode 100644 index 00000000000..bf6b048654b --- /dev/null +++ b/nixpkgs/nixos/modules/services/x11/display-managers/default.nix @@ -0,0 +1,377 @@ +# This module declares the options to define a *display manager*, the +# program responsible for handling X logins (such as xdm, gdb, or +# SLiM). The display manager allows the user to select a *session +# type*. When the user logs in, the display manager starts the +# *session script* ("xsession" below) to launch the selected session +# type. The session type defines two things: the *desktop manager* +# (e.g., KDE, Gnome or a plain xterm), and optionally the *window +# manager* (e.g. kwin or twm). + +{ config, lib, pkgs, ... }: + +with lib; + +let + + cfg = config.services.xserver; + xorg = pkgs.xorg; + + fontconfig = config.fonts.fontconfig; + xresourcesXft = pkgs.writeText "Xresources-Xft" '' + ${optionalString (fontconfig.dpi != 0) ''Xft.dpi: ${toString fontconfig.dpi}''} + Xft.antialias: ${if fontconfig.antialias then "1" else "0"} + Xft.rgba: ${fontconfig.subpixel.rgba} + Xft.lcdfilter: lcd${fontconfig.subpixel.lcdfilter} + Xft.hinting: ${if fontconfig.hinting.enable then "1" else "0"} + Xft.autohint: ${if fontconfig.hinting.autohint then "1" else "0"} + Xft.hintstyle: hintslight + ''; + + mkCases = session: + concatStrings ( + mapAttrsToList (name: starts: '' + (${name}) + ${concatMapStringsSep "\n " (n: n.start) starts} + ;; + '') (lib.groupBy (n: n.name) session) + ); + + # file provided by services.xserver.displayManager.session.wrapper + xsessionWrapper = pkgs.writeScript "xsession-wrapper" + '' + #! ${pkgs.bash}/bin/bash + + # Shared environment setup for graphical sessions. + + . /etc/profile + cd "$HOME" + + ${optionalString cfg.startDbusSession '' + if test -z "$DBUS_SESSION_BUS_ADDRESS"; then + exec ${pkgs.dbus.dbus-launch} --exit-with-session "$0" "$@" + fi + ''} + + ${optionalString cfg.displayManager.job.logToJournal '' + if [ -z "$_DID_SYSTEMD_CAT" ]; then + export _DID_SYSTEMD_CAT=1 + exec ${config.systemd.package}/bin/systemd-cat -t xsession "$0" "$@" + fi + ''} + + ${optionalString cfg.displayManager.job.logToFile '' + exec &> >(tee ~/.xsession-errors) + ''} + + # Start PulseAudio if enabled. + ${optionalString (config.hardware.pulseaudio.enable) '' + # Publish access credentials in the root window. + if ${config.hardware.pulseaudio.package.out}/bin/pulseaudio --dump-modules | grep module-x11-publish &> /dev/null; then + ${config.hardware.pulseaudio.package.out}/bin/pactl load-module module-x11-publish "display=$DISPLAY" + fi + ''} + + # Tell systemd about our $DISPLAY and $XAUTHORITY. + # This is needed by the ssh-agent unit. + # + # Also tell systemd about the dbus session bus address. + # This is required by user units using the session bus. + ${config.systemd.package}/bin/systemctl --user import-environment DISPLAY XAUTHORITY DBUS_SESSION_BUS_ADDRESS + + # Load X defaults. This should probably be safe on wayland too. + ${xorg.xrdb}/bin/xrdb -merge ${xresourcesXft} + if test -e ~/.Xresources; then + ${xorg.xrdb}/bin/xrdb -merge ~/.Xresources + elif test -e ~/.Xdefaults; then + ${xorg.xrdb}/bin/xrdb -merge ~/.Xdefaults + fi + + # Speed up application start by 50-150ms according to + # http://kdemonkey.blogspot.nl/2008/04/magic-trick.html + rm -rf "$HOME/.compose-cache" + mkdir "$HOME/.compose-cache" + + # Work around KDE errors when a user first logs in and + # .local/share doesn't exist yet. + mkdir -p "$HOME/.local/share" + + unset _DID_SYSTEMD_CAT + + ${cfg.displayManager.sessionCommands} + + # Allow the user to execute commands at the beginning of the X session. + if test -f ~/.xprofile; then + source ~/.xprofile + fi + + # Start systemd user services for graphical sessions + ${config.systemd.package}/bin/systemctl --user start graphical-session.target + + # Allow the user to setup a custom session type. + if test -x ~/.xsession; then + eval exec ~/.xsession "$@" + fi + + if test "$1"; then + # Run the supplied session command. Remove any double quotes with eval. + eval exec "$@" + else + # Fall back to the default window/desktopManager + exec ${cfg.displayManager.session.script} + fi + ''; + + # file provided by services.xserver.displayManager.session.script + xsession = wm: dm: pkgs.writeScript "xsession" + '' + #! ${pkgs.bash}/bin/bash + + # Legacy session script used to construct .desktop files from + # `services.xserver.displayManager.session` entries. Called from + # `sessionWrapper`. + + # Expected parameters: + # $1 = <desktop-manager>+<window-manager> + + # The first argument of this script is the session type. + sessionType="$1" + if [ "$sessionType" = default ]; then sessionType=""; fi + + # The session type is "<desktop-manager>+<window-manager>", so + # extract those (see: + # http://wiki.bash-hackers.org/syntax/pe#substring_removal). + windowManager="''${sessionType##*+}" + : ''${windowManager:=${cfg.windowManager.default}} + desktopManager="''${sessionType%%+*}" + : ''${desktopManager:=${cfg.desktopManager.default}} + + # Start the window manager. + case "$windowManager" in + ${mkCases wm} + (*) echo "$0: Window manager '$windowManager' not found.";; + esac + + # Start the desktop manager. + case "$desktopManager" in + ${mkCases dm} + (*) echo "$0: Desktop manager '$desktopManager' not found.";; + esac + + ${optionalString cfg.updateDbusEnvironment '' + ${lib.getBin pkgs.dbus}/bin/dbus-update-activation-environment --systemd --all + ''} + + test -n "$waitPID" && wait "$waitPID" + + ${config.systemd.package}/bin/systemctl --user stop graphical-session.target + + exit 0 + ''; + + # Desktop Entry Specification: + # - https://standards.freedesktop.org/desktop-entry-spec/latest/ + # - https://standards.freedesktop.org/desktop-entry-spec/latest/ar01s06.html + mkDesktops = names: pkgs.runCommand "desktops" + { # trivial derivation + preferLocalBuild = true; + allowSubstitutes = false; + } + '' + mkdir -p "$out/share/xsessions" + ${concatMapStrings (n: '' + cat - > "$out/share/xsessions/${n}.desktop" << EODESKTOP + [Desktop Entry] + Version=1.0 + Type=XSession + TryExec=${cfg.displayManager.session.script} + Exec=${cfg.displayManager.session.script} "${n}" + Name=${n} + Comment= + EODESKTOP + '') names} + + ${concatMapStrings (pkg: '' + if test -d ${pkg}/share/xsessions; then + ${xorg.lndir}/bin/lndir ${pkg}/share/xsessions $out/share/xsessions + fi + '') cfg.displayManager.extraSessionFilePackages} + + + ${concatMapStrings (pkg: '' + if test -d ${pkg}/share/wayland-sessions; then + mkdir -p "$out/share/wayland-sessions" + ${xorg.lndir}/bin/lndir ${pkg}/share/wayland-sessions $out/share/wayland-sessions + fi + '') cfg.displayManager.extraSessionFilePackages} + ''; + +in + +{ + + options = { + + services.xserver.displayManager = { + + xauthBin = mkOption { + internal = true; + default = "${xorg.xauth}/bin/xauth"; + description = "Path to the <command>xauth</command> program used by display managers."; + }; + + xserverBin = mkOption { + type = types.path; + description = "Path to the X server used by display managers."; + }; + + xserverArgs = mkOption { + type = types.listOf types.str; + default = []; + example = [ "-ac" "-logverbose" "-verbose" "-nolisten tcp" ]; + description = "List of arguments for the X server."; + }; + + setupCommands = mkOption { + type = types.lines; + default = ""; + description = '' + Shell commands executed just after the X server has started. + + This option is only effective for display managers for which this feature + is supported; currently these are LightDM, GDM and SDDM. + ''; + }; + + sessionCommands = mkOption { + type = types.lines; + default = ""; + example = + '' + xmessage "Hello World!" & + ''; + description = '' + Shell commands executed just before the window or desktop manager is + started. These commands are not currently sourced for Wayland sessions. + ''; + }; + + hiddenUsers = mkOption { + type = types.listOf types.str; + default = [ "nobody" ]; + description = '' + A list of users which will not be shown in the display manager. + ''; + }; + + extraSessionFilePackages = mkOption { + type = types.listOf types.package; + default = []; + description = '' + A list of packages containing xsession files to be passed to the display manager. + ''; + }; + + session = mkOption { + default = []; + example = literalExample + '' + [ { manage = "desktop"; + name = "xterm"; + start = ''' + ''${pkgs.xterm}/bin/xterm -ls & + waitPID=$! + '''; + } + ] + ''; + description = '' + List of sessions supported with the command used to start each + session. Each session script can set the + <varname>waitPID</varname> shell variable to make this script + wait until the end of the user session. Each script is used + to define either a window manager or a desktop manager. These + can be differentiated by setting the attribute + <varname>manage</varname> either to <literal>"window"</literal> + or <literal>"desktop"</literal>. + + The list of desktop manager and window manager should appear + inside the display manager with the desktop manager name + followed by the window manager name. + ''; + apply = list: rec { + wm = filter (s: s.manage == "window") list; + dm = filter (s: s.manage == "desktop") list; + names = flip concatMap dm + (d: map (w: d.name + optionalString (w.name != "none") ("+" + w.name)) + (filter (w: d.name != "none" || w.name != "none") wm)); + desktops = mkDesktops names; + script = xsession wm dm; + wrapper = xsessionWrapper; + }; + }; + + job = { + + preStart = mkOption { + type = types.lines; + default = ""; + example = "rm -f /var/log/my-display-manager.log"; + description = "Script executed before the display manager is started."; + }; + + execCmd = mkOption { + type = types.str; + example = literalExample '' + "''${pkgs.slim}/bin/slim" + ''; + description = "Command to start the display manager."; + }; + + environment = mkOption { + type = types.attrsOf types.unspecified; + default = {}; + example = { SLIM_CFGFILE = "/etc/slim.conf"; }; + description = "Additional environment variables needed by the display manager."; + }; + + logToFile = mkOption { + type = types.bool; + default = false; + description = '' + Whether the display manager redirects the output of the + session script to <filename>~/.xsession-errors</filename>. + ''; + }; + + logToJournal = mkOption { + type = types.bool; + default = true; + description = '' + Whether the display manager redirects the output of the + session script to the systemd journal. + ''; + }; + + }; + + }; + + }; + + config = { + services.xserver.displayManager.xserverBin = "${xorg.xorgserver.out}/bin/X"; + + systemd.user.targets.graphical-session = { + unitConfig = { + RefuseManualStart = false; + StopWhenUnneeded = false; + }; + }; + }; + + imports = [ + (mkRemovedOptionModule [ "services" "xserver" "displayManager" "desktopManagerHandlesLidAndPower" ] + "The option is no longer necessary because all display managers have already delegated lid management to systemd.") + ]; + +} diff --git a/nixpkgs/nixos/modules/services/x11/display-managers/gdm.nix b/nixpkgs/nixos/modules/services/x11/display-managers/gdm.nix new file mode 100644 index 00000000000..0a5d52e319e --- /dev/null +++ b/nixpkgs/nixos/modules/services/x11/display-managers/gdm.nix @@ -0,0 +1,294 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + + cfg = config.services.xserver.displayManager; + gdm = pkgs.gnome3.gdm; + + xSessionWrapper = if (cfg.setupCommands == "") then null else + pkgs.writeScript "gdm-x-session-wrapper" '' + #!${pkgs.bash}/bin/bash + ${cfg.setupCommands} + exec "$@" + ''; + + # Solves problems like: + # https://wiki.archlinux.org/index.php/Talk:Bluetooth_headset#GDMs_pulseaudio_instance_captures_bluetooth_headset + # Instead of blacklisting plugins, we use Fedora's PulseAudio configuration for GDM: + # https://src.fedoraproject.org/rpms/gdm/blob/master/f/default.pa-for-gdm + pulseConfig = pkgs.writeText "default.pa" '' + load-module module-device-restore + load-module module-card-restore + load-module module-udev-detect + load-module module-native-protocol-unix + load-module module-default-device-restore + load-module module-rescue-streams + load-module module-always-sink + load-module module-intended-roles + load-module module-suspend-on-idle + load-module module-position-event-sounds + ''; + +in + +{ + + ###### interface + + options = { + + services.xserver.displayManager.gdm = { + + enable = mkEnableOption '' + GDM as the display manager. + <emphasis>GDM in NixOS is not well-tested with desktops other + than GNOME, so use with caution, as it could render the + system unusable.</emphasis> + ''; + + debug = mkEnableOption '' + debugging messages in GDM + ''; + + autoLogin = mkOption { + default = {}; + description = '' + Auto login configuration attrset. + ''; + + type = types.submodule { + options = { + enable = mkOption { + type = types.bool; + default = false; + description = '' + Automatically log in as the sepecified <option>autoLogin.user</option>. + ''; + }; + + user = mkOption { + type = types.nullOr types.str; + default = null; + description = '' + User to be used for the autologin. + ''; + }; + + delay = mkOption { + type = types.int; + default = 0; + description = '' + Seconds of inactivity after which the autologin will be performed. + ''; + }; + + }; + }; + }; + + wayland = mkOption { + default = true; + description = '' + Allow GDM run on Wayland instead of Xserver + ''; + type = types.bool; + }; + + autoSuspend = mkOption { + default = true; + description = '' + Suspend the machine after inactivity. + ''; + type = types.bool; + }; + + }; + + }; + + + ###### implementation + + config = mkIf cfg.gdm.enable { + + assertions = [ + { assertion = cfg.gdm.autoLogin.enable -> cfg.gdm.autoLogin.user != null; + message = "GDM auto-login requires services.xserver.displayManager.gdm.autoLogin.user to be set"; + } + ]; + + services.xserver.displayManager.lightdm.enable = false; + + users.users.gdm = + { name = "gdm"; + uid = config.ids.uids.gdm; + group = "gdm"; + home = "/run/gdm"; + description = "GDM user"; + }; + + users.groups.gdm.gid = config.ids.gids.gdm; + + # GDM needs different xserverArgs, presumable because using wayland by default. + services.xserver.tty = null; + services.xserver.display = null; + services.xserver.verbose = null; + + services.xserver.displayManager.job = + { + environment = { + GDM_X_SERVER_EXTRA_ARGS = toString + (filter (arg: arg != "-terminate") cfg.xserverArgs); + XDG_DATA_DIRS = "${cfg.session.desktops}/share/"; + } // optionalAttrs (xSessionWrapper != null) { + # Make GDM use this wrapper before running the session, which runs the + # configured setupCommands. This relies on a patched GDM which supports + # this environment variable. + GDM_X_SESSION_WRAPPER = "${xSessionWrapper}"; + }; + execCmd = "exec ${gdm}/bin/gdm"; + preStart = optionalString config.hardware.pulseaudio.enable '' + mkdir -p /run/gdm/.config/pulse + ln -sf ${pulseConfig} /run/gdm/.config/pulse/default.pa + chown -R gdm:gdm /run/gdm/.config + ''; + }; + + # Because sd_login_monitor_new requires /run/systemd/machines + systemd.services.display-manager.wants = [ "systemd-machined.service" ]; + systemd.services.display-manager.after = [ + "rc-local.service" + "systemd-machined.service" + "systemd-user-sessions.service" + ]; + + systemd.services.display-manager.serviceConfig = { + # Restart = "always"; - already defined in xserver.nix + KillMode = "mixed"; + IgnoreSIGPIPE = "no"; + BusName = "org.gnome.DisplayManager"; + StandardOutput = "syslog"; + StandardError = "inherit"; + }; + + systemd.services.display-manager.path = [ pkgs.gnome3.gnome-session ]; + + # Allow choosing an user account + services.accounts-daemon.enable = true; + + services.dbus.packages = [ gdm ]; + + systemd.user.services.dbus.wantedBy = [ "default.target" ]; + + programs.dconf.profiles.gdm = + let + customDconf = pkgs.writeTextFile { + name = "gdm-dconf"; + destination = "/dconf/gdm-custom"; + text = '' + ${optionalString (!cfg.gdm.autoSuspend) '' + [org/gnome/settings-daemon/plugins/power] + sleep-inactive-ac-type='nothing' + sleep-inactive-battery-type='nothing' + sleep-inactive-ac-timeout=0 + sleep-inactive-battery-timeout=0 + ''} + ''; + }; + + customDconfDb = pkgs.stdenv.mkDerivation { + name = "gdm-dconf-db"; + buildCommand = '' + ${pkgs.gnome3.dconf}/bin/dconf compile $out ${customDconf}/dconf + ''; + }; + in pkgs.stdenv.mkDerivation { + name = "dconf-gdm-profile"; + buildCommand = '' + # Check that the GDM profile starts with what we expect. + if [ $(head -n 1 ${gdm}/share/dconf/profile/gdm) != "user-db:user" ]; then + echo "GDM dconf profile changed, please update gdm.nix" + exit 1 + fi + # Insert our custom DB behind it. + sed '2ifile-db:${customDconfDb}' ${gdm}/share/dconf/profile/gdm > $out + ''; + }; + + # Use AutomaticLogin if delay is zero, because it's immediate. + # Otherwise with TimedLogin with zero seconds the prompt is still + # presented and there's a little delay. + environment.etc."gdm/custom.conf".text = '' + [daemon] + WaylandEnable=${if cfg.gdm.wayland then "true" else "false"} + ${optionalString cfg.gdm.autoLogin.enable ( + if cfg.gdm.autoLogin.delay > 0 then '' + TimedLoginEnable=true + TimedLogin=${cfg.gdm.autoLogin.user} + TimedLoginDelay=${toString cfg.gdm.autoLogin.delay} + '' else '' + AutomaticLoginEnable=true + AutomaticLogin=${cfg.gdm.autoLogin.user} + '') + } + + [security] + + [xdmcp] + + [greeter] + + [chooser] + + [debug] + ${optionalString cfg.gdm.debug "Enable=true"} + ''; + + environment.etc."gdm/Xsession".source = config.services.xserver.displayManager.session.wrapper; + + # GDM LFS PAM modules, adapted somehow to NixOS + security.pam.services = { + gdm-launch-environment.text = '' + auth required pam_succeed_if.so audit quiet_success user = gdm + auth optional pam_permit.so + + account required pam_succeed_if.so audit quiet_success user = gdm + account sufficient pam_unix.so + + password required pam_deny.so + + session required pam_succeed_if.so audit quiet_success user = gdm + session required pam_env.so conffile=${config.system.build.pamEnvironment} readenv=0 + session optional ${pkgs.systemd}/lib/security/pam_systemd.so + session optional pam_keyinit.so force revoke + session optional pam_permit.so + ''; + + gdm-password.text = '' + auth substack login + account include login + password substack login + session include login + ''; + + gdm-autologin.text = '' + auth requisite pam_nologin.so + + auth required pam_succeed_if.so uid >= 1000 quiet + auth required pam_permit.so + + account sufficient pam_unix.so + + password requisite pam_unix.so nullok sha512 + + session optional pam_keyinit.so revoke + session include login + ''; + + }; + + }; + +} diff --git a/nixpkgs/nixos/modules/services/x11/display-managers/lightdm-greeters/enso-os.nix b/nixpkgs/nixos/modules/services/x11/display-managers/lightdm-greeters/enso-os.nix new file mode 100644 index 00000000000..129df139c61 --- /dev/null +++ b/nixpkgs/nixos/modules/services/x11/display-managers/lightdm-greeters/enso-os.nix @@ -0,0 +1,140 @@ +{ config, lib, pkgs, ... }: + +with lib; +let + dmcfg = config.services.xserver.displayManager; + ldmcfg = dmcfg.lightdm; + cfg = ldmcfg.greeters.enso; + + theme = cfg.theme.package; + icons = cfg.iconTheme.package; + cursors = cfg.cursorTheme.package; + + ensoGreeterConf = pkgs.writeText "lightdm-enso-os-greeter.conf" '' + [greeter] + default-wallpaper=${ldmcfg.background} + gtk-theme=${cfg.theme.name} + icon-theme=${cfg.iconTheme.name} + cursor-theme=${cfg.cursorTheme.name} + blur=${toString cfg.blur} + brightness=${toString cfg.brightness} + ${cfg.extraConfig} + ''; +in { + options = { + services.xserver.displayManager.lightdm.greeters.enso = { + enable = mkOption { + type = types.bool; + default = false; + description = '' + Whether to enable enso-os-greeter as the lightdm greeter + ''; + }; + + theme = { + package = mkOption { + type = types.package; + default = pkgs.gnome3.gnome-themes-extra; + defaultText = "pkgs.gnome3.gnome-themes-extra"; + description = '' + The package path that contains the theme given in the name option. + ''; + }; + + name = mkOption { + type = types.str; + default = "Adwaita"; + description = '' + Name of the theme to use for the lightdm-enso-os-greeter + ''; + }; + }; + + iconTheme = { + package = mkOption { + type = types.package; + default = pkgs.papirus-icon-theme; + defaultText = "pkgs.papirus-icon-theme"; + description = '' + The package path that contains the icon theme given in the name option. + ''; + }; + + name = mkOption { + type = types.str; + default = "ePapirus"; + description = '' + Name of the icon theme to use for the lightdm-enso-os-greeter + ''; + }; + }; + + cursorTheme = { + package = mkOption { + type = types.package; + default = pkgs.capitaine-cursors; + defaultText = "pkgs.capitaine-cursors"; + description = '' + The package path that contains the cursor theme given in the name option. + ''; + }; + + name = mkOption { + type = types.str; + default = "capitane-cursors"; + description = '' + Name of the cursor theme to use for the lightdm-enso-os-greeter + ''; + }; + }; + + blur = mkOption { + type = types.bool; + default = false; + description = '' + Whether or not to enable blur + ''; + }; + + brightness = mkOption { + type = types.int; + default = 7; + description = '' + Brightness + ''; + }; + + extraConfig = mkOption { + type = types.lines; + default = ""; + description = '' + Extra configuration that should be put in the greeter.conf + configuration file + ''; + }; + }; + }; + + config = mkIf (ldmcfg.enable && cfg.enable) { + environment.etc."lightdm/greeter.conf".source = ensoGreeterConf; + + environment.systemPackages = [ + cursors + icons + theme + ]; + + services.xserver.displayManager.lightdm = { + greeter = mkDefault { + package = pkgs.lightdm-enso-os-greeter.xgreeters; + name = "pantheon-greeter"; + }; + + greeters = { + gtk = { + enable = mkDefault false; + }; + }; + }; + }; +} diff --git a/nixpkgs/nixos/modules/services/x11/display-managers/lightdm-greeters/gtk.nix b/nixpkgs/nixos/modules/services/x11/display-managers/lightdm-greeters/gtk.nix new file mode 100644 index 00000000000..de932e6e840 --- /dev/null +++ b/nixpkgs/nixos/modules/services/x11/display-managers/lightdm-greeters/gtk.nix @@ -0,0 +1,173 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + + dmcfg = config.services.xserver.displayManager; + ldmcfg = dmcfg.lightdm; + xcfg = config.services.xserver; + cfg = ldmcfg.greeters.gtk; + + inherit (pkgs) writeText; + + theme = cfg.theme.package; + icons = cfg.iconTheme.package; + cursors = cfg.cursorTheme.package; + + gtkGreeterConf = writeText "lightdm-gtk-greeter.conf" + '' + [greeter] + theme-name = ${cfg.theme.name} + icon-theme-name = ${cfg.iconTheme.name} + cursor-theme-name = ${cfg.cursorTheme.name} + cursor-theme-size = ${toString cfg.cursorTheme.size} + background = ${ldmcfg.background} + ${optionalString (cfg.clock-format != null) "clock-format = ${cfg.clock-format}"} + ${optionalString (cfg.indicators != null) "indicators = ${concatStringsSep ";" cfg.indicators}"} + ${optionalString (xcfg.dpi != null) "xft-dpi=${toString xcfg.dpi}"} + ${cfg.extraConfig} + ''; + +in +{ + options = { + + services.xserver.displayManager.lightdm.greeters.gtk = { + + enable = mkOption { + type = types.bool; + default = true; + description = '' + Whether to enable lightdm-gtk-greeter as the lightdm greeter. + ''; + }; + + theme = { + + package = mkOption { + type = types.package; + default = pkgs.gnome3.gnome-themes-extra; + defaultText = "pkgs.gnome3.gnome-themes-extra"; + description = '' + The package path that contains the theme given in the name option. + ''; + }; + + name = mkOption { + type = types.str; + default = "Adwaita"; + description = '' + Name of the theme to use for the lightdm-gtk-greeter. + ''; + }; + + }; + + iconTheme = { + + package = mkOption { + type = types.package; + default = pkgs.gnome3.adwaita-icon-theme; + defaultText = "pkgs.gnome3.adwaita-icon-theme"; + description = '' + The package path that contains the icon theme given in the name option. + ''; + }; + + name = mkOption { + type = types.str; + default = "Adwaita"; + description = '' + Name of the icon theme to use for the lightdm-gtk-greeter. + ''; + }; + + }; + + cursorTheme = { + + package = mkOption { + default = pkgs.gnome3.adwaita-icon-theme; + defaultText = "pkgs.gnome3.adwaita-icon-theme"; + description = '' + The package path that contains the cursor theme given in the name option. + ''; + }; + + name = mkOption { + type = types.str; + default = "Adwaita"; + description = '' + Name of the cursor theme to use for the lightdm-gtk-greeter. + ''; + }; + + size = mkOption { + type = types.int; + default = 16; + description = '' + Size of the cursor theme to use for the lightdm-gtk-greeter. + ''; + }; + }; + + clock-format = mkOption { + type = types.nullOr types.str; + default = null; + example = "%F"; + description = '' + Clock format string (as expected by strftime, e.g. "%H:%M") + to use with the lightdm gtk greeter panel. + + If set to null the default clock format is used. + ''; + }; + + indicators = mkOption { + type = types.nullOr (types.listOf types.str); + default = null; + example = [ "~host" "~spacer" "~clock" "~spacer" "~session" "~language" "~a11y" "~power" ]; + description = '' + List of allowed indicator modules to use for the lightdm gtk + greeter panel. + + Built-in indicators include "~a11y", "~language", "~session", + "~power", "~clock", "~host", "~spacer". Unity indicators can be + represented by short name (e.g. "sound", "power"), service file name, + or absolute path. + + If set to null the default indicators are used. + ''; + }; + + extraConfig = mkOption { + type = types.lines; + default = ""; + description = '' + Extra configuration that should be put in the lightdm-gtk-greeter.conf + configuration file. + ''; + }; + + }; + + }; + + config = mkIf (ldmcfg.enable && cfg.enable) { + + services.xserver.displayManager.lightdm.greeter = mkDefault { + package = pkgs.lightdm_gtk_greeter.xgreeters; + name = "lightdm-gtk-greeter"; + }; + + environment.systemPackages = [ + cursors + icons + theme + ]; + + environment.etc."lightdm/lightdm-gtk-greeter.conf".source = gtkGreeterConf; + + }; +} diff --git a/nixpkgs/nixos/modules/services/x11/display-managers/lightdm-greeters/mini.nix b/nixpkgs/nixos/modules/services/x11/display-managers/lightdm-greeters/mini.nix new file mode 100644 index 00000000000..fa9445af32e --- /dev/null +++ b/nixpkgs/nixos/modules/services/x11/display-managers/lightdm-greeters/mini.nix @@ -0,0 +1,95 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + + dmcfg = config.services.xserver.displayManager; + ldmcfg = dmcfg.lightdm; + cfg = ldmcfg.greeters.mini; + + miniGreeterConf = pkgs.writeText "lightdm-mini-greeter.conf" + '' + [greeter] + user = ${cfg.user} + show-password-label = true + password-label-text = Password: + show-input-cursor = true + + [greeter-hotkeys] + mod-key = meta + shutdown-key = s + restart-key = r + hibernate-key = h + suspend-key = u + + [greeter-theme] + font = Sans + font-size = 1em + text-color = "#080800" + error-color = "#F8F8F0" + background-image = "${ldmcfg.background}" + background-color = "#1B1D1E" + window-color = "#F92672" + border-color = "#080800" + border-width = 2px + layout-space = 15 + password-color = "#F8F8F0" + password-background-color = "#1B1D1E" + + ${cfg.extraConfig} + ''; + +in +{ + options = { + + services.xserver.displayManager.lightdm.greeters.mini = { + + enable = mkOption { + type = types.bool; + default = false; + description = '' + Whether to enable lightdm-mini-greeter as the lightdm greeter. + + Note that this greeter starts only the default X session. + You can configure the default X session by + <option>services.xserver.desktopManager.default</option> and + <option>services.xserver.windowManager.default</option>. + ''; + }; + + user = mkOption { + type = types.str; + default = "root"; + description = '' + The user to login as. + ''; + }; + + extraConfig = mkOption { + type = types.lines; + default = ""; + description = '' + Extra configuration that should be put in the lightdm-mini-greeter.conf + configuration file. + ''; + }; + + }; + + }; + + config = mkIf (ldmcfg.enable && cfg.enable) { + + services.xserver.displayManager.lightdm.greeters.gtk.enable = false; + + services.xserver.displayManager.lightdm.greeter = mkDefault { + package = pkgs.lightdm-mini-greeter.xgreeters; + name = "lightdm-mini-greeter"; + }; + + environment.etc."lightdm/lightdm-mini-greeter.conf".source = miniGreeterConf; + + }; +} diff --git a/nixpkgs/nixos/modules/services/x11/display-managers/lightdm-greeters/pantheon.nix b/nixpkgs/nixos/modules/services/x11/display-managers/lightdm-greeters/pantheon.nix new file mode 100644 index 00000000000..29cb6ccbc06 --- /dev/null +++ b/nixpkgs/nixos/modules/services/x11/display-managers/lightdm-greeters/pantheon.nix @@ -0,0 +1,42 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + + dmcfg = config.services.xserver.displayManager; + ldmcfg = dmcfg.lightdm; + cfg = ldmcfg.greeters.pantheon; + +in +{ + options = { + + services.xserver.displayManager.lightdm.greeters.pantheon = { + + enable = mkOption { + type = types.bool; + default = false; + description = '' + Whether to enable elementary-greeter as the lightdm greeter. + ''; + }; + + }; + + }; + + config = mkIf (ldmcfg.enable && cfg.enable) { + + services.xserver.displayManager.lightdm.greeters.gtk.enable = false; + + services.xserver.displayManager.lightdm.greeter = mkDefault { + package = pkgs.pantheon.elementary-greeter.xgreeters; + name = "io.elementary.greeter"; + }; + + environment.etc."lightdm/io.elementary.greeter.conf".source = "${pkgs.pantheon.elementary-greeter}/etc/lightdm/io.elementary.greeter.conf"; + environment.etc."wingpanel.d/io.elementary.greeter.whitelist".source = "${pkgs.pantheon.elementary-default-settings}/etc/wingpanel.d/io.elementary.greeter.whitelist"; + + }; +} diff --git a/nixpkgs/nixos/modules/services/x11/display-managers/lightdm.nix b/nixpkgs/nixos/modules/services/x11/display-managers/lightdm.nix new file mode 100644 index 00000000000..f105cb496e6 --- /dev/null +++ b/nixpkgs/nixos/modules/services/x11/display-managers/lightdm.nix @@ -0,0 +1,290 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + + xcfg = config.services.xserver; + dmcfg = xcfg.displayManager; + xEnv = config.systemd.services.display-manager.environment; + cfg = dmcfg.lightdm; + + dmDefault = xcfg.desktopManager.default; + wmDefault = xcfg.windowManager.default; + hasDefaultUserSession = dmDefault != "none" || wmDefault != "none"; + + inherit (pkgs) lightdm writeScript writeText; + + # lightdm runs with clearenv(), but we need a few things in the environment for X to startup + xserverWrapper = writeScript "xserver-wrapper" + '' + #! ${pkgs.bash}/bin/bash + ${concatMapStrings (n: "export ${n}=\"${getAttr n xEnv}\"\n") (attrNames xEnv)} + + display=$(echo "$@" | xargs -n 1 | grep -P ^:\\d\$ | head -n 1 | sed s/^://) + if [ -z "$display" ] + then additionalArgs=":0 -logfile /var/log/X.0.log" + else additionalArgs="-logfile /var/log/X.$display.log" + fi + + exec ${dmcfg.xserverBin} ${toString dmcfg.xserverArgs} $additionalArgs "$@" + ''; + + usersConf = writeText "users.conf" + '' + [UserList] + minimum-uid=500 + hidden-users=${concatStringsSep " " dmcfg.hiddenUsers} + hidden-shells=/run/current-system/sw/bin/nologin + ''; + + lightdmConf = writeText "lightdm.conf" + '' + [LightDM] + ${optionalString cfg.greeter.enable '' + greeter-user = ${config.users.users.lightdm.name} + greeters-directory = ${cfg.greeter.package} + ''} + sessions-directory = ${dmcfg.session.desktops}/share/xsessions + ${cfg.extraConfig} + + [Seat:*] + xserver-command = ${xserverWrapper} + session-wrapper = ${dmcfg.session.wrapper} + ${optionalString cfg.greeter.enable '' + greeter-session = ${cfg.greeter.name} + ''} + ${optionalString cfg.autoLogin.enable '' + autologin-user = ${cfg.autoLogin.user} + autologin-user-timeout = ${toString cfg.autoLogin.timeout} + autologin-session = ${defaultSessionName} + ''} + ${optionalString hasDefaultUserSession '' + user-session=${defaultSessionName} + ''} + ${optionalString (dmcfg.setupCommands != "") '' + display-setup-script=${pkgs.writeScript "lightdm-display-setup" '' + #!${pkgs.bash}/bin/bash + ${dmcfg.setupCommands} + ''} + ''} + ${cfg.extraSeatDefaults} + ''; + + defaultSessionName = dmDefault + optionalString (wmDefault != "none") ("+" + wmDefault); +in +{ + # Note: the order in which lightdm greeter modules are imported + # here determines the default: later modules (if enable) are + # preferred. + imports = [ + ./lightdm-greeters/gtk.nix + ./lightdm-greeters/mini.nix + ./lightdm-greeters/enso-os.nix + ./lightdm-greeters/pantheon.nix + ]; + + options = { + + services.xserver.displayManager.lightdm = { + + enable = mkOption { + type = types.bool; + default = false; + description = '' + Whether to enable lightdm as the display manager. + ''; + }; + + greeter = { + enable = mkOption { + type = types.bool; + default = true; + description = '' + If set to false, run lightdm in greeterless mode. This only works if autologin + is enabled and autoLogin.timeout is zero. + ''; + }; + package = mkOption { + type = types.package; + description = '' + The LightDM greeter to login via. The package should be a directory + containing a .desktop file matching the name in the 'name' option. + ''; + + }; + name = mkOption { + type = types.str; + description = '' + The name of a .desktop file in the directory specified + in the 'package' option. + ''; + }; + }; + + extraConfig = mkOption { + type = types.lines; + default = ""; + example = '' + user-authority-in-system-dir = true + ''; + description = "Extra lines to append to LightDM section."; + }; + + background = mkOption { + type = types.str; + default = "${pkgs.nixos-artwork.wallpapers.simple-dark-gray-bottom}/share/artwork/gnome/nix-wallpaper-simple-dark-gray_bottom.png"; + description = '' + The background image or color to use. + ''; + }; + + extraSeatDefaults = mkOption { + type = types.lines; + default = ""; + example = '' + greeter-show-manual-login=true + ''; + description = "Extra lines to append to SeatDefaults section."; + }; + + autoLogin = mkOption { + default = {}; + description = '' + Configuration for automatic login. + ''; + + type = types.submodule { + options = { + enable = mkOption { + type = types.bool; + default = false; + description = '' + Automatically log in as the specified <option>autoLogin.user</option>. + ''; + }; + + user = mkOption { + type = types.nullOr types.str; + default = null; + description = '' + User to be used for the automatic login. + ''; + }; + + timeout = mkOption { + type = types.int; + default = 0; + description = '' + Show the greeter for this many seconds before automatic login occurs. + ''; + }; + }; + }; + }; + + }; + }; + + config = mkIf cfg.enable { + + assertions = [ + { assertion = xcfg.enable; + message = '' + LightDM requires services.xserver.enable to be true + ''; + } + { assertion = cfg.autoLogin.enable -> cfg.autoLogin.user != null; + message = '' + LightDM auto-login requires services.xserver.displayManager.lightdm.autoLogin.user to be set + ''; + } + { assertion = cfg.autoLogin.enable -> dmDefault != "none" || wmDefault != "none"; + message = '' + LightDM auto-login requires that services.xserver.desktopManager.default and + services.xserver.windowManager.default are set to valid values. The current + default session: ${defaultSessionName} is not valid. + ''; + } + { assertion = !cfg.greeter.enable -> (cfg.autoLogin.enable && cfg.autoLogin.timeout == 0); + message = '' + LightDM can only run without greeter if automatic login is enabled and the timeout for it + is set to zero. + ''; + } + ]; + + # lightdm relaunches itself via just `lightdm`, so needs to be on the PATH + services.xserver.displayManager.job.execCmd = '' + export PATH=${lightdm}/sbin:$PATH + exec ${lightdm}/sbin/lightdm + ''; + + environment.etc."lightdm/lightdm.conf".source = lightdmConf; + environment.etc."lightdm/users.conf".source = usersConf; + + services.dbus.enable = true; + services.dbus.packages = [ lightdm ]; + + # lightdm uses the accounts daemon to remember language/window-manager per user + services.accounts-daemon.enable = true; + + # Enable the accounts daemon to find lightdm's dbus interface + environment.systemPackages = [ lightdm ]; + + security.pam.services.lightdm.text = '' + auth substack login + account include login + password substack login + session include login + ''; + + security.pam.services.lightdm-greeter.text = '' + auth required pam_succeed_if.so audit quiet_success user = lightdm + auth optional pam_permit.so + + account required pam_succeed_if.so audit quiet_success user = lightdm + account sufficient pam_unix.so + + password required pam_deny.so + + session required pam_succeed_if.so audit quiet_success user = lightdm + session required pam_env.so conffile=${config.system.build.pamEnvironment} readenv=0 + session optional ${pkgs.systemd}/lib/security/pam_systemd.so + session optional pam_keyinit.so force revoke + session optional pam_permit.so + ''; + + security.pam.services.lightdm-autologin.text = '' + auth requisite pam_nologin.so + + auth required pam_succeed_if.so uid >= 1000 quiet + auth required pam_permit.so + + account sufficient pam_unix.so + + password requisite pam_unix.so nullok sha512 + + session optional pam_keyinit.so revoke + session include login + ''; + + users.users.lightdm = { + home = "/var/lib/lightdm"; + group = "lightdm"; + uid = config.ids.uids.lightdm; + }; + + systemd.tmpfiles.rules = [ + "d /run/lightdm 0711 lightdm lightdm 0" + "d /var/cache/lightdm 0711 root lightdm -" + "d /var/lib/lightdm 1770 lightdm lightdm -" + "d /var/lib/lightdm-data 1775 lightdm lightdm -" + "d /var/log/lightdm 0711 root lightdm -" + ]; + + users.groups.lightdm.gid = config.ids.gids.lightdm; + services.xserver.tty = null; # We might start multiple X servers so let the tty increment themselves.. + services.xserver.display = null; # We specify our own display (and logfile) in xserver-wrapper up there + }; +} diff --git a/nixpkgs/nixos/modules/services/x11/display-managers/sddm.nix b/nixpkgs/nixos/modules/services/x11/display-managers/sddm.nix new file mode 100644 index 00000000000..8847acb0c60 --- /dev/null +++ b/nixpkgs/nixos/modules/services/x11/display-managers/sddm.nix @@ -0,0 +1,298 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + + xcfg = config.services.xserver; + dmcfg = xcfg.displayManager; + cfg = dmcfg.sddm; + xEnv = config.systemd.services.display-manager.environment; + + inherit (pkgs) sddm; + + xserverWrapper = pkgs.writeScript "xserver-wrapper" '' + #!/bin/sh + ${concatMapStrings (n: "export ${n}=\"${getAttr n xEnv}\"\n") (attrNames xEnv)} + exec systemd-cat ${dmcfg.xserverBin} ${toString dmcfg.xserverArgs} "$@" + ''; + + Xsetup = pkgs.writeScript "Xsetup" '' + #!/bin/sh + ${cfg.setupScript} + ${dmcfg.setupCommands} + ''; + + Xstop = pkgs.writeScript "Xstop" '' + #!/bin/sh + ${cfg.stopScript} + ''; + + cfgFile = pkgs.writeText "sddm.conf" '' + [General] + HaltCommand=${pkgs.systemd}/bin/systemctl poweroff + RebootCommand=${pkgs.systemd}/bin/systemctl reboot + ${optionalString cfg.autoNumlock '' + Numlock=on + ''} + + [Theme] + Current=${cfg.theme} + ThemeDir=/run/current-system/sw/share/sddm/themes + FacesDir=/run/current-system/sw/share/sddm/faces + + [Users] + MaximumUid=${toString config.ids.uids.nixbld} + HideUsers=${concatStringsSep "," dmcfg.hiddenUsers} + HideShells=/run/current-system/sw/bin/nologin + + [X11] + MinimumVT=${toString (if xcfg.tty != null then xcfg.tty else 7)} + ServerPath=${xserverWrapper} + XephyrPath=${pkgs.xorg.xorgserver.out}/bin/Xephyr + SessionCommand=${dmcfg.session.wrapper} + SessionDir=${dmcfg.session.desktops}/share/xsessions + XauthPath=${pkgs.xorg.xauth}/bin/xauth + DisplayCommand=${Xsetup} + DisplayStopCommand=${Xstop} + EnableHidpi=${if cfg.enableHidpi then "true" else "false"} + + [Wayland] + EnableHidpi=${if cfg.enableHidpi then "true" else "false"} + SessionDir=${dmcfg.session.desktops}/share/wayland-sessions + + ${optionalString cfg.autoLogin.enable '' + [Autologin] + User=${cfg.autoLogin.user} + Session=${defaultSessionName}.desktop + Relogin=${boolToString cfg.autoLogin.relogin} + ''} + + ${cfg.extraConfig} + ''; + + defaultSessionName = + let + dm = xcfg.desktopManager.default; + wm = xcfg.windowManager.default; + in dm + optionalString (wm != "none") ("+" + wm); + +in +{ + options = { + + services.xserver.displayManager.sddm = { + enable = mkOption { + type = types.bool; + default = false; + description = '' + Whether to enable sddm as the display manager. + ''; + }; + + enableHidpi = mkOption { + type = types.bool; + default = true; + description = '' + Whether to enable automatic HiDPI mode. + </para> + <para> + Versions up to 0.17 are broken so this only works from 0.18 onwards. + ''; + }; + + extraConfig = mkOption { + type = types.lines; + default = ""; + example = '' + [Autologin] + User=john + Session=plasma.desktop + ''; + description = '' + Extra lines appended to the configuration of SDDM. + ''; + }; + + theme = mkOption { + type = types.str; + default = ""; + description = '' + Greeter theme to use. + ''; + }; + + autoNumlock = mkOption { + type = types.bool; + default = false; + description = '' + Enable numlock at login. + ''; + }; + + setupScript = mkOption { + type = types.str; + default = ""; + example = '' + # workaround for using NVIDIA Optimus without Bumblebee + xrandr --setprovideroutputsource modesetting NVIDIA-0 + xrandr --auto + ''; + description = '' + A script to execute when starting the display server. DEPRECATED, please + use <option>services.xserver.displayManager.setupCommands</option>. + ''; + }; + + stopScript = mkOption { + type = types.str; + default = ""; + description = '' + A script to execute when stopping the display server. + ''; + }; + + autoLogin = mkOption { + default = {}; + description = '' + Configuration for automatic login. + ''; + + type = types.submodule { + options = { + enable = mkOption { + type = types.bool; + default = false; + description = '' + Automatically log in as <option>autoLogin.user</option>. + ''; + }; + + user = mkOption { + type = types.nullOr types.str; + default = null; + description = '' + User to be used for the automatic login. + ''; + }; + + relogin = mkOption { + type = types.bool; + default = false; + description = '' + If true automatic login will kick in again on session exit (logout), otherwise it + will only log in automatically when the display-manager is started. + ''; + }; + }; + }; + }; + + }; + + }; + + config = mkIf cfg.enable { + + assertions = [ + { assertion = xcfg.enable; + message = '' + SDDM requires services.xserver.enable to be true + ''; + } + { assertion = cfg.autoLogin.enable -> cfg.autoLogin.user != null; + message = '' + SDDM auto-login requires services.xserver.displayManager.sddm.autoLogin.user to be set + ''; + } + { assertion = cfg.autoLogin.enable -> elem defaultSessionName dmcfg.session.names; + message = '' + SDDM auto-login requires that services.xserver.desktopManager.default and + services.xserver.windowManager.default are set to valid values. The current + default session: ${defaultSessionName} is not valid. + ''; + } + ]; + + services.xserver.displayManager.job = { + environment = { + # Load themes from system environment + QT_PLUGIN_PATH = "/run/current-system/sw/" + pkgs.qt5.qtbase.qtPluginPrefix; + QML2_IMPORT_PATH = "/run/current-system/sw/" + pkgs.qt5.qtbase.qtQmlPrefix; + }; + + execCmd = "exec /run/current-system/sw/bin/sddm"; + }; + + security.pam.services = { + sddm = { + allowNullPassword = true; + startSession = true; + }; + + sddm-greeter.text = '' + auth required pam_succeed_if.so audit quiet_success user = sddm + auth optional pam_permit.so + + account required pam_succeed_if.so audit quiet_success user = sddm + account sufficient pam_unix.so + + password required pam_deny.so + + session required pam_succeed_if.so audit quiet_success user = sddm + session required pam_env.so conffile=${config.system.build.pamEnvironment} readenv=0 + session optional ${pkgs.systemd}/lib/security/pam_systemd.so + session optional pam_keyinit.so force revoke + session optional pam_permit.so + ''; + + sddm-autologin.text = '' + auth requisite pam_nologin.so + auth required pam_succeed_if.so uid >= 1000 quiet + auth required pam_permit.so + + account include sddm + + password include sddm + + session include sddm + ''; + }; + + users.users.sddm = { + createHome = true; + home = "/var/lib/sddm"; + group = "sddm"; + uid = config.ids.uids.sddm; + }; + + environment.etc."sddm.conf".source = cfgFile; + environment.pathsToLink = [ + "/share/sddm" + ]; + + users.groups.sddm.gid = config.ids.gids.sddm; + + environment.systemPackages = [ sddm ]; + services.dbus.packages = [ sddm ]; + + # To enable user switching, allow sddm to allocate TTYs/displays dynamically. + services.xserver.tty = null; + services.xserver.display = null; + + systemd.tmpfiles.rules = [ + # Prior to Qt 5.9.2, there is a QML cache invalidation bug which sometimes + # strikes new Plasma 5 releases. If the QML cache is not invalidated, SDDM + # will segfault without explanation. We really tore our hair out for awhile + # before finding the bug: + # https://bugreports.qt.io/browse/QTBUG-62302 + # We work around the problem by deleting the QML cache before startup. + # This was supposedly fixed in Qt 5.9.2 however it has been reported with + # 5.10 and 5.11 as well. The initial workaround was to delete the directory + # in the Xsetup script but that doesn't do anything. + # Instead we use tmpfiles.d to ensure it gets wiped. + # This causes a small but perceptible delay when SDDM starts. + "e ${config.users.users.sddm.home}/.cache - - - 0" + ]; + }; +} diff --git a/nixpkgs/nixos/modules/services/x11/display-managers/slim.nix b/nixpkgs/nixos/modules/services/x11/display-managers/slim.nix new file mode 100644 index 00000000000..124660a43f0 --- /dev/null +++ b/nixpkgs/nixos/modules/services/x11/display-managers/slim.nix @@ -0,0 +1,156 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + + dmcfg = config.services.xserver.displayManager; + + cfg = dmcfg.slim; + + slimConfig = pkgs.writeText "slim.cfg" + '' + xauth_path ${dmcfg.xauthBin} + default_xserver ${dmcfg.xserverBin} + xserver_arguments ${toString dmcfg.xserverArgs} + sessiondir ${dmcfg.session.desktops}/share/xsessions + login_cmd exec ${pkgs.runtimeShell} ${dmcfg.session.wrapper} "%session" + halt_cmd ${config.systemd.package}/sbin/shutdown -h now + reboot_cmd ${config.systemd.package}/sbin/shutdown -r now + logfile /dev/stderr + ${optionalString (cfg.defaultUser != null) ("default_user " + cfg.defaultUser)} + ${optionalString (cfg.defaultUser != null) ("focus_password yes")} + ${optionalString cfg.autoLogin "auto_login yes"} + ${optionalString (cfg.consoleCmd != null) "console_cmd ${cfg.consoleCmd}"} + ${cfg.extraConfig} + ''; + + # Unpack the SLiM theme, or use the default. + slimThemesDir = + let + unpackedTheme = pkgs.runCommand "slim-theme" { preferLocalBuild = true; } + '' + mkdir -p $out + cd $out + unpackFile ${cfg.theme} + ln -s * default + ''; + in if cfg.theme == null then "${pkgs.slim}/share/slim/themes" else unpackedTheme; + +in + +{ + + ###### interface + + options = { + + services.xserver.displayManager.slim = { + + enable = mkOption { + type = types.bool; + default = false; + description = '' + Whether to enable SLiM as the display manager. + ''; + }; + + theme = mkOption { + type = types.nullOr types.path; + default = pkgs.fetchurl { + url = "https://github.com/jagajaga/nixos-slim-theme/archive/2.0.tar.gz"; + sha256 = "0lldizhigx7bjhxkipii87y432hlf5wdvamnfxrryf9z7zkfypc8"; + }; + defaultText = ''pkgs.fetchurl { + url = "https://github.com/jagajaga/nixos-slim-theme/archive/2.0.tar.gz"; + sha256 = "0lldizhigx7bjhxkipii87y432hlf5wdvamnfxrryf9z7zkfypc8"; + }''; + example = literalExample '' + pkgs.fetchurl { + url = "mirror://sourceforge/slim.berlios/slim-wave.tar.gz"; + sha256 = "0ndr419i5myzcylvxb89m9grl2xyq6fbnyc3lkd711mzlmnnfxdy"; + } + ''; + description = '' + The theme for the SLiM login manager. If not specified, SLiM's + default theme is used. See <link + xlink:href='http://slim.berlios.de/themes01.php'/> for a + collection of themes. TODO: berlios shut down. + ''; + }; + + defaultUser = mkOption { + type = types.nullOr types.str; + default = null; + example = "login"; + description = '' + The default user to load. If you put a username here you + get it automatically loaded into the username field, and + the focus is placed on the password. + ''; + }; + + autoLogin = mkOption { + type = types.bool; + default = false; + description = '' + Automatically log in as the default user. + ''; + }; + + extraConfig = mkOption { + type = types.lines; + default = ""; + description = '' + Extra configuration options for SLiM login manager. Do not + add options that can be configured directly. + ''; + }; + + consoleCmd = mkOption { + type = types.nullOr types.str; + default = '' + ${pkgs.xterm}/bin/xterm -C -fg white -bg black +sb -T "Console login" -e ${pkgs.shadow}/bin/login + ''; + defaultText = '' + ''${pkgs.xterm}/bin/xterm -C -fg white -bg black +sb -T "Console login" -e ''${pkgs.shadow}/bin/login + ''; + description = '' + The command to run when "console" is given as the username. + ''; + }; + }; + + }; + + + ###### implementation + + config = mkIf cfg.enable { + + services.xserver.displayManager.job = + { environment = + { SLIM_CFGFILE = slimConfig; + SLIM_THEMESDIR = slimThemesDir; + }; + execCmd = "exec ${pkgs.slim}/bin/slim"; + }; + + services.xserver.displayManager.sessionCommands = + '' + # Export the config/themes for slimlock. + export SLIM_THEMESDIR=${slimThemesDir} + ''; + + # Allow null passwords so that the user can login as root on the + # installation CD. + security.pam.services.slim = { allowNullPassword = true; startSession = true; }; + + # Allow slimlock to work. + security.pam.services.slimlock = {}; + + environment.systemPackages = [ pkgs.slim ]; + + }; + +} diff --git a/nixpkgs/nixos/modules/services/x11/display-managers/startx.nix b/nixpkgs/nixos/modules/services/x11/display-managers/startx.nix new file mode 100644 index 00000000000..57046984358 --- /dev/null +++ b/nixpkgs/nixos/modules/services/x11/display-managers/startx.nix @@ -0,0 +1,44 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + + cfg = config.services.xserver.displayManager.startx; + +in + +{ + + ###### interface + + options = { + services.xserver.displayManager.startx = { + enable = mkOption { + default = false; + description = '' + Whether to enable the dummy "startx" pseudo-display manager, + which allows users to start X manually via the "startx" command + from a vt shell. The X server runs under the user's id, not as root. + The user must provide a ~/.xinitrc file containing session startup + commands, see startx(1). This is not automatically generated + from the desktopManager and windowManager settings. + ''; + }; + }; + }; + + + ###### implementation + + config = mkIf cfg.enable { + services.xserver = { + exportConfiguration = true; + displayManager.job.execCmd = ""; + displayManager.lightdm.enable = lib.mkForce false; + }; + systemd.services.display-manager.enable = false; + environment.systemPackages = with pkgs; [ xorg.xinit ]; + }; + +} diff --git a/nixpkgs/nixos/modules/services/x11/display-managers/xpra.nix b/nixpkgs/nixos/modules/services/x11/display-managers/xpra.nix new file mode 100644 index 00000000000..c23e479140f --- /dev/null +++ b/nixpkgs/nixos/modules/services/x11/display-managers/xpra.nix @@ -0,0 +1,252 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + cfg = config.services.xserver.displayManager.xpra; + dmcfg = config.services.xserver.displayManager; + +in + +{ + ###### interface + + options = { + services.xserver.displayManager.xpra = { + enable = mkOption { + type = types.bool; + default = false; + description = "Whether to enable xpra as display manager."; + }; + + bindTcp = mkOption { + default = "127.0.0.1:10000"; + example = "0.0.0.0:10000"; + type = types.nullOr types.str; + description = "Bind xpra to TCP"; + }; + + auth = mkOption { + type = types.str; + default = "pam"; + example = "password:value=mysecret"; + description = "Authentication to use when connecting to xpra"; + }; + + pulseaudio = mkEnableOption "pulseaudio audio streaming"; + + extraOptions = mkOption { + description = "Extra xpra options"; + default = []; + type = types.listOf types.str; + }; + }; + }; + + ###### implementation + + config = mkIf cfg.enable { + services.xserver.videoDrivers = ["dummy"]; + + services.xserver.monitorSection = '' + HorizSync 1.0 - 2000.0 + VertRefresh 1.0 - 200.0 + #To add your own modes here, use a modeline calculator, like: + # cvt: + # http://www.x.org/archive/X11R7.5/doc/man/man1/cvt.1.html + # xtiming: + # http://xtiming.sourceforge.net/cgi-bin/xtiming.pl + # gtf: + # http://gtf.sourceforge.net/ + #This can be used to get a specific DPI, but only for the default resolution: + #DisplaySize 508 317 + #NOTE: the highest modes will not work without increasing the VideoRam + # for the dummy video card. + #Modeline "16000x15000" 300.00 16000 16408 18000 20000 15000 15003 15013 15016 + #Modeline "15000x15000" 281.25 15000 15376 16872 18744 15000 15003 15013 15016 + #Modeline "16384x8192" 167.75 16384 16800 18432 20480 8192 8195 8205 8208 + #Modeline "15360x8640" 249.00 15360 15752 17280 19200 8640 8643 8648 8651 + Modeline "8192x4096" 193.35 8192 8224 8952 8984 4096 4196 4200 4301 + Modeline "7680x4320" 208.00 7680 7880 8640 9600 4320 4323 4328 4335 + Modeline "6400x4096" 151.38 6400 6432 7000 7032 4096 4196 4200 4301 + Modeline "6400x2560" 91.59 6400 6432 6776 6808 2560 2623 2626 2689 + Modeline "6400x2160" 160.51 6400 6432 7040 7072 2160 2212 2216 2269 + Modeline "5760x2160" 149.50 5760 5768 6320 6880 2160 2161 2164 2173 + Modeline "5680x1440" 142.66 5680 5712 6248 6280 1440 1474 1478 1513 + Modeline "5496x1200" 199.13 5496 5528 6280 6312 1200 1228 1233 1261 + Modeline "5280x2560" 75.72 5280 5312 5592 5624 2560 2623 2626 2689 + Modeline "5280x1920" 56.04 5280 5312 5520 5552 1920 1967 1969 2017 + Modeline "5280x1200" 191.40 5280 5312 6032 6064 1200 1228 1233 1261 + Modeline "5280x1080" 169.96 5280 5312 5952 5984 1080 1105 1110 1135 + Modeline "5120x3200" 199.75 5120 5152 5904 5936 3200 3277 3283 3361 + Modeline "5120x2560" 73.45 5120 5152 5424 5456 2560 2623 2626 2689 + Modeline "5120x2880" 185.50 5120 5256 5760 6400 2880 2883 2888 2899 + Modeline "4800x1200" 64.42 4800 4832 5072 5104 1200 1229 1231 1261 + Modeline "4720x3840" 227.86 4720 4752 5616 5648 3840 3933 3940 4033 + Modeline "4400x2560" 133.70 4400 4432 4936 4968 2560 2622 2627 2689 + Modeline "4480x1440" 72.94 4480 4512 4784 4816 1440 1475 1478 1513 + Modeline "4240x1440" 69.09 4240 4272 4528 4560 1440 1475 1478 1513 + Modeline "4160x1440" 67.81 4160 4192 4448 4480 1440 1475 1478 1513 + Modeline "4096x2304" 249.25 4096 4296 4720 5344 2304 2307 2312 2333 + Modeline "4096x2160" 111.25 4096 4200 4608 5120 2160 2163 2173 2176 + Modeline "4000x1660" 170.32 4000 4128 4536 5072 1660 1661 1664 1679 + Modeline "4000x1440" 145.00 4000 4088 4488 4976 1440 1441 1444 1457 + Modeline "3904x1440" 63.70 3904 3936 4176 4208 1440 1475 1478 1513 + Modeline "3840x2880" 133.43 3840 3872 4376 4408 2880 2950 2955 3025 + Modeline "3840x2560" 116.93 3840 3872 4312 4344 2560 2622 2627 2689 + Modeline "3840x2160" 104.25 3840 3944 4320 4800 2160 2163 2168 2175 + Modeline "3840x2048" 91.45 3840 3872 4216 4248 2048 2097 2101 2151 + Modeline "3840x1200" 108.89 3840 3872 4280 4312 1200 1228 1232 1261 + Modeline "3840x1080" 100.38 3840 3848 4216 4592 1080 1081 1084 1093 + Modeline "3864x1050" 94.58 3864 3896 4248 4280 1050 1074 1078 1103 + Modeline "3600x1200" 106.06 3600 3632 3984 4368 1200 1201 1204 1214 + Modeline "3600x1080" 91.02 3600 3632 3976 4008 1080 1105 1109 1135 + Modeline "3520x1196" 99.53 3520 3552 3928 3960 1196 1224 1228 1256 + Modeline "3360x2560" 102.55 3360 3392 3776 3808 2560 2622 2627 2689 + Modeline "3360x1050" 293.75 3360 3576 3928 4496 1050 1053 1063 1089 + Modeline "3288x1080" 39.76 3288 3320 3464 3496 1080 1106 1108 1135 + Modeline "3200x1800" 233.00 3200 3384 3720 4240 1800 1803 1808 1834 + Modeline "3200x1080" 236.16 3200 3232 4128 4160 1080 1103 1112 1135 + Modeline "3120x2560" 95.36 3120 3152 3512 3544 2560 2622 2627 2689 + Modeline "3120x1050" 272.75 3120 3320 3648 4176 1050 1053 1063 1089 + Modeline "3072x2560" 93.92 3072 3104 3456 3488 2560 2622 2627 2689 + Modeline "3008x1692" 130.93 3008 3112 3416 3824 1692 1693 1696 1712 + Modeline "3000x2560" 91.77 3000 3032 3376 3408 2560 2622 2627 2689 + Modeline "2880x1620" 396.25 2880 3096 3408 3936 1620 1623 1628 1679 + Modeline "2728x1680" 148.02 2728 2760 3320 3352 1680 1719 1726 1765 + Modeline "2560x2240" 151.55 2560 2688 2952 3344 2240 2241 2244 2266 + Modeline "2560x1600" 47.12 2560 2592 2768 2800 1600 1639 1642 1681 + Modeline "2560x1440" 42.12 2560 2592 2752 2784 1440 1475 1478 1513 + Modeline "2560x1400" 267.86 2560 2592 3608 3640 1400 1429 1441 1471 + Modeline "2048x2048" 49.47 2048 2080 2264 2296 2048 2097 2101 2151 + Modeline "2048x1536" 80.06 2048 2104 2312 2576 1536 1537 1540 1554 + Modeline "2048x1152" 197.97 2048 2184 2408 2768 1152 1153 1156 1192 + Modeline "2048x1152" 165.92 2048 2080 2704 2736 1152 1176 1186 1210 + Modeline "1920x1440" 69.47 1920 1960 2152 2384 1440 1441 1444 1457 + Modeline "1920x1200" 26.28 1920 1952 2048 2080 1200 1229 1231 1261 + Modeline "1920x1080" 23.53 1920 1952 2040 2072 1080 1106 1108 1135 + Modeline "1728x1520" 205.42 1728 1760 2536 2568 1520 1552 1564 1597 + Modeline "1680x1050" 20.08 1680 1712 1784 1816 1050 1075 1077 1103 + Modeline "1600x1200" 22.04 1600 1632 1712 1744 1200 1229 1231 1261 + Modeline "1600x900" 33.92 1600 1632 1760 1792 900 921 924 946 + Modeline "1440x900" 30.66 1440 1472 1584 1616 900 921 924 946 + Modeline "1400x900" 103.50 1400 1480 1624 1848 900 903 913 934 + ModeLine "1366x768" 72.00 1366 1414 1446 1494 768 771 777 803 + Modeline "1360x768" 24.49 1360 1392 1480 1512 768 786 789 807 + Modeline "1280x1024" 31.50 1280 1312 1424 1456 1024 1048 1052 1076 + Modeline "1280x800" 24.15 1280 1312 1400 1432 800 819 822 841 + Modeline "1280x768" 23.11 1280 1312 1392 1424 768 786 789 807 + Modeline "1280x720" 59.42 1280 1312 1536 1568 720 735 741 757 + Modeline "1024x768" 18.71 1024 1056 1120 1152 768 786 789 807 + Modeline "1024x640" 41.98 1024 1056 1208 1240 640 653 659 673 + Modeline "1024x576" 46.50 1024 1064 1160 1296 576 579 584 599 + Modeline "768x1024" 19.50 768 800 872 904 1024 1048 1052 1076 + Modeline "960x540" 40.75 960 992 1088 1216 540 543 548 562 + Modeline "864x486" 32.50 864 888 968 1072 486 489 494 506 + Modeline "720x405" 22.50 720 744 808 896 405 408 413 422 + Modeline "640x360" 14.75 640 664 720 800 360 363 368 374 + #common resolutions for android devices (both orientations): + Modeline "800x1280" 25.89 800 832 928 960 1280 1310 1315 1345 + Modeline "1280x800" 24.15 1280 1312 1400 1432 800 819 822 841 + Modeline "720x1280" 30.22 720 752 864 896 1280 1309 1315 1345 + Modeline "1280x720" 27.41 1280 1312 1416 1448 720 737 740 757 + Modeline "768x1024" 24.93 768 800 888 920 1024 1047 1052 1076 + Modeline "1024x768" 23.77 1024 1056 1144 1176 768 785 789 807 + Modeline "600x1024" 19.90 600 632 704 736 1024 1047 1052 1076 + Modeline "1024x600" 18.26 1024 1056 1120 1152 600 614 617 631 + Modeline "536x960" 16.74 536 568 624 656 960 982 986 1009 + Modeline "960x536" 15.23 960 992 1048 1080 536 548 551 563 + Modeline "600x800" 15.17 600 632 688 720 800 818 822 841 + Modeline "800x600" 14.50 800 832 880 912 600 614 617 631 + Modeline "480x854" 13.34 480 512 560 592 854 873 877 897 + Modeline "848x480" 12.09 848 880 920 952 480 491 493 505 + Modeline "480x800" 12.43 480 512 552 584 800 818 822 841 + Modeline "800x480" 11.46 800 832 872 904 480 491 493 505 + #resolutions for android devices (both orientations) + #minus the status bar + #38px status bar (and width rounded up) + Modeline "800x1242" 25.03 800 832 920 952 1242 1271 1275 1305 + Modeline "1280x762" 22.93 1280 1312 1392 1424 762 780 783 801 + Modeline "720x1242" 29.20 720 752 856 888 1242 1271 1276 1305 + Modeline "1280x682" 25.85 1280 1312 1408 1440 682 698 701 717 + Modeline "768x986" 23.90 768 800 888 920 986 1009 1013 1036 + Modeline "1024x730" 22.50 1024 1056 1136 1168 730 747 750 767 + Modeline "600x986" 19.07 600 632 704 736 986 1009 1013 1036 + Modeline "1024x562" 17.03 1024 1056 1120 1152 562 575 578 591 + Modeline "536x922" 16.01 536 568 624 656 922 943 947 969 + Modeline "960x498" 14.09 960 992 1040 1072 498 509 511 523 + Modeline "600x762" 14.39 600 632 680 712 762 779 783 801 + Modeline "800x562" 13.52 800 832 880 912 562 575 578 591 + Modeline "480x810" 12.59 480 512 552 584 810 828 832 851 + Modeline "848x442" 11.09 848 880 920 952 442 452 454 465 + Modeline "480x762" 11.79 480 512 552 584 762 779 783 801 + ''; + + services.xserver.resolutions = [ + {x="8192"; y="4096";} + {x="5120"; y="3200";} + {x="3840"; y="2880";} + {x="3840"; y="2560";} + {x="3840"; y="2048";} + {x="3840"; y="2160";} + {x="2048"; y="2048";} + {x="2560"; y="1600";} + {x="1920"; y="1440";} + {x="1920"; y="1200";} + {x="1920"; y="1080";} + {x="1600"; y="1200";} + {x="1680"; y="1050";} + {x="1600"; y="900";} + {x="1400"; y="1050";} + {x="1440"; y="900";} + {x="1280"; y="1024";} + {x="1366"; y="768";} + {x="1280"; y="800";} + {x="1024"; y="768";} + {x="1024"; y="600";} + {x="800"; y="600";} + {x="320"; y="200";} + ]; + + services.xserver.serverFlagsSection = '' + Option "DontVTSwitch" "true" + Option "PciForceNone" "true" + Option "AutoEnableDevices" "false" + Option "AutoAddDevices" "false" + ''; + + services.xserver.deviceSection = '' + VideoRam 192000 + ''; + + services.xserver.displayManager.job.execCmd = '' + ${optionalString (cfg.pulseaudio) + "export PULSE_COOKIE=/run/pulse/.config/pulse/cookie"} + exec ${pkgs.xpra}/bin/xpra start \ + --daemon=off \ + --log-dir=/var/log \ + --log-file=xpra.log \ + --opengl=on \ + --clipboard=on \ + --notifications=on \ + --speaker=yes \ + --mdns=no \ + --pulseaudio=no \ + ${optionalString (cfg.pulseaudio) "--sound-source=pulse"} \ + --socket-dirs=/run/xpra \ + --xvfb="xpra_Xdummy ${concatStringsSep " " dmcfg.xserverArgs}" \ + ${optionalString (cfg.bindTcp != null) "--bind-tcp=${cfg.bindTcp}"} \ + --auth=${cfg.auth} \ + ${concatStringsSep " " cfg.extraOptions} + ''; + + services.xserver.terminateOnReset = false; + + environment.systemPackages = [pkgs.xpra]; + + virtualisation.virtualbox.guest.x11 = false; + hardware.pulseaudio.enable = mkDefault cfg.pulseaudio; + hardware.pulseaudio.systemWide = mkDefault cfg.pulseaudio; + }; + +} diff --git a/nixpkgs/nixos/modules/services/x11/extra-layouts.nix b/nixpkgs/nixos/modules/services/x11/extra-layouts.nix new file mode 100644 index 00000000000..1af98a1318b --- /dev/null +++ b/nixpkgs/nixos/modules/services/x11/extra-layouts.nix @@ -0,0 +1,168 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + layouts = config.services.xserver.extraLayouts; + + layoutOpts = { + options = { + description = mkOption { + type = types.str; + description = "A short description of the layout."; + }; + + languages = mkOption { + type = types.listOf types.str; + description = + '' + A list of languages provided by the layout. + (Use ISO 639-2 codes, for example: "eng" for english) + ''; + }; + + compatFile = mkOption { + type = types.nullOr types.path; + default = null; + description = '' + The path to the xkb compat file. + This file sets the compatibility state, used to preserve + compatibility with xkb-unaware programs. + It must contain a <literal>xkb_compat "name" { ... }</literal> block. + ''; + }; + + geometryFile = mkOption { + type = types.nullOr types.path; + default = null; + description = '' + The path to the xkb geometry file. + This (completely optional) file describes the physical layout of + keyboard, which maybe be used by programs to depict it. + It must contain a <literal>xkb_geometry "name" { ... }</literal> block. + ''; + }; + + keycodesFile = mkOption { + type = types.nullOr types.path; + default = null; + description = '' + The path to the xkb keycodes file. + This file specifies the range and the interpretation of the raw + keycodes sent by the keyboard. + It must contain a <literal>xkb_keycodes "name" { ... }</literal> block. + ''; + }; + + symbolsFile = mkOption { + type = types.nullOr types.path; + default = null; + description = '' + The path to the xkb symbols file. + This is the most important file: it defines which symbol or action + maps to each key and must contain a + <literal>xkb_symbols "name" { ... }</literal> block. + ''; + }; + + typesFile = mkOption { + type = types.nullOr types.path; + default = null; + description = '' + The path to the xkb types file. + This file specifies the key types that can be associated with + the various keyboard keys. + It must contain a <literal>xkb_types "name" { ... }</literal> block. + ''; + }; + + }; + }; + +in + +{ + + ###### interface + + options.services.xserver = { + extraLayouts = mkOption { + type = types.attrsOf (types.submodule layoutOpts); + default = {}; + example = literalExample + '' + { + mine = { + description = "My custom xkb layout."; + languages = [ "eng" ]; + symbolsFile = /path/to/my/layout; + }; + } + ''; + description = '' + Extra custom layouts that will be included in the xkb configuration. + Information on how to create a new layout can be found here: + <link xlink:href="https://www.x.org/releases/current/doc/xorg-docs/input/XKB-Enhancing.html#Defining_New_Layouts"></link>. + For more examples see + <link xlink:href="https://wiki.archlinux.org/index.php/X_KeyBoard_extension#Basic_examples"></link> + ''; + }; + + }; + + ###### implementation + + config = mkIf (layouts != { }) { + + # We don't override xkeyboard_config directly to + # reduce the amount of packages to be recompiled. + # Only the following packages are necessary to set + # a custom layout anyway: + nixpkgs.overlays = lib.singleton (self: super: { + + xkb_patched = self.xorg.xkeyboardconfig_custom { + layouts = config.services.xserver.extraLayouts; + }; + + xorg = super.xorg // { + xorgserver = super.xorg.xorgserver.overrideAttrs (old: { + configureFlags = old.configureFlags ++ [ + "--with-xkb-bin-directory=${self.xorg.xkbcomp}/bin" + "--with-xkb-path=${self.xkb_patched}/share/X11/xkb" + ]; + }); + + setxkbmap = super.xorg.setxkbmap.overrideAttrs (old: { + postInstall = + '' + mkdir -p $out/share + ln -sfn ${self.xkb_patched}/etc/X11 $out/share/X11 + ''; + }); + + xkbcomp = super.xorg.xkbcomp.overrideAttrs (old: { + configureFlags = "--with-xkb-config-root=${self.xkb_patched}/share/X11/xkb"; + }); + + }; + + ckbcomp = super.ckbcomp.override { + xkeyboard_config = self.xkb_patched; + }; + + xkbvalidate = super.xkbvalidate.override { + libxkbcommon = self.libxkbcommon.override { + xkeyboard_config = self.xkb_patched; + }; + }; + + }); + + services.xserver = { + xkbDir = "${pkgs.xkb_patched}/etc/X11/xkb"; + exportConfiguration = config.services.xserver.displayManager.startx.enable; + }; + + }; + +} diff --git a/nixpkgs/nixos/modules/services/x11/fractalart.nix b/nixpkgs/nixos/modules/services/x11/fractalart.nix new file mode 100644 index 00000000000..448248a5879 --- /dev/null +++ b/nixpkgs/nixos/modules/services/x11/fractalart.nix @@ -0,0 +1,36 @@ +{ config, lib, pkgs, ... }: +with lib; +let + cfg = config.services.fractalart; +in { + options.services.fractalart = { + enable = mkOption { + type = types.bool; + default = false; + example = true; + description = "Enable FractalArt for generating colorful wallpapers on login"; + }; + + width = mkOption { + type = types.nullOr types.int; + default = null; + example = 1920; + description = "Screen width"; + }; + + height = mkOption { + type = types.nullOr types.int; + default = null; + example = 1080; + description = "Screen height"; + }; + }; + + config = mkIf cfg.enable { + environment.systemPackages = [ pkgs.haskellPackages.FractalArt ]; + services.xserver.displayManager.sessionCommands = + "${pkgs.haskellPackages.FractalArt}/bin/FractalArt --no-bg -f .background-image" + + optionalString (cfg.width != null) " -w ${toString cfg.width}" + + optionalString (cfg.height != null) " -h ${toString cfg.height}"; + }; +} diff --git a/nixpkgs/nixos/modules/services/x11/gdk-pixbuf.nix b/nixpkgs/nixos/modules/services/x11/gdk-pixbuf.nix new file mode 100644 index 00000000000..9ad926369ec --- /dev/null +++ b/nixpkgs/nixos/modules/services/x11/gdk-pixbuf.nix @@ -0,0 +1,45 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + cfg = config.services.xserver.gdk-pixbuf; + + # Get packages to generate the cache for. We always include gdk-pixbuf. + effectivePackages = unique ([pkgs.gdk-pixbuf] ++ cfg.modulePackages); + + # Generate the cache file by running gdk-pixbuf-query-loaders for each + # package and concatenating the results. + loadersCache = pkgs.runCommand "gdk-pixbuf-loaders.cache" { preferLocalBuild = true; } '' + ( + for package in ${concatStringsSep " " effectivePackages}; do + module_dir="$package/${pkgs.gdk-pixbuf.moduleDir}" + if [[ ! -d $module_dir ]]; then + echo "Warning (services.xserver.gdk-pixbuf): missing module directory $module_dir" 1>&2 + continue + fi + GDK_PIXBUF_MODULEDIR="$module_dir" \ + ${pkgs.gdk-pixbuf.dev}/bin/gdk-pixbuf-query-loaders + done + ) > "$out" + ''; +in + +{ + options = { + services.xserver.gdk-pixbuf.modulePackages = mkOption { + type = types.listOf types.package; + default = [ ]; + description = "Packages providing GDK-Pixbuf modules, for cache generation."; + }; + }; + + # If there is any package configured in modulePackages, we generate the + # loaders.cache based on that and set the environment variable + # GDK_PIXBUF_MODULE_FILE to point to it. + config = mkIf (cfg.modulePackages != []) { + environment.variables = { + GDK_PIXBUF_MODULE_FILE = "${loadersCache}"; + }; + }; +} diff --git a/nixpkgs/nixos/modules/services/x11/hardware/cmt.nix b/nixpkgs/nixos/modules/services/x11/hardware/cmt.nix new file mode 100644 index 00000000000..95353e92098 --- /dev/null +++ b/nixpkgs/nixos/modules/services/x11/hardware/cmt.nix @@ -0,0 +1,54 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + +cfg = config.services.xserver.cmt; +etcPath = "X11/xorg.conf.d"; + +in { + + options = { + + services.xserver.cmt = { + enable = mkOption { + type = types.bool; + default = false; + description = "Enable chrome multitouch input (cmt). Touchpad drivers that are configured for chromebooks."; + }; + models = mkOption { + type = types.enum [ "atlas" "banjo" "candy" "caroline" "cave" "celes" "clapper" "cyan" "daisy" "elan" "elm" "enguarde" "eve" "expresso" "falco" "gandof" "glimmer" "gnawty" "heli" "kevin" "kip" "leon" "lulu" "orco" "pbody" "peppy" "pi" "pit" "puppy" "quawks" "rambi" "samus" "snappy" "spring" "squawks" "swanky" "winky" "wolf" "auron_paine" "auron_yuna" "daisy_skate" "nyan_big" "nyan_blaze" "veyron_jaq" "veyron_jerry" "veyron_mighty" "veyron_minnie" "veyron_speedy" ]; + example = "banjo"; + description = '' + Which models to enable cmt for. Enter the Code Name for your Chromebook. + Code Name can be found at <link xlink:href="https://www.chromium.org/chromium-os/developer-information-for-chrome-os-devices" />. + ''; + }; + }; #closes services + }; #closes options + + config = mkIf cfg.enable { + + services.xserver.modules = [ pkgs.xf86_input_cmt ]; + + environment.etc = { + "${etcPath}/40-touchpad-cmt.conf" = { + source = "${pkgs.chromium-xorg-conf}/40-touchpad-cmt.conf"; + }; + "${etcPath}/50-touchpad-cmt-${cfg.models}.conf" = { + source = "${pkgs.chromium-xorg-conf}/50-touchpad-cmt-${cfg.models}.conf"; + }; + "${etcPath}/60-touchpad-cmt-${cfg.models}.conf" = { + source = "${pkgs.chromium-xorg-conf}/60-touchpad-cmt-${cfg.models}.conf"; + }; + }; + + assertions = [ + { + assertion = !config.services.xserver.libinput.enable; + message = "cmt and libinput are incompatible, you cannot enable both (in services.xserver)."; + } + ]; + }; +} diff --git a/nixpkgs/nixos/modules/services/x11/hardware/libinput.nix b/nixpkgs/nixos/modules/services/x11/hardware/libinput.nix new file mode 100644 index 00000000000..bd289976532 --- /dev/null +++ b/nixpkgs/nixos/modules/services/x11/hardware/libinput.nix @@ -0,0 +1,247 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let cfg = config.services.xserver.libinput; + xorgBool = v: if v then "on" else "off"; +in { + + options = { + + services.xserver.libinput = { + + enable = mkEnableOption "libinput"; + + dev = mkOption { + type = types.nullOr types.str; + default = null; + example = "/dev/input/event0"; + description = + '' + Path for touchpad device. Set to null to apply to any + auto-detected touchpad. + ''; + }; + + accelProfile = mkOption { + type = types.enum [ "flat" "adaptive" ]; + default = "adaptive"; + example = "flat"; + description = + '' + Sets the pointer acceleration profile to the given profile. + Permitted values are adaptive, flat. + Not all devices support this option or all profiles. + If a profile is unsupported, the default profile for this is used. + <literal>flat</literal>: Pointer motion is accelerated by a constant + (device-specific) factor, depending on the current speed. + <literal>adaptive</literal>: Pointer acceleration depends on the input speed. + This is the default profile for most devices. + ''; + }; + + accelSpeed = mkOption { + type = types.nullOr types.str; + default = null; + description = "Cursor acceleration (how fast speed increases from minSpeed to maxSpeed)."; + }; + + buttonMapping = mkOption { + type = types.nullOr types.str; + default = null; + description = + '' + Sets the logical button mapping for this device, see XSetPointerMapping(3). The string must + be a space-separated list of button mappings in the order of the logical buttons on the + device, starting with button 1. The default mapping is "1 2 3 ... 32". A mapping of 0 deac‐ + tivates the button. Multiple buttons can have the same mapping. Invalid mapping strings are + discarded and the default mapping is used for all buttons. Buttons not specified in the + user's mapping use the default mapping. See section BUTTON MAPPING for more details. + ''; + }; + + calibrationMatrix = mkOption { + type = types.nullOr types.str; + default = null; + description = + '' + A string of 9 space-separated floating point numbers. Sets the calibration matrix to the + 3x3 matrix where the first row is (abc), the second row is (def) and the third row is (ghi). + ''; + }; + + clickMethod = mkOption { + type = types.nullOr (types.enum [ "none" "buttonareas" "clickfinger" ]); + default = null; + description = + '' + Enables a click method. Permitted values are <literal>none</literal>, + <literal>buttonareas</literal>, <literal>clickfinger</literal>. + Not all devices support all methods, if an option is unsupported, + the default click method for this device is used. + ''; + }; + + leftHanded = mkOption { + type = types.bool; + default = false; + description = "Enables left-handed button orientation, i.e. swapping left and right buttons."; + }; + + middleEmulation = mkOption { + type = types.bool; + default = true; + description = + '' + Enables middle button emulation. When enabled, pressing the left and right buttons + simultaneously produces a middle mouse button click. + ''; + }; + + naturalScrolling = mkOption { + type = types.bool; + default = false; + description = "Enables or disables natural scrolling behavior."; + }; + + scrollButton = mkOption { + type = types.nullOr types.int; + default = null; + example = 1; + description = + '' + Designates a button as scroll button. If the ScrollMethod is button and the button is logically + held down, x/y axis movement is converted into scroll events. + ''; + }; + + scrollMethod = mkOption { + type = types.enum [ "twofinger" "edge" "button" "none" ]; + default = "twofinger"; + example = "edge"; + description = + '' + Specify the scrolling method: <literal>twofinger</literal>, <literal>edge</literal>, + or <literal>none</literal> + ''; + }; + + horizontalScrolling = mkOption { + type = types.bool; + default = true; + description = + '' + Disables horizontal scrolling. When disabled, this driver will discard any horizontal scroll + events from libinput. Note that this does not disable horizontal scrolling, it merely + discards the horizontal axis from any scroll events. + ''; + }; + + sendEventsMode = mkOption { + type = types.enum [ "disabled" "enabled" "disabled-on-external-mouse" ]; + default = "enabled"; + example = "disabled"; + description = + '' + Sets the send events mode to <literal>disabled</literal>, <literal>enabled</literal>, + or <literal>disabled-on-external-mouse</literal> + ''; + }; + + tapping = mkOption { + type = types.bool; + default = true; + description = + '' + Enables or disables tap-to-click behavior. + ''; + }; + + tappingDragLock = mkOption { + type = types.bool; + default = true; + description = + '' + Enables or disables drag lock during tapping behavior. When enabled, a finger up during tap- + and-drag will not immediately release the button. If the finger is set down again within the + timeout, the draging process continues. + ''; + }; + + disableWhileTyping = mkOption { + type = types.bool; + default = false; + description = + '' + Disable input method while typing. + ''; + }; + + additionalOptions = mkOption { + type = types.lines; + default = ""; + example = + '' + Option "DragLockButtons" "L1 B1 L2 B2" + ''; + description = "Additional options for libinput touchpad driver."; + }; + + }; + + }; + + + config = mkIf cfg.enable { + + services.xserver.modules = [ pkgs.xorg.xf86inputlibinput ]; + + environment.systemPackages = [ pkgs.xorg.xf86inputlibinput ]; + + environment.etc = [ + (let cfgPath = "X11/xorg.conf.d/40-libinput.conf"; in { + source = pkgs.xorg.xf86inputlibinput.out + "/share/" + cfgPath; + target = cfgPath; + }) + ]; + + services.udev.packages = [ pkgs.libinput.out ]; + + services.xserver.config = + '' + # Automatically enable the libinput driver for all touchpads. + Section "InputClass" + Identifier "libinputConfiguration" + MatchIsTouchpad "on" + ${optionalString (cfg.dev != null) ''MatchDevicePath "${cfg.dev}"''} + Driver "libinput" + Option "AccelProfile" "${cfg.accelProfile}" + ${optionalString (cfg.accelSpeed != null) ''Option "AccelSpeed" "${cfg.accelSpeed}"''} + ${optionalString (cfg.buttonMapping != null) ''Option "ButtonMapping" "${cfg.buttonMapping}"''} + ${optionalString (cfg.calibrationMatrix != null) ''Option "CalibrationMatrix" "${cfg.calibrationMatrix}"''} + ${optionalString (cfg.clickMethod != null) ''Option "ClickMethod" "${cfg.clickMethod}"''} + Option "LeftHanded" "${xorgBool cfg.leftHanded}" + Option "MiddleEmulation" "${xorgBool cfg.middleEmulation}" + Option "NaturalScrolling" "${xorgBool cfg.naturalScrolling}" + ${optionalString (cfg.scrollButton != null) ''Option "ScrollButton" "${toString cfg.scrollButton}"''} + Option "ScrollMethod" "${cfg.scrollMethod}" + Option "HorizontalScrolling" "${xorgBool cfg.horizontalScrolling}" + Option "SendEventsMode" "${cfg.sendEventsMode}" + Option "Tapping" "${xorgBool cfg.tapping}" + Option "TappingDragLock" "${xorgBool cfg.tappingDragLock}" + Option "DisableWhileTyping" "${xorgBool cfg.disableWhileTyping}" + ${cfg.additionalOptions} + EndSection + ''; + + assertions = [ + # already present in synaptics.nix + /* { + assertion = !config.services.xserver.synaptics.enable; + message = "Synaptics and libinput are incompatible, you cannot enable both (in services.xserver)."; + } */ + ]; + + }; + +} diff --git a/nixpkgs/nixos/modules/services/x11/hardware/multitouch.nix b/nixpkgs/nixos/modules/services/x11/hardware/multitouch.nix new file mode 100644 index 00000000000..c03bb3b494f --- /dev/null +++ b/nixpkgs/nixos/modules/services/x11/hardware/multitouch.nix @@ -0,0 +1,94 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let cfg = config.services.xserver.multitouch; + disabledTapConfig = '' + Option "MaxTapTime" "0" + Option "MaxTapMove" "0" + Option "TapButton1" "0" + Option "TapButton2" "0" + Option "TapButton3" "0" + ''; +in { + + options = { + + services.xserver.multitouch = { + + enable = mkOption { + default = false; + description = "Whether to enable multitouch touchpad support."; + }; + + invertScroll = mkOption { + default = false; + type = types.bool; + description = "Whether to invert scrolling direction à la OSX Lion"; + }; + + ignorePalm = mkOption { + default = false; + type = types.bool; + description = "Whether to ignore touches detected as being the palm (i.e when typing)"; + }; + + tapButtons = mkOption { + type = types.bool; + default = true; + description = "Whether to enable tap buttons."; + }; + + buttonsMap = mkOption { + type = types.listOf types.int; + default = [3 2 0]; + example = [1 3 2]; + description = "Remap touchpad buttons."; + apply = map toString; + }; + + additionalOptions = mkOption { + type = types.str; + default = ""; + example = '' + Option "ScaleDistance" "50" + Option "RotateDistance" "60" + ''; + description = '' + Additional options for mtrack touchpad driver. + ''; + }; + + }; + + }; + + config = mkIf cfg.enable { + + services.xserver.modules = [ pkgs.xf86_input_mtrack ]; + + services.xserver.config = + '' + # Automatically enable the multitouch driver + Section "InputClass" + MatchIsTouchpad "on" + Identifier "Touchpads" + Driver "mtrack" + Option "IgnorePalm" "${boolToString cfg.ignorePalm}" + Option "ClickFinger1" "${builtins.elemAt cfg.buttonsMap 0}" + Option "ClickFinger2" "${builtins.elemAt cfg.buttonsMap 1}" + Option "ClickFinger3" "${builtins.elemAt cfg.buttonsMap 2}" + ${optionalString (!cfg.tapButtons) disabledTapConfig} + ${optionalString cfg.invertScroll '' + Option "ScrollUpButton" "5" + Option "ScrollDownButton" "4" + Option "ScrollLeftButton" "7" + Option "ScrollRightButton" "6" + ''} + ${cfg.additionalOptions} + EndSection + ''; + + }; + +} diff --git a/nixpkgs/nixos/modules/services/x11/hardware/synaptics.nix b/nixpkgs/nixos/modules/services/x11/hardware/synaptics.nix new file mode 100644 index 00000000000..22af869f1f8 --- /dev/null +++ b/nixpkgs/nixos/modules/services/x11/hardware/synaptics.nix @@ -0,0 +1,213 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let cfg = config.services.xserver.synaptics; + tapConfig = if cfg.tapButtons then enabledTapConfig else disabledTapConfig; + enabledTapConfig = '' + Option "MaxTapTime" "180" + Option "MaxTapMove" "220" + Option "TapButton1" "${builtins.elemAt cfg.fingersMap 0}" + Option "TapButton2" "${builtins.elemAt cfg.fingersMap 1}" + Option "TapButton3" "${builtins.elemAt cfg.fingersMap 2}" + ''; + disabledTapConfig = '' + Option "MaxTapTime" "0" + Option "MaxTapMove" "0" + Option "TapButton1" "0" + Option "TapButton2" "0" + Option "TapButton3" "0" + ''; + pkg = pkgs.xorg.xf86inputsynaptics; + etcFile = "X11/xorg.conf.d/70-synaptics.conf"; +in { + + options = { + + services.xserver.synaptics = { + + enable = mkOption { + type = types.bool; + default = false; + description = "Whether to enable touchpad support. Deprecated: Consider services.xserver.libinput.enable."; + }; + + dev = mkOption { + type = types.nullOr types.str; + default = null; + example = "/dev/input/event0"; + description = + '' + Path for touchpad device. Set to null to apply to any + auto-detected touchpad. + ''; + }; + + accelFactor = mkOption { + type = types.nullOr types.str; + default = "0.001"; + description = "Cursor acceleration (how fast speed increases from minSpeed to maxSpeed)."; + }; + + minSpeed = mkOption { + type = types.nullOr types.str; + default = "0.6"; + description = "Cursor speed factor for precision finger motion."; + }; + + maxSpeed = mkOption { + type = types.nullOr types.str; + default = "1.0"; + description = "Cursor speed factor for highest-speed finger motion."; + }; + + scrollDelta = mkOption { + type = types.nullOr types.int; + default = null; + example = 75; + description = "Move distance of the finger for a scroll event."; + }; + + twoFingerScroll = mkOption { + type = types.bool; + default = false; + description = "Whether to enable two-finger drag-scrolling. Overridden by horizTwoFingerScroll and vertTwoFingerScroll."; + }; + + horizTwoFingerScroll = mkOption { + type = types.bool; + default = cfg.twoFingerScroll; + description = "Whether to enable horizontal two-finger drag-scrolling."; + }; + + vertTwoFingerScroll = mkOption { + type = types.bool; + default = cfg.twoFingerScroll; + description = "Whether to enable vertical two-finger drag-scrolling."; + }; + + horizEdgeScroll = mkOption { + type = types.bool; + default = ! cfg.horizTwoFingerScroll; + description = "Whether to enable horizontal edge drag-scrolling."; + }; + + vertEdgeScroll = mkOption { + type = types.bool; + default = ! cfg.vertTwoFingerScroll; + description = "Whether to enable vertical edge drag-scrolling."; + }; + + tapButtons = mkOption { + type = types.bool; + default = true; + description = "Whether to enable tap buttons."; + }; + + buttonsMap = mkOption { + type = types.listOf types.int; + default = [1 2 3]; + example = [1 3 2]; + description = "Remap touchpad buttons."; + apply = map toString; + }; + + fingersMap = mkOption { + type = types.listOf types.int; + default = [1 2 3]; + example = [1 3 2]; + description = "Remap several-fingers taps."; + apply = map toString; + }; + + palmDetect = mkOption { + type = types.bool; + default = false; + description = "Whether to enable palm detection (hardware support required)"; + }; + + palmMinWidth = mkOption { + type = types.nullOr types.int; + default = null; + example = 5; + description = "Minimum finger width at which touch is considered a palm"; + }; + + palmMinZ = mkOption { + type = types.nullOr types.int; + default = null; + example = 20; + description = "Minimum finger pressure at which touch is considered a palm"; + }; + + horizontalScroll = mkOption { + type = types.bool; + default = true; + description = "Whether to enable horizontal scrolling (on touchpad)"; + }; + + additionalOptions = mkOption { + type = types.str; + default = ""; + example = '' + Option "RTCornerButton" "2" + Option "RBCornerButton" "3" + ''; + description = '' + Additional options for synaptics touchpad driver. + ''; + }; + + }; + + }; + + + config = mkIf cfg.enable { + + services.xserver.modules = [ pkg.out ]; + + environment.etc.${etcFile}.source = + "${pkg.out}/share/X11/xorg.conf.d/70-synaptics.conf"; + + environment.systemPackages = [ pkg ]; + + services.xserver.config = + '' + # Automatically enable the synaptics driver for all touchpads. + Section "InputClass" + Identifier "synaptics touchpad catchall" + MatchIsTouchpad "on" + ${optionalString (cfg.dev != null) ''MatchDevicePath "${cfg.dev}"''} + Driver "synaptics" + ${optionalString (cfg.minSpeed != null) ''Option "MinSpeed" "${cfg.minSpeed}"''} + ${optionalString (cfg.maxSpeed != null) ''Option "MaxSpeed" "${cfg.maxSpeed}"''} + ${optionalString (cfg.accelFactor != null) ''Option "AccelFactor" "${cfg.accelFactor}"''} + ${optionalString cfg.tapButtons tapConfig} + Option "ClickFinger1" "${builtins.elemAt cfg.buttonsMap 0}" + Option "ClickFinger2" "${builtins.elemAt cfg.buttonsMap 1}" + Option "ClickFinger3" "${builtins.elemAt cfg.buttonsMap 2}" + Option "VertTwoFingerScroll" "${if cfg.vertTwoFingerScroll then "1" else "0"}" + Option "HorizTwoFingerScroll" "${if cfg.horizTwoFingerScroll then "1" else "0"}" + Option "VertEdgeScroll" "${if cfg.vertEdgeScroll then "1" else "0"}" + Option "HorizEdgeScroll" "${if cfg.horizEdgeScroll then "1" else "0"}" + ${optionalString cfg.palmDetect ''Option "PalmDetect" "1"''} + ${optionalString (cfg.palmMinWidth != null) ''Option "PalmMinWidth" "${toString cfg.palmMinWidth}"''} + ${optionalString (cfg.palmMinZ != null) ''Option "PalmMinZ" "${toString cfg.palmMinZ}"''} + ${optionalString (cfg.scrollDelta != null) ''Option "VertScrollDelta" "${toString cfg.scrollDelta}"''} + ${if !cfg.horizontalScroll then ''Option "HorizScrollDelta" "0"'' + else (optionalString (cfg.scrollDelta != null) ''Option "HorizScrollDelta" "${toString cfg.scrollDelta}"'')} + ${cfg.additionalOptions} + EndSection + ''; + + assertions = [ + { + assertion = !config.services.xserver.libinput.enable; + message = "Synaptics and libinput are incompatible, you cannot enable both (in services.xserver)."; + } + ]; + + }; + +} diff --git a/nixpkgs/nixos/modules/services/x11/hardware/wacom.nix b/nixpkgs/nixos/modules/services/x11/hardware/wacom.nix new file mode 100644 index 00000000000..a27889c36a7 --- /dev/null +++ b/nixpkgs/nixos/modules/services/x11/hardware/wacom.nix @@ -0,0 +1,47 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + + cfg = config.services.xserver.wacom; + +in + +{ + + options = { + + services.xserver.wacom = { + + enable = mkOption { + default = false; + description = '' + Whether to enable the Wacom touchscreen/digitizer/tablet. + If you ever have any issues such as, try switching to terminal (ctrl-alt-F1) and back + which will make Xorg reconfigure the device ? + + If you're not satisfied by the default behaviour you can override + <option>environment.etc."X11/xorg.conf.d/70-wacom.conf"</option> in + configuration.nix easily. + ''; + }; + + }; + + }; + + + config = mkIf cfg.enable { + + environment.systemPackages = [ pkgs.xf86_input_wacom ]; # provides xsetwacom + + services.xserver.modules = [ pkgs.xf86_input_wacom ]; + + services.udev.packages = [ pkgs.xf86_input_wacom ]; + + environment.etc."X11/xorg.conf.d/70-wacom.conf".source = "${pkgs.xf86_input_wacom}/share/X11/xorg.conf.d/70-wacom.conf"; + + }; + +} diff --git a/nixpkgs/nixos/modules/services/x11/redshift.nix b/nixpkgs/nixos/modules/services/x11/redshift.nix new file mode 100644 index 00000000000..21b0b33553a --- /dev/null +++ b/nixpkgs/nixos/modules/services/x11/redshift.nix @@ -0,0 +1,129 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + + cfg = config.services.redshift; + lcfg = config.location; + +in { + + imports = [ + (mkChangedOptionModule [ "services" "redshift" "latitude" ] [ "location" "latitude" ] + (config: + let value = getAttrFromPath [ "services" "redshift" "latitude" ] config; + in if value == null then + throw "services.redshift.latitude is set to null, you can remove this" + else builtins.fromJSON value)) + (mkChangedOptionModule [ "services" "redshift" "longitude" ] [ "location" "longitude" ] + (config: + let value = getAttrFromPath [ "services" "redshift" "longitude" ] config; + in if value == null then + throw "services.redshift.longitude is set to null, you can remove this" + else builtins.fromJSON value)) + (mkRenamedOptionModule [ "services" "redshift" "provider" ] [ "location" "provider" ]) + ]; + + options.services.redshift = { + enable = mkOption { + type = types.bool; + default = false; + description = '' + Enable Redshift to change your screen's colour temperature depending on + the time of day. + ''; + }; + + temperature = { + day = mkOption { + type = types.int; + default = 5500; + description = '' + Colour temperature to use during the day, between + <literal>1000</literal> and <literal>25000</literal> K. + ''; + }; + night = mkOption { + type = types.int; + default = 3700; + description = '' + Colour temperature to use at night, between + <literal>1000</literal> and <literal>25000</literal> K. + ''; + }; + }; + + brightness = { + day = mkOption { + type = types.str; + default = "1"; + description = '' + Screen brightness to apply during the day, + between <literal>0.1</literal> and <literal>1.0</literal>. + ''; + }; + night = mkOption { + type = types.str; + default = "1"; + description = '' + Screen brightness to apply during the night, + between <literal>0.1</literal> and <literal>1.0</literal>. + ''; + }; + }; + + package = mkOption { + type = types.package; + default = pkgs.redshift; + defaultText = "pkgs.redshift"; + description = '' + redshift derivation to use. + ''; + }; + + extraOptions = mkOption { + type = types.listOf types.str; + default = []; + example = [ "-v" "-m randr" ]; + description = '' + Additional command-line arguments to pass to + <command>redshift</command>. + ''; + }; + }; + + config = mkIf cfg.enable { + # needed so that .desktop files are installed, which geoclue cares about + environment.systemPackages = [ cfg.package ]; + + services.geoclue2.appConfig.redshift = { + isAllowed = true; + isSystem = true; + }; + + systemd.user.services.redshift = + let + providerString = if lcfg.provider == "manual" + then "${toString lcfg.latitude}:${toString lcfg.longitude}" + else lcfg.provider; + in + { + description = "Redshift colour temperature adjuster"; + wantedBy = [ "graphical-session.target" ]; + partOf = [ "graphical-session.target" ]; + serviceConfig = { + ExecStart = '' + ${cfg.package}/bin/redshift \ + -l ${providerString} \ + -t ${toString cfg.temperature.day}:${toString cfg.temperature.night} \ + -b ${toString cfg.brightness.day}:${toString cfg.brightness.night} \ + ${lib.strings.concatStringsSep " " cfg.extraOptions} + ''; + RestartSec = 3; + Restart = "always"; + }; + }; + }; + +} diff --git a/nixpkgs/nixos/modules/services/x11/terminal-server.nix b/nixpkgs/nixos/modules/services/x11/terminal-server.nix new file mode 100644 index 00000000000..503c14c9b62 --- /dev/null +++ b/nixpkgs/nixos/modules/services/x11/terminal-server.nix @@ -0,0 +1,56 @@ +# This module implements a terminal service based on ‘x11vnc’. It +# listens on port 5900 for VNC connections. It then presents a login +# screen to the user. If the user successfully authenticates, x11vnc +# checks to see if a X server is already running for that user. If +# not, a X server (Xvfb) is started for that user. The Xvfb instances +# persist across VNC sessions. + +{ lib, pkgs, ... }: + +with lib; + +{ + + config = { + + services.xserver.enable = true; + services.xserver.videoDrivers = []; + + # Enable GDM. Any display manager will do as long as it supports XDMCP. + services.xserver.displayManager.gdm.enable = true; + + systemd.sockets.terminal-server = + { description = "Terminal Server Socket"; + wantedBy = [ "sockets.target" ]; + before = [ "multi-user.target" ]; + socketConfig.Accept = true; + socketConfig.ListenStream = 5900; + }; + + systemd.services."terminal-server@" = + { description = "Terminal Server"; + + path = + [ pkgs.xorg.xorgserver.out pkgs.gawk pkgs.which pkgs.openssl pkgs.xorg.xauth + pkgs.nettools pkgs.shadow pkgs.procps pkgs.utillinux pkgs.bash + ]; + + environment.FD_GEOM = "1024x786x24"; + environment.FD_XDMCP_IF = "127.0.0.1"; + #environment.FIND_DISPLAY_OUTPUT = "/tmp/foo"; # to debug the "find display" script + + serviceConfig = + { StandardInput = "socket"; + StandardOutput = "socket"; + StandardError = "journal"; + ExecStart = "@${pkgs.x11vnc}/bin/x11vnc x11vnc -inetd -display WAIT:1024x786:cmd=FINDCREATEDISPLAY-Xvfb.xdmcp -unixpw -ssl SAVE"; + # Don't kill the X server when the user quits the VNC + # connection. FIXME: the X server should run in a + # separate systemd session. + KillMode = "process"; + }; + }; + + }; + +} diff --git a/nixpkgs/nixos/modules/services/x11/unclutter-xfixes.nix b/nixpkgs/nixos/modules/services/x11/unclutter-xfixes.nix new file mode 100644 index 00000000000..71262431b68 --- /dev/null +++ b/nixpkgs/nixos/modules/services/x11/unclutter-xfixes.nix @@ -0,0 +1,58 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let cfg = config.services.unclutter-xfixes; + +in { + options.services.unclutter-xfixes = { + + enable = mkOption { + description = "Enable unclutter-xfixes to hide your mouse cursor when inactive."; + type = types.bool; + default = false; + }; + + package = mkOption { + description = "unclutter-xfixes derivation to use."; + type = types.package; + default = pkgs.unclutter-xfixes; + defaultText = "pkgs.unclutter-xfixes"; + }; + + timeout = mkOption { + description = "Number of seconds before the cursor is marked inactive."; + type = types.int; + default = 1; + }; + + threshold = mkOption { + description = "Minimum number of pixels considered cursor movement."; + type = types.int; + default = 1; + }; + + extraOptions = mkOption { + description = "More arguments to pass to the unclutter-xfixes command."; + type = types.listOf types.str; + default = []; + example = [ "exclude-root" "ignore-scrolling" "fork" ]; + }; + }; + + config = mkIf cfg.enable { + systemd.user.services.unclutter-xfixes = { + description = "unclutter-xfixes"; + wantedBy = [ "graphical-session.target" ]; + partOf = [ "graphical-session.target" ]; + serviceConfig.ExecStart = '' + ${cfg.package}/bin/unclutter \ + --timeout ${toString cfg.timeout} \ + --jitter ${toString (cfg.threshold - 1)} \ + ${concatMapStrings (x: " --"+x) cfg.extraOptions} \ + ''; + serviceConfig.RestartSec = 3; + serviceConfig.Restart = "always"; + }; + }; +} diff --git a/nixpkgs/nixos/modules/services/x11/unclutter.nix b/nixpkgs/nixos/modules/services/x11/unclutter.nix new file mode 100644 index 00000000000..5f16a680050 --- /dev/null +++ b/nixpkgs/nixos/modules/services/x11/unclutter.nix @@ -0,0 +1,74 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let cfg = config.services.unclutter; + +in { + options.services.unclutter = { + + enable = mkOption { + description = "Enable unclutter to hide your mouse cursor when inactive"; + type = types.bool; + default = false; + }; + + package = mkOption { + type = types.package; + default = pkgs.unclutter; + defaultText = "pkgs.unclutter"; + description = "unclutter derivation to use."; + }; + + keystroke = mkOption { + description = "Wait for a keystroke before hiding the cursor"; + type = types.bool; + default = false; + }; + + timeout = mkOption { + description = "Number of seconds before the cursor is marked inactive"; + type = types.int; + default = 1; + }; + + threeshold = mkOption { + description = "Minimum number of pixels considered cursor movement"; + type = types.int; + default = 1; + }; + + excluded = mkOption { + description = "Names of windows where unclutter should not apply"; + type = types.listOf types.str; + default = []; + example = [ "" ]; + }; + + extraOptions = mkOption { + description = "More arguments to pass to the unclutter command"; + type = types.listOf types.str; + default = []; + example = [ "noevent" "grab" ]; + }; + }; + + config = mkIf cfg.enable { + systemd.user.services.unclutter = { + description = "unclutter"; + wantedBy = [ "graphical-session.target" ]; + partOf = [ "graphical-session.target" ]; + serviceConfig.ExecStart = '' + ${cfg.package}/bin/unclutter \ + -idle ${toString cfg.timeout} \ + -jitter ${toString (cfg.threeshold - 1)} \ + ${optionalString cfg.keystroke "-keystroke"} \ + ${concatMapStrings (x: " -"+x) cfg.extraOptions} \ + -not ${concatStringsSep " " cfg.excluded} \ + ''; + serviceConfig.PassEnvironment = "DISPLAY"; + serviceConfig.RestartSec = 3; + serviceConfig.Restart = "always"; + }; + }; +} diff --git a/nixpkgs/nixos/modules/services/x11/urxvtd.nix b/nixpkgs/nixos/modules/services/x11/urxvtd.nix new file mode 100644 index 00000000000..d916fa5bb39 --- /dev/null +++ b/nixpkgs/nixos/modules/services/x11/urxvtd.nix @@ -0,0 +1,48 @@ +{ config, lib, pkgs, ... }: + +# maintainer: siddharthist + +with lib; + +let + cfg = config.services.urxvtd; +in { + options.services.urxvtd = { + enable = mkOption { + type = types.bool; + default = false; + description = '' + Enable urxvtd, the urxvt terminal daemon. To use urxvtd, run + "urxvtc". + ''; + }; + + package = mkOption { + default = pkgs.rxvt_unicode-with-plugins; + defaultText = "pkgs.rxvt_unicode-with-plugins"; + description = '' + Package to install. Usually pkgs.rxvt_unicode-with-plugins or pkgs.rxvt_unicode + ''; + type = types.package; + }; + }; + + config = mkIf cfg.enable { + systemd.user.services.urxvtd = { + description = "urxvt terminal daemon"; + wantedBy = [ "graphical-session.target" ]; + partOf = [ "graphical-session.target" ]; + path = [ pkgs.xsel ]; + serviceConfig = { + ExecStart = "${cfg.package}/bin/urxvtd -o"; + Environment = "RXVT_SOCKET=%t/urxvtd-socket"; + Restart = "on-failure"; + RestartSec = "5s"; + }; + }; + + environment.systemPackages = [ cfg.package ]; + environment.variables.RXVT_SOCKET = "/run/user/$(id -u)/urxvtd-socket"; + }; + +} diff --git a/nixpkgs/nixos/modules/services/x11/window-managers/2bwm.nix b/nixpkgs/nixos/modules/services/x11/window-managers/2bwm.nix new file mode 100644 index 00000000000..fdbdf35b0f5 --- /dev/null +++ b/nixpkgs/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/nixpkgs/nixos/modules/services/x11/window-managers/afterstep.nix b/nixpkgs/nixos/modules/services/x11/window-managers/afterstep.nix new file mode 100644 index 00000000000..ba88a64c702 --- /dev/null +++ b/nixpkgs/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/nixpkgs/nixos/modules/services/x11/window-managers/awesome.nix b/nixpkgs/nixos/modules/services/x11/window-managers/awesome.nix new file mode 100644 index 00000000000..089e9f769f0 --- /dev/null +++ b/nixpkgs/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 = literalExample "[ luaPackages.oocairo ]"; + }; + + 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/nixpkgs/nixos/modules/services/x11/window-managers/bspwm.nix b/nixpkgs/nixos/modules/services/x11/window-managers/bspwm.nix new file mode 100644 index 00000000000..23cd4f6529a --- /dev/null +++ b/nixpkgs/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 = "pkgs.bspwm"; + example = "pkgs.bspwm-unstable"; + description = '' + bspwm package to use. + ''; + }; + configFile = mkOption { + type = with types; nullOr path; + example = "${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 = "pkgs.sxhkd"; + example = "pkgs.sxhkd-unstable"; + description = '' + sxhkd package to use. + ''; + }; + configFile = mkOption { + type = with types; nullOr path; + example = "${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/nixpkgs/nixos/modules/services/x11/window-managers/clfswm.nix b/nixpkgs/nixos/modules/services/x11/window-managers/clfswm.nix new file mode 100644 index 00000000000..176c1f46127 --- /dev/null +++ b/nixpkgs/nixos/modules/services/x11/window-managers/clfswm.nix @@ -0,0 +1,24 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + cfg = config.services.xserver.windowManager.clfswm; +in + +{ + options = { + services.xserver.windowManager.clfswm.enable = mkEnableOption "clfswm"; + }; + + config = mkIf cfg.enable { + services.xserver.windowManager.session = singleton { + name = "clfswm"; + start = '' + ${pkgs.clfswm}/bin/clfswm & + waitPID=$! + ''; + }; + environment.systemPackages = [ pkgs.clfswm ]; + }; +} diff --git a/nixpkgs/nixos/modules/services/x11/window-managers/default.nix b/nixpkgs/nixos/modules/services/x11/window-managers/default.nix new file mode 100644 index 00000000000..2a1f22fa9a4 --- /dev/null +++ b/nixpkgs/nixos/modules/services/x11/window-managers/default.nix @@ -0,0 +1,79 @@ +{ config, lib, ... }: + +with lib; + +let + cfg = config.services.xserver.windowManager; +in + +{ + imports = [ + ./2bwm.nix + ./afterstep.nix + ./bspwm.nix + ./dwm.nix + ./evilwm.nix + ./exwm.nix + ./fluxbox.nix + ./fvwm.nix + ./herbstluftwm.nix + ./i3.nix + ./jwm.nix + ./leftwm.nix + ./metacity.nix + ./mwm.nix + ./openbox.nix + ./pekwm.nix + ./notion.nix + ./ratpoison.nix + ./sawfish.nix + ./stumpwm.nix + ./spectrwm.nix + ./twm.nix + ./windowmaker.nix + ./wmii.nix + ./xmonad.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.str; + default = "none"; + example = "wmii"; + description = "Default window manager loaded if none have been chosen."; + apply = defaultWM: + if any (w: w.name == defaultWM) cfg.session then + defaultWM + else + throw "Default window manager (${defaultWM}) not found."; + }; + + }; + + }; + + config = { + services.xserver.displayManager.session = cfg.session; + }; +} diff --git a/nixpkgs/nixos/modules/services/x11/window-managers/dwm.nix b/nixpkgs/nixos/modules/services/x11/window-managers/dwm.nix new file mode 100644 index 00000000000..7777913ce1e --- /dev/null +++ b/nixpkgs/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/nixpkgs/nixos/modules/services/x11/window-managers/evilwm.nix b/nixpkgs/nixos/modules/services/x11/window-managers/evilwm.nix new file mode 100644 index 00000000000..6e19e3572c7 --- /dev/null +++ b/nixpkgs/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/nixpkgs/nixos/modules/services/x11/window-managers/exwm.nix b/nixpkgs/nixos/modules/services/x11/window-managers/exwm.nix new file mode 100644 index 00000000000..dc1d957c170 --- /dev/null +++ b/nixpkgs/nixos/modules/services/x11/window-managers/exwm.nix @@ -0,0 +1,54 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + cfg = config.services.xserver.windowManager.exwm; + loadScript = pkgs.writeText "emacs-exwm-load" '' + (require 'exwm) + ${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"; + enableDefaultConfig = mkOption { + default = true; + type = lib.types.bool; + description = "Enable an uncustomised exwm configuration."; + }; + extraPackages = mkOption { + default = self: []; + example = literalExample '' + 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>emacsPackages</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/nixpkgs/nixos/modules/services/x11/window-managers/fluxbox.nix b/nixpkgs/nixos/modules/services/x11/window-managers/fluxbox.nix new file mode 100644 index 00000000000..b409335702a --- /dev/null +++ b/nixpkgs/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/nixpkgs/nixos/modules/services/x11/window-managers/fvwm.nix b/nixpkgs/nixos/modules/services/x11/window-managers/fvwm.nix new file mode 100644 index 00000000000..9a51b9cd660 --- /dev/null +++ b/nixpkgs/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 { gestures = 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/nixpkgs/nixos/modules/services/x11/window-managers/herbstluftwm.nix b/nixpkgs/nixos/modules/services/x11/window-managers/herbstluftwm.nix new file mode 100644 index 00000000000..e3ea61cb9a6 --- /dev/null +++ b/nixpkgs/nixos/modules/services/x11/window-managers/herbstluftwm.nix @@ -0,0 +1,38 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + cfg = config.services.xserver.windowManager.herbstluftwm; +in + +{ + options = { + services.xserver.windowManager.herbstluftwm = { + enable = mkEnableOption "herbstluftwm"; + + 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 "${pkgs.herbstluftwm}/bin/herbstluftwm ${configFileClause}"; + }; + environment.systemPackages = [ pkgs.herbstluftwm ]; + }; +} diff --git a/nixpkgs/nixos/modules/services/x11/window-managers/i3.nix b/nixpkgs/nixos/modules/services/x11/window-managers/i3.nix new file mode 100644 index 00000000000..0ef55d5f2c0 --- /dev/null +++ b/nixpkgs/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 = "pkgs.i3"; + example = "pkgs.i3-gaps"; + description = '' + i3 package to use. + ''; + }; + + extraPackages = mkOption { + type = with types; listOf package; + default = with pkgs; [ dmenu i3status i3lock ]; + example = literalExample '' + 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/nixpkgs/nixos/modules/services/x11/window-managers/icewm.nix b/nixpkgs/nixos/modules/services/x11/window-managers/icewm.nix new file mode 100644 index 00000000000..f4ae9222df6 --- /dev/null +++ b/nixpkgs/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/nixpkgs/nixos/modules/services/x11/window-managers/jwm.nix b/nixpkgs/nixos/modules/services/x11/window-managers/jwm.nix new file mode 100644 index 00000000000..0e8dab2e922 --- /dev/null +++ b/nixpkgs/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/nixpkgs/nixos/modules/services/x11/window-managers/leftwm.nix b/nixpkgs/nixos/modules/services/x11/window-managers/leftwm.nix new file mode 100644 index 00000000000..3ef40df95df --- /dev/null +++ b/nixpkgs/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/nixpkgs/nixos/modules/services/x11/window-managers/metacity.nix b/nixpkgs/nixos/modules/services/x11/window-managers/metacity.nix new file mode 100644 index 00000000000..5175fd7f3b1 --- /dev/null +++ b/nixpkgs/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) gnome3; +in + +{ + options = { + services.xserver.windowManager.metacity.enable = mkEnableOption "metacity"; + }; + + config = mkIf cfg.enable { + + services.xserver.windowManager.session = singleton + { name = "metacity"; + start = '' + ${gnome3.metacity}/bin/metacity & + waitPID=$! + ''; + }; + + environment.systemPackages = [ gnome3.metacity ]; + + }; + +} diff --git a/nixpkgs/nixos/modules/services/x11/window-managers/mwm.nix b/nixpkgs/nixos/modules/services/x11/window-managers/mwm.nix new file mode 100644 index 00000000000..31f7b725f74 --- /dev/null +++ b/nixpkgs/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/nixpkgs/nixos/modules/services/x11/window-managers/none.nix b/nixpkgs/nixos/modules/services/x11/window-managers/none.nix new file mode 100644 index 00000000000..84cf1d77077 --- /dev/null +++ b/nixpkgs/nixos/modules/services/x11/window-managers/none.nix @@ -0,0 +1,12 @@ +{ + services = { + xserver = { + windowManager = { + session = [{ + name = "none"; + start = ""; + }]; + }; + }; + }; +} diff --git a/nixpkgs/nixos/modules/services/x11/window-managers/notion.nix b/nixpkgs/nixos/modules/services/x11/window-managers/notion.nix new file mode 100644 index 00000000000..4ece0d241c9 --- /dev/null +++ b/nixpkgs/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/nixpkgs/nixos/modules/services/x11/window-managers/openbox.nix b/nixpkgs/nixos/modules/services/x11/window-managers/openbox.nix new file mode 100644 index 00000000000..165772d1aa0 --- /dev/null +++ b/nixpkgs/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/nixpkgs/nixos/modules/services/x11/window-managers/oroborus.nix b/nixpkgs/nixos/modules/services/x11/window-managers/oroborus.nix new file mode 100644 index 00000000000..bd7e3396864 --- /dev/null +++ b/nixpkgs/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/nixpkgs/nixos/modules/services/x11/window-managers/pekwm.nix b/nixpkgs/nixos/modules/services/x11/window-managers/pekwm.nix new file mode 100644 index 00000000000..850335ce7dd --- /dev/null +++ b/nixpkgs/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/nixpkgs/nixos/modules/services/x11/window-managers/qtile.nix b/nixpkgs/nixos/modules/services/x11/window-managers/qtile.nix new file mode 100644 index 00000000000..ad3b65150b0 --- /dev/null +++ b/nixpkgs/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 & + waitPID=$! + ''; + }]; + + environment.systemPackages = [ pkgs.qtile ]; + }; +} diff --git a/nixpkgs/nixos/modules/services/x11/window-managers/ratpoison.nix b/nixpkgs/nixos/modules/services/x11/window-managers/ratpoison.nix new file mode 100644 index 00000000000..0d58481d457 --- /dev/null +++ b/nixpkgs/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/nixpkgs/nixos/modules/services/x11/window-managers/sawfish.nix b/nixpkgs/nixos/modules/services/x11/window-managers/sawfish.nix new file mode 100644 index 00000000000..b988b5e1829 --- /dev/null +++ b/nixpkgs/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/nixpkgs/nixos/modules/services/x11/window-managers/spectrwm.nix b/nixpkgs/nixos/modules/services/x11/window-managers/spectrwm.nix new file mode 100644 index 00000000000..a1dc298d242 --- /dev/null +++ b/nixpkgs/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/nixpkgs/nixos/modules/services/x11/window-managers/stumpwm.nix b/nixpkgs/nixos/modules/services/x11/window-managers/stumpwm.nix new file mode 100644 index 00000000000..27a17178476 --- /dev/null +++ b/nixpkgs/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/nixpkgs/nixos/modules/services/x11/window-managers/twm.nix b/nixpkgs/nixos/modules/services/x11/window-managers/twm.nix new file mode 100644 index 00000000000..fc09901aae3 --- /dev/null +++ b/nixpkgs/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/nixpkgs/nixos/modules/services/x11/window-managers/windowlab.nix b/nixpkgs/nixos/modules/services/x11/window-managers/windowlab.nix new file mode 100644 index 00000000000..fb891a39fa4 --- /dev/null +++ b/nixpkgs/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/nixpkgs/nixos/modules/services/x11/window-managers/windowmaker.nix b/nixpkgs/nixos/modules/services/x11/window-managers/windowmaker.nix new file mode 100644 index 00000000000..b6272375805 --- /dev/null +++ b/nixpkgs/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/nixpkgs/nixos/modules/services/x11/window-managers/wmii.nix b/nixpkgs/nixos/modules/services/x11/window-managers/wmii.nix new file mode 100644 index 00000000000..9b50a99bf23 --- /dev/null +++ b/nixpkgs/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/nixpkgs/nixos/modules/services/x11/window-managers/xmonad.nix b/nixpkgs/nixos/modules/services/x11/window-managers/xmonad.nix new file mode 100644 index 00000000000..0e131412276 --- /dev/null +++ b/nixpkgs/nixos/modules/services/x11/window-managers/xmonad.nix @@ -0,0 +1,97 @@ +{pkgs, lib, config, ...}: + +with lib; +let + inherit (lib) mkOption mkIf optionals literalExample; + cfg = config.services.xserver.windowManager.xmonad; + xmonad = pkgs.xmonad-with-packages.override { + ghcWithPackages = cfg.haskellPackages.ghcWithPackages; + packages = self: cfg.extraPackages self ++ + optionals cfg.enableContribAndExtras + [ self.xmonad-contrib self.xmonad-extras ]; + }; + xmonadBin = pkgs.writers.writeHaskell "xmonad" { + ghc = cfg.haskellPackages.ghc; + libraries = [ cfg.haskellPackages.xmonad ] ++ + cfg.extraPackages cfg.haskellPackages ++ + optionals cfg.enableContribAndExtras + (with cfg.haskellPackages; [ xmonad-contrib xmonad-extras ]); + } cfg.config; + +in +{ + options = { + services.xserver.windowManager.xmonad = { + enable = mkEnableOption "xmonad"; + haskellPackages = mkOption { + default = pkgs.haskellPackages; + defaultText = "pkgs.haskellPackages"; + example = literalExample "pkgs.haskell.packages.ghc784"; + 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 { + default = self: []; + defaultText = "self: []"; + example = literalExample '' + haskellPackages: [ + haskellPackages.xmonad-contrib + haskellPackages.monad-logger + ] + ''; + description = '' + Extra packages available to ghc when rebuilding Xmonad. The + value must be a function which receives the 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, the xmonad config from $HOME/.xmonad is taken. + If you use xmonad --recompile, $HOME/.xmonad will be taken as + the configuration, but on the next restart of display-manager + this config will be reapplied. + ''; + example = '' + import XMonad + + main = launch defaultConfig + { modMask = mod4Mask -- Use Super instead of Alt + , terminal = "urxvt" + } + ''; + }; + }; + }; + config = mkIf cfg.enable { + services.xserver.windowManager = { + session = [{ + name = "xmonad"; + start = if (cfg.config != null) then '' + ${xmonadBin} + waitPID=$! + '' else '' + ${xmonad}/bin/xmonad & + waitPID=$! + ''; + }]; + }; + + environment.systemPackages = [ xmonad ]; + }; +} diff --git a/nixpkgs/nixos/modules/services/x11/xautolock.nix b/nixpkgs/nixos/modules/services/x11/xautolock.nix new file mode 100644 index 00000000000..3e03131ca11 --- /dev/null +++ b/nixpkgs/nixos/modules/services/x11/xautolock.nix @@ -0,0 +1,140 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + cfg = config.services.xserver.xautolock; +in + { + options = { + services.xserver.xautolock = { + enable = mkEnableOption "xautolock"; + enableNotifier = mkEnableOption "xautolock.notify" // { + description = '' + Whether to enable the notifier feature of xautolock. + This publishes a notification before the autolock. + ''; + }; + + time = mkOption { + default = 15; + type = types.int; + + description = '' + Idle time (in minutes) to wait until xautolock locks the computer. + ''; + }; + + locker = mkOption { + default = "${pkgs.xlockmore}/bin/xlock"; # default according to `man xautolock` + example = "${pkgs.i3lock}/bin/i3lock -i /path/to/img"; + type = types.str; + + description = '' + The script to use when automatically locking the computer. + ''; + }; + + nowlocker = mkOption { + default = null; + example = "${pkgs.i3lock}/bin/i3lock -i /path/to/img"; + type = types.nullOr types.str; + + description = '' + The script to use when manually locking the computer with <command>xautolock -locknow</command>. + ''; + }; + + notify = mkOption { + default = 10; + type = types.int; + + description = '' + Time (in seconds) before the actual lock when the notification about the pending lock should be published. + ''; + }; + + notifier = mkOption { + default = null; + example = "${pkgs.libnotify}/bin/notify-send \"Locking in 10 seconds\""; + type = types.nullOr types.str; + + description = '' + Notification script to be used to warn about the pending autolock. + ''; + }; + + killer = mkOption { + default = null; # default according to `man xautolock` is none + example = "${pkgs.systemd}/bin/systemctl suspend"; + type = types.nullOr types.str; + + description = '' + The script to use when nothing has happend for as long as <option>killtime</option> + ''; + }; + + killtime = mkOption { + default = 20; # default according to `man xautolock` + type = types.int; + + description = '' + Minutes xautolock waits until it executes the script specified in <option>killer</option> + (Has to be at least 10 minutes) + ''; + }; + + extraOptions = mkOption { + type = types.listOf types.str; + default = [ ]; + example = [ "-detectsleep" ]; + description = '' + Additional command-line arguments to pass to + <command>xautolock</command>. + ''; + }; + }; + }; + + config = mkIf cfg.enable { + environment.systemPackages = with pkgs; [ xautolock ]; + systemd.user.services.xautolock = { + description = "xautolock service"; + wantedBy = [ "graphical-session.target" ]; + partOf = [ "graphical-session.target" ]; + serviceConfig = with lib; { + ExecStart = strings.concatStringsSep " " ([ + "${pkgs.xautolock}/bin/xautolock" + "-noclose" + "-time ${toString cfg.time}" + "-locker '${cfg.locker}'" + ] ++ optionals cfg.enableNotifier [ + "-notify ${toString cfg.notify}" + "-notifier '${cfg.notifier}'" + ] ++ optionals (cfg.nowlocker != null) [ + "-nowlocker '${cfg.nowlocker}'" + ] ++ optionals (cfg.killer != null) [ + "-killer '${cfg.killer}'" + "-killtime ${toString cfg.killtime}" + ] ++ cfg.extraOptions); + Restart = "always"; + }; + }; + assertions = [ + { + assertion = cfg.enableNotifier -> cfg.notifier != null; + message = "When enabling the notifier for xautolock, you also need to specify the notify script"; + } + { + assertion = cfg.killer != null -> cfg.killtime >= 10; + message = "killtime has to be at least 10 minutes according to `man xautolock`"; + } + ] ++ (lib.forEach [ "locker" "notifier" "nowlocker" "killer" ] + (option: + { + assertion = cfg.${option} != null -> builtins.substring 0 1 cfg.${option} == "/"; + message = "Please specify a canonical path for `services.xserver.xautolock.${option}`"; + }) + ); + }; + } diff --git a/nixpkgs/nixos/modules/services/x11/xbanish.nix b/nixpkgs/nixos/modules/services/x11/xbanish.nix new file mode 100644 index 00000000000..b95fac68f16 --- /dev/null +++ b/nixpkgs/nixos/modules/services/x11/xbanish.nix @@ -0,0 +1,31 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let cfg = config.services.xbanish; + +in { + options.services.xbanish = { + + enable = mkEnableOption "xbanish"; + + arguments = mkOption { + description = "Arguments to pass to xbanish command"; + default = ""; + example = "-d -i shift"; + type = types.str; + }; + }; + + config = mkIf cfg.enable { + systemd.user.services.xbanish = { + description = "xbanish hides the mouse pointer"; + wantedBy = [ "graphical-session.target" ]; + partOf = [ "graphical-session.target" ]; + serviceConfig.ExecStart = '' + ${pkgs.xbanish}/bin/xbanish ${cfg.arguments} + ''; + serviceConfig.Restart = "always"; + }; + }; +} diff --git a/nixpkgs/nixos/modules/services/x11/xfs.conf b/nixpkgs/nixos/modules/services/x11/xfs.conf new file mode 100644 index 00000000000..13dcf803db2 --- /dev/null +++ b/nixpkgs/nixos/modules/services/x11/xfs.conf @@ -0,0 +1,15 @@ +# font server configuration file +# $Xorg: config.cpp,v 1.3 2000/08/17 19:54:19 cpqbld Exp $ + +clone-self = on +use-syslog = off +error-file = /var/log/xfs.log +# in decipoints +default-point-size = 120 +default-resolutions = 75,75,100,100 + +# font cache control, specified in KB +cache-hi-mark = 2048 +cache-low-mark = 1433 +cache-balance = 70 +catalogue = /run/current-system/sw/share/X11-fonts/ diff --git a/nixpkgs/nixos/modules/services/x11/xfs.nix b/nixpkgs/nixos/modules/services/x11/xfs.nix new file mode 100644 index 00000000000..ea7cfa1aa43 --- /dev/null +++ b/nixpkgs/nixos/modules/services/x11/xfs.nix @@ -0,0 +1,46 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + + configFile = ./xfs.conf; + +in + +{ + + ###### interface + + options = { + + services.xfs = { + + enable = mkOption { + type = types.bool; + default = false; + description = "Whether to enable the X Font Server."; + }; + + }; + + }; + + + ###### implementation + + config = mkIf config.services.xfs.enable { + assertions = singleton + { assertion = config.fonts.enableFontDir; + message = "Please enable fonts.enableFontDir to use the X Font Server."; + }; + + systemd.services.xfs = { + description = "X Font Server"; + after = [ "network.target" ]; + wantedBy = [ "multi-user.target" ]; + path = [ pkgs.xorg.xfs ]; + script = "xfs -config ${configFile}"; + }; + }; +} diff --git a/nixpkgs/nixos/modules/services/x11/xserver.nix b/nixpkgs/nixos/modules/services/x11/xserver.nix new file mode 100644 index 00000000000..a8406544a72 --- /dev/null +++ b/nixpkgs/nixos/modules/services/x11/xserver.nix @@ -0,0 +1,822 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + + # Abbreviations. + cfg = config.services.xserver; + xorg = pkgs.xorg; + + + # Map video driver names to driver packages. FIXME: move into card-specific modules. + knownVideoDrivers = { + # Alias so people can keep using "virtualbox" instead of "vboxvideo". + virtualbox = { modules = [ xorg.xf86videovboxvideo ]; driverName = "vboxvideo"; }; + + # Alias so that "radeon" uses the xf86-video-ati driver. + radeon = { modules = [ xorg.xf86videoati ]; driverName = "ati"; }; + + # modesetting does not have a xf86videomodesetting package as it is included in xorgserver + modesetting = {}; + }; + + fontsForXServer = + config.fonts.fonts ++ + # We don't want these fonts in fonts.conf, because then modern, + # fontconfig-based applications will get horrible bitmapped + # Helvetica fonts. It's better to get a substitution (like Nimbus + # Sans) than that horror. But we do need the Adobe fonts for some + # old non-fontconfig applications. (Possibly this could be done + # better using a fontconfig rule.) + [ pkgs.xorg.fontadobe100dpi + pkgs.xorg.fontadobe75dpi + ]; + + xrandrOptions = { + output = mkOption { + type = types.str; + example = "DVI-0"; + description = '' + The output name of the monitor, as shown by <citerefentry> + <refentrytitle>xrandr</refentrytitle> + <manvolnum>1</manvolnum> + </citerefentry> invoked without arguments. + ''; + }; + + primary = mkOption { + type = types.bool; + default = false; + description = '' + Whether this head is treated as the primary monitor, + ''; + }; + + monitorConfig = mkOption { + type = types.lines; + default = ""; + example = '' + DisplaySize 408 306 + Option "DPMS" "false" + ''; + description = '' + Extra lines to append to the <literal>Monitor</literal> section + verbatim. Available options are documented in the MONITOR section in + <citerefentry><refentrytitle>xorg.conf</refentrytitle> + <manvolnum>5</manvolnum></citerefentry>. + ''; + }; + }; + + # Just enumerate all heads without discarding XRandR output information. + xrandrHeads = let + mkHead = num: config: { + name = "multihead${toString num}"; + inherit config; + }; + in imap1 mkHead cfg.xrandrHeads; + + xrandrDeviceSection = let + monitors = forEach xrandrHeads (h: '' + Option "monitor-${h.config.output}" "${h.name}" + ''); + # First option is indented through the space in the config but any + # subsequent options aren't so we need to apply indentation to + # them here + monitorsIndented = if length monitors > 1 + then singleton (head monitors) ++ map (m: " " + m) (tail monitors) + else monitors; + in concatStrings monitorsIndented; + + # Here we chain every monitor from the left to right, so we have: + # m4 right of m3 right of m2 right of m1 .----.----.----.----. + # Which will end up in reverse ----------> | m1 | m2 | m3 | m4 | + # `----^----^----^----' + xrandrMonitorSections = let + mkMonitor = previous: current: singleton { + inherit (current) name; + value = '' + Section "Monitor" + Identifier "${current.name}" + ${optionalString (current.config.primary) '' + Option "Primary" "true" + ''} + ${optionalString (previous != []) '' + Option "RightOf" "${(head previous).name}" + ''} + ${current.config.monitorConfig} + EndSection + ''; + } ++ previous; + monitors = reverseList (foldl mkMonitor [] xrandrHeads); + in concatMapStrings (getAttr "value") monitors; + + configFile = pkgs.runCommand "xserver.conf" + { xfs = optionalString (cfg.useXFS != false) + ''FontPath "${toString cfg.useXFS}"''; + inherit (cfg) config; + preferLocalBuild = true; + } + '' + echo 'Section "Files"' >> $out + echo $xfs >> $out + + for i in ${toString fontsForXServer}; do + if test "''${i:0:''${#NIX_STORE}}" == "$NIX_STORE"; then + for j in $(find $i -name fonts.dir); do + echo " FontPath \"$(dirname $j)\"" >> $out + done + fi + done + + for i in $(find ${toString cfg.modules} -type d); do + if test $(echo $i/*.so* | wc -w) -ne 0; then + echo " ModulePath \"$i\"" >> $out + fi + done + + echo 'EndSection' >> $out + + echo "$config" >> $out + ''; # */ + +in + +{ + + imports = + [ ./display-managers/default.nix + ./window-managers/default.nix + ./desktop-managers/default.nix + ]; + + + ###### interface + + options = { + + services.xserver = { + + enable = mkOption { + type = types.bool; + default = false; + description = '' + Whether to enable the X server. + ''; + }; + + autorun = mkOption { + type = types.bool; + default = true; + description = '' + Whether to start the X server automatically. + ''; + }; + + exportConfiguration = mkOption { + type = types.bool; + default = false; + description = '' + Whether to symlink the X server configuration under + <filename>/etc/X11/xorg.conf</filename>. + ''; + }; + + enableTCP = mkOption { + type = types.bool; + default = false; + description = '' + Whether to allow the X server to accept TCP connections. + ''; + }; + + autoRepeatDelay = mkOption { + type = types.nullOr types.int; + default = null; + description = '' + Sets the autorepeat delay (length of time in milliseconds that a key must be depressed before autorepeat starts). + ''; + }; + + autoRepeatInterval = mkOption { + type = types.nullOr types.int; + default = null; + description = '' + Sets the autorepeat interval (length of time in milliseconds that should elapse between autorepeat-generated keystrokes). + ''; + }; + + inputClassSections = mkOption { + type = types.listOf types.lines; + default = []; + example = literalExample '' + [ ''' + Identifier "Trackpoint Wheel Emulation" + MatchProduct "ThinkPad USB Keyboard with TrackPoint" + Option "EmulateWheel" "true" + Option "EmulateWheelButton" "2" + Option "Emulate3Buttons" "false" + ''' + ] + ''; + description = "Content of additional InputClass sections of the X server configuration file."; + }; + + modules = mkOption { + type = types.listOf types.path; + default = []; + example = literalExample "[ pkgs.xf86_input_wacom ]"; + description = "Packages to be added to the module search path of the X server."; + }; + + resolutions = mkOption { + type = types.listOf types.attrs; + default = []; + example = [ { x = 1600; y = 1200; } { x = 1024; y = 786; } ]; + description = '' + The screen resolutions for the X server. The first element + is the default resolution. If this list is empty, the X + server will automatically configure the resolution. + ''; + }; + + videoDrivers = mkOption { + type = types.listOf types.str; + # !!! We'd like "nv" here, but it segfaults the X server. + default = [ "radeon" "cirrus" "vesa" "vmware" "modesetting" ]; + example = [ + "ati_unfree" "amdgpu" "amdgpu-pro" + "nv" "nvidia" "nvidiaLegacy390" "nvidiaLegacy340" "nvidiaLegacy304" + ]; + # TODO(@oxij): think how to easily add the rest, like those nvidia things + relatedPackages = concatLists + (mapAttrsToList (n: v: + optional (hasPrefix "xf86video" n) { + path = [ "xorg" n ]; + title = removePrefix "xf86video" n; + }) pkgs.xorg); + description = '' + The names of the video drivers the configuration + supports. They will be tried in order until one that + supports your card is found. + Don't combine those with "incompatible" OpenGL implementations, + e.g. free ones (mesa-based) with proprietary ones. + + For unfree "nvidia*", the supported GPU lists are on + https://www.nvidia.com/object/unix.html + ''; + }; + + videoDriver = mkOption { + type = types.nullOr types.str; + default = null; + example = "i810"; + description = '' + The name of the video driver for your graphics card. This + option is obsolete; please set the + <option>services.xserver.videoDrivers</option> instead. + ''; + }; + + drivers = mkOption { + type = types.listOf types.attrs; + internal = true; + description = '' + A list of attribute sets specifying drivers to be loaded by + the X11 server. + ''; + }; + + dpi = mkOption { + type = types.nullOr types.int; + default = null; + description = "DPI resolution to use for X server."; + }; + + startDbusSession = mkOption { + type = types.bool; + default = true; + description = '' + Whether to start a new DBus session when you log in with dbus-launch. + ''; + }; + + updateDbusEnvironment = mkOption { + type = types.bool; + default = false; + description = '' + Whether to update the DBus activation environment after launching the + desktop manager. + ''; + }; + + layout = mkOption { + type = types.str; + default = "us"; + description = '' + Keyboard layout, or multiple keyboard layouts separated by commas. + ''; + }; + + xkbModel = mkOption { + type = types.str; + default = "pc104"; + example = "presario"; + description = '' + Keyboard model. + ''; + }; + + xkbOptions = mkOption { + type = types.str; + default = "terminate:ctrl_alt_bksp"; + example = "grp:caps_toggle, grp_led:scroll"; + description = '' + X keyboard options; layout switching goes here. + ''; + }; + + xkbVariant = mkOption { + type = types.str; + default = ""; + example = "colemak"; + description = '' + X keyboard variant. + ''; + }; + + xkbDir = mkOption { + type = types.path; + default = "${pkgs.xkeyboard_config}/etc/X11/xkb"; + description = '' + Path used for -xkbdir xserver parameter. + ''; + }; + + config = mkOption { + type = types.lines; + description = '' + The contents of the configuration file of the X server + (<filename>xorg.conf</filename>). + ''; + }; + + deviceSection = mkOption { + type = types.lines; + default = ""; + example = "VideoRAM 131072"; + description = "Contents of the first Device section of the X server configuration file."; + }; + + screenSection = mkOption { + type = types.lines; + default = ""; + example = '' + Option "RandRRotation" "on" + ''; + description = "Contents of the first Screen section of the X server configuration file."; + }; + + monitorSection = mkOption { + type = types.lines; + default = ""; + example = "HorizSync 28-49"; + description = "Contents of the first Monitor section of the X server configuration file."; + }; + + extraConfig = mkOption { + type = types.lines; + default = ""; + description = "Additional contents (sections) included in the X server configuration file"; + }; + + xrandrHeads = mkOption { + default = []; + example = [ + "HDMI-0" + { output = "DVI-0"; primary = true; } + { output = "DVI-1"; monitorConfig = "Option \"Rotate\" \"left\""; } + ]; + type = with types; listOf (coercedTo str (output: { + inherit output; + }) (submodule { options = xrandrOptions; })); + # Set primary to true for the first head if no other has been set + # primary already. + apply = heads: let + hasPrimary = any (x: x.primary) heads; + firstPrimary = head heads // { primary = true; }; + newHeads = singleton firstPrimary ++ tail heads; + in if heads != [] && !hasPrimary then newHeads else heads; + description = '' + Multiple monitor configuration, just specify a list of XRandR + outputs. The individual elements should be either simple strings or + an attribute set of output options. + + If the element is a string, it is denoting the physical output for a + monitor, if it's an attribute set, you must at least provide the + <option>output</option> option. + + The monitors will be mapped from left to right in the order of the + list. + + By default, the first monitor will be set as the primary monitor if + none of the elements contain an option that has set + <option>primary</option> to <literal>true</literal>. + + <note><para>Only one monitor is allowed to be primary.</para></note> + + Be careful using this option with multiple graphic adapters or with + drivers that have poor support for XRandR, unexpected things might + happen with those. + ''; + }; + + serverFlagsSection = mkOption { + default = ""; + example = + '' + Option "BlankTime" "0" + Option "StandbyTime" "0" + Option "SuspendTime" "0" + Option "OffTime" "0" + ''; + description = "Contents of the ServerFlags section of the X server configuration file."; + }; + + moduleSection = mkOption { + type = types.lines; + default = ""; + example = + '' + SubSection "extmod" + EndSubsection + ''; + description = "Contents of the Module section of the X server configuration file."; + }; + + serverLayoutSection = mkOption { + type = types.lines; + default = ""; + example = + '' + Option "AIGLX" "true" + ''; + description = "Contents of the ServerLayout section of the X server configuration file."; + }; + + extraDisplaySettings = mkOption { + type = types.lines; + default = ""; + example = "Virtual 2048 2048"; + description = "Lines to be added to every Display subsection of the Screen section."; + }; + + defaultDepth = mkOption { + type = types.int; + default = 0; + example = 8; + description = "Default colour depth."; + }; + + useXFS = mkOption { + # FIXME: what's the type of this option? + default = false; + example = "unix/:7100"; + description = "Determines how to connect to the X Font Server."; + }; + + tty = mkOption { + type = types.nullOr types.int; + default = 7; + description = "Virtual console for the X server."; + }; + + display = mkOption { + type = types.nullOr types.int; + default = 0; + description = "Display number for the X server."; + }; + + virtualScreen = mkOption { + type = types.nullOr types.attrs; + default = null; + example = { x = 2048; y = 2048; }; + description = '' + Virtual screen size for Xrandr. + ''; + }; + + verbose = mkOption { + type = types.nullOr types.int; + default = 3; + example = 7; + description = '' + Controls verbosity of X logging. + ''; + }; + + useGlamor = mkOption { + type = types.bool; + default = false; + description = '' + Whether to use the Glamor module for 2D acceleration, + if possible. + ''; + }; + + enableCtrlAltBackspace = mkOption { + type = types.bool; + default = false; + description = '' + Whether to enable the DontZap option, which binds Ctrl+Alt+Backspace + to forcefully kill X. This can lead to data loss and is disabled + by default. + ''; + }; + + terminateOnReset = mkOption { + type = types.bool; + default = true; + description = '' + Whether to terminate X upon server reset. + ''; + }; + }; + + }; + + + + ###### implementation + + config = mkIf cfg.enable { + + services.xserver.displayManager.lightdm.enable = + let dmconf = cfg.displayManager; + default = !( dmconf.auto.enable + || dmconf.gdm.enable + || dmconf.sddm.enable + || dmconf.slim.enable + || dmconf.xpra.enable ); + in mkIf (default) true; + + hardware.opengl.enable = mkDefault true; + + services.xserver.videoDrivers = mkIf (cfg.videoDriver != null) [ cfg.videoDriver ]; + + # FIXME: somehow check for unknown driver names. + services.xserver.drivers = flip concatMap cfg.videoDrivers (name: + let driver = + attrByPath [name] + (if xorg ? ${"xf86video" + name} + then { modules = [xorg.${"xf86video" + name}]; } + else null) + knownVideoDrivers; + in optional (driver != null) ({ inherit name; modules = []; driverName = name; } // driver)); + + assertions = [ + { assertion = config.security.polkit.enable; + message = "X11 requires Polkit to be enabled (‘security.polkit.enable = true’)."; + } + (let primaryHeads = filter (x: x.primary) cfg.xrandrHeads; in { + assertion = length primaryHeads < 2; + message = "Only one head is allowed to be primary in " + + "‘services.xserver.xrandrHeads’, but there are " + + "${toString (length primaryHeads)} heads set to primary: " + + concatMapStringsSep ", " (x: x.output) primaryHeads; + }) + ]; + + environment.etc = + (optionals cfg.exportConfiguration + [ { source = "${configFile}"; + target = "X11/xorg.conf"; + } + # -xkbdir command line option does not seems to be passed to xkbcomp. + { source = "${cfg.xkbDir}"; + target = "X11/xkb"; + } + ]) + # localectl looks into 00-keyboard.conf + ++ [ + { + text = '' + Section "InputClass" + Identifier "Keyboard catchall" + MatchIsKeyboard "on" + Option "XkbModel" "${cfg.xkbModel}" + Option "XkbLayout" "${cfg.layout}" + Option "XkbOptions" "${cfg.xkbOptions}" + Option "XkbVariant" "${cfg.xkbVariant}" + EndSection + ''; + target = "X11/xorg.conf.d/00-keyboard.conf"; + } + ] + # Needed since 1.18; see https://bugs.freedesktop.org/show_bug.cgi?id=89023#c5 + ++ (let cfgPath = "/X11/xorg.conf.d/10-evdev.conf"; in + [{ + source = xorg.xf86inputevdev.out + "/share" + cfgPath; + target = cfgPath; + }] + ); + + environment.systemPackages = + [ xorg.xorgserver.out + xorg.xrandr + xorg.xrdb + xorg.setxkbmap + xorg.iceauth # required for KDE applications (it's called by dcopserver) + xorg.xlsclients + xorg.xset + xorg.xsetroot + xorg.xinput + xorg.xprop + xorg.xauth + pkgs.xterm + pkgs.xdg_utils + xorg.xf86inputevdev.out # get evdev.4 man page + ] + ++ optional (elem "virtualbox" cfg.videoDrivers) xorg.xrefresh; + + environment.pathsToLink = [ "/share/X11" ]; + + xdg = { + autostart.enable = true; + menus.enable = true; + mime.enable = true; + icons.enable = true; + }; + + # The default max inotify watches is 8192. + # Nowadays most apps require a good number of inotify watches, + # the value below is used by default on several other distros. + boot.kernel.sysctl."fs.inotify.max_user_watches" = mkDefault 524288; + + systemd.defaultUnit = mkIf cfg.autorun "graphical.target"; + + systemd.services.display-manager = + { description = "X11 Server"; + + after = [ "systemd-udev-settle.service" "acpid.service" "systemd-logind.service" ]; + wants = [ "systemd-udev-settle.service" ]; + + restartIfChanged = false; + + environment = + optionalAttrs config.hardware.opengl.setLdLibraryPath + { LD_LIBRARY_PATH = pkgs.addOpenGLRunpath.driverLink; } + // cfg.displayManager.job.environment; + + preStart = + '' + ${cfg.displayManager.job.preStart} + + rm -f /tmp/.X0-lock + ''; + + script = "${cfg.displayManager.job.execCmd}"; + + serviceConfig = { + Restart = "always"; + RestartSec = "200ms"; + SyslogIdentifier = "display-manager"; + # Stop restarting if the display manager stops (crashes) 2 times + # in one minute. Starting X typically takes 3-4s. + StartLimitInterval = "30s"; + StartLimitBurst = "3"; + }; + }; + + services.xserver.displayManager.xserverArgs = + [ "-config ${configFile}" + "-xkbdir" "${cfg.xkbDir}" + # Log at the default verbosity level to stderr rather than /var/log/X.*.log. + "-logfile" "/dev/null" + ] ++ optional (cfg.display != null) ":${toString cfg.display}" + ++ optional (cfg.tty != null) "vt${toString cfg.tty}" + ++ optional (cfg.dpi != null) "-dpi ${toString cfg.dpi}" + ++ optional (cfg.verbose != null) "-verbose ${toString cfg.verbose}" + ++ optional (!cfg.enableTCP) "-nolisten tcp" + ++ optional (cfg.autoRepeatDelay != null) "-ardelay ${toString cfg.autoRepeatDelay}" + ++ optional (cfg.autoRepeatInterval != null) "-arinterval ${toString cfg.autoRepeatInterval}" + ++ optional cfg.terminateOnReset "-terminate"; + + services.xserver.modules = + concatLists (catAttrs "modules" cfg.drivers) ++ + [ xorg.xorgserver.out + xorg.xf86inputevdev.out + ]; + + system.extraDependencies = singleton (pkgs.runCommand "xkb-validated" { + inherit (cfg) xkbModel layout xkbVariant xkbOptions; + nativeBuildInputs = [ pkgs.xkbvalidate ]; + preferLocalBuild = true; + } '' + xkbvalidate "$xkbModel" "$layout" "$xkbVariant" "$xkbOptions" + touch "$out" + ''); + + services.xserver.config = + '' + Section "ServerFlags" + Option "AllowMouseOpenFail" "on" + Option "DontZap" "${if cfg.enableCtrlAltBackspace then "off" else "on"}" + ${cfg.serverFlagsSection} + EndSection + + Section "Module" + ${cfg.moduleSection} + EndSection + + Section "Monitor" + Identifier "Monitor[0]" + ${cfg.monitorSection} + EndSection + + # Additional "InputClass" sections + ${flip concatMapStrings cfg.inputClassSections (inputClassSection: '' + Section "InputClass" + ${inputClassSection} + EndSection + '')} + + + Section "ServerLayout" + Identifier "Layout[all]" + ${cfg.serverLayoutSection} + # Reference the Screen sections for each driver. This will + # cause the X server to try each in turn. + ${flip concatMapStrings cfg.drivers (d: '' + Screen "Screen-${d.name}[0]" + '')} + EndSection + + ${if cfg.useGlamor then '' + Section "Module" + Load "dri2" + Load "glamoregl" + EndSection + '' else ""} + + # For each supported driver, add a "Device" and "Screen" + # section. + ${flip concatMapStrings cfg.drivers (driver: '' + + Section "Device" + Identifier "Device-${driver.name}[0]" + Driver "${driver.driverName or driver.name}" + ${if cfg.useGlamor then ''Option "AccelMethod" "glamor"'' else ""} + ${cfg.deviceSection} + ${driver.deviceSection or ""} + ${xrandrDeviceSection} + EndSection + + Section "Screen" + Identifier "Screen-${driver.name}[0]" + Device "Device-${driver.name}[0]" + ${optionalString (cfg.monitorSection != "") '' + Monitor "Monitor[0]" + ''} + + ${cfg.screenSection} + ${driver.screenSection or ""} + + ${optionalString (cfg.defaultDepth != 0) '' + DefaultDepth ${toString cfg.defaultDepth} + ''} + + ${optionalString + (driver.name != "virtualbox" && + (cfg.resolutions != [] || + cfg.extraDisplaySettings != "" || + cfg.virtualScreen != null)) + (let + f = depth: + '' + SubSection "Display" + Depth ${toString depth} + ${optionalString (cfg.resolutions != []) + "Modes ${concatMapStrings (res: ''"${toString res.x}x${toString res.y}"'') cfg.resolutions}"} + ${cfg.extraDisplaySettings} + ${optionalString (cfg.virtualScreen != null) + "Virtual ${toString cfg.virtualScreen.x} ${toString cfg.virtualScreen.y}"} + EndSubSection + ''; + in concatMapStrings f [8 16 24] + )} + + EndSection + '')} + + ${xrandrMonitorSections} + + ${cfg.extraConfig} + ''; + + fonts.enableDefaultFonts = mkDefault true; + + }; + +} |