# Niri Desktop Environment Niri is a scrollable-tiling Wayland compositor written in Rust. Unlike Hyprland's dwindle/master layouts, Niri arranges windows in **columns that scroll horizontally** within each workspace — think a continuous horizontal strip instead of a fixed grid. --- ## Overview | Component | Role | |-----------|------| | **Niri** | Wayland scrollable-tiling compositor | | **Kitty** | Primary terminal emulator | | **EWW** | Status bar (three device variants) | | **Waybar** | Alternative status bar | | **Wofi** | App launcher (keyboard-driven) | | **Walker** | Fast CLI launcher | | **uLauncher** | GUI app launcher | | **Dunst** | Notification daemon | | **swaylock** | Screen locker | | **swaybg** | Wallpaper daemon | | **swayidle** | Idle management (lock, suspend) | | **gammastep** | Colour temperature (night light) | | **nwg-drawer** | Application drawer | | **nwg-panel** | Desktop menu | | **Vicinae** | Gesture-triggered context launcher | | **xfce-polkit** | PolicyKit authentication agent | | **ly** | TUI login manager | --- ## Config File Map ``` desktopenvs/niri/ ├── niri/ │ └── config.kdl # Single KDL config — everything in one file ├── greetd-tuigreet/ │ └── config.toml # Greeter → launches niri ├── scripts/ # Utility scripts (niri-adapted) │ ├── ewwstart.sh # Start EWW bar (niri monitor detection) │ ├── togglebar.sh # Show/hide EWW bar │ ├── monitorhandler.sh # swaybg wallpaper + eww bar on startup │ ├── caffeine.sh # Toggle swayidle (prevent sleep) │ ├── activewindow # Focused window title for EWW │ ├── workspace # Workspace widget (niri event-stream) │ ├── wallpaper-picker # swaybg-based wallpaper picker │ ├── unified-rotate.sh # Screen rotation via niri IPC │ ├── niri-toggle-touchpad.sh # Touchpad on/off (xinput) │ ├── windowswitcher # Window list via niri msg + wofi │ ├── drawer.sh # nwg-drawer launcher │ └── [shared with hyprlua] # screenshot.sh, screenrec.sh, etc. ├── eww/ # EWW bar (PC, no battery) ├── eww-nobattery/ # EWW bar (desktop alias) ├── eww-touch/ # EWW bar (laptop/tablet + battery) ├── config-updater/ │ └── updater.conf # Config sync manifest │ │ # Shared configs — symlinked from desktopenvs/hyprlua/ ├── kitty → ../hyprlua/kitty ├── dunst → ../hyprlua/dunst ├── wofi → ../hyprlua/wofi ├── btop → ../hyprlua/btop ├── walker → ../hyprlua/walker ├── vicinae → ../hyprlua/vicinae └── [alacritty, gtk-3.0, ulauncher, xfce4, waybar, nwg-drawer, ...] ``` --- ## Niri vs Hyprland — Key Differences | Feature | HyprLua | Niri | |---------|---------|------| | Layout model | Dwindle / Master | Scrollable columns | | Config format | Lua (`hyprland.lua`) | KDL (`config.kdl`) | | Workspace direction | Horizontal (1→9) | Vertical (stacked) | | Wallpaper | hyprpaper | swaybg | | Screen locker | hyprlock | swaylock | | Idle daemon | hypridle | swayidle | | Colour temp | hyprsunset | gammastep | | Polkit agent | hyprpolkitagent | xfce-polkit | | Dock | nwg-dock-hyprland | — (not compatible) | | IPC tool | `hyprctl` | `niri msg` | > **No dock:** nwg-dock-hyprland uses the `wlr-foreign-toplevel-management` protocol which niri does not implement. The app drawer (`nwg-drawer`) and launcher (`vicinae`) serve the same role. --- ## Keybindings All bindings are defined in `niri/config.kdl` under the `binds { }` section. Edit with `Mod+Shift+F1`. ### Applications | Binding | Action | |---------|--------| | `Super + T` | Kitty terminal | | `Super + Shift + T` | Cool Retro Term | | `Super + M` | Kitty + Neovim | | `Super + E` | Thunar file manager | | `Super + Alt + E` | PCManFM-Qt | | `Super + X` | Wofi run launcher | | `Super + R` / `Super + Return` | Vicinae launcher | | `Super + Shift + R` | Wofi drun | | `Super + F` | File search | | `Super + Shift + F` | Folder search | | `Super + Alt + F` | Wofi calculator | | `Super + S` | PulseAudio mixer (pavucontrol) | | `Super + U` | btop system monitor | | `Super + W` | Wallpaper picker | | `Super + D` | App drawer (nwg-drawer) | | `Super + I` | Network menu (iwmenu) | | `Super + N` | Nextcloud | ### Window Management | Binding | Action | |---------|--------| | `Super + Q` | Close window | | `Super + V` | Toggle floating | | `Super + Shift + V` / `Super + C` | Centre column | | `Super + Backspace` | Cycle preset column width | | `Super + Shift + Backspace` | Maximise column | | `Super + Ctrl + Backspace` | Fullscreen | | `Super + A` | Consume window into column | | `Super + Y` | Expel window from column | ### Focus & Move | Binding | Action | |---------|--------| | `Super + H / L / J / K` | Focus column left/right, window up/down | | `Super + Arrow keys` | Same as above | | `Super + Tab` | Focus next window/column | | `Super + Shift + H/L/J/K` | Move column/window | | `Super + Alt + H/L/J/K` | Resize column/window | ### Workspaces > Niri workspaces are **vertical** — they stack top-to-bottom on each output. > `Ctrl+L` goes **down** (next workspace), `Ctrl+H` goes **up** (previous). | Binding | Action | |---------|--------| | `Super + [1–9]` | Switch to workspace N | | `Super + Shift + [1–9]` | Move column to workspace N | | `Super + Ctrl + L / Right` | Next workspace (down) | | `Super + Ctrl + H / Left` | Previous workspace (up) | | `Super + Ctrl + Shift + L/H` | Move column to next/prev workspace | | `Super + Scroll up/down` | Navigate workspaces | | `Super + Space` | Focus workspace with recent window | ### System | Binding | Action | |---------|--------| | `Super + O` | Lock screen (swaylock) | | `Super + Shift + O` | Quit niri | | `Super + Ctrl + O` | Shutdown | | `Super + Alt + O` | Power menu | | `Super + Z` | Toggle EWW bar | | `Super + Ctrl + B` | Reload EWW | | `Super + Shift + C` | Toggle caffeine (swayidle) | | `Super + Ctrl + P` | Start/stop screen recording | | `Print` / `Super + P` | Screenshot (region) | | `Super + Shift + P` | Screenshot full screen | ### Audio / Brightness | Binding | Action | |---------|--------| | `XF86AudioRaiseVolume` | Volume +5% | | `XF86AudioLowerVolume` | Volume -5% | | `XF86AudioMute` | Mute toggle | | `XF86AudioPlay` | Play/pause | | `XF86MonBrightnessUp/Down` | Brightness | ### Colour Temperature (gammastep) Unlike hyprsunset, gammastep has no runtime IPC. Each binding kills and restarts it at a preset: | Binding | Temperature | |---------|-------------| | `Super + Ctrl + X` | 6500 K (neutral / reset) | | `Super + Ctrl + W` | 5000 K (warm) | | `Super + Ctrl + A` | 4000 K (warmer) | | `Super + Ctrl + Q` | 3000 K (very warm) | | `Super + Ctrl + S` | 2700 K (night mode) | --- ## Status Bar (EWW) Three EWW bar variants — installed during setup: | Variant | Target device | Battery widget | |---------|---------------|----------------| | `eww/` | Desktop PC | No | | `eww-nobattery/` | Desktop PC | No | | `eww-touch/` | Laptop / tablet | Yes | The workspace widget uses `~/.config/scripts/workspace` — a bash script that listens to `niri msg event-stream` and outputs EWW Yuck literals whenever workspaces change. The EWW style (`eww.scss`) is shared with hyprlua via symlink — CyberQueer colours apply identically. --- ## Wallpaper The wallpaper is managed by `swaybg`. At startup `monitorhandler.sh` runs: ```bash swaybg -m fill -i ~/Pictures/background.jpg & ``` To pick a wallpaper interactively: ``` Super + W ``` This opens `wallpaper-picker` in a Kitty terminal — navigate with `h/l`, apply with `Enter`, quit with `q`. The selected image is reloaded via `swaybg` and saved to `~/.config/niri-wallpaper`. --- ## Screen Lock & Idle **swaylock** is the screen locker (`Super + O` or via swayidle timeout). **swayidle** launches at startup with: - 5 min idle → `swaylock -f` - 10 min idle → `systemctl suspend` - before sleep → `swaylock -f` **Caffeine mode** (`Super + Shift + C`) kills swayidle and restarts it when toggled off. --- ## Screen Rotation `Super + Ctrl + E` (clockwise) and `Super + Ctrl + D` (anti-clockwise) call `unified-rotate.sh`, which uses `niri msg action set-output-transform` on the currently focused output. --- ## Config Updater The config updater syncs `desktopenvs/niri/` into `~/.config/`: ```bash ~/update-configs.sh ``` Config: `~/.config/config-updater/updater.conf` Managed entries: `niri`, `kitty`, `dunst`, `wofi`, `scripts`, and more. --- ## Installing Niri ```bash # Via the TUI installer bash ~/Dotfiles/setup/tui-install.sh # → select "Niri" in the Desktop Environment dialog # Direct script (on an existing Arch system) bash ~/Dotfiles/setup/modules/Desktop-Environments/niri.sh ``` The installer: 1. Installs all packages (niri, swaybg, swaylock, swayidle, gammastep, xfce-polkit, etc.) 2. Compiles EWW from source (requires Rust) 3. Copies all configs to `~/.config/` 4. Deploys greetd config to `/etc/greetd/config.toml` 5. Installs CyberQueer GTK theme and Nordzy-cursors-lefthand 6. Enables `ly@tty1`, `NetworkManager`, `bluetooth`, `iwd`, `udisks2` 7. Installs Python venv for scripts 8. Sets up the config-updater symlinks