One island that changes shape for what is happening: a desktop shell for niri and Umbriel, in Rust.
Install | CLI | Configuration | Settings | Keyboard | Limitations | Domain | Decisions | Wiki
Warning
Kanade is in active pre-1.0 development. Expect bugs, missing pieces, and breaking changes to config, CLI, and behavior until 1.0. See Limitations for known gaps.
Kanade is a personal project, made for the author's own niri session and shared as is. There is no support or stability promise: issues and pull requests may go unanswered, and APIs and config can change before 1.0.
There is no status bar. Each monitor hosts one Island, positioned at the top center by default.
At Rest, the Island displays only the local clock and battery level, rendering one frame a minute. When an Activity occurs (a track starts playing, volume changes, a notification arrives, battery runs low, a timer counts down, or a background script reports progress), it takes over the Island. The Island morphs to display the Activity, then returns to Rest when it finishes. Hovering peeks at details without expanding; clicking or pressing a shortcut expands a full interactive Surface. Secondary ongoing Activities remain visible beside the Island body as Satellites.
Around the Island, Kanade provides the session shell: a notification daemon with Banners, an application Dock, a PAM-based lock screen, and an OSD for hardware feedback. Kanade is written in Rust on its own Wayland layer-shell and Vulkan GPU runtime (crates/runtime), drawing only when content changes.
The Island adapts its geometry and contents across distinct Presentation states:
- Rest: The baseline state showing the time and battery level. Draws once a minute. If both clock and battery indicators are disabled, the Island autohides past the screen edge until touched or summoned.
- Compact: The primary Activity occupies the Island in a compact pill shape, showing concise glyphs, progress meters, or track titles.
- Split: When a secondary Satellite accompanies the primary Activity, the Island divides into two connected segments. The primary leads and the top Satellite trails.
- Peek: Hovering the pointer reveals richer information and inline controls (such as playback controls, action buttons, or countdown values) without expanding into a full window.
- Expanded: A click or shortcut expands the Island into a full interactive Surface dedicated to that Activity or control domain.
- Satellites: Small secondary indicators that emerge from under the Island body for persistent, ongoing tasks like active timers, live builds, or screen recordings.
- Privacy cluster: Distinct dots nested inside the trailing end of the Island body (round for microphone, square for camera, ring for screen cast). They appear whenever an application captures media through PipeWire. The Controls Surface identifies active capture applications and lets you end screen shares with Stop sharing.
Expanding the Island opens one of its dedicated Surfaces, navigable by keyboard or pointer:
- Media: Track metadata, album artwork, timeline seeking for supported MPRIS players, and synchronized lyrics via LRCLIB or local LRC files.
- Notifications: Notification center with application grouping, expandable history, Do Not Disturb toggles, and dismiss actions.
- Controls: Quick toggles and sub-surfaces for Wi-Fi networks, Bluetooth pairing, per-app audio output routing, power profiles, night light, caffeine, battery charge limits, and active share termination.
- Launcher: Fuzzy search across installed applications, open window switcher, desktop actions, unit and base conversions, mathematical calculator, and built-in shell commands;
:,>,@and?open Emoji, Clipboard, Wallpapers or the command list. - Clipboard: Searchable clipboard history for text and images, persistent pinned entries that survive restarts, and automatic exclusion of sensitive password-manager selections.
- Calendar: Agenda view supporting local iCalendar files, Google Calendar synchronization, read-only webcal subscriptions, and one-click Join actions for video meeting links.
- Weather: Current conditions alongside hourly and multi-day forecasts retrieved from Open-Meteo.
- Timer: Quick countdown timer, stopwatch, and configurable pomodoro intervals with automatic phase transitions.
- Capture: Full-screen, output, or region screenshots, screen color picker, and output, area, or window screen recording.
- Wallpapers: Visual wallpaper browser and selector driven by awww, integrating with Matugen for dynamic palette generation; with
wallpaper.movingon, an animated GIF or APNG picked as the wallpaper is drawn by Kanade itself, at its own speed, pausing while the session is locked, the selected compositor's overview (niri or Umbriel) is open or a fullscreen window covers its output. - Keys: Searchable cheatsheet of compositor keybindings and Kanade shell shortcuts.
- Session: Lock, logout, suspend, reboot, and power off controls with a grace-period countdown and inhibitor warnings.
- Tray: StatusNotifierItem system tray host exposing application status icons and sub-surface menus.
- Files: A read-only shelf of the desktop's recent files, newest first, searched by name and folder; Enter opens the file and Right its folder. Not a file manager: nothing is deleted, renamed, moved, copied or dragged out.
Beyond the Island, Kanade coordinates the surrounding desktop environment:
- Desk: optional plain-text faces of the shell's Services on the desktop, under every window, one per monitor; the clock (
desk.clock), the weather (desk.weather), the next event (desk.agenda), the player's previous, play-pause and next buttons (desk.media) and your own notes (desk.notes, typed into in place on the card), each off by default. Event titles (desk.agenda_titles) and the track's title and artist (desk.media_titles) are off by default. A face stands wheredesk.placeputs it, else in the cornerdesk.clock_cornernames; drag its handle to move it, and the place is kept per output. - Notification daemon: Kanade acts as the session notification server. Notification Banners emerge directly from the Island edge on the focused monitor. Features include urgency rules, per-app sound effects, Do Not Disturb, and inline text replies directly on the Banner.
- Dock: Per-monitor dock strip supporting pinned and running applications, multi-window preview menus, middle-click to launch new instances, and drag-and-drop file launching. The Dock supports autohide, edge positioning, and three Island merge modes when sharing an edge:
crown(Island sitting atop the Dock),keystone(Island centered in the Dock row), andfold(Dock revealed on hover). - Lock screen and idle: Built-in PAM screen locker (
crates/lock) running over an independent Wayland connection. Features include lock-before-sleep hooks, optional idle stages (idle.dim,idle.lock,idle.screen_off,idle.suspend), and a companion SDDM theme generator (kanade sddm) to mirror the login experience. - Appearance and finishes: Shell surfaces (Panes) support three visual finishes: tinted solid, paper, and compositor blur. Matugen extracts wallpaper color palettes, which
appearance.syncapplies across GTK, Qt, kitty, niri borders, and Firefox or Zen.
- CLI socket: A comprehensive IPC client (
kanade <verb>) allows controlling every Surface, switch, and session action from shell scripts or niri keybindings. - Live Activities: External processes post custom Live Activities to the Island via
kanade activity. Used for monitoring long-running compiles, downloads, or AI agent sessions (such as Claude Code hooks). Live Activities support interactive action buttons on Peek. - Semantic UI tree:
kanade uiinspects the shell's semantic control hierarchy by name and executes pointer or keyboard actions without hardcoded screen coordinates. - Diagnostic doctor:
kanade doctorverifies the runtime environment, GPU render nodes, audio helpers, video encoders, notification bus state, and required niri layer rules.
- Supported compositors: Kanade integrates with niri and Umbriel over their IPC sockets. It selects a reachable Umbriel socket first, then niri. Window and Strip Surfaces, the Dock, Launcher window selection, keybindings and compositor Settings follow the selected compositor. Hyprland and Sway are unsupported; capture and other compositor-specific limits are listed in Limitations.
- No permanent status bar: Kanade does not offer a static tray strip or permanent resource meters (such as continuous CPU, RAM, or network graphs). Information surfaces only when an Activity demands attention or when explicitly summoned.
- Not a video wallpaper renderer: Kanade manages wallpaper selection and palette extraction through awww and Matugen, and draws desktop wallpapers through it; only an animated GIF or APNG picked with
wallpaper.movingon is drawn by Kanade itself.
On Arch Linux and derivatives, the script installs dependencies, clones main and builds Kanade with cargo install --locked --path . into ~/.cargo/bin. Run it again to update. Packages come from paru, or an existing yay; if neither is available, the script installs paru through pacman. See Installation.
curl -fsSL https://raw.githubusercontent.com/0x1d1e/kanade/main/scripts/install | shFor existing niri or Umbriel setups or selective installs, pass options after sh -s --:
--shell-only: Installs Kanade without the desktop packages; a missing niri config is installed only with--nirior--sddm.--yes: Accepted for compatibility.--optional: Installs optional feature packages and enables Bluetooth, UPower, and power-profiles-daemon services.--ref REF: Builds that branch or tag instead ofmain.--uninstall: Removes the Kanade binary, completions, systemd unit, and desktop icon, and keeps thekanade.service.bak.*copies; removes the root-owned SDDM files--sddmwrote, withsudo, and nothing else.
To build and run manually from source:
cargo install --locked --path .
mkdir -p ~/.config/systemd/user
cp dist/kanade.service ~/.config/systemd/user/
systemctl --user daemon-reload
systemctl --user enable --now kanade.serviceImportant
Kanade must be the only active notification daemon in your session. Disable alternative daemons such as mako or dunst (systemctl --user disable --now mako) before starting Kanade.
On Arch Linux and derivatives, all packages come from official repositories unless marked AUR.
To build and run the shell:
sudo pacman -S --needed niri rust base-devel pkgconf wayland libxkbcommon fontconfig freetype2 \
expat vulkan-icd-loader libpulse pamA Vulkan driver matching your GPU is also required: vulkan-intel for Intel, vulkan-radeon for AMD, or nvidia-utils for NVIDIA. The command above installs niri; for an Umbriel session, install Umbriel separately and omit niri. The supplied systemd unit starts with niri's graphical session (niri-session or display manager); Umbriel startup and screenshot helpers are covered in Installation.
Kanade runs without these packages, but individual features require them:
| Feature | Packages | Notes |
|---|---|---|
| Audio and device tracking | libpulse pipewire systemd dbus util-linux |
Audio control (pactl), privacy dots (pw-dump), device detection (udevadm, dbus-monitor), and process isolation (setpriv). |
| Clipboard history | wl-clipboard |
Requires version 2.3 or later to detect sensitive password-manager selections. |
| Screen recording (base) | wf-recorder |
Records focused output or selected area. |
| Recording pause and join | ffmpeg |
Allows pausing recordings and concatenates multi-part segments into a single file. |
| GPU recording (VA-API) | intel-media-driver or mesa |
Hardware-accelerated H.264 encoding for Intel (intel-media-driver) or AMD (mesa). Window recording also requires gst-plugin-va. |
| GPU recording (NVENC) | nvidia-utils |
Hardware-accelerated H.264 encoding on NVIDIA cards. Window recording also requires gst-plugins-bad. |
| CPU recording (fallback) | ffmpeg |
Software H.264 encoding with libx264. Window recording also requires gst-plugins-ugly. |
| Window recording pipeline | gstreamer gst-plugin-pipewire gst-plugins-base |
Captures niri DMA-BUF window casts over PipeWire with EGL frame download. |
| Wallpaper management | awww |
Wallpaper daemon and image display. |
| Wallpaper-derived colors | matugen |
Material You palette extraction from the active wallpaper. |
Theme synchronization (appearance.sync) |
qt5ct qt6ct glib2 dconfAUR: darkly-qt6-git, python-pywalfox |
Synchronizes wallpaper palette across Qt, GTK, kitty, niri borders, and Firefox or Zen. |
| Night light | wlsunset |
Color temperature adjustment based on location or time. |
| Power and idle inhibitors | systemd util-linux |
Inhibitor management (systemd-inhibit) and process lifetime scoping (setpriv). |
| Notification sounds | pipewire or libcanberra |
Audio cues via pw-play or canberra-gtk-play. |
| Google Calendar | gnome-keyring (or KWallet, KeePassXC) and xdg-utils |
Secret Service storage for OAuth tokens and browser redirection via xdg-open. |
| Terminal applications | xdg-terminal-exec |
Opens terminal-based applications launched from the Launcher Surface. |
| Guide | Description |
|---|---|
| Installation | Package requirements, manual builds, systemd service management, and niri layer rules. |
| CLI | Command-line IPC syntax and available verbs for controlling Kanade. |
| Configuration | Configuration file format, option reference, and defaults. |
| Settings | Built-in graphical settings editor and niri/Umbriel configuration support. |
| Keyboard | Keyboard shortcuts for every Surface and recommended niri keybindings. |
| Limitations | Documented design boundaries, trade-offs, and known gaps. |
| Agent hooks | Recipe for connecting Claude Code sessions as Live Activities. |
| Dictation | Voice dictation setup with the Gemini API and privacy disclosures. |
| Google Calendar | OAuth client creation and synchronization setup. |
| SDDM | Matching SDDM login theme generation via kanade sddm. |
| Architecture decisions | Decisions and supersessions. |
| Domain terms | Canonical domain language, invariants, and naming rules. |
| Branding | Mascot assets, mark specifications, and visual identity. |
- Amane by MystiaFin: A foundational Rust Wayland shell runtime.
- iNiR: Adaptive island concept for niri, demonstrating one body across multiple contexts.
Apache-2.0, see LICENSE.
