nixos-config/modules/nixos/programs/sessiond/default.nix
Gabriel Arazas b8616bd7b2
nixos/programs/sessiond: force disabling of default sessiond session
This will completely break if set otherwise so we'll have to force it.
2024-03-06 17:02:08 +08:00

203 lines
6.6 KiB
Nix

{ config, lib, pkgs, utils, ... }:
let
cfg = config.programs.sessiond;
sessionPackages = lib.mapAttrsToList
(name: session:
let
displaySession = ''
[Desktop Entry]
Name=${session.fullName}
Comment=${session.description}
Exec="@out@/libexec/${name}-session"
Type=Application
DesktopNames=${lib.concatStringsSep ";" session.desktopNames};
'';
sessionScript = ''
#!${pkgs.runtimeShell}
${lib.getExe' cfg.package "sessionctl"} run "${name}.target"
'';
in
pkgs.runCommandLocal "${name}-desktop-session-files"
{
inherit displaySession sessionScript;
passAsFile = [ "displaySession" "sessionScript" ];
passthru.providedSessions = [ name ];
}
''
SESSION_SCRIPT="$out/libexec/${name}-session"
install -Dm0755 "$sessionScriptPath" "$SESSION_SCRIPT"
substituteAllInPlace "$SESSION_SCRIPT"
DISPLAY_SESSION_FILE="$out/share/xsessions/${name}.desktop"
install -Dm0644 "$displaySessionPath" "$DISPLAY_SESSION_FILE"
substituteAllInPlace "$DISPLAY_SESSION_FILE"
''
)
cfg.sessions;
sessionSystemdUnits = lib.mapAttrsToList
(name: session:
let
inherit (utils.systemdUtils.lib)
pathToUnit serviceToUnit targetToUnit timerToUnit socketToUnit;
sessionComponents =
lib.foldlAttrs
(acc: name: component:
acc // {
"${component.id}.service" = serviceToUnit component.id component.serviceUnit;
"${component.id}.target" = targetToUnit component.id component.targetUnit;
} // lib.optionalAttrs (component.socketUnit != null) {
"${component.id}.socket" = socketToUnit component.id component.socketUnit;
} // lib.optionalAttrs (component.timerUnit != null) {
"${component.id}.timer" = timerToUnit component.id component.timerUnit;
} // lib.optionalAttrs (component.pathUnit != null) {
"${component.id}.path" = pathToUnit component.id component.pathUnit;
})
{ }
session.components;
in
sessionComponents // {
"${name}.service" = serviceToUnit name session.serviceUnit;
"${name}.target" = targetToUnit name session.targetUnit;
}
)
cfg.sessions;
in
{
options.programs.sessiond = {
enable = lib.mkEnableOption "creating X11-based desktop sessions with sessiond";
package = lib.mkOption {
type = lib.types.package;
default = pkgs.sessiond;
defaultText = "pkgs.sessiond";
description = ''
The package containing sessiond executable and systemd units. This
module will use the `sessiond` executable for the generated session
script.
'';
};
sessions = lib.mkOption {
type = with lib.types; attrsOf (submoduleWith {
specialArgs = {
inherit utils pkgs;
sessiondPkg = cfg.package;
};
modules = [ ./submodules/session-type.nix ];
});
example = lib.literalExpression ''
{
"com.example.Beepeedobolyuessemm" = {
description = "Simple desktop environment featuring bspwm";
desktopNames = [ "Beepeedobolyuessemm" ];
settings = {
Idle = {
Inputs = [ "motion" "button-press" "key-press" ];
IdleSec = 120;
};
Lock = {
OnIdle = true;
OnSleep = true;
MuteAudio = true;
};
Hook = [
{
Trigger = "Idle";
ExecStart = "''${lib.getExe' pkgs.betterlockscreen "betterlockscreen"} --off 240";
}
];
};
components = {
window-manager = {
description = "Window manager";
serviceUnit = {
# This is required for sessiond to recognize which unit is the
# window manager.
aliases = [ "window-manager.service" ];
script = '''
''${lib.getExe' pkgs.bspwm "bspwm"} -c ''${./config/bspwm/bspwmrc}
''';
serviceConfig = {
ExecStopPost = "''${lib.getExe' sessiondPkg "sessionctl"} stop";
OOMScoreAdjust = -1000;
};
};
targetUnit = {
requires = [ "sessiond-session.target" ];
partOf = [ "sessiond-session.target" ];
wantedBy = [ "sessiond-session.target" ];
};
};
hotkey-daemon = {
description = "Hotkey daemon";
serviceUnit = {
documentation = [ "man:sxhkd(1)" ];
script = '''
''${lib.getExe' pkgs.sxhkd "sxhkd"} -c ''${./config/sxhkd/bindings}
''';
serviceConfig = {
ExecReload = "''${lib.getExe' pkgs.coreutils "kill"} -SIGUSR1 $MAINPID";
ExecStopPost = "''${lib.getExe' sessiondPkg "sessionctl"} stop";
OOMScoreAdjust = -1000;
};
};
targetUnit = {
after = [ "display-manager.service" ];
partOf = [ "sessiond-session.target" ];
};
};
};
};
}
'';
description = ''
A set of desktop sessions to be configured with sessiond. 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. The recommended method is a reverse DNS-like scheme
preferably with a domain name you own (e.g.,
`com.example.MoseyBranch`).
:::
'';
default = { };
};
};
config = lib.mkIf (cfg.enable && cfg.sessions != { }) {
environment.systemPackages = [ cfg.package ];
# Install all of the desktop session files.
services.xserver.displayManager.sessionPackages = sessionPackages;
# Import those systemd units from sessiond as well.
systemd.packages = [ cfg.package ];
systemd.user.units = lib.mkMerge sessionSystemdUnits;
# We're disabling the upstream sessiond service since we have our own set
# of sessiond sessions here.
systemd.user.services.sessiond.enable = lib.mkForce false;
};
}