1{
2 config,
3 lib,
4 pkgs,
5 ...
6}:
7let
8 cfg = config.services.greetd;
9 tty = "tty${toString cfg.vt}";
10 settingsFormat = pkgs.formats.toml { };
11in
12{
13 options.services.greetd = {
14 enable = lib.mkEnableOption "greetd, a minimal and flexible login manager daemon";
15
16 package = lib.mkPackageOption pkgs [ "greetd" "greetd" ] { };
17
18 settings = lib.mkOption {
19 type = settingsFormat.type;
20 example = lib.literalExpression ''
21 {
22 default_session = {
23 command = "''${pkgs.greetd.greetd}/bin/agreety --cmd sway";
24 };
25 }
26 '';
27 description = ''
28 greetd configuration ([documentation](https://man.sr.ht/~kennylevinsen/greetd/))
29 as a Nix attribute set.
30 '';
31 };
32
33 greeterManagesPlymouth = lib.mkOption {
34 type = lib.types.bool;
35 internal = true;
36 default = false;
37 description = ''
38 Don't configure the greetd service to wait for Plymouth to exit.
39
40 Enable this if the greeter you're using can manage Plymouth itself to provide a smoother handoff.
41 '';
42 };
43
44 vt = lib.mkOption {
45 type = lib.types.int;
46 default = 1;
47 description = ''
48 The virtual console (tty) that greetd should use. This option also disables getty on that tty.
49 '';
50 };
51
52 restart = lib.mkOption {
53 type = lib.types.bool;
54 default = !(cfg.settings ? initial_session);
55 defaultText = lib.literalExpression "!(config.services.greetd.settings ? initial_session)";
56 description = ''
57 Whether to restart greetd when it terminates (e.g. on failure).
58 This is usually desirable so a user can always log in, but should be disabled when using 'settings.initial_session' (autologin),
59 because every greetd restart will trigger the autologin again.
60 '';
61 };
62 };
63 config = lib.mkIf cfg.enable {
64
65 services.greetd.settings.terminal.vt = lib.mkDefault cfg.vt;
66 services.greetd.settings.default_session.user = lib.mkDefault "greeter";
67
68 security.pam.services.greetd = {
69 allowNullPassword = true;
70 startSession = true;
71 enableGnomeKeyring = lib.mkDefault config.services.gnome.gnome-keyring.enable;
72 };
73
74 # This prevents nixos-rebuild from killing greetd by activating getty again
75 systemd.services."autovt@${tty}".enable = false;
76
77 # Enable desktop session data
78 services.displayManager.enable = lib.mkDefault true;
79
80 systemd.services.greetd = {
81 aliases = [ "display-manager.service" ];
82
83 unitConfig = {
84 Wants = [
85 "systemd-user-sessions.service"
86 ];
87 After =
88 [
89 "systemd-user-sessions.service"
90 "getty@${tty}.service"
91 ]
92 ++ lib.optionals (!cfg.greeterManagesPlymouth) [
93 "plymouth-quit-wait.service"
94 ];
95 Conflicts = [
96 "getty@${tty}.service"
97 ];
98 };
99
100 serviceConfig = {
101 ExecStart = "${pkgs.greetd.greetd}/bin/greetd --config ${settingsFormat.generate "greetd.toml" cfg.settings}";
102
103 Restart = lib.mkIf cfg.restart "on-success";
104
105 # Defaults from greetd upstream configuration
106 IgnoreSIGPIPE = false;
107 SendSIGHUP = true;
108 TimeoutStopSec = "30s";
109 KeyringMode = "shared";
110
111 Type = "idle";
112 };
113
114 # Don't kill a user session when using nixos-rebuild
115 restartIfChanged = false;
116
117 wantedBy = [ "graphical.target" ];
118 };
119
120 systemd.defaultUnit = "graphical.target";
121
122 # Create directories potentially required by supported greeters
123 # See https://github.com/NixOS/nixpkgs/issues/248323
124 systemd.tmpfiles.rules = [
125 "d '/var/cache/tuigreet' - greeter greeter - -"
126 ];
127
128 users.users.greeter = {
129 isSystemUser = true;
130 group = "greeter";
131 };
132
133 users.groups.greeter = { };
134 };
135
136 meta.maintainers = with lib.maintainers; [ queezle ];
137}