555 lines
17 KiB
Nix
555 lines
17 KiB
Nix
#
|
|
# Desktop module — import this instead of manual WM/virtualisation imports.
|
|
#
|
|
# Usage in hosts/<hostname>/default.nix:
|
|
#
|
|
# imports = [
|
|
# ./hardware-configuration.nix
|
|
# ../../modules/desktop
|
|
# ];
|
|
#
|
|
# myDesktop.windowManager = "niri"; # niri (default) | sway | kde
|
|
# myDesktop.cpu = "amd"; # amd | intel | none (default)
|
|
#
|
|
# myDesktop.virtualisation.enable = true;
|
|
#
|
|
# myDesktop.syncthing.enable = true;
|
|
# myDesktop.syncthing.devices = { "jupiter.home.example.de" = { id = "XXXXX-..."; }; };
|
|
# myDesktop.syncthing.folders = { "Sync" = { path = "/home/user/Sync"; devices = [...]; }; };
|
|
#
|
|
# myDesktop.openrgb.enable = true;
|
|
# myDesktop.openrgb.motherboard = "amd"; # or "intel"
|
|
#
|
|
# myDesktop.laptop.enable = true;
|
|
# myDesktop.laptop.lidSwitch = "suspend-then-hibernate";
|
|
# myDesktop.laptop.hibernateDelaySec = "1h";
|
|
#
|
|
# myDesktop.nitrokey.enable = true;
|
|
#
|
|
# myDesktop.extraSystemPackages = with pkgs; [ some-tool ];
|
|
#
|
|
{
|
|
config,
|
|
lib,
|
|
pkgs,
|
|
inputs,
|
|
user,
|
|
...
|
|
}: let
|
|
cfg = config.myDesktop;
|
|
in {
|
|
# Hardware modules that are always useful on desktops (bluetooth, …)
|
|
imports = import ../hardware;
|
|
|
|
# ── Options ──────────────────────────────────────────────────────────────
|
|
|
|
options.myDesktop = with lib; {
|
|
windowManager = mkOption {
|
|
type = types.enum ["niri" "sway" "kde"];
|
|
default = "niri";
|
|
description = "Window manager / desktop environment for this host.";
|
|
};
|
|
|
|
cpu = mkOption {
|
|
type = types.enum ["amd" "intel" "none"];
|
|
default = "none";
|
|
description = "CPU type — selects the matching KVM kernel parameters.";
|
|
};
|
|
|
|
virtualisation.enable =
|
|
mkEnableOption "virtualisation stack (podman/docker-compat, qemu/libvirt, virt-manager)";
|
|
|
|
syncthing = {
|
|
enable = mkEnableOption "syncthing continuous file synchronisation";
|
|
devices = mkOption {
|
|
type = types.attrs;
|
|
default = {};
|
|
example =
|
|
literalExpression
|
|
''{ "jupiter.home.example.de" = { id = "XXXXX-XXXXX-XXXXX-..."; }; }'';
|
|
description = "Syncthing peer devices.";
|
|
};
|
|
folders = mkOption {
|
|
type = types.attrs;
|
|
default = {};
|
|
example =
|
|
literalExpression
|
|
''{ "Sync" = { path = "/home/user/Sync"; devices = [ "jupiter" ]; ignorePerms = false; }; }'';
|
|
description = "Syncthing shared folders.";
|
|
};
|
|
};
|
|
|
|
openrgb = {
|
|
enable = mkEnableOption "OpenRGB RGB motherboard control";
|
|
motherboard = mkOption {
|
|
type = types.str;
|
|
default = "amd";
|
|
description = "Motherboard vendor string passed to OpenRGB (amd or intel).";
|
|
};
|
|
};
|
|
|
|
laptop = {
|
|
enable = mkEnableOption "laptop-specific settings (lid-switch, hibernate delay)";
|
|
lidSwitch = mkOption {
|
|
type = types.str;
|
|
default = "suspend-then-hibernate";
|
|
description = "systemd-logind action on lid close.";
|
|
};
|
|
hibernateDelaySec = mkOption {
|
|
type = types.str;
|
|
default = "1h";
|
|
description = "Delay before transitioning from suspend to hibernate.";
|
|
};
|
|
};
|
|
|
|
nitrokey.enable = mkEnableOption "Nitrokey hardware security key support";
|
|
|
|
niri.hotkeyVariant = mkOption {
|
|
type = types.enum ["default" "lifebook"];
|
|
default = "default";
|
|
description = "Niri hotkey variant to deploy — selects binds/<variant>.kdl.";
|
|
};
|
|
|
|
git.signingKey = mkOption {
|
|
type = types.str;
|
|
default = "/home/${user}/.ssh/id_ed25519_sk_rk_red";
|
|
description = "SSH key used for git commit signing on this host.";
|
|
};
|
|
|
|
extraSystemPackages = mkOption {
|
|
type = types.listOf types.package;
|
|
default = [];
|
|
description = "Additional system packages specific to this host.";
|
|
};
|
|
};
|
|
|
|
# ── Configuration ────────────────────────────────────────────────────────
|
|
|
|
config = lib.mkMerge [
|
|
# ── Base desktop config (replaces configuration_desktop.nix) ───────────
|
|
{
|
|
users.users.${user} = {
|
|
isNormalUser = true;
|
|
uid = 2000;
|
|
extraGroups = [
|
|
"wheel"
|
|
"video"
|
|
"audio"
|
|
"camera"
|
|
"networkmanager"
|
|
"lp"
|
|
"kvm"
|
|
"libvirtd"
|
|
"adb"
|
|
"dialout"
|
|
"tss"
|
|
];
|
|
};
|
|
|
|
security = {
|
|
pam.services.login.enableGnomeKeyring = true;
|
|
# swaylock PAM is harmless on non-sway WMs
|
|
pam.services.swaylock = {};
|
|
rtkit.enable = true;
|
|
};
|
|
|
|
environment.systemPackages = with pkgs;
|
|
[
|
|
file
|
|
powertop
|
|
cpufrequtils
|
|
lm_sensors
|
|
libva-utils
|
|
at-spi2-core
|
|
qmk-udev-rules
|
|
gptfdisk
|
|
age-plugin-yubikey
|
|
pwgen
|
|
sbctl
|
|
ausweisapp
|
|
e2fsprogs
|
|
orca-slicer
|
|
]
|
|
++ cfg.extraSystemPackages;
|
|
|
|
nixpkgs.config.permittedInsecurePackages = ["mbedtls-2.28.10"];
|
|
|
|
services = {
|
|
pipewire = {
|
|
enable = true;
|
|
alsa.enable = true;
|
|
pulse.enable = true;
|
|
wireplumber.enable = true;
|
|
};
|
|
pcscd.enable = true;
|
|
yubikey-agent.enable = true;
|
|
udev.packages = with pkgs; [yubikey-personalization nitrokey-udev-rules];
|
|
flatpak.enable = true;
|
|
gvfs.enable = true;
|
|
fwupd.enable = true;
|
|
blueman.enable = true;
|
|
avahi = {
|
|
enable = true;
|
|
nssmdns4 = true;
|
|
publish = {
|
|
enable = true;
|
|
addresses = true;
|
|
userServices = true;
|
|
};
|
|
};
|
|
};
|
|
|
|
programs.dconf.enable = true;
|
|
system.autoUpgrade.enable = false;
|
|
|
|
home-manager.users.${user}.programs.git.signing.key =
|
|
cfg.git.signingKey;
|
|
}
|
|
|
|
# ── Niri ───────────────────────────────────────────────────────────────
|
|
(lib.mkIf (cfg.windowManager == "niri") {
|
|
environment = {
|
|
systemPackages = with pkgs; [
|
|
alacritty
|
|
xdg-desktop-portal-gnome
|
|
xdg-desktop-portal-gtk
|
|
swaylock
|
|
swayidle
|
|
slurp
|
|
grim
|
|
lxqt.lxqt-openssh-askpass
|
|
clinfo
|
|
glib
|
|
brightnessctl
|
|
playerctl
|
|
xwayland-satellite
|
|
breeze-hacked-cursor-theme
|
|
pwvucontrol
|
|
satty
|
|
wl-clipboard
|
|
];
|
|
loginShellInit = ''
|
|
export GTK_IM_MODULE="simple"
|
|
export ELECTRON_OZONE_PLATFORM_HINT="auto"
|
|
export NIXOS_OZONE_WL="1"
|
|
export WLR_RENDERER="vulkan"
|
|
export _JAVA_AWT_WM_NONREPARENTING="1"
|
|
'';
|
|
};
|
|
|
|
services = {
|
|
iio-niri.enable = false;
|
|
greetd = {
|
|
enable = true;
|
|
useTextGreeter = true;
|
|
settings.default_session.command = "${pkgs.tuigreet}/bin/tuigreet --time --cmd niri-session";
|
|
};
|
|
tuned.enable = true;
|
|
upower.enable = true;
|
|
};
|
|
|
|
programs = {
|
|
niri.enable = true;
|
|
ssh.enableAskPassword = true;
|
|
ssh.askPassword = "${pkgs.lxqt.lxqt-openssh-askpass}/bin/lxqt-openssh-askpass";
|
|
};
|
|
|
|
# Noctalia shell + niri home config via home-manager
|
|
home-manager.users.${user} = {
|
|
imports = [
|
|
inputs.noctalia.homeModules.default
|
|
../wm/niri/home.nix
|
|
];
|
|
|
|
xdg.configFile."niri/binds.kdl".source =
|
|
../wm/niri/binds/${cfg.niri.hotkeyVariant}.kdl;
|
|
|
|
services = {
|
|
mako.enable = true;
|
|
polkit-gnome.enable = true;
|
|
};
|
|
|
|
programs = {
|
|
fuzzel.enable = true;
|
|
|
|
noctalia-shell = {
|
|
enable = true;
|
|
settings = {
|
|
appLauncher.terminalCommand = "alacritty -e";
|
|
|
|
bar = {
|
|
density = "compact";
|
|
position = "top";
|
|
showCapsule = false;
|
|
widgets = {
|
|
left = [
|
|
{
|
|
id = "ControlCenter";
|
|
useDistroLogo = true;
|
|
}
|
|
{
|
|
hideUnoccupied = false;
|
|
id = "Workspace";
|
|
labelMode = "index";
|
|
showApplications = true;
|
|
}
|
|
{id = "ActiveWindow";}
|
|
];
|
|
center = [
|
|
{
|
|
formatHorizontal = "HH:mm\\ndd-MM-yy";
|
|
formatVertical = "HH mm";
|
|
id = "Clock";
|
|
useMonospacedFont = true;
|
|
usePrimaryColor = true;
|
|
}
|
|
];
|
|
right = [
|
|
{id = "MediaMini";}
|
|
{
|
|
id = "SystemMonitor";
|
|
showNetworkStats = true;
|
|
compactMode = false;
|
|
}
|
|
{id = "WiFi";}
|
|
{id = "Bluetooth";}
|
|
{
|
|
id = "Battery";
|
|
displayMode = "icon-always";
|
|
hideIfNotDetected = true;
|
|
}
|
|
{
|
|
id = "Volume";
|
|
displayMode = "alwaysShow";
|
|
}
|
|
{
|
|
id = "NotificationHistory";
|
|
hideWhenZero = true;
|
|
}
|
|
{id = "Tray";}
|
|
];
|
|
};
|
|
};
|
|
|
|
colorSchemes.predefinedScheme = "Catppuccin";
|
|
|
|
general = {
|
|
avatarImage = "/home/${user}/.face";
|
|
radiusRatio = 0.2;
|
|
lockOnSusepnd = true;
|
|
};
|
|
|
|
location = {
|
|
monthBeforeDay = true;
|
|
name = "Munich, Germany";
|
|
showWeekNumberInCalendar = true;
|
|
firstDayOfWeek = 0;
|
|
};
|
|
|
|
wallpaper = {
|
|
enabled = true;
|
|
overviewEnabled = false;
|
|
directory = "/home/${user}/.setup/modules/themes/";
|
|
};
|
|
|
|
brightness = {
|
|
enforceMinimum = true;
|
|
brightnessStep = 5;
|
|
};
|
|
|
|
controlCenter.shortcuts.left = [
|
|
{id = "WiFi";}
|
|
{id = "Bluetooth";}
|
|
{id = "ScreenRecorder";}
|
|
{id = "PowerProfile";}
|
|
{id = "KeepAwake";}
|
|
];
|
|
|
|
dock.enabled = false;
|
|
sessionMenu.enableCountdown = false;
|
|
|
|
templates = {
|
|
fuzzel = true;
|
|
alacritty = true;
|
|
qt = true;
|
|
gtk = true;
|
|
discord = true;
|
|
code = true;
|
|
telegram = true;
|
|
niri = true;
|
|
firefox = true;
|
|
};
|
|
};
|
|
};
|
|
};
|
|
|
|
home.file.".cache/noctalia/wallpapers.json".text = builtins.toJSON {
|
|
defaultWallpaper = "/home/${user}/.setup/modules/themes/wall.jpg";
|
|
};
|
|
};
|
|
})
|
|
|
|
# ── Sway ───────────────────────────────────────────────────────────────
|
|
(lib.mkIf (cfg.windowManager == "sway") {
|
|
environment = {
|
|
loginShellInit = ''
|
|
if [ -z $DISPLAY ] && [ $UID != 0 ] && [ "$(tty)" = "/dev/tty1" ]; then
|
|
exec sway
|
|
fi
|
|
'';
|
|
systemPackages = with pkgs; [
|
|
xdg-desktop-portal-wlr
|
|
sway
|
|
swaylock
|
|
swayidle
|
|
slurp
|
|
grim
|
|
bemenu
|
|
lxqt.lxqt-openssh-askpass
|
|
clinfo
|
|
waybar
|
|
glib
|
|
];
|
|
};
|
|
|
|
programs = {
|
|
sway = {
|
|
enable = true;
|
|
extraSessionCommands = ''
|
|
export MOZ_ENABLE_WAYLAND="1"
|
|
export MOZ_WEBRENDER="1"
|
|
export WLR_RENDERER="vulkan"
|
|
export XDG_SESSION_TYPE="wayland"
|
|
export GTK_THEME="Arc"
|
|
export _JAVA_AWT_WM_NONREPARENTING="1"
|
|
'';
|
|
};
|
|
ssh.enableAskPassword = true;
|
|
ssh.askPassword = "${pkgs.lxqt.lxqt-openssh-askpass}/bin/lxqt-openssh-askpass";
|
|
};
|
|
|
|
xdg.portal = {
|
|
enable = true;
|
|
wlr.enable = true;
|
|
extraPortals = [pkgs.xdg-desktop-portal-gtk];
|
|
};
|
|
|
|
home-manager.users.${user}.imports = [
|
|
../wm/sway/home.nix
|
|
../wm/waybar.nix # sway uses waybar for the bar
|
|
];
|
|
})
|
|
|
|
# ── KDE Plasma ─────────────────────────────────────────────────────────
|
|
(lib.mkIf (cfg.windowManager == "kde") {
|
|
environment.systemPackages = with pkgs; [
|
|
kdePackages.discover
|
|
maliit-keyboard
|
|
maliit-framework
|
|
kdePackages.ksshaskpass
|
|
];
|
|
|
|
programs.ssh = {
|
|
enableAskPassword = true;
|
|
askPassword = lib.mkDefault "${pkgs.kdePackages.ksshaskpass}/bin/ksshaskpass";
|
|
};
|
|
|
|
services = {
|
|
packagekit.enable = true;
|
|
desktopManager.plasma6.enable = true;
|
|
udev.packages = with pkgs; [gnome-settings-daemon];
|
|
};
|
|
|
|
qt.platformTheme = "kde";
|
|
|
|
home-manager.users.${user}.imports = [../wm/kde/home.nix];
|
|
})
|
|
|
|
# ── Virtualisation (podman/docker-compat + qemu/libvirt) ───────────────
|
|
(lib.mkIf cfg.virtualisation.enable {
|
|
users.groups = {
|
|
docker.members = [user];
|
|
libvirtd.members = ["root" user];
|
|
};
|
|
|
|
virtualisation = {
|
|
podman = {
|
|
enable = true;
|
|
autoPrune.enable = true;
|
|
dockerCompat = true;
|
|
};
|
|
libvirtd = {
|
|
enable = true;
|
|
onShutdown = "shutdown";
|
|
qemu.runAsRoot = false;
|
|
};
|
|
spiceUSBRedirection.enable = true;
|
|
};
|
|
|
|
environment.systemPackages = with pkgs; [
|
|
virt-manager
|
|
virt-viewer
|
|
qemu
|
|
OVMF
|
|
OVMF-cloud-hypervisor
|
|
gvfs
|
|
cloud-hypervisor
|
|
];
|
|
})
|
|
|
|
# ── KVM – AMD ──────────────────────────────────────────────────────────
|
|
(lib.mkIf (cfg.virtualisation.enable && cfg.cpu == "amd") {
|
|
boot.extraModprobeConfig = ''
|
|
options kvm_amd nested=0 avic=1 npt=1
|
|
'';
|
|
})
|
|
|
|
# ── KVM – Intel ────────────────────────────────────────────────────────
|
|
(lib.mkIf (cfg.virtualisation.enable && cfg.cpu == "intel") {
|
|
boot.extraModprobeConfig = ''
|
|
options kvm_intel nested=1
|
|
options kvm_intel emulate_invalid_guest_state=0
|
|
options kvm ignore_nsrs=1
|
|
'';
|
|
})
|
|
|
|
# ── Syncthing ──────────────────────────────────────────────────────────
|
|
(lib.mkIf cfg.syncthing.enable {
|
|
services.syncthing = {
|
|
enable = true;
|
|
group = "users";
|
|
user = user;
|
|
dataDir = "/home/${user}/Sync";
|
|
configDir = "/home/${user}/.config/syncthing";
|
|
overrideDevices = true;
|
|
overrideFolders = true;
|
|
openDefaultPorts = true;
|
|
settings = {
|
|
devices = cfg.syncthing.devices;
|
|
folders = cfg.syncthing.folders;
|
|
};
|
|
};
|
|
})
|
|
|
|
# ── OpenRGB ────────────────────────────────────────────────────────────
|
|
(lib.mkIf cfg.openrgb.enable {
|
|
services.hardware.openrgb = {
|
|
enable = true;
|
|
motherboard = cfg.openrgb.motherboard;
|
|
};
|
|
})
|
|
|
|
# ── Laptop ─────────────────────────────────────────────────────────────
|
|
(lib.mkIf cfg.laptop.enable {
|
|
systemd.sleep.extraConfig = "HibernateDelaySec=${cfg.laptop.hibernateDelaySec}";
|
|
services.logind.settings.Login.HandleLidSwitch =
|
|
cfg.laptop.lidSwitch;
|
|
})
|
|
|
|
# ── Nitrokey ───────────────────────────────────────────────────────────
|
|
(lib.mkIf cfg.nitrokey.enable {
|
|
hardware.nitrokey.enable = true;
|
|
})
|
|
];
|
|
}
|