Home Manager xsession for your default graphical shell on NixOS

To make home.sessionVariables available for graphical (GUI) applications, e.g. to make JAVA_HOME visible to the editor extensions, you need to let Home Manager take over the graphical session by setting xsession.enable = true; and either by choosing a Window Manager or to set the xsession.windowManager.command manually. However, standalone Window Managers are not for everyone, and it’s hard to get the right the correct command (at least for me).

Here’s a simple hack to steal the command from the NixOS configuration:

  1. Find a way to access the NixOS configuration from your Home Manager configuration. The easiest way to do so is by using the Nix Flakes to setup both the NixOS configuration and the Home Manager configuration, and use the specialArgs attribute to pass over the input flakes. Similar strategy also enables local flake-based nix search/run/shell.

The flake.nix for your Home Manager Configuration would look like:

{
  inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixos-21.05";
  inputs.home-manager.url = "github:nix-community/home-manager/release-21.05";
  inputs.home-manager.inputs.nixpkgs.follows = "nixpkgs";
  system-config-flake.url = "git+file:///etc/nixos";

  outputs = inputs@{ self, home-manager, nixpkgs, ... }:
    let
      system = "x86_64-linux";
      username = "shamrock";
      hostname = "nixos-202104";
    in {
      homeConfigurations.${username} = home-manager.lib.homeManagerConfiguration {
        configuration = import ./home.nix;
        inherit system username;
	homeDirectory = "/home/${username}";
        stateVersion = "21.11";
        extraSpecialArgs = {
          inherit (inputs) system-config-flake;
          inherit system hostname;
        };
      };
  };
}
  1. Extract the start command of the chosen DesktopManager / WindowManager and inject to xsession.windowManager.command
{ config, lib, pkgs, system-config-flakes, hostname, ... }:
{
  xsession = {
    enable = true;
    windowManager.command = (lib.findFirst
      (_session: lib.hasInfix "lxqt" _session.name) (abort "Specified session not found")
      system-config-flake.nixosConfigurations.${hostname}.config.services.xserver.displayManager.session
    ).start;
  };
}

Change "lxqt" to the name of the DE or WM you specified for your NixOS system-wide.

  1. Rebuild the Home Manager configuration, activate, and reboot.
    If succeeded, you can now enjoy those variables and settings in your familiar graphical environment!

The trick is that, in the NixOS configuration, config.services.xserver.displayManager.session contains a list of specified graphical shells, each of which provides name attribute with it’s name and a start attribute with the command to start the corresponding xsession. We use these two attribute to get the command we need.

It’s a hack which doesn’t guarantee to work. It may fail, for example, should the command invokes something that requires the root privileges. Nevertheless, it’s still worth a try :grinning_face_with_smiling_eyes:

1 Like