{
  pkgs,
  config,
  lib,
  ...
}:
{
  imports = [
    ./audio
    ./autorandr
    ./background
    ./browser
    ./frobar/module.nix
    ./i3.nix
    ./lock
    ./mpd
    ./presentation
    ./redness
    ./screenshots
    ./terminal
  ];
  config = lib.mkIf config.frogeye.desktop.xorg {
    xsession = {
      enable = true;
      # Not using config.xdg.configHome because it needs to be $HOME-relative paths and path manipulation is hard
      scriptPath = ".config/xsession";
      profilePath = ".config/xprofile";
      windowManager = {
        i3.enable = true;
      };
      numlock.enable = config.frogeye.desktop.numlock;
    };

    programs = {
      # Terminal
      bash.shellAliases = {
        x = "startx ${config.home.homeDirectory}/${config.xsession.scriptPath}; logout";
        lmms = "lmms --config ${config.xdg.configHome}/lmmsrc.xml";
      };
      rofi = {
        # TODO This theme template, that was used for Arch, looks much better:
        # https://gitlab.com/jordiorlando/base16-rofi/-/blob/master/templates/default.mustache
        enable = true;
        pass.enable = true;
        extraConfig = {
          lazy-grab = false;
          matching = "regex";
        };
      };
      mpv = {
        enable = true;
        config = {
          audio-display = false;
          save-position-on-quit = true;
          osc = false; # Required by thumbnail script
          # Hardware acceleration (from https://nixos.wiki/wiki/Accelerated_Video_Playback#MPV, vo=gpu already default)
          hwdec = "auto-safe";
          profile = "gpu-hq";
        };
        scripts = with pkgs.mpvScripts; [
          thumbnail
          mpris
        ];
        scriptOpts = {
          mpv_thumbnail_script = {
            autogenerate = false; # TODO It creates too many processes at once, crashing the system
            cache_directory = "/tmp/mpv_thumbs_${config.home.username}";
            mpv_hwdec = "auto-safe";
          };
        };
      };
    };

    xdg = {
      userDirs =
        let
          wellKnownUserDirs = [
            "desktop"
            "documents"
            "download"
            "music"
            "pictures"
            "publicShare"
            "templates"
            "videos"
          ];
          wellKnownUserDirsNulled = builtins.listToAttrs (
            builtins.map (name: {
              inherit name;
              value = null;
            }) wellKnownUserDirs
          );
          allFolders = builtins.attrValues config.frogeye.folders;
          folders = builtins.filter (
            folder: folder.xdgUserDirVariable != null && folder.user == config.home.username
          ) allFolders;
        in
        {
          enable = true;
          createDirectories = true;
          extraConfig = builtins.listToAttrs (
            builtins.map (folder: {
              name = folder.xdgUserDirVariable;
              value = "${config.home.homeDirectory}/${folder.path}";
            }) folders
          );
        }
        // wellKnownUserDirsNulled; # Don't use defaults dirs
    };
    services = {
      blueman-applet.enable = true;
      unclutter.enable = true;
      dunst = {
        enable = true;
        settings =
          # TODO Change dmenu for rofi, so we can use context
          with config.lib.stylix.colors.withHashtag; {
            global = {
              separator_color = lib.mkForce base05;
              idle_threshold = 120;
              markup = "full";
              max_icon_size = 48;
              # TODO Those shortcuts don't seem to work, maybe try:
              # > define shortcuts inside your window manager and bind them to dunstctl(1) commands
              close_all = "ctrl+mod4+n";
              close = "mod4+n";
              context = "mod1+mod4+n";
              history = "shift+mod4+n";
            };

            urgency_low = {
              background = lib.mkForce base01;
              foreground = lib.mkForce base03;
              frame_color = lib.mkForce base05;
            };
            urgency_normal = {
              background = lib.mkForce base02;
              foreground = lib.mkForce base05;
              frame_color = lib.mkForce base05;
            };
            urgency_critical = {
              background = lib.mkForce base08;
              foreground = lib.mkForce base06;
              frame_color = lib.mkForce base05;
            };
          };
      };
    };

    home = {
      file = {
        ".face" = {
          # TODO Only works on pindakaas? See https://wiki.archlinux.org/title/LightDM#Changing_your_avatar
          source =
            pkgs.runCommand "face.png" { }
              "${pkgs.inkscape}/bin/inkscape ${./face.svg} -w 1024 -o $out";
        };
      };
      packages = with pkgs; [
        # remote
        tigervnc

        # multimedia common
        gimp
        inkscape
        libreoffice

        # data management
        freefilesync

        # misc
        gedit
        xfce.thunar
        nomacs
        feh
        zbar
        evince
        zathura
        meld
        python3Packages.magic

        # x11-exclusive
        simplescreenrecorder
        trayer
        xclip
        keynav
        xorg.xinit
        scrot
      ];
      sessionVariables = {
        # XAUTHORITY = "${config.xdg.configHome}/Xauthority"; # Disabled as this causes lock-ups with DMs
      };
    };
  };
}