# 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, pkgs, ... }: { imports = [ ./hardware-configuration.nix ]; boot.loader.grub.enable = true; boot.loader.grub.device = "/dev/vda"; boot.loader.grub.useOSProber = true; services.xserver.videoDrivers = [ "modesetting" ]; hardware.graphics = { enable = true; extraPackages = with pkgs; [ # Required for modern Intel GPUs (Xe iGPU and ARC) intel-media-driver # VA-API (iHD) userspace vpl-gpu-rt # oneVPL (QSV) runtime # Optional (compute / tooling): intel-compute-runtime # OpenCL (NEO) + Level Zero for Arc/Xe # NOTE: 'intel-ocl' also exists as a legacy package; not recommended for Arc/Xe. # libvdpau-va-gl # Only if you must run VDPAU-only apps ]; }; environment.sessionVariables = { LIBVA_DRIVER_NAME = "iHD"; # Prefer the modern iHD backend # VDPAU_DRIVER = "va_gl"; # Only if using libvdpau-va-gl }; # May help if FFmpeg/VAAPI/QSV init fails (esp. on Arc with i915): hardware.enableRedistributableFirmware = true; boot.kernelParams = [ "i915.enable_guc=3" ]; networking.hostName = "nixos-lnf"; networking.wireless.enable = true; networking.networkmanager.enable = true; networking.firewall.enable = false; time.timeZone = "Europe/Vienna"; i18n.defaultLocale = "en_US.UTF-8"; i18n.extraLocaleSettings = { LC_ADDRESS = "de_AT.UTF-8"; LC_IDENTIFICATION = "de_AT.UTF-8"; LC_MEASUREMENT = "de_AT.UTF-8"; LC_MONETARY = "de_AT.UTF-8"; LC_NAME = "de_AT.UTF-8"; LC_NUMERIC = "de_AT.UTF-8"; LC_PAPER = "de_AT.UTF-8"; LC_TELEPHONE = "de_AT.UTF-8"; LC_TIME = "de_AT.UTF-8"; }; services.xserver.xkb = { layout = "de"; variant = ""; }; console.keyMap = "de"; users.users.user = { isNormalUser = true; description = "user"; extraGroups = [ "networkmanager" "wheel" "video" ]; packages = with pkgs; [ ]; openssh.authorizedKeys.keys = [ "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAINGHadFhDCUU/ta3p1FQgpm7NExHkyHNrJbNJP6np5w9 kempinger@ins.jku.at" "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMTpZThOE2EeDZ1rS7ynLS3mGtoSIQ9WazZDBUdP9THi tth@tth-worker" ]; }; users.users.root = { openssh.authorizedKeys.keys = [ "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAINGHadFhDCUU/ta3p1FQgpm7NExHkyHNrJbNJP6np5w9 kempinger@ins.jku.at" "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMTpZThOE2EeDZ1rS7ynLS3mGtoSIQ9WazZDBUdP9THi tth@tth-worker" ]; }; nixpkgs.config.allowUnfree = true; environment.systemPackages = with pkgs; [ git nil nixd wlr-randr kmsxx libinput vlc jq sway ffmpeg python3 (pkgs.writeScriptBin "run-on-output" '' #!/usr/bin/env bash # Usage: run-on-output # Example: run-on-output 1 firefox --kiosk https://example.com # run-on-output 2 vlc --fullscreen /path/to/video.mp4 set -euo pipefail if [[ $# -lt 2 ]]; then echo "Usage: run-on-output " >&2 exit 1 fi IDX="$1" shift MYUID=$(id -u) SOCK=$(ls /run/user/"$MYUID"/sway-ipc.* 2>/dev/null | head -n1) if [[ -z "$SOCK" ]]; then echo "Error: no sway IPC socket found for uid $MYUID" >&2 exit 1 fi export SWAYSOCK="$SOCK" # Inherit Wayland env from the running sway instance export WAYLAND_DISPLAY=$(${pkgs.sway}/bin/swaymsg -t get_version -r \ | ${pkgs.jq}/bin/jq -r '.loaded_config_file' 2>/dev/null \ | xargs -I{} sh -c 'echo "wayland-1"' 2>/dev/null || echo "wayland-1") export XDG_RUNTIME_DIR="/run/user/$MYUID" OUT=$(${pkgs.sway}/bin/swaymsg -t get_outputs -r \ | ${pkgs.jq}/bin/jq -r ".[$((IDX-1))].name") if [[ "$OUT" == "null" || -z "$OUT" ]]; then echo "Error: no output found at index $IDX" >&2 ${pkgs.sway}/bin/swaymsg -t get_outputs -r \ | ${pkgs.jq}/bin/jq -r '.[].name' | nl -v1 -ba >&2 exit 1 fi echo "Launching on output $IDX ($OUT): $*" # Workspace management only — no exec via swaymsg ${pkgs.sway}/bin/swaymsg "[workspace=$IDX] kill" 2>/dev/null || true sleep 0.3 ${pkgs.sway}/bin/swaymsg "workspace $IDX; move workspace to output $OUT" # Launch directly — inherits full PATH and Wayland env from this shell nohup "$@" >> /tmp/run-on-output-$IDX.log 2>&1 & echo "Launched PID $! on workspace $IDX ($OUT)" '') ]; programs.firefox.enable = true; # ── Sway: multi-monitor Wayland compositor ───────────────────────────────── programs.sway = { enable = true; wrapperFeatures.gtk = true; }; # Script that runs inside the sway session. # It detects every active output, pins a numbered workspace to each, # then launches one VLC per workspace (→ per monitor). environment.etc."sway/kiosk-start.sh" = { mode = "0755"; text = '' #!/usr/bin/env bash exec >> /tmp/kiosk-start.log 2>&1 echo "[$(date)] kiosk-start.sh running" sleep 2 # give sway more time to settle readarray -t outputs < <( ${pkgs.sway}/bin/swaymsg -t get_outputs \ | ${pkgs.jq}/bin/jq -r '.[] | select(.active) | .name' ) echo "[$(date)] Found outputs: ''${outputs[*]}" # for i in "''${!outputs[@]}"; do # ws=$(( i + 1 )) # output="''${outputs[$i]}" # echo "[$(date)] Launching VLC on output $output (workspace $ws)" # ${pkgs.sway}/bin/swaymsg "workspace $ws output $output" # ${pkgs.sway}/bin/swaymsg "workspace $ws" # ${pkgs.sway}/bin/swaymsg "exec ${pkgs.firefox}/bin/firefox" # sleep 0.5 # done echo "[$(date)] Done" ''; }; # # Minimal sway config for the kiosk session # environment.etc."sway/kiosk.conf".text = '' # output * bg #000000 solid_color # default_border none # hide_edge_borders both # input * { # xkb_layout de # } # for_window [app_id="vlc"] fullscreen enable, inhibit_idle open # for_window [class="vlc"] fullscreen enable, inhibit_idle open # for_window [title="VLC.*"] fullscreen enable, inhibit_idle open # exec /etc/sway/kiosk-start.sh # ''; # Minimal sway config for the kiosk session environment.etc."sway/kiosk.conf".text = '' output * bg #000000 solid_color default_border none hide_edge_borders both input * { xkb_layout de } exec /etc/sway/kiosk-start.sh ''; environment.sessionVariables = { QT_QPA_PLATFORM = "wayland"; WLR_NO_HARDWARE_CURSORS = "1"; }; # ── greetd: replaces cage, autologins user and starts sway ───────────────── services.greetd = { enable = true; settings = { default_session = { command = "${pkgs.sway}/bin/sway --config /etc/sway/kiosk.conf"; user = "user"; }; }; }; # ── SSH ───────────────────────────────────────────────────────────────────── services.openssh = { enable = true; settings = { PasswordAuthentication = false; KbdInteractiveAuthentication = false; PermitRootLogin = "prohibit-password"; }; }; nix.settings.experimental-features = [ "nix-command" "flakes" ]; system.stateVersion = "25.11"; }