279 lines
9.2 KiB
Markdown
279 lines
9.2 KiB
Markdown
# 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
|