nixos-config/modules/nixos/programs/gnome-session/default.nix
Gabriel Arazas 929d3968ad
programs/gnome-session: set session systemd user units as part of NixOS
While it is nice to have it as part of the desktop session package,
we're missing features which requires reimplementing parts of the
systemd-lib anyways. We can always have this later once this is
upstreamed into nixpkgs where one could modify systemd-lib to split
the unit generation step. Right now, not willing to do that.
2024-01-09 10:45:43 +08:00

182 lines
6.0 KiB
Nix

{ 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. 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;
}
);
}