aboutsummaryrefslogtreecommitdiff
path: root/home-manager/modules/xsession.nix
diff options
context:
space:
mode:
Diffstat (limited to 'home-manager/modules/xsession.nix')
-rw-r--r--home-manager/modules/xsession.nix176
1 files changed, 176 insertions, 0 deletions
diff --git a/home-manager/modules/xsession.nix b/home-manager/modules/xsession.nix
new file mode 100644
index 00000000000..e1cf9942e7c
--- /dev/null
+++ b/home-manager/modules/xsession.nix
@@ -0,0 +1,176 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+
+ cfg = config.xsession;
+
+in
+
+{
+ meta.maintainers = [ maintainers.rycee ];
+
+ options = {
+ xsession = {
+ enable = mkEnableOption "X Session";
+
+ scriptPath = mkOption {
+ type = types.str;
+ default = ".xsession";
+ example = ".xsession-hm";
+ description = ''
+ Path, relative <envar>HOME</envar>, where Home Manager
+ should write the X session script.
+ '';
+ };
+
+ windowManager.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.
+ '';
+ };
+
+ preferStatusNotifierItems = mkOption {
+ type = types.bool;
+ default = false;
+ example = true;
+ description = ''
+ Whether tray applets should prefer using the Status Notifier
+ Items (SNI) protocol, commonly called App Indicators. Note,
+ not all tray applets or status bars support SNI.
+ '';
+ };
+
+ profileExtra = mkOption {
+ type = types.lines;
+ default = "";
+ description = "Extra shell commands to run before session start.";
+ };
+
+ initExtra = mkOption {
+ type = types.lines;
+ default = "";
+ description = "Extra shell commands to run during initialization.";
+ };
+
+ importedVariables = mkOption {
+ type = types.listOf (types.strMatching "[a-zA-Z_][a-zA-Z0-9_]*");
+ example = [ "GDK_PIXBUF_ICON_LOADER" ];
+ visible = false;
+ description = ''
+ Environment variables to import into the user systemd
+ session. The will be available for use by graphical
+ services.
+ '';
+ };
+ };
+ };
+
+ config = mkIf cfg.enable {
+ xsession.importedVariables = [
+ "DBUS_SESSION_BUS_ADDRESS"
+ "DISPLAY"
+ "SSH_AUTH_SOCK"
+ "XAUTHORITY"
+ "XDG_DATA_DIRS"
+ "XDG_RUNTIME_DIR"
+ "XDG_SESSION_ID"
+ ];
+
+ systemd.user = {
+ services = mkIf (config.home.keyboard != null) {
+ 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";
+ RemainAfterExit = true;
+ ExecStart =
+ with config.home.keyboard;
+ let
+ args =
+ optional (layout != null) "-layout '${layout}'"
+ ++ optional (variant != null) "-variant '${variant}'"
+ ++ optional (model != null) "-model '${model}'"
+ ++ map (v: "-option '${v}'") options;
+ in
+ "${pkgs.xorg.setxkbmap}/bin/setxkbmap ${toString args}";
+ };
+ };
+ };
+
+ # A basic graphical session target for Home Manager.
+ targets.hm-graphical-session = {
+ Unit = {
+ Description = "Home Manager X session";
+ Requires = [ "graphical-session-pre.target" ];
+ BindsTo = [ "graphical-session.target" ];
+ };
+ };
+ };
+
+ home.file.".xprofile".text = ''
+ . "${config.home.profileDirectory}/etc/profile.d/hm-session-vars.sh"
+
+ if [ -e "$HOME/.profile" ]; then
+ . "$HOME/.profile"
+ fi
+
+ # If there are any running services from a previous session.
+ # Need to run this in xprofile because the NixOS xsession
+ # script starts up graphical-session.target.
+ systemctl --user stop graphical-session.target graphical-session-pre.target
+
+ ${optionalString (cfg.importedVariables != []) (
+ "systemctl --user import-environment "
+ + toString (unique cfg.importedVariables)
+ )}
+
+ ${cfg.profileExtra}
+
+ export HM_XPROFILE_SOURCED=1
+ '';
+
+ home.file.${cfg.scriptPath} = {
+ executable = true;
+ text = ''
+ if [ -z "$HM_XPROFILE_SOURCED" ]; then
+ . ~/.xprofile
+ fi
+ unset HM_XPROFILE_SOURCED
+
+ 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
+ '';
+ };
+ };
+}