-
-
Notifications
You must be signed in to change notification settings - Fork 62
COMPOSITORS
iNiR is built for Niri. Secondary Hyprland support is maintained from the project's origins as a fork of end-4's Hyprland dots.
CompositorService figures out which compositor is running by checking environment variables at startup:
-
$HYPRLAND_INSTANCE_SIGNATUREset? Hyprland. -
$NIRI_SOCKETset? Niri. -
$XDG_CURRENT_DESKTOPcontains "GNOME"? GNOME (unsupported, but detected). - None of the above? Unknown.
Code that behaves differently per compositor uses guards:
if (CompositorService.isNiri) {
// niri-only path
}
visible: CompositorService.isHyprland // hide on other compositorsPrimary compositor. Full IPC integration.
NiriService opens a Unix socket at $NIRI_SOCKET and subscribes to the event stream. Every workspace change, window open/close, output hotplug, and keyboard layout switch arrives as a JSON event and updates reactive QML properties.
For commands (focus workspace, move window, etc.), a separate socket connection sends requests and reads responses.
| Property | What it tracks |
|---|---|
workspaces |
All workspaces with IDs, names, active state, output assignment |
windows |
All windows with title, app ID, position, size, workspace |
outputs |
All monitors with name, scale, resolution, position |
activeWindow |
Currently focused window |
focusedWorkspaceId |
Current workspace on the focused monitor |
keyboardLayoutNames |
Available keyboard layouts |
displayScales |
Per-monitor scale factors |
iNiR manages Niri's config through modular KDL files in ~/.config/niri/config.d/:
| File | What it controls |
|---|---|
10-input-and-cursor.kdl |
Mouse, touchpad, keyboard, cursor theme |
20-layout-and-overview.kdl |
Workspace layout, gaps, struts |
30-window-rules.kdl |
Window rules (floating, size, opacity) |
40-environment.kdl |
Environment variables for apps |
50-startup.kdl |
Autostart entries (clipboard, polkit, etc.) |
60-animations.kdl |
Window animation settings |
70-binds.kdl |
All keybinds |
80-layer-rules.kdl |
Layer shell rules (for the shell itself) |
90-user-extra.kdl |
User overrides. Never touched by updates. |
scripts/niri-config.py does surgical edits to these files, preserving comments and unknown settings. It never rewrites entire files.
Secondary support. Uses the Quickshell Hyprland module (built-in) plus hyprctl for queries that the module doesn't cover.
| Aspect | Niri | Hyprland |
|---|---|---|
| IPC | Unix socket, JSON events | Quickshell module + hyprctl |
| Window sorting | Native via IPC | Complex 300+ line sort (monitor > workspace > column > Y) |
| Workspace model | Scrolling (infinite horizontal) | Fixed grid |
| Config | KDL, modular files | hyprland.conf |
-
HyprlandData.qml: window list, workspaces, monitors, layers -
HyprlandKeybinds.qml: keybind parsing for cheatsheet -
HyprlandXkb.qml: keyboard layout tracking
Some features require Niri-specific IPC that has no Hyprland equivalent:
- Workspace scrolling gestures
- Column-based window management
- Some Overview features
The shell adapts gracefully. Missing features hide themselves rather than crashing.
CompositorService provides compositor-agnostic APIs that modules use instead of talking to Niri/Hyprland directly:
-
sortedToplevels: sorted window list (delegates to the active compositor's sorting logic) -
filterCurrentWorkspace(toplevels, screen): workspace-aware window filtering -
powerOffMonitors()/powerOnMonitors(): DPMS control
This means most UI components don't need compositor guards at all. They just read CompositorService.sortedToplevels and it works regardless of which compositor is running.
Always use compositor guards when writing compositor-specific code. Never assume Niri is running.
Prefer shared abstractions over direct NiriService/HyprlandData access when possible. If you need something that only Niri provides, gate it with CompositorService.isNiri and provide a fallback (even if the fallback is just hiding the feature).
Test both if you're touching compositor-facing code. At minimum, check that the feature doesn't crash on the other compositor.