2024-01-24 02:40:22 +00:00
|
|
|
{ config, lib, pkgs, utils, ... }:
|
|
|
|
|
|
|
|
let
|
|
|
|
cfg = config.programs.sessiond;
|
|
|
|
|
|
|
|
sessionPackages = lib.mapAttrsToList
|
2024-05-17 02:56:46 +00:00
|
|
|
(_: session:
|
2024-01-24 02:40:22 +00:00
|
|
|
let
|
|
|
|
displaySession = ''
|
|
|
|
[Desktop Entry]
|
|
|
|
Name=${session.fullName}
|
|
|
|
Comment=${session.description}
|
2024-05-17 02:56:46 +00:00
|
|
|
Exec="@out@/libexec/${session.name}-session"
|
2024-01-24 02:40:22 +00:00
|
|
|
Type=Application
|
|
|
|
DesktopNames=${lib.concatStringsSep ";" session.desktopNames};
|
|
|
|
'';
|
|
|
|
|
|
|
|
sessionScript = ''
|
|
|
|
#!${pkgs.runtimeShell}
|
|
|
|
|
2024-05-17 02:56:46 +00:00
|
|
|
${lib.getExe' cfg.package "sessionctl"} run "${session.name}.target"
|
2024-01-24 02:40:22 +00:00
|
|
|
'';
|
|
|
|
in
|
2024-05-17 02:56:46 +00:00
|
|
|
pkgs.runCommandLocal "${session.name}-desktop-session-files"
|
2024-01-24 02:40:22 +00:00
|
|
|
{
|
|
|
|
inherit displaySession sessionScript;
|
|
|
|
passAsFile = [ "displaySession" "sessionScript" ];
|
2024-05-17 02:56:46 +00:00
|
|
|
passthru.providedSessions = [ session.name ];
|
2024-01-24 02:40:22 +00:00
|
|
|
}
|
|
|
|
''
|
2024-05-17 02:56:46 +00:00
|
|
|
SESSION_SCRIPT="$out/libexec/${session.name}-session"
|
2024-01-24 02:40:22 +00:00
|
|
|
install -Dm0755 "$sessionScriptPath" "$SESSION_SCRIPT"
|
|
|
|
substituteAllInPlace "$SESSION_SCRIPT"
|
|
|
|
|
2024-05-17 02:56:46 +00:00
|
|
|
DISPLAY_SESSION_FILE="$out/share/xsessions/${session.name}.desktop"
|
2024-01-24 02:40:22 +00:00
|
|
|
install -Dm0644 "$displaySessionPath" "$DISPLAY_SESSION_FILE"
|
|
|
|
substituteAllInPlace "$DISPLAY_SESSION_FILE"
|
|
|
|
''
|
|
|
|
)
|
|
|
|
cfg.sessions;
|
|
|
|
|
2024-03-07 07:54:04 +00:00
|
|
|
sessionSystemdUnits = lib.concatMapAttrs
|
2024-01-24 02:40:22 +00:00
|
|
|
(name: session:
|
|
|
|
let
|
|
|
|
inherit (utils.systemdUtils.lib)
|
|
|
|
pathToUnit serviceToUnit targetToUnit timerToUnit socketToUnit;
|
|
|
|
|
2024-04-24 12:59:06 +00:00
|
|
|
mkSystemdUnits = name: component: {
|
2024-05-17 02:56:46 +00:00
|
|
|
"${component.id}.service" = serviceToUnit component.serviceUnit;
|
|
|
|
"${component.id}.target" = targetToUnit component.targetUnit;
|
2024-04-24 12:59:06 +00:00
|
|
|
} // lib.optionalAttrs (component.socketUnit != null) {
|
2024-05-17 02:56:46 +00:00
|
|
|
"${component.id}.socket" = socketToUnit component.socketUnit;
|
2024-04-24 12:59:06 +00:00
|
|
|
} // lib.optionalAttrs (component.timerUnit != null) {
|
2024-05-17 02:56:46 +00:00
|
|
|
"${component.id}.timer" = timerToUnit component.timerUnit;
|
2024-04-24 12:59:06 +00:00
|
|
|
} // lib.optionalAttrs (component.pathUnit != null) {
|
2024-05-17 02:56:46 +00:00
|
|
|
"${component.id}.path" = pathToUnit component.pathUnit;
|
2024-04-24 12:59:06 +00:00
|
|
|
};
|
|
|
|
|
2024-02-02 04:40:16 +00:00
|
|
|
sessionComponents =
|
2024-04-24 12:59:06 +00:00
|
|
|
lib.concatMapAttrs mkSystemdUnits session.components;
|
2024-01-24 02:40:22 +00:00
|
|
|
in
|
2024-02-02 04:40:16 +00:00
|
|
|
sessionComponents // {
|
2024-05-17 02:56:46 +00:00
|
|
|
"${session.name}.service" = serviceToUnit session.serviceUnit;
|
|
|
|
"${session.name}.target" = targetToUnit session.targetUnit;
|
2024-02-02 04:40:16 +00:00
|
|
|
}
|
2024-01-24 02:40:22 +00:00
|
|
|
)
|
|
|
|
cfg.sessions;
|
|
|
|
in
|
|
|
|
{
|
|
|
|
options.programs.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 ];
|
|
|
|
});
|
2024-01-25 04:17:47 +00:00
|
|
|
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" ];
|
|
|
|
};
|
|
|
|
};
|
|
|
|
};
|
|
|
|
};
|
|
|
|
}
|
|
|
|
'';
|
2024-01-24 02:40:22 +00:00
|
|
|
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}
|
2024-02-02 04:40:16 +00:00
|
|
|
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`).
|
2024-01-24 02:40:22 +00:00
|
|
|
:::
|
|
|
|
'';
|
|
|
|
default = { };
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
2024-03-07 07:54:22 +00:00
|
|
|
config = lib.mkIf (cfg.sessions != { }) {
|
2024-01-24 02:40:22 +00:00
|
|
|
environment.systemPackages = [ cfg.package ];
|
|
|
|
|
|
|
|
# Install all of the desktop session files.
|
2024-04-17 05:33:36 +00:00
|
|
|
services.displayManager.sessionPackages = sessionPackages;
|
2024-01-24 02:40:22 +00:00
|
|
|
|
|
|
|
# Import those systemd units from sessiond as well.
|
|
|
|
systemd.packages = [ cfg.package ];
|
2024-03-07 07:54:04 +00:00
|
|
|
systemd.user.units = sessionSystemdUnits;
|
2024-01-24 02:40:22 +00:00
|
|
|
|
2024-01-25 04:17:47 +00:00
|
|
|
# We're disabling the upstream sessiond service since we have our own set
|
|
|
|
# of sessiond sessions here.
|
2024-03-06 09:02:08 +00:00
|
|
|
systemd.user.services.sessiond.enable = lib.mkForce false;
|
2024-01-24 02:40:22 +00:00
|
|
|
};
|
|
|
|
}
|