home-manager/modules/xsession.nix
Robert Helgesson 9c859d2655
xmonad: add module
Adapted from #78 and originally authored by Infinisil.
2017-10-04 20:36:31 +02:00

177 lines
4.9 KiB
Nix

{ config, lib, pkgs, ... }:
with lib;
with import ./lib/dag.nix { inherit lib; };
let
cfg = config.xsession;
# Hack to support xsession.windowManager.command option.
wmBaseModule = {
options = {
command = mkOption {
type = types.str;
example = literalExample ''
let
xmonad = pkgs.xmonad-with-packages.override {
packages = self: [ self.xmonad-contrib self.taffybar ];
};
in
"''${xmonad}/bin/xmonad";
'';
description = ''
Window manager start command.
'';
};
usesDeprecated = mkOption {
internal = true;
type = types.bool;
default = false;
};
};
};
xmonadModule = import ./services/window-managers/xmonad.nix {
inherit pkgs;
};
in
{
meta.maintainers = [ maintainers.rycee ];
options = {
xsession = {
enable = mkEnableOption "X Session";
windowManager = mkOption {
type =
types.coercedTo
types.str
(command: { inherit command; usesDeprecated = true; })
(types.submodule [ wmBaseModule xmonadModule ]);
description = ''
Window manager start command. DEPRECATED: Use
<varname>xsession.windowManager.command</varname> instead.
'';
};
initExtra = mkOption {
type = types.lines;
default = "";
description = "Extra shell commands to run during initialization.";
};
};
};
config = mkIf cfg.enable (mkMerge [
(mkIf cfg.windowManager.usesDeprecated {
warnings = [
("xsession.windowManager is deprecated, "
+ "please use xsession.windowManager.command")
];
})
# Hack to support xsession.windowManager as a string. Once that is
# removed this code should go back into the xmonad.nix file.
(mkIf (cfg.windowManager.xmonad.enable
&& cfg.windowManager.xmonad.config != null) {
home.file.".xmonad/xmonad.hs".source = cfg.windowManager.xmonad.config;
home.activation.checkXmonad = dagEntryBefore [ "linkGeneration" ] ''
if ! cmp --quiet \
"${cfg.windowManager.xmonad.config}" \
"$HOME/.xmonad/xmonad.hs"; then
xmonadChanged=1
fi
'';
home.activation.applyXmonad = dagEntryAfter [ "linkGeneration" ] ''
if [[ -v xmonadChanged ]]; then
echo "Recompiling xmonad"
${cfg.windowManager.command} --recompile
# Attempt to restart xmonad if X is running.
if [[ -v DISPLAY ]] ; then
echo "Restarting xmonad"
${cfg.windowManager.command} --restart
fi
fi
'';
})
{
systemd.user.services.setxkbmap = {
Unit = {
Description = "Set up keyboard in X";
After = [ "graphical-session-pre.target" ];
PartOf = [ "graphical-session.target" ];
};
Install = {
WantedBy = [ "graphical-session.target" ];
};
Service = {
Type = "oneshot";
ExecStart =
let
args = concatStringsSep " " (
[
"-layout '${config.home.keyboard.layout}'"
"-variant '${config.home.keyboard.variant}'"
] ++
(map (v: "-option '${v}'") config.home.keyboard.options)
);
in
"${pkgs.xorg.setxkbmap}/bin/setxkbmap ${args}";
};
};
# A basic graphical session target for Home Manager.
systemd.user.targets.hm-graphical-session = {
Unit = {
Description = "Home Manager X session";
Requires = [ "graphical-session-pre.target" ];
BindsTo = [ "graphical-session.target" ];
};
};
home.file.".xsession" = {
mode = "555";
text = ''
if [[ -e "$HOME/.profile" ]]; then
. "$HOME/.profile"
fi
# If there are any running services from a previous session.
systemctl --user stop graphical-session.target graphical-session-pre.target
systemctl --user import-environment DBUS_SESSION_BUS_ADDRESS
systemctl --user import-environment DISPLAY
systemctl --user import-environment SSH_AUTH_SOCK
systemctl --user import-environment XAUTHORITY
systemctl --user import-environment XDG_DATA_DIRS
systemctl --user import-environment XDG_RUNTIME_DIR
systemctl --user import-environment XDG_SESSION_ID
systemctl --user start hm-graphical-session.target
${cfg.initExtra}
${cfg.windowManager.command}
systemctl --user stop graphical-session.target
systemctl --user stop graphical-session-pre.target
# Wait until the units actually stop.
while [[ -n "$(systemctl --user --no-legend --state=deactivating list-units)" ]]; do
sleep 0.5
done
'';
};
}
]);
}