Programs.xfconf.enable in configuration.nix not working

Last week I decided to try NixOS. First I imported a standard ova in VirtualBox, after that I went on to install a xfce desktop from the minimal iso. Because I don’t want some apps preinstalled, I copied a lot of settings from xfce.nix to configuration.nix and customized it to my needs. It was trial and error, but I got it working.

Most information came from Google and, of course, the manual. However, not all is explained, at least I could not find the answers.

  • What is the difference between local installed packages with nix-env and packages installed through users.users.<user>.packages in configuration.nix?
  • In xfce.nix there is a line programs.xfconf.enable = true;. When I copy this line to configuration.nix, nixos-build says that there is no xfconf in programs. When I comment this line out, everything is fine. What am I missing here?

Can someone point me in the right direction?

Mainly that one is imperative and the other is declarative.

Also, since nixos-rebuild does not support writing directly to user’s home directory, the users.users.<name>.packages option affects /etc/profiles/per-user/$name profile, whereas nix-env manages the profile in ~/.nix-profile.

Could you share the complete config? Or maybe what you are trying to achieve?

Thanks for explaining. I believe the preferred method is declarative?

As for the second part, I’m trying to duplicate the desktop I have on my Ubuntu machine. When I have done this in VirtualBox, I can use the configuration.nix to replace Ubuntu with NixOS.
My starting point was xfce.nix:

{ config, lib, pkgs, ... }:

with lib;

let
  cfg = config.services.xserver.desktopManager.xfce;

in
{
  meta = {
    maintainers = teams.xfce.members;
  };

  imports = [
    ...
  ];

  options = {
    services.xserver.desktopManager.xfce = {
      ...
    };
  };

  config = mkIf cfg.enable {
    environment.systemPackages = with pkgs.xfce // pkgs; [
      glib # for gsettings
      gtk3.out # gtk-update-icon-cache

      gnome.gnome-themes-extra
      gnome.adwaita-icon-theme
      hicolor-icon-theme
      tango-icon-theme
      xfce4-icon-theme

      desktop-file-utils
      shared-mime-info # for update-mime-database

      # For a polkit authentication agent
      polkit_gnome

      # Needed by Xfce's xinitrc script
      xdg-user-dirs # Update user dirs as described in https://freedesktop.org/wiki/Software/xdg-user-dirs/

      exo
      garcon
      libxfce4ui

      mousepad
      parole
      ristretto
      xfce4-appfinder
      xfce4-notifyd
      xfce4-screenshooter
      xfce4-session
      xfce4-settings
      xfce4-taskmanager
      xfce4-terminal
    ] # TODO: NetworkManager doesn't belong here
      ++ optional config.networking.networkmanager.enable networkmanagerapplet
      ++ optional config.powerManagement.enable xfce4-power-manager
      ++ optionals config.hardware.pulseaudio.enable [
        pavucontrol
        # volume up/down keys support:
        # xfce4-pulseaudio-plugin includes all the functionalities of xfce4-volumed-pulse
        # but can only be used with xfce4-panel, so for no-desktop usage we still include
        # xfce4-volumed-pulse
        (if cfg.noDesktop then xfce4-volumed-pulse else xfce4-pulseaudio-plugin)
      ] ++ optionals cfg.enableXfwm [
        xfwm4
        xfwm4-themes
      ] ++ optionals (!cfg.noDesktop) [
        xfce4-panel
        xfdesktop
      ] ++ optional cfg.enableScreensaver xfce4-screensaver;

    programs.xfconf.enable = true;
    programs.thunar.enable = true;

    environment.pathsToLink = [
      "/share/xfce4"
      "/lib/xfce4"
      "/share/gtksourceview-3.0"
      "/share/gtksourceview-4.0"
    ];

    services.xserver.desktopManager.session = [{
      name = "xfce";
      desktopNames = [ "XFCE" ];
      bgSupport = true;
      start = ''
        ${pkgs.runtimeShell} ${pkgs.xfce.xfce4-session.xinitrc} &
        waitPID=$!
      '';
    }];

    services.xserver.updateDbusEnvironment = true;
    services.xserver.gdk-pixbuf.modulePackages = [ pkgs.librsvg ];

    # Enable helpful DBus services.
    services.udisks2.enable = true;
    security.polkit.enable = true;
    services.accounts-daemon.enable = true;
    services.upower.enable = config.powerManagement.enable;
    services.gnome.glib-networking.enable = true;
    services.gvfs.enable = true;
    services.tumbler.enable = true;
    services.system-config-printer.enable = (mkIf config.services.printing.enable (mkDefault true));
    services.xserver.libinput.enable = mkDefault true; # used in xfce4-settings-manager

    # Enable default programs
    programs.dconf.enable = true;

    # Shell integration for VTE terminals
    programs.bash.vteIntegration = mkDefault true;
    programs.zsh.vteIntegration = mkDefault true;

    # Systemd services
    systemd.packages = with pkgs.xfce; [
      xfce4-notifyd
    ];

    security.pam.services.xfce4-screensaver.unixAuth = cfg.enableScreensaver;
  };
}

I have copied the settings from config = mkIf cfg.enable in configuration.nix which looks like this:

# Edit this configuration file to define what should be installed on
# your system.  Help is available in the configuration.nix(5) man page
# and in the NixOS manual (accessible by running ‘nixos-help’).

{ config, lib, pkgs, ... }:

{
  imports =
    [ # Include the results of the hardware scan.
      ./hardware-configuration.nix
    ];

  # Use the GRUB 2 boot loader.
  boot.loader.grub.enable = true;
  boot.loader.grub.version = 2;
  # boot.loader.grub.efiSupport = true;
  # boot.loader.grub.efiInstallAsRemovable = true;
  # boot.loader.efi.efiSysMountPoint = "/boot/efi";
  # Define on which hard drive you want to install Grub.
  boot.loader.grub.device = "/dev/sda"; # or "nodev" for efi only

  boot.plymouth.enable = true;

  # networking.hostName = "nixos"; # Define your hostname.
  # Pick only one of the below networking options.
  # networking.wireless.enable = true;  # Enables wireless support via wpa_supplicant.
  networking.networkmanager.enable = true;  # Easiest to use and most distros use this by default.

  # Set your time zone.
  time.timeZone = "Europe/Amsterdam";

  # Configure network proxy if necessary
  # networking.proxy.default = "http://user:password@proxy:port/";
  # networking.proxy.noProxy = "127.0.0.1,localhost,internal.domain";

  # Select internationalisation properties.
  i18n.defaultLocale = "nl_NL.UTF-8";
  # console = {
  #   font = "Lat2-Terminus16";
  #   keyMap = "us";
  #   useXkbConfig = true; # use xkbOptions in tty.
  # };

  # Enable the X11 windowing system.
  services.xserver.enable = true;
  services.xserver.excludePackages = [ pkgs.xterm ];
  #services.xserver.desktopManager.xfce.enable = true;
  services.xserver.displayManager.defaultSession = "xfce";
  services.xserver.displayManager.lightdm = {
    enable = true;
    greeters.gtk.enable = true;
    greeters.gtk.theme.name = "Arc-Dark";
    greeters.gtk.iconTheme.name = "Papirus-Dark";
    background = "...";
  };
  services.xserver.xautolock.enable = true;

  documentation.nixos.enable = false;

  # Configure keymap in X11
  # services.xserver.layout = "us";
  # services.xserver.xkbOptions = {
  #   "eurosign:e";
  #   "caps:escape" # map caps to escape.
  # };

  # Enable CUPS to print documents.
  # services.printing.enable = true;

  # Enable sound.
  sound.enable = true;
  hardware.pulseaudio.enable = true;

  # Enable touchpad support (enabled default in most desktopManager).
  # services.xserver.libinput.enable = true;

  # Define a user account. Don't forget to set a password with ‘passwd’.
  users.users.me = {
    isNormalUser = true;
    extraGroups = [ "wheel" ]; # Enable ‘sudo’ for the user.
    packages = with pkgs; [
      firefox
      thunderbird
      vlc
    ];
  };

  qt5 = { 
    enable = true; 
    style = lib.mkForce "gtk2"; 
    platformTheme = lib.mkForce "gtk2"; 
  }; 

  # List packages installed in system profile. To search, run:
  # $ nix search wget
  environment.systemPackages = with pkgs; [
    # vim # Do not forget to add an editor to edit configuration.nix! The Nano editor is also installed by default.
    wget
    bamf
    plymouth

    glib # for gsettings
    gtk3.out # gtk-update-icon-cache

    # Uiterlijk
    arc-theme
    papirus-icon-theme
    hicolor-icon-theme
    libsForQt5.qtstyleplugins

    desktop-file-utils
    shared-mime-info # for update-mime-database

    # For a polkit authentication agent
    polkit_gnome

    # Needed by Xfce's xinitrc script
    xdg-user-dirs # Update user dirs as described in https://freedesktop.org/wiki/Software/xdg-user-dirs/

    # Desktop Environment
    xfce.exo
    xfce.garcon
    xfce.libxfce4ui
    xfce.mousepad
    #xfce.parole
    xfce.ristretto
    xfce.xfce4-appfinder
    xfce.xfce4-notifyd
	xfce.xfce4-panel
	xfce.xfce4-power-manager
	xfce.xfce4-pulseaudio-plugin
    xfce.xfce4-screenshooter
    xfce.xfce4-session
    xfce.xfce4-settings
    xfce.xfce4-taskmanager
    xfce.xfce4-terminal
    xfce.xfce4-whiskermenu-plugin
	xfce.xfdesktop
	xfce.xfwm4
    #xfce.xfwm4-themes
    xfce.thunar
    xfce.xfconf
    lightlocker
    pavucontrol
    plank
    networkmanagerapplet
  ];

  #programs.xfconf.enable = true;
  #programs.thunar.enable = true;

  environment.pathsToLink = [
    "/share/xfce4"
    "/lib/xfce4"
    "/share/gtksourceview-3.0"
    "/share/gtksourceview-4.0"
  ];

  services.xserver.desktopManager.session = [{
    name = "xfce";
    name = "xfce";
    desktopNames = [ "XFCE" ];
    bgSupport = true;
    start = ''
      ${pkgs.runtimeShell} ${pkgs.xfce.xfce4-session.xinitrc} &
      waitPID=$!
    '';
  }];

  services.xserver.updateDbusEnvironment = true;
  services.xserver.gdk-pixbuf.modulePackages = [ pkgs.librsvg ];


  # Enable helpful DBus services.
  services.udisks2.enable = true;
  security.polkit.enable = true;
  services.accounts-daemon.enable = true;
  services.upower.enable = config.powerManagement.enable;
  services.gnome.glib-networking.enable = true;
  services.gvfs.enable = true;
  services.tumbler.enable = true;
  #services.system-config-printer.enable = (mkIf config.services.printing.enable (mkDefault true));
  #services.xserver.libinput.enable = mkDefault true; # used in xfce4-settings-manager


  # Enable default programs
  programs.dconf.enable = true;

  # Shell integration for VTE terminals
  programs.bash.vteIntegration = true;
  #programs.zsh.vteIntegration = true;

  # Systemd services
  systemd.packages = with pkgs.xfce; [
    xfce4-notifyd
  ];


  # Some programs need SUID wrappers, can be configured further or are
  # started in user sessions.
  # programs.mtr.enable = true;
  # programs.gnupg.agent = {
  #   enable = true;
  #   enableSSHSupport = true;
  # };

  # List services that you want to enable:

  # Enable the OpenSSH daemon.
  # services.openssh.enable = true;

  # Open ports in the firewall.
  # networking.firewall.allowedTCPPorts = [ ... ];
  # networking.firewall.allowedUDPPorts = [ ... ];
  # Or disable the firewall altogether.
  # networking.firewall.enable = false;

  # Copy the NixOS configuration file and link it from the resulting system
  # (/run/current-system/configuration.nix). This is useful in case you
  # accidentally delete configuration.nix.
  # system.copySystemConfiguration = true;

  # This value determines the NixOS release from which the default
  # settings for stateful data, like file locations and database versions
  # on your system were taken. It‘s perfectly fine and recommended to leave
  # this value at the release version of the first install of this system.
  # Before changing this value read the documentation for this option
  # (e.g. man configuration.nix or on https://nixos.org/nixos/options.html).
  system.stateVersion = "22.05"; # Did you read the comment?
}

The lines programs.xfconf.enable = true; and programs.thunar.enable = true; from xfce.nix do not work directly in configuration.nix. My impression was that the content from xfce.nix was included in configuration.nix. But in configuration.nix xconf and thunar are not in programs.

Yeah, it is one of the main benefits of NixOS.

Looks like those modules were only added recently nixos/xfconf: init by romildo · Pull Request #179220 · NixOS/nixpkgs · GitHub. So you will need to switch to the nixos-unstable channel.

Though why not just add:

services.xserver.desktopManager.xfce.enable = true;

Then you will use the whole Xfce module from your Nixpkgs version, instead of what is essentially maintaining your own fork.

You can always disable the parts you do not like.

Yes, I know I can disable parts of it. I came across services.xserver.excludePackages = [ pkgs.xterm ];. Perhaps it will come to this. But for now I want to experiment with it to see what happens and what remains after I have adjusted everything to my needs. And perhaps I will create an own module for a pentesting distribution (like Kali), just because I can :sunglasses: and it is the way I have learned Linux in the first place

And on a personal note, I prefer to control what is installed instead of excluding packages. For example, you do not know what might change in the future in the xfce module.

I will probably still have some questions in the future, but for now thank you for your explanation.