river: add systemd.runInService option
Add a runInService option that allows users to run `systemctl --user start river`. This makes lifecycles of river be managed by systemd and fixes long shutdown times & graphics-session.target not stopping.
This commit is contained in:
parent
465ea1f994
commit
6e9380d426
|
@ -1,16 +1,14 @@
|
||||||
{ config, lib, pkgs, ... }:
|
{ config, lib, pkgs, ... }:
|
||||||
|
|
||||||
let
|
let
|
||||||
inherit (lib) types;
|
inherit (lib) types;
|
||||||
cfg = config.wayland.windowManager.river;
|
cfg = config.wayland.windowManager.river;
|
||||||
|
|
||||||
# Systemd integration
|
# Systemd integration
|
||||||
variables = builtins.concatStringsSep " " cfg.systemd.variables;
|
variables = builtins.concatStringsSep " " cfg.systemd.variables;
|
||||||
extraCommands = builtins.concatStringsSep " "
|
systemdActivation = builtins.concatStringsSep " && " ([
|
||||||
(map (f: "&& ${f}") cfg.systemd.extraCommands);
|
"${pkgs.dbus}/bin/dbus-update-activation-environment --systemd ${variables}"
|
||||||
systemdActivation = ''
|
] ++ (lib.optional cfg.systemd.runInService "systemd-notify --ready")
|
||||||
${pkgs.dbus}/bin/dbus-update-activation-environment --systemd ${variables} ${extraCommands}
|
++ cfg.systemd.extraCommands);
|
||||||
'';
|
|
||||||
|
|
||||||
toValue = val:
|
toValue = val:
|
||||||
if lib.isString val || lib.isDerivation val then
|
if lib.isString val || lib.isDerivation val then
|
||||||
|
@ -28,7 +26,6 @@ let
|
||||||
|
|
||||||
# Intermediary function that converts some value (attrs, str, ...) to one or several commands.
|
# Intermediary function that converts some value (attrs, str, ...) to one or several commands.
|
||||||
toArgs = path: value:
|
toArgs = path: value:
|
||||||
|
|
||||||
let
|
let
|
||||||
stringValue = lib.concatStringsSep " " (path ++ [ (toValue value) ]);
|
stringValue = lib.concatStringsSep " " (path ++ [ (toValue value) ]);
|
||||||
finalValue = if lib.isAttrs value then
|
finalValue = if lib.isAttrs value then
|
||||||
|
@ -47,7 +44,6 @@ let
|
||||||
toCommand = basePath: attrs:
|
toCommand = basePath: attrs:
|
||||||
lib.concatLists (lib.mapAttrsToList
|
lib.concatLists (lib.mapAttrsToList
|
||||||
(key: value: let path = basePath ++ [ key ]; in toArgs path value) attrs);
|
(key: value: let path = basePath ++ [ key ]; in toArgs path value) attrs);
|
||||||
|
|
||||||
in {
|
in {
|
||||||
meta.maintainers = [ lib.maintainers.GaetanLepage ];
|
meta.maintainers = [ lib.maintainers.GaetanLepage ];
|
||||||
|
|
||||||
|
@ -81,6 +77,25 @@ in {
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
runInService = lib.mkEnableOption null // {
|
||||||
|
default = false;
|
||||||
|
description = ''
|
||||||
|
Whether river should run inside systemd (`true`) or outside of systemd
|
||||||
|
(`false`).
|
||||||
|
|
||||||
|
Running inside systemd means river lifecycle is fully known/managed by
|
||||||
|
systemd. Stopping your computer or river crashing will stop the
|
||||||
|
appropriate targets and will make sure everything stays in sync.
|
||||||
|
|
||||||
|
If river runs inside systemd, river logs will be available with
|
||||||
|
{command}`journalctl`.
|
||||||
|
|
||||||
|
To start river, you will need to run
|
||||||
|
{command}`systemctl --user start river`
|
||||||
|
and not run it from the command line.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
variables = lib.mkOption {
|
variables = lib.mkOption {
|
||||||
type = types.listOf types.str;
|
type = types.listOf types.str;
|
||||||
default = [
|
default = [
|
||||||
|
@ -100,10 +115,11 @@ in {
|
||||||
|
|
||||||
extraCommands = lib.mkOption {
|
extraCommands = lib.mkOption {
|
||||||
type = types.listOf types.str;
|
type = types.listOf types.str;
|
||||||
default = [
|
default = if (!cfg.systemd.runInService) then [
|
||||||
"systemctl --user stop river-session.target"
|
"systemctl --user stop river-session.target"
|
||||||
"systemctl --user start river-session.target"
|
"systemctl --user start river-session.target"
|
||||||
];
|
] else
|
||||||
|
[ ];
|
||||||
description = "Extra commands to be run after D-Bus activation.";
|
description = "Extra commands to be run after D-Bus activation.";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
@ -180,16 +196,17 @@ in {
|
||||||
### SHELL VARIABLES ###
|
### SHELL VARIABLES ###
|
||||||
${config.lib.shell.exportAll cfg.extraSessionVariables}
|
${config.lib.shell.exportAll cfg.extraSessionVariables}
|
||||||
|
|
||||||
|
'' + (lib.optionalString cfg.systemd.enable ''
|
||||||
|
### SYSTEMD INTEGRATION ###
|
||||||
|
${systemdActivation}
|
||||||
|
'') + ''
|
||||||
|
|
||||||
### CONFIGURATION ###
|
### CONFIGURATION ###
|
||||||
${lib.concatStringsSep "\n" (toCommand [ "riverctl" ] cfg.settings)}
|
${lib.concatStringsSep "\n" (toCommand [ "riverctl" ] cfg.settings)}
|
||||||
|
|
||||||
### EXTRA CONFIGURATION ###
|
### EXTRA CONFIGURATION ###
|
||||||
${cfg.extraConfig}
|
${cfg.extraConfig}
|
||||||
|
'');
|
||||||
'' + (lib.optionalString cfg.systemd.enable ''
|
|
||||||
### SYSTEMD INTEGRATION ###
|
|
||||||
${systemdActivation}
|
|
||||||
''));
|
|
||||||
|
|
||||||
# Systemd integration
|
# Systemd integration
|
||||||
systemd.user.targets.river-session = lib.mkIf cfg.systemd.enable {
|
systemd.user.targets.river-session = lib.mkIf cfg.systemd.enable {
|
||||||
|
@ -197,8 +214,31 @@ in {
|
||||||
Description = "river compositor session";
|
Description = "river compositor session";
|
||||||
Documentation = [ "man:systemd.special(7)" ];
|
Documentation = [ "man:systemd.special(7)" ];
|
||||||
BindsTo = [ "graphical-session.target" ];
|
BindsTo = [ "graphical-session.target" ];
|
||||||
|
Before = [ "graphical-session.target" ];
|
||||||
Wants = [ "graphical-session-pre.target" ];
|
Wants = [ "graphical-session-pre.target" ];
|
||||||
After = [ "graphical-session-pre.target" ];
|
After = [ "graphical-session-pre.target" ];
|
||||||
|
RefuseManualStart = if cfg.systemd.runInService then "yes" else "no";
|
||||||
|
StopWhenUnneeded = "yes";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
systemd.user.services.river =
|
||||||
|
lib.mkIf (cfg.systemd.enable && cfg.systemd.runInService) {
|
||||||
|
Unit = {
|
||||||
|
Description = "River compositor";
|
||||||
|
Documentation = "man:river(1)";
|
||||||
|
BindsTo = [ "river-session.target" ];
|
||||||
|
Before = [ "river-session.target" ];
|
||||||
|
};
|
||||||
|
|
||||||
|
Service = {
|
||||||
|
Type = "notify";
|
||||||
|
# /bin/sh -lc is used to get env/session vars (and path).
|
||||||
|
ExecStart = "/bin/sh -lc ${pkgs.river}/bin/river";
|
||||||
|
TimeoutStopSec = 10;
|
||||||
|
NotifyAccess = "all";
|
||||||
|
ExecStopPost =
|
||||||
|
"${pkgs.systemd}/bin/systemctl --user unset-environment ${variables}";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,9 @@ export BAR="bar"
|
||||||
export FOO="foo"
|
export FOO="foo"
|
||||||
export FOURTY_TWO="42"
|
export FOURTY_TWO="42"
|
||||||
|
|
||||||
|
### SYSTEMD INTEGRATION ###
|
||||||
|
@dbus@/bin/dbus-update-activation-environment --systemd DISPLAY WAYLAND_DISPLAY XDG_CURRENT_DESKTOP NIXOS_OZONE_WL XCURSOR_THEME XCURSOR_SIZE && systemctl --user stop river-session.target && systemctl --user start river-session.target
|
||||||
|
|
||||||
### CONFIGURATION ###
|
### CONFIGURATION ###
|
||||||
riverctl attach-mode bottom
|
riverctl attach-mode bottom
|
||||||
riverctl background-color 0x002b36
|
riverctl background-color 0x002b36
|
||||||
|
@ -61,7 +64,3 @@ some
|
||||||
extra config
|
extra config
|
||||||
|
|
||||||
|
|
||||||
### SYSTEMD INTEGRATION ###
|
|
||||||
@dbus@/bin/dbus-update-activation-environment --systemd DISPLAY WAYLAND_DISPLAY XDG_CURRENT_DESKTOP NIXOS_OZONE_WL XCURSOR_THEME XCURSOR_SIZE && systemctl --user stop river-session.target && systemctl --user start river-session.target
|
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue