Niri + 4-Monitor Intel (DP) Migration Notes (Ubuntu 24.04+ → NixOS) OWNER / CONTEXT - User: sam (IT) - Goal: Move to NixOS and daily-drive Niri on a 4-monitor setup. - Priority: Reliability and broad tool compatibility over “polish”. - Testing style: often SSH in from another machine because local display can go black during compositor/DM experiments. REMOTE REQUIREMENT (clarified) - SSH is sufficient even when nobody is logged in locally (sshd runs pre-login). - Remote GUI login is optional/rare. Do not design around RustDesk-at-greeter on Wayland. - If remote GUI login is ever needed later, consider adding GNOME+GDM+RDP as a separate capability; keep Niri as main local session. HARDWARE SUMMARY - GPU: Intel iGPU (exact model TBD) - Outputs: 4x DisplayPort to 4x HP LA2205 monitors - DRM nodes observed on Ubuntu (node numbering may differ on NixOS): - Primary KMS card for the 4 DP outputs: /dev/dri/card2 - Render node: /dev/dri/renderD129 - Notes: There may be multiple /dev/dri/card* devices. Session must pick the correct device driving the 4 DP outputs. KNOWN KERNEL / PLATFORM ISSUES - IOMMU faults / “Operation not permitted” style crashes were avoided on Ubuntu with kernel flags: - intel_iommu=off - dev_mem_signed_off=1 - These flags may or may not be needed on NixOS; keep them as a known-good baseline and only remove once stable. UBUNTU WORKING STATE (IMPORTANT BEHAVIORAL FINDINGS) 1) GDM “gear icon” / Wayland sessions - GDM did not show Wayland sessions until Wayland was enabled. - /etc/gdm3/custom.conf had WaylandEnable=false. Commenting it out fixed session availability after restarting GDM. 2) .desktop Exec path issue - Session .desktop pointing Exec to /home/sam/start-niri.sh caused GDM issues. - Home perms were drwxr-x--- (750), so greeter user couldn’t traverse /home reliably. - Fix: Exec must point to a system path (/usr/bin or /usr/local/bin), not /home. 3) niri-session issue (major root cause of login loop) - /usr/bin/niri-session existed but session immediately returned to login. - Logs showed: Failed to start niri.service: Unit niri.service not found. Failed to start niri-shutdown.target: Unit niri-shutdown.target not found. - Therefore niri-session was not usable as packaged (missing systemd user units). 4) FINAL WORKING FIX ON UBUNTU (proven) - /usr/share/wayland-sessions/niri.desktop set to start Niri directly: Exec=/usr/bin/niri --session - This bypassed niri-session and made Niri start successfully from GDM. SESSION START METHOD (proven) - Known working from a display manager: Exec = `niri --session` - Avoid relying on `niri-session` unless NixOS packaging provides the required systemd user units (niri.service, niri-shutdown.target). PERMISSIONS / SECURITY WORKAROUNDS USED DURING TESTING - User group membership on Ubuntu: video, render, seat - Custom udev rules were created to chmod 666 DRM nodes. - Result: /dev/dri/card2 and /dev/dri/renderD129 became world-writable. - This is NOT desired long term; prefer logind seat ACLs. - On NixOS, aim to avoid chmod 666 rules unless absolutely needed for debugging. NIRI CONFIG NOTES - Config validated successfully on Ubuntu: ~/.config/niri/config.kdl - Xwayland started via config: - spawn-at-startup "Xwayland" ":" "1" - Avoid exporting XDG_RUNTIME_DIR manually; let pam/systemd-logind manage it. - If needed to force GPU device, Niri supports choosing a render DRM device (exact config syntax/version dependent). On Ubuntu, correct render node was renderD129. NIXOS TARGET STATE (WHAT WE WANT) - Boot to a login method that reliably starts Niri on the Intel GPU with 4 monitors. - Must keep a working fallback (at minimum TTY + SSH; optionally a full DE). - Remote recovery/admin always possible via SSH. LOGIN / DISPLAY MANAGER STRATEGY OPTIONS (pick one) Option A: greetd + tuigreet (recommended for Niri-first reliability) - Minimal moving parts, compositor-agnostic. - Start the session with: `niri --session`. - Ideal when “polish doesn’t matter” and reliability does. Option B: GDM (works; proven on Ubuntu) - Ensure Wayland sessions enabled. - Ensure session Exec is not in /home. - If `niri-session` is incomplete, start `niri --session` directly. DISPLAY MANAGER DECISION NOTE - If SSH-only remote is the requirement: prefer greetd for simplicity. - If remote graphical login is ever required: consider GDM + GNOME RDP later as a separate capability. (Not required now.) SCREENSHARE / PORTALS REQUIREMENTS (broad tool compatibility) - Enable PipeWire + WirePlumber. - Ensure xdg-desktop-portal is installed and functional in the user session. - Choose a portal backend compatible with Niri (often portal-gnome and/or portal gtk; exact best choice may be NixOS-specific). - If screencast/screen-share fails in apps: check portal backend selection, permissions prompts, and PipeWire. GPU/DRM PERMISSIONS - Avoid global chmod 666 udev rules in final config. - Use logind seat/ACLs; add user to video/render groups if needed. - When debugging device selection: - ls -l /dev/dri /dev/dri/by-path - loginctl seat-status seat0 FALLBACK PLAN - Minimum: TTY + SSH access always available. - Optional: install a full fallback DE only if needed (GNOME or Plasma). - Not required for Niri; just a safety net. DEBUG / TROUBLESHOOTING CHECKLIST (capture these on failure) - niri config: - niri validate - user session logs: - journalctl --user -b -l --no-pager | tail -n 300 - kernel DRM messages: - journalctl -b -k -l --no-pager | grep -iE "drm|i915|kms|atomic|permission" | tail - device inventory: - ls -l /dev/dri /dev/dri/by-path - session type: - echo $XDG_SESSION_TYPE - loginctl session-status ACCEPTANCE CRITERIA (DONE WHEN) - Niri starts reliably after reboot from the chosen DM - All 4 monitors are active consistently - Screen sharing works in at least one browser-based app and one native app - SSH recovery works even if local display is broken - No chmod 666 DRM hacks required in the final config (preferred) OPEN QUESTIONS FOR NIXOS MIGRATION - Exact Intel GPU model + correct DRM node mapping on NixOS (may differ) - Whether the kernel flags are still required on NixOS - Whether NixOS niri packaging includes full systemd integration units (niri.service, niri-shutdown.target) - Best portal backend combo for Niri screencast on NixOS