{ config, lib, pkgs, utils, ... }@moduleArgs: let cfg = config.programs.gnome-session; inherit (import ./submodules.nix moduleArgs) sessionType; in { options.programs.gnome-session = { package = lib.mkOption { type = lib.types.package; default = pkgs.gnome.gnome-session; defaultText = "pkgs.gnome.gnome-session"; description = '' The package containing gnome-session binary and systemd units. This module will use the `gnome-session` executable for the generated session script. ''; }; sessions = lib.mkOption { type = with lib.types; attrsOf (submodule sessionType); description = '' A set of desktop sessions to be created with {manpage}`gnome-session(1)`. This gnome-session configuration generates both the `.desktop` file and systemd units to be able to support both the built-in and the systemd-managed GNOME session. Each of the attribute name will be used as the identifier of the desktop environment. ::: {.tip} While you can make identifiers in any way, it is encouraged to stick to a naming scheme. Here's two common ways to name a desktop environment. * Reverse DNS-like scheme (e.g., `com.example.MoseyBranch`). * Kebab-case (e.g., `mosey-branch`). ::: ''; default = { }; example = lib.literalExpression '' { "gnome-minimal" = let sessionCfg = config.programs.gnome-session.sessions."gnome-minimal"; in { fullName = "GNOME (minimal)"; description = "Minimal GNOME session"; display = [ "wayland" "xorg" ]; extraArgs = [ "--systemd" ]; requiredComponents = let gsdComponents = builtins.map (gsdc: "org.gnome.SettingsDaemon.''${gsdc}") [ "A11ySettings" "Color" "Housekeeping" "Power" "Keyboard" "Sound" "Wacom" "XSettings" ]; in gsdComponents ++ [ "org.gnome.Shell" ]; targetUnit = { requires = [ "org.gnome.Shell.target" ]; wants = builtins.map (c: "''${c}.target") (lib.lists.remove "org.gnome.Shell" sessionCfg.requiredComponents); }; }; "one.foodogsquared.SimpleWay" = { fullName = "Simple Way"; description = "A desktop environment featuring Sway window manager."; display = [ "wayland" ]; extraArgs = [ "--systemd" ]; components = { # This unit is intended to start with gnome-session. window-manager = { script = ''' ''${lib.getExe' config.programs.sway.package "sway"} --config ''${./config/sway/config} '''; description = "An i3 clone for Wayland."; serviceUnit = { serviceConfig = { Type = "notify"; NotifyAccess = "all"; OOMScoreAdjust = -1000; }; unitConfig = { OnFailure = [ "gnome-session-shutdown.target" ]; OnFailureJobMode = "replace-irreversibly"; }; }; targetUnit = { requisite = [ "gnome-session-initialized.target" ]; partOf = [ "gnome-session-initialized.target" ]; before = [ "gnome-session-initialized.target" ]; }; }; desktop-widgets = { script = ''' ''${lib.getExe' pkgs.ags "ags"} --config ''${./config/ags/config.js} '''; description = "A desktop widget system using layer-shell protocol."; serviceUnit = { serviceConfig = { OOMScoreAdjust = -1000; }; path = with pkgs; [ ags ]; startLimitBurst = 5; startLimitIntervalSec = 15; }; targetUnit = { requisite = [ "gnome-session-initialized.target" ]; partOf = [ "gnome-session-initialized.target" ]; before = [ "gnome-session-initialized.target" ]; }; }; auth-agent = { script = "''${pkgs.polkit_gnome}/libexec/polkit-gnome-authentication-agent-1"; description = "Authentication agent"; serviceUnit = { startLimitBurst = 5; startLimitIntervalSec = 15; }; targetUnit = { partOf = [ "gnome-session.target" "graphical-session.target" ]; requisite = [ "gnome-session.target" ]; after = [ "gnome-session.target" ]; }; }; }; }; } ''; }; }; config = lib.mkIf (cfg.sessions != { }) ( let sessionPackages = lib.mapAttrsToList (_: session: session.sessionPackage) cfg.sessions; sessionSystemdUnits = lib.mapAttrsToList (_: session: session.systemdUserUnits) cfg.sessions; in { # Install all of the desktop session files. services.xserver.displayManager.sessionPackages = sessionPackages; environment.systemPackages = [ cfg.package ] ++ sessionPackages; # Make sure it is searchable within gnome-session. environment.pathsToLink = [ "/share/gnome-session" ]; # Import those systemd units from gnome-session as well. systemd.packages = [ cfg.package ]; systemd.user.units = lib.mkMerge sessionSystemdUnits; } ); }