# UWSM Integration with Niri ## Status: ✅ FULLY INTEGRATED This Niri configuration has been **fully migrated** to use UWSM (Universal Wayland Session Manager) for comprehensive systemd-based session management. All components now use UWSM: - ✅ Session launch via `programs.uwsm.waylandCompositors` - ✅ Startup applications via `systemd.user.services` with `graphical-session.target` - ✅ Application launches via `uwsm app --` wrapper (for proper systemd slice placement) - ✅ Fuzzel launcher configured with UWSM launch-prefix ## Overview UWSM (Universal Wayland Session Manager) is a systemd-based session manager that provides: 1. **Proper environment variable inheritance** - Ensures environment variables from login shells, PAM, and system profiles are properly propagated to the Wayland session and all child processes 2. **Systemd integration** - Wraps the compositor in proper systemd units with lifecycle management 3. **XDG autostart support** - Handles XDG autostart applications with proper slices and dependencies 4. **Clean startup/shutdown** - Manages session lifecycle with proper cleanup on exit 5. **Session binding** - Can bind session lifecycle to login shell PID for proper TTY management ## Benefits for Niri Currently, our Niri setup uses: - `programs.niri.settings.spawn-at-startup` for starting applications like nm-applet - `programs.waybar.systemd.enable = true` for waybar systemd service - Manual systemd user services for various components With UWSM: - All startup applications would be managed consistently through systemd units - Environment variables would be properly inherited from login shell → PAM → systemd → compositor → applications - Better integration with systemd targets (`graphical-session.target`, etc.) - Proper cleanup on logout/shutdown - XDG autostart applications would work automatically - Better compatibility with applications that expect standard Wayland session management ## Implementation Plan ### 1. Host-Level Changes (`hosts/common/optional/niri.nix`) Add UWSM package and configure it: ```nix environment.systemPackages = with pkgs; [ uwsm ]; ``` Enable UWSM mode for Niri (if the niri-flake supports it), or configure it manually. ### 2. User-Level Changes (`home/panotaka/common/optional/desktops/niri/`) #### Option A: Use UWSM's systemd units (Recommended) Remove manual `spawn-at-startup` entries and rely on: - Systemd user services with `WantedBy=graphical-session.target` - XDG autostart desktop entries - UWSM's built-in environment preparation #### Option B: Hybrid Approach Keep some `spawn-at-startup` for compositor-specific tools, but use UWSM for: - Environment variable management - Session lifecycle binding - XDG autostart apps ### 3. Migration Path 1. **Phase 1**: Add UWSM package and test manual invocation ```bash uwsm start -o niri systemctl --user start wayland-wm@niri.service ``` 2. **Phase 2**: Migrate startup applications to systemd services - Convert `spawn-at-startup` entries to `systemd.user.services` - Use `WantedBy = ["graphical-session.target"]` for dependency 3. **Phase 3**: Create UWSM desktop entry for display managers ```desktop [Desktop Entry] Name=Niri (with UWSM) Comment=Niri Wayland compositor with UWSM session management Exec=uwsm start -D niri -N Niri -C "Niri compositor" -- niri Type=Application DesktopNames=niri ``` 4. **Phase 4**: Configure environment finalization - Have Niri execute `uwsm finalize` in its config to propagate compositor-specific variables ## Current State ### What Uses `spawn-at-startup` Currently: - `Restart` policies for resilience #### 3. Application Launches → UWSM App Wrapper All applications launched from Niri now use `uwsm app --` wrapper: - **Fuzzel launcher**: `uwsm app -- fuzzel` - Also configured with `launch-prefix = "uwsm app -- "` so apps launched from fuzzel are properly managed - **Swaylock**: `uwsm app -- swaylock` (Mod+L keybind) - **Zenbook tools**: `uwsm app -- zenbook-set-displays` (Mod+Z keybind) This ensures all applications are placed in the correct systemd slices (`app-graphical.slice`) and inherit proper environment variables. ### Files Modified 1. **`hosts/common/optional/niri.nix`** - Replaced manual desktop entries with `programs.uwsm` module - Configured Niri as a UWSM-managed compositor 2. **`home/panotaka/common/optional/desktops/niri/waybar.nix`** - Migrated nm-applet from spawn-at-startup to systemd.user.services.nm-applet 3. **`home/panotaka/common/optional/desktops/niri/zenbook-screen.nix`** - Migrated all zenbook display management tools to systemd services: - zenbook-autostart (oneshot initial setup) - zenbook-delayed-setup (delayed secondary setup) - zenbook-inotify-monitor (long-running DRM status watcher) - zenbook-udev-monitor (long-running udev event watcher) - Updated Mod+Z keybind to use `uwsm app --` 4. **`home/panotaka/common/optional/desktops/niri/fuzzel.nix`** - Updated keybind to launch fuzzel via `uwsm app --` - Added `launch-prefix = "uwsm app -- "` to fuzzel config 5. **`home/panotaka/common/optional/desktops/niri/swaylock.nix`** - Updated Mod+L keybind to launch swaylock via `uwsm app --` ### Files Modified 1. **`home/panotaka/common/optional/desktops/niri/waybar.nix`** - Migrated nm-applet from spawn-at-startup to systemd.user.services.nm-applet 2. **`home/panotaka/common/optional/desktops/niri/zenbook-screen.nix`** ### What Already Uses Systemd: - `programs.waybar.systemd.enable = true` - polkit-kde-authentication-agent-1 ## Recommendation For now, I recommend a **soft introduction** of UWSM: 1. **Add UWSM package** to the system so it's available 2. **Document how to use it** (this file) 3. **Keep current setup** working as-is 4. **Provide opt-in migration path** for users who want systemd-managed session Later, when fully tested, we can: - Make UWSM the default - Migrate all startup apps to systemd services - Remove manual `spawn-at-startup` entries - Add UWSM desktop entry for GDM/SDDM ### Systemd User Services (graphical-session.target) These services start automatically when the graphical session begins: - **waybar** (via programs.waybar.systemd.enable) - **nm-applet** (network manager applet for tray) - **polkit-kde-authentication-agent-1** (authentication dialogs) - **zenbook-autostart** (initial display setup) - **zenbook-delayed-setup** (secondary setup after delay) - **zenbook-inotify-monitor** (DRM status change monitoring) - **zenbook-udev-monitor** (udev event monitoring) ## Monitoring and Debugging ### Check Service Status ```bash # List all graphical session services systemctl --user list-units --type=service | grep graphical # Check specific service systemctl --user status nm-applet systemctl --user status zenbook-autostart # View logs journalctl --user -u nm-applet -f journalctl --user -u zenbook-inotify-monitor -f ``` ### UWSM Session Management ```bash # Check current UWSM session uwsm status # List UWSM-managed units systemctl --user list-units 'wayland-*' # Stop session cleanly uwsm stop ``` ## Troubleshooting ### Service Not Starting ```bash # Check why service failed systemctl --user status journalctl --user -u -n 50 # Manually start for testing systemctl --user start ``` ### Environment Variables Missing UWSM should automatically propagate environment variables. If something is missing: ```bash # Check what's in systemd's environment systemctl --user show-environment # Manually import if needed (shouldn't be necessary with UWSM) systemctl --user import-environment VARIABLE_NAME ``` ## Testing UWSM To test UWSM without changing your current setup: ```bash # Generate units without starting uwsm start -o niri # Check generated units systemctl --user list-units 'wayland-*' # Start manually systemctl --user start wayland-wm@niri.service # Stop uwsm stop ``` ## References - UWSM GitHub: https://github.com/vladimir-csp/uwsm - UWSM in NixOS: Available as `pkgs.uwsm` - Hyprland UWSM integration: `programs.hyprland.withUWSM` option exists in nixpkgs