From a41fefa906c51f950be10dcf25c17a2087b483a9 Mon Sep 17 00:00:00 2001 From: Colin Date: Fri, 1 Sep 2023 23:59:21 +0000 Subject: [PATCH] consolidate greetd stuff out of sway --- hosts/modules/gui/default.nix | 1 + hosts/modules/gui/greetd.nix | 132 +++++++++++++++++++++++++++++ hosts/modules/gui/sway/default.nix | 60 +++---------- 3 files changed, 143 insertions(+), 50 deletions(-) create mode 100644 hosts/modules/gui/greetd.nix diff --git a/hosts/modules/gui/default.nix b/hosts/modules/gui/default.nix index 0a0cd7d8..1cc942e5 100644 --- a/hosts/modules/gui/default.nix +++ b/hosts/modules/gui/default.nix @@ -2,6 +2,7 @@ { imports = [ ./gnome.nix + ./greetd.nix ./gtk.nix ./phosh.nix ./sway diff --git a/hosts/modules/gui/greetd.nix b/hosts/modules/gui/greetd.nix new file mode 100644 index 00000000..ffb6bd5e --- /dev/null +++ b/hosts/modules/gui/greetd.nix @@ -0,0 +1,132 @@ +# greetd source/docs: +# - +{ config, lib, pkgs, ... }: + +let + systemd-cat = "${pkgs.systemd}/bin/systemd-cat"; + runWithLogger = identifier: cmd: pkgs.writeShellScriptBin identifier '' + echo "launching ${identifier}..." | ${systemd-cat} --identifier=${identifier} + ${cmd} 2>&1 | ${systemd-cat} --identifier=${identifier} + ''; + cfg = config.sane.gui.greetd; +in +{ + options = with lib; { + sane.gui.greetd.enable = mkOption { + default = false; + type = types.bool; + }; + sane.gui.greetd.session.command = mkOption { + type = types.string; + }; + sane.gui.greetd.session.name = mkOption { + default = "greetd-session"; + type = types.string; + description = "name of session to use in logger"; + }; + sane.gui.greetd.session.user = mkOption { + default = null; + type = types.nullOr types.string; + }; + + # helpers for common things to layer on top of greetd + sane.gui.greetd.sway.enable = mkOption { + default = false; + type = types.bool; + description = '' + use sway as a wayland compositor in which to host a graphical greeter like gtkgreet, phog, etc. + ''; + }; + sane.gui.greetd.sway.greeterCmd = mkOption { + type = types.nullOr types.string; + default = null; + description = '' + command for sway to `exec` that provides the actual graphical greeter. + ''; + }; + sane.gui.greetd.sway.gtkgreet.enable = mkOption { + default = false; + type = types.bool; + description = '' + have sway launch gtkgreet instead of directly presenting a desktop. + ''; + }; + sane.gui.greetd.sway.gtkgreet.sessionCmd = mkOption { + type = types.string; + description = '' + command for gtkgreet to execute on successful authentication. + ''; + }; + sane.gui.greetd.sway.gtkgreet.sessionName = mkOption { + type = types.string; + description = '' + name to use for the default session in syslog and in the gtkgreet menu. + note that this `sessionName` will become a binary on the user's PATH. + ''; + }; + sane.gui.greetd.sway.gtkgreet.sessionUser = mkOption { + type = types.string; + default = "colin"; + description = '' + name of user which one expects to login as. + ''; + }; + }; + + config = lib.mkIf cfg.enable (lib.mkMerge [ + (lib.mkIf cfg.sway.enable { + sane.gui.greetd.session = if cfg.sway.greeterCmd != null then { + name = "sway-as-greeter"; + command = let + swayAsGreeter = runWithLogger + "sway-as-greeter" + "${pkgs.sway}/bin/sway --debug --config ${swayAsGreeterConfig}"; + swayAsGreeterConfig = pkgs.writeText "sway-as-greeter-config" '' + exec ${cfg.sway.greeterCmd} + ''; + in "${swayAsGreeter}/bin/sway-as-greeter"; + } else { + name = "sway"; + user = lib.mkDefault "colin"; + command = let + swayWithLogging = runWithLogger + "sway" + "${pkgs.sway}/bin/sway --debug"; + in "${swayWithLogging}/bin/sway"; + }; + }) + (lib.mkIf cfg.sway.gtkgreet.enable ( + let + inherit (cfg.sway.gtkgreet) sessionName sessionCmd sessionUser; + sessionProvider = runWithLogger sessionName sessionCmd; + in { + # gtkgreet shows the --command argument in the UI + # - so we want it to look nice (not a /nix/store/... path) + # - to do that we put it in the user's PATH. + sane.gui.greetd.sway.greeterCmd = "${pkgs.greetd.gtkgreet}/bin/gtkgreet --layer-shell --command ${sessionName}"; + users.users.${sessionUser}.packages = [ sessionProvider ]; + } + )) + + { + services.greetd = { + enable = true; + + # i could have gtkgreet launch the session directly: but stdout/stderr gets dropped + # settings.default_session.command = cfg.session.command; + + # wrapper to launch with stdout/stderr redirected to system journal. + settings.default_session.command = let + launchWithLogger = runWithLogger cfg.session.name cfg.session.command; + in "${launchWithLogger}/bin/${cfg.session.name}"; + }; + + # persisting fontconfig & mesa_shader_cache improves start time by ~5x + users.users.greeter.home = "/var/lib/greeter"; + sane.persist.sys.plaintext = [ + { user = "greeter"; group = "greeter"; path = "/var/lib/greeter/.cache/fontconfig"; } + { user = "greeter"; group = "greeter"; path = "/var/lib/greeter/.cache/mesa_shader_cache"; } + ]; + } + ]); +} diff --git a/hosts/modules/gui/sway/default.nix b/hosts/modules/gui/sway/default.nix index d6c0675b..f1440196 100644 --- a/hosts/modules/gui/sway/default.nix +++ b/hosts/modules/gui/sway/default.nix @@ -1,44 +1,11 @@ { config, lib, pkgs, ... }: - + # docs: https://nixos.wiki/wiki/Sway -with lib; let cfg = config.sane.gui.sway; - - # bare sway launcher - sway-launcher = pkgs.writeShellScriptBin "sway-launcher" '' - ${pkgs.sway}/bin/sway --debug > /var/log/sway/sway.log 2>&1 - ''; - # start sway and have it construct the gtkgreeter - sway-as-greeter = pkgs.writeShellScriptBin "sway-as-greeter" '' - ${pkgs.sway}/bin/sway --debug --config ${sway-config-into-gtkgreet} > /var/log/sway/sway-as-greeter.log 2>&1 - ''; - # (config file for the above) - sway-config-into-gtkgreet = pkgs.writeText "greetd-sway-config" '' - exec "${gtkgreet-launcher}" - ''; - # gtkgreet which launches a layered sway instance - gtkgreet-launcher = pkgs.writeShellScript "gtkgreet-launcher" '' - # NB: the "command" field here is run in the user's shell. - # so that command must exist on the specific user's path who is logging in. it doesn't need to exist system-wide. - ${pkgs.greetd.gtkgreet}/bin/gtkgreet --layer-shell --command sway-launcher - ''; - greeter-session = { - # greeter session config - command = "${sway-as-greeter}/bin/sway-as-greeter"; - # alternatives: - # - TTY: `command = "${pkgs.greetd.greetd}/bin/agreety --cmd ${pkgs.sway}/bin/sway";` - # - autologin: `command = "${pkgs.sway}/bin/sway"; user = "colin";` - # - Dumb Login (doesn't work)": `command = "${pkgs.greetd.dlm}/bin/dlm";` - }; - greeterless-session = { - # no greeter - command = "${sway-launcher}/bin/sway-launcher"; - user = "colin"; - }; in { - options = { + options = with lib; { sane.gui.sway.enable = mkOption { default = false; type = types.bool; @@ -52,7 +19,8 @@ in type = types.bool; }; }; - config = mkMerge [ + + config = lib.mkMerge [ { sane.programs.swayApps = { package = null; @@ -75,11 +43,9 @@ in }; } - (mkIf cfg.enable { + (lib.mkIf cfg.enable { sane.programs.fontconfig.enableFor.system = true; sane.programs.swayApps.enableFor.user.colin = true; - # we need the greeter's command to be on our PATH - users.users.colin.packages = [ sway-launcher ]; sane.gui.gtk.enable = lib.mkDefault true; # sane.gui.gtk.gtk-theme = lib.mkDefault "Fluent-Light-compact"; @@ -88,13 +54,12 @@ in # swap in these lines to use SDDM instead of `services.greetd`. # services.xserver.displayManager.sddm.enable = true; # services.xserver.enable = true; - services.greetd = { - # greetd source/docs: - # - + sane.gui.greetd.enable = true; + sane.gui.greetd.sway.enable = true; # have greetd launch a sway compositor in which we host a greeter + sane.gui.greetd.sway.gtkgreet = lib.mkIf cfg.useGreeter { enable = true; - settings = { - default_session = if cfg.useGreeter then greeter-session else greeterless-session; - }; + sessionName = "sway-on-gtkgreet"; + sessionCmd = "${pkgs.sway}/bin/sway --debug"; }; # unlike other DEs, sway configures no audio stack @@ -124,11 +89,6 @@ in # a system service can't depend on a user service, so just launch it at graphical-session systemd.user.services."pipewire".wantedBy = [ "graphical-session.target" ]; - sane.fs."/var/log/sway" = { - dir.acl.mode = "0777"; - wantedBeforeBy = [ "greetd.service" "display-manager.service" ]; - }; - programs.sway = { # provides xdg-desktop-portal-wlr, which exposes on dbus: # - org.freedesktop.impl.portal.ScreenCast