ctucx.git: nixfiles

ctucx' nixfiles

commit 48a73f07b68402e6b2c61bcce795228df1407de0
parent 1070e5c7f69e51f14560c32c98fec98111bd1bdf
Author: Katja (ctucx) <git@ctu.cx>
Date: Mon, 3 Mar 2025 17:11:53 +0100

configurations: move gnome module to `modules`
3 files changed, 370 insertions(+), 369 deletions(-)
D
configurations/linux/programs/gnome.nix
|
369
-------------------------------------------------------------------------------
M
modules/default.nix
|
1
+
A
modules/linux/gnome.nix
|
369
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
diff --git a/configurations/linux/programs/gnome.nix b/configurations/linux/programs/gnome.nix
@@ -1,369 +0,0 @@
-{ config, pkgs, lib, utils, ... }:
-
-let
-  cfg = config.ctucxConfig.wm.gnome;
-
-  settingsFormat = pkgs.formats.ini { };
-  configFile     = settingsFormat.generate "custom.conf" cfg.gdm.settings;
-
-  mimeAppsList = pkgs.writeTextFile {
-    name        = "gnome-mimeapps";
-    destination = "/share/applications/mimeapps.list";
-    text = ''
-      [Default Applications]
-      inode/directory=nautilus.desktop;org.gnome.Nautilus.desktop
-    '';
-  };
-
-  nixos-background-info  = pkgs.writeTextFile rec {
-    name        = "nixos-background-info";
-    destination = "/share/gnome-background-properties/nixos.xml";
-    text = ''
-      <?xml version="1.0"?>
-      <!DOCTYPE wallpapers SYSTEM "gnome-wp-list.dtd">
-      <wallpapers>
-        <wallpaper deleted="false">
-          <name>Blobs</name>
-          <filename>${pkgs.nixos-artwork.wallpapers.simple-blue.gnomeFilePath}</filename>
-          <filename-dark>${pkgs.nixos-artwork.wallpapers.simple-dark-gray.gnomeFilePath}</filename-dark>
-          <options>zoom</options>
-          <shade_type>solid</shade_type>
-          <pcolor>#3a4ba0</pcolor>
-          <scolor>#2f302f</scolor>
-        </wallpaper>
-      </wallpapers>
-    '';
-  };
-
-in {
-
-  options = {
-    ctucxConfig.wm.gnome  = {
-      enable = lib.mkEnableOption "gnome";
-      gdm    = {
-        dconfSettings = lib.mkOption {
-          type = lib.types.attrs;
-          default = { };
-        };
-        settings = lib.mkOption {
-          type = settingsFormat.type;
-          default = { };
-        };
-      };
-    };
-  };
-
-  config = lib.mkIf cfg.enable {
-
-    # patched to remove xorg and xwayland completely
-    nixpkgs.overlays = [(final: prev: {
-
-      mutter = prev.mutter.overrideAttrs( prevAttrs: {
-        mesonFlags = [
-          "-Dinstalled_tests=false" "-Dtests=disabled" "-Ddocs=true"
-          "-Degl_device=true"
-          "-Dwayland_eglstream=true"
-          "-Dprofiler=true"
-          "-Dsm=false"
-          "-Dx11=false"
-          "-Dxwayland=false"
-          "-Dwayland=true"
-        ];
-        buildInputs = (utils.removePackagesByName prevAttrs.buildInputs [
-          prev.xorg.libSM
-          prev.xwayland
-          prev.gtk4
-          prev.xorg.libICE
-          prev.xorg.libX11
-          prev.xorg.libXcomposite
-          prev.xorg.libXcursor
-          prev.xorg.libXdamage
-          prev.xorg.libXext
-          prev.xorg.libXfixes
-          prev.xorg.libXi
-          prev.xorg.libXtst
-          prev.xorg.libxkbfile
-          prev.xkeyboard_config
-          prev.xorg.libxcb
-          prev.xorg.libXrandr
-          prev.xorg.libXinerama
-          prev.xorg.libXau
-        ]) ++ [ prev.libGL ];
-        nativeBuildInputs = utils.removePackagesByName prevAttrs.nativeBuildInputs [
-          prev.xorg.xorgserver
-        ];
-      });
-
-      gdm = prev.gdm.overrideAttrs( prevAttrs: {
-        mesonFlags  = prev.lib.lists.remove "--Dgdm-xsession=true" (prevAttrs.mesonFlags ++ [ "-Dgdm-xsession=false" "-Dx11-support=false" ]);
-        patches = [
-          # GDM fails to find g-s with the following error in the journal.
-          # gdm-x-session[976]: dbus-run-session: failed to exec 'gnome-session': No such file or directory
-          # https://gitlab.gnome.org/GNOME/gdm/-/merge_requests/92
-          (prev.fetchpatch {
-            url = "https://gitlab.gnome.org/GNOME/gdm/-/commit/ccecd9c975d04da80db4cd547b67a1a94fa83292.patch";
-            hash = "sha256-5hKS9wjjhuSAYwXct5vS0dPbmPRIINJoLC0Zm1naz6Q=";
-            revert = true;
-          })
-
-          ../../../pkgs/gdm-fix-wayland.patch
-
-          # Change hardcoded paths to nix store paths.
-          (prev.substituteAll {
-            src       = ../../../pkgs/gdm-fix-paths.patch;
-            coreutils = prev.coreutils;
-            plymouth  = prev.plymouth;
-            dbus      = prev.dbus;
-          })
-        ];
-        postPatch = ''
-          # Reverts https://gitlab.gnome.org/GNOME/gdm/-/commit/b0f802e36ff948a415bfd2bccaa268b6990515b7
-          # The gdm-auth-config tool is probably not too useful for NixOS, but we still want the dconf profile
-          # installed (mostly just because .passthru.tests can make use of it).
-          substituteInPlace meson.build \
-            --replace-fail "dconf_prefix = dconf_dep.get_variable(pkgconfig: 'prefix')" "dconf_prefix = gdm_prefix"
-        '';
-        buildInputs = utils.removePackagesByName prevAttrs.buildInputs [
-          prev.xorg.libX11
-          prev.xorg.libXdmcp
-          prev.xorg.libxcb
-        ];
-      });
-
-      gnome-session = prev.gnome-session.overrideAttrs( prevAttrs: {
-        mesonFlags  = [ "-Dx11=false" ];
-        buildInputs = utils.removePackagesByName prevAttrs.buildInputs [
-          prev.xorg.libICE
-          prev.xorg.xtrans
-        ];
-      });
-
-    })];
-
-    users.groups.gdm.gid = config.ids.gids.gdm;
-    users.users.gdm = {
-      name = "gdm";
-      uid = config.ids.uids.gdm;
-      group = "gdm";
-      home = "/run/gdm";
-      description = "GDM user";
-    };
-
-    security.polkit.enable           = true;
-    networking.networkmanager.enable = lib.mkDefault true;
-
-    hardware = {
-      graphics.enable   = true;
-      bluetooth.enable  = lib.mkDefault true;
-    };
-
-    fonts.packages = with pkgs; [
-      cantarell-fonts
-      dejavu_fonts
-      source-code-pro
-      source-sans
-    ];
-
-    environment = {
-      etc."gdm/custom.conf".source = configFile;
-
-      systemPackages = with pkgs; [
-        gnome-shell
-        (lib.mkIf config.hardware.bluetooth.enable gnome-bluetooth)
-        (lib.mkIf config.services.colord.enable gnome-color-manager)
-        gnome-control-center
-        ghostty
-        nautilus
-        sushi #quick-preview for nautilus
-        adwaita-icon-theme
-        sound-theme-freedesktop
-        nixos-icons
-        nixos-background-info
-        glib # for gsettings program
-        gnome-menus
-        gtk3.out # for gtk-launch program
-        xdg-user-dirs # Update user dirs as described in https://freedesktop.org/wiki/Software/xdg-user-dirs/
-        xdg-user-dirs-gtk
-      ];
-
-      # Needed for themes and backgrounds
-      pathsToLink = [
-        "/share" # TODO: https://github.com/NixOS/nixpkgs/issues/47173
-        "/share/nautilus-python/extensions"
-      ];
-
-      sessionVariables = {
-        # Let nautilus find extensions
-        NAUTILUS_4_EXTENSION_DIR = "${config.system.path}/lib/nautilus/extensions-4";
-        # Override default mimeapps for nautilus
-        XDG_DATA_DIRS = [ "${mimeAppsList}/share" ];
-      };
-    };
-
-    services = {
-      gvfs.enable                       = true;
-      udisks2.enable                    = true;
-      libinput.enable                   = true;
-      accounts-daemon.enable            = true;
-      pipewire.enable                   = lib.mkDefault true;
-      hardware.bolt.enable              = lib.mkDefault true;
-      colord.enable                     = lib.mkDefault true;
-      power-profiles-daemon.enable      = lib.mkDefault true;
-      upower.enable                     = config.powerManagement.enable;
-      system-config-printer.enable      = (lib.mkIf config.services.printing.enable (lib.mkDefault true));
-
-      gnome = {
-        glib-networking.enable          = true;
-        gnome-settings-daemon.enable    = true;
-        at-spi2-core.enable             = lib.mkDefault true;
-        gnome-keyring.enable            = lib.mkDefault true;
-      };
-
-      geoclue2 = {
-        enable          = lib.mkDefault true;
-        enableDemoAgent = false; # GNOME has its own geoclue agent
-        appConfig = {
-          gnome-datetime-panel = {
-            isAllowed = true;
-            isSystem = true;
-          };
-          gnome-color-panel = {
-            isAllowed = true;
-            isSystem = true;
-          };
-          "org.gnome.Shell" = {
-            isAllowed = true;
-            isSystem = true;
-          };
-        };
-      };
-
-      udev.packages = [ pkgs.mutter ];
-      dbus.packages = with pkgs; [ gdm sushi ];
-    };
-
-    programs = {
-      dconf.enable                 = true;
-      dconf.profiles.gdm.databases = [
-        { settings = cfg.gdm.dconfSettings; }
-        "${pkgs.gdm}/share/gdm/greeter-dconf-defaults"
-      ];
-    };
-
-    xdg = {
-      mime.enable  = true;
-      icons.enable = true;
-
-      portal = {
-        enable         = true;
-        configPackages = lib.mkDefault [ pkgs.gnome-session ];
-        extraPortals   = with pkgs; [
-          xdg-desktop-portal-gnome
-          xdg-desktop-portal-gtk
-        ];
-      };
-    };
-
-
-    systemd = {
-      packages = with pkgs; [
-        gdm
-        gnome-session
-        gnome-shell
-      ];
-
-      tmpfiles.rules = [ "d /run/gdm/.config 0711 gdm gdm" ];
-
-      user.services.dbus.wantedBy = [ "default.target" ];
-
-      services = {
-        # We dont use the upstream gdm service
-        # it has to be disabled since the gdm package has it
-        # https://github.com/NixOS/nixpkgs/issues/108672
-        gdm.enable = false;
-
-        display-manager = {
-          description = "Display Manager";
-
-          wants     = [ "systemd-machined.service" "accounts-daemon.service" ];
-          conflicts = [ "getty@${pkgs.gdm.initialVT}.service" "plymouth-quit.service" ];
-          onFailure = [ "plymouth-quit.service" ];
-          wantedBy  = [ "multi-user.target" ];
-          after     = [
-            "systemd-logind.service" "systemd-user-sessions.service" "systemd-machined.service"
-            "getty@${pkgs.gdm.initialVT}.service"
-            "acpid.service"
-            "plymouth-quit.service" "plymouth-start.service"
-          ];
-
-          path        = [ pkgs.gnome-session ];
-          environment = {
-            XDG_DATA_DIRS = lib.makeSearchPath "share" (with pkgs; [
-              gdm
-              gnome-session.sessions
-              gnome-control-center # for accessibility icon
-              adwaita-icon-theme
-              hicolor-icon-theme
-            ]);
-          };
-
-          serviceConfig = {
-            KillMode         = "mixed";
-            IgnoreSIGPIPE    = "no";
-            BusName          = "org.gnome.DisplayManager";
-            StandardError    = "inherit";
-            ExecStart        = "${pkgs.gdm}/bin/gdm";
-            ExecReload       = "${pkgs.coreutils}/bin/kill -SIGHUP $MAINPID";
-            KeyringMode      = "shared";
-            EnvironmentFile  = "-/etc/locale.conf";
-            Restart          = "always";
-            RestartSec       = "200ms";
-            SyslogIdentifier = "display-manager";
-          };
-
-          restartIfChanged = false;
-
-          # Stop restarting if the display manager stops (crashes) 2 times in one minute.
-          startLimitIntervalSec = 30;
-          startLimitBurst = 3;
-        };
-
-        # Prevent nixos-rebuild switch from bringing down the graphical
-        # session. (If multi-user.target wants plymouth-quit.service which
-        # conflicts display-manager.service, then when nixos-rebuild
-        # switch starts multi-user.target, display-manager.service is
-        # stopped so plymouth-quit.service can be started.)
-        plymouth-quit = lib.mkIf config.boot.plymouth.enable {
-          wantedBy = lib.mkForce [];
-        };
-      };
-    };
-
-    # 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=/etc/pam/environment readenv=0
-        session  optional       ${config.systemd.package}/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
-      '';
-    };
-  };
-
-}
diff --git a/modules/default.nix b/modules/default.nix
@@ -27,6 +27,7 @@
       ./linux/email-notify.nix
       ./linux/dns.nix
       ./linux/gotosocial.nix
+      ./linux/gnome.nix
     ] else [])
 
     (if (currentSystem == "aarch64-darwin") then [
diff --git a/modules/linux/gnome.nix b/modules/linux/gnome.nix
@@ -0,0 +1,369 @@
+{ config, pkgs, lib, utils, ... }:
+
+let
+  cfg = config.wm.gnome;
+
+  settingsFormat = pkgs.formats.ini { };
+  configFile     = settingsFormat.generate "custom.conf" cfg.gdm.settings;
+
+  mimeAppsList = pkgs.writeTextFile {
+    name        = "gnome-mimeapps";
+    destination = "/share/applications/mimeapps.list";
+    text = ''
+      [Default Applications]
+      inode/directory=nautilus.desktop;org.gnome.Nautilus.desktop
+    '';
+  };
+
+  nixos-background-info  = pkgs.writeTextFile rec {
+    name        = "nixos-background-info";
+    destination = "/share/gnome-background-properties/nixos.xml";
+    text = ''
+      <?xml version="1.0"?>
+      <!DOCTYPE wallpapers SYSTEM "gnome-wp-list.dtd">
+      <wallpapers>
+        <wallpaper deleted="false">
+          <name>Blobs</name>
+          <filename>${pkgs.nixos-artwork.wallpapers.simple-blue.gnomeFilePath}</filename>
+          <filename-dark>${pkgs.nixos-artwork.wallpapers.simple-dark-gray.gnomeFilePath}</filename-dark>
+          <options>zoom</options>
+          <shade_type>solid</shade_type>
+          <pcolor>#3a4ba0</pcolor>
+          <scolor>#2f302f</scolor>
+        </wallpaper>
+      </wallpapers>
+    '';
+  };
+
+in {
+
+  options = {
+    wm.gnome  = {
+      enable = lib.mkEnableOption "gnome";
+      gdm    = {
+        dconfSettings = lib.mkOption {
+          type = lib.types.attrs;
+          default = { };
+        };
+        settings = lib.mkOption {
+          type = settingsFormat.type;
+          default = { };
+        };
+      };
+    };
+  };
+
+  config = lib.mkIf cfg.enable {
+
+    # patched to remove xorg and xwayland completely
+    nixpkgs.overlays = [(final: prev: {
+
+      mutter = prev.mutter.overrideAttrs( prevAttrs: {
+        mesonFlags = [
+          "-Dinstalled_tests=false" "-Dtests=disabled" "-Ddocs=true"
+          "-Degl_device=true"
+          "-Dwayland_eglstream=true"
+          "-Dprofiler=true"
+          "-Dsm=false"
+          "-Dx11=false"
+          "-Dxwayland=false"
+          "-Dwayland=true"
+        ];
+        buildInputs = (utils.removePackagesByName prevAttrs.buildInputs [
+          prev.xorg.libSM
+          prev.xwayland
+          prev.gtk4
+          prev.xorg.libICE
+          prev.xorg.libX11
+          prev.xorg.libXcomposite
+          prev.xorg.libXcursor
+          prev.xorg.libXdamage
+          prev.xorg.libXext
+          prev.xorg.libXfixes
+          prev.xorg.libXi
+          prev.xorg.libXtst
+          prev.xorg.libxkbfile
+          prev.xkeyboard_config
+          prev.xorg.libxcb
+          prev.xorg.libXrandr
+          prev.xorg.libXinerama
+          prev.xorg.libXau
+        ]) ++ [ prev.libGL ];
+        nativeBuildInputs = utils.removePackagesByName prevAttrs.nativeBuildInputs [
+          prev.xorg.xorgserver
+        ];
+      });
+
+      gdm = prev.gdm.overrideAttrs( prevAttrs: {
+        mesonFlags  = prev.lib.lists.remove "--Dgdm-xsession=true" (prevAttrs.mesonFlags ++ [ "-Dgdm-xsession=false" "-Dx11-support=false" ]);
+        patches = [
+          # GDM fails to find g-s with the following error in the journal.
+          # gdm-x-session[976]: dbus-run-session: failed to exec 'gnome-session': No such file or directory
+          # https://gitlab.gnome.org/GNOME/gdm/-/merge_requests/92
+          (prev.fetchpatch {
+            url = "https://gitlab.gnome.org/GNOME/gdm/-/commit/ccecd9c975d04da80db4cd547b67a1a94fa83292.patch";
+            hash = "sha256-5hKS9wjjhuSAYwXct5vS0dPbmPRIINJoLC0Zm1naz6Q=";
+            revert = true;
+          })
+
+          ../../pkgs/gdm-fix-wayland.patch
+
+          # Change hardcoded paths to nix store paths.
+          (prev.substituteAll {
+            src       = ../../pkgs/gdm-fix-paths.patch;
+            coreutils = prev.coreutils;
+            plymouth  = prev.plymouth;
+            dbus      = prev.dbus;
+          })
+        ];
+        postPatch = ''
+          # Reverts https://gitlab.gnome.org/GNOME/gdm/-/commit/b0f802e36ff948a415bfd2bccaa268b6990515b7
+          # The gdm-auth-config tool is probably not too useful for NixOS, but we still want the dconf profile
+          # installed (mostly just because .passthru.tests can make use of it).
+          substituteInPlace meson.build \
+            --replace-fail "dconf_prefix = dconf_dep.get_variable(pkgconfig: 'prefix')" "dconf_prefix = gdm_prefix"
+        '';
+        buildInputs = utils.removePackagesByName prevAttrs.buildInputs [
+          prev.xorg.libX11
+          prev.xorg.libXdmcp
+          prev.xorg.libxcb
+        ];
+      });
+
+      gnome-session = prev.gnome-session.overrideAttrs( prevAttrs: {
+        mesonFlags  = [ "-Dx11=false" ];
+        buildInputs = utils.removePackagesByName prevAttrs.buildInputs [
+          prev.xorg.libICE
+          prev.xorg.xtrans
+        ];
+      });
+
+    })];
+
+    users.groups.gdm.gid = config.ids.gids.gdm;
+    users.users.gdm = {
+      name = "gdm";
+      uid = config.ids.uids.gdm;
+      group = "gdm";
+      home = "/run/gdm";
+      description = "GDM user";
+    };
+
+    security.polkit.enable           = true;
+    networking.networkmanager.enable = lib.mkDefault true;
+
+    hardware = {
+      graphics.enable   = true;
+      bluetooth.enable  = lib.mkDefault true;
+    };
+
+    fonts.packages = with pkgs; [
+      cantarell-fonts
+      dejavu_fonts
+      source-code-pro
+      source-sans
+    ];
+
+    environment = {
+      etc."gdm/custom.conf".source = configFile;
+
+      systemPackages = with pkgs; [
+        gnome-shell
+        (lib.mkIf config.hardware.bluetooth.enable gnome-bluetooth)
+        (lib.mkIf config.services.colord.enable gnome-color-manager)
+        gnome-control-center
+        ghostty
+        nautilus
+        sushi #quick-preview for nautilus
+        adwaita-icon-theme
+        sound-theme-freedesktop
+        nixos-icons
+        nixos-background-info
+        glib # for gsettings program
+        gnome-menus
+        gtk3.out # for gtk-launch program
+        xdg-user-dirs # Update user dirs as described in https://freedesktop.org/wiki/Software/xdg-user-dirs/
+        xdg-user-dirs-gtk
+      ];
+
+      # Needed for themes and backgrounds
+      pathsToLink = [
+        "/share" # TODO: https://github.com/NixOS/nixpkgs/issues/47173
+        "/share/nautilus-python/extensions"
+      ];
+
+      sessionVariables = {
+        # Let nautilus find extensions
+        NAUTILUS_4_EXTENSION_DIR = "${config.system.path}/lib/nautilus/extensions-4";
+        # Override default mimeapps for nautilus
+        XDG_DATA_DIRS = [ "${mimeAppsList}/share" ];
+      };
+    };
+
+    services = {
+      gvfs.enable                       = true;
+      udisks2.enable                    = true;
+      libinput.enable                   = true;
+      accounts-daemon.enable            = true;
+      pipewire.enable                   = lib.mkDefault true;
+      hardware.bolt.enable              = lib.mkDefault true;
+      colord.enable                     = lib.mkDefault true;
+      power-profiles-daemon.enable      = lib.mkDefault true;
+      upower.enable                     = config.powerManagement.enable;
+      system-config-printer.enable      = (lib.mkIf config.services.printing.enable (lib.mkDefault true));
+
+      gnome = {
+        glib-networking.enable          = true;
+        gnome-settings-daemon.enable    = true;
+        at-spi2-core.enable             = lib.mkDefault true;
+        gnome-keyring.enable            = lib.mkDefault true;
+      };
+
+      geoclue2 = {
+        enable          = lib.mkDefault true;
+        enableDemoAgent = false; # GNOME has its own geoclue agent
+        appConfig = {
+          gnome-datetime-panel = {
+            isAllowed = true;
+            isSystem = true;
+          };
+          gnome-color-panel = {
+            isAllowed = true;
+            isSystem = true;
+          };
+          "org.gnome.Shell" = {
+            isAllowed = true;
+            isSystem = true;
+          };
+        };
+      };
+
+      udev.packages = [ pkgs.mutter ];
+      dbus.packages = with pkgs; [ gdm sushi ];
+    };
+
+    programs = {
+      dconf.enable                 = true;
+      dconf.profiles.gdm.databases = [
+        { settings = cfg.gdm.dconfSettings; }
+        "${pkgs.gdm}/share/gdm/greeter-dconf-defaults"
+      ];
+    };
+
+    xdg = {
+      mime.enable  = true;
+      icons.enable = true;
+
+      portal = {
+        enable         = true;
+        configPackages = lib.mkDefault [ pkgs.gnome-session ];
+        extraPortals   = with pkgs; [
+          xdg-desktop-portal-gnome
+          xdg-desktop-portal-gtk
+        ];
+      };
+    };
+
+
+    systemd = {
+      packages = with pkgs; [
+        gdm
+        gnome-session
+        gnome-shell
+      ];
+
+      tmpfiles.rules = [ "d /run/gdm/.config 0711 gdm gdm" ];
+
+      user.services.dbus.wantedBy = [ "default.target" ];
+
+      services = {
+        # We dont use the upstream gdm service
+        # it has to be disabled since the gdm package has it
+        # https://github.com/NixOS/nixpkgs/issues/108672
+        gdm.enable = false;
+
+        display-manager = {
+          description = "Display Manager";
+
+          wants     = [ "systemd-machined.service" "accounts-daemon.service" ];
+          conflicts = [ "getty@${pkgs.gdm.initialVT}.service" "plymouth-quit.service" ];
+          onFailure = [ "plymouth-quit.service" ];
+          wantedBy  = [ "multi-user.target" ];
+          after     = [
+            "systemd-logind.service" "systemd-user-sessions.service" "systemd-machined.service"
+            "getty@${pkgs.gdm.initialVT}.service"
+            "acpid.service"
+            "plymouth-quit.service" "plymouth-start.service"
+          ];
+
+          path        = [ pkgs.gnome-session ];
+          environment = {
+            XDG_DATA_DIRS = lib.makeSearchPath "share" (with pkgs; [
+              gdm
+              gnome-session.sessions
+              gnome-control-center # for accessibility icon
+              adwaita-icon-theme
+              hicolor-icon-theme
+            ]);
+          };
+
+          serviceConfig = {
+            KillMode         = "mixed";
+            IgnoreSIGPIPE    = "no";
+            BusName          = "org.gnome.DisplayManager";
+            StandardError    = "inherit";
+            ExecStart        = "${pkgs.gdm}/bin/gdm";
+            ExecReload       = "${pkgs.coreutils}/bin/kill -SIGHUP $MAINPID";
+            KeyringMode      = "shared";
+            EnvironmentFile  = "-/etc/locale.conf";
+            Restart          = "always";
+            RestartSec       = "200ms";
+            SyslogIdentifier = "display-manager";
+          };
+
+          restartIfChanged = false;
+
+          # Stop restarting if the display manager stops (crashes) 2 times in one minute.
+          startLimitIntervalSec = 30;
+          startLimitBurst = 3;
+        };
+
+        # Prevent nixos-rebuild switch from bringing down the graphical
+        # session. (If multi-user.target wants plymouth-quit.service which
+        # conflicts display-manager.service, then when nixos-rebuild
+        # switch starts multi-user.target, display-manager.service is
+        # stopped so plymouth-quit.service can be started.)
+        plymouth-quit = lib.mkIf config.boot.plymouth.enable {
+          wantedBy = lib.mkForce [];
+        };
+      };
+    };
+
+    # 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=/etc/pam/environment readenv=0
+        session  optional       ${config.systemd.package}/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
+      '';
+    };
+  };
+
+}