A fast, stable tiling Wayland compositor built on wlroots and SceneFX.
A Hyprland/niri alternative for minimalists. The goal is a compositor that is small, fast, and stays out of the way. Performance and stability are the primary goals over tons of features and eye-candy. It tiles your windows, reads a config file, speaks a small IPC, and otherwise does nothing you didn't ask for.
- Great tiling support: dwindle BSP layout, floating, fullscreen, pinned, and per-window rules.
- As performant as possible, with a small codebase, minimal dependencies, and extremely low resource use.
- Stable and predictable: no surprises, no crashes, no memory leaks, no breaking changes every other release.
- Perfect multi-monitor and clamshell support out of the box (see Multi-monitor and Clamshell).
- Integration with existing Wayland tools: quickshell, swaybar, waybar, wlogout, wdisplays, wlr-randr, etc.
I use this as my daily driver. It is stable and usable, but still under active development. Expect bugs, missing features, and rough edges.
yay -S fenriz
Build from source (see Build).
Full setup, config, and screen-sharing walkthrough: docs/USER_GUIDE.md.
wlroots 0.20, scenefx 0.5, wayland-server, xkbcommon, pixman, libinput, EGL, GLESv2. On Arch:
sudo pacman -S wlroots wayland xkbcommon pixman libinput mesa
scenefx (scenefx-0.5) is not in the official repos; install from the AUR or build it.
Also needs cmake (>= 3.19) and ninja.
make debug # configure + build into build/debug
make release
make test # run the config/tiling/keybind/output self-checks
make run # build debug and launch
make install # install to /usr/local/bin/fenriz
fenriz # launch the compositor (from a greeter, TTY, or inside an existing Wayland session)
None of this needs configuring. Each of the 10 workspaces lives on one output. When a screen goes away — lid shut, cable pulled, suspend — its workspaces move to a surviving screen with layouts and focus intact, and return exactly where they were when it comes back. The internal panel turns off when the lid shuts with an external connected, and back on otherwise; suspend-on-lid is left to logind, which already gets it right.
Your bar does not need reloading on monitor change: disabling a screen removes its
wl_output global, so a per-screen shell rebuilds through the normal registry events.
Override the defaults only if you want to:
output = eDP-1, preferred, auto, 2.0 # per-screen mode/position/scale
output = DP-1, 3840x2160@144, auto, 1.0
workspace = 3, DP-1 # pin ws3 to the big monitor, always
fenriz supports screen sharing through the wlr-screencopy and ext-image-copy-capture protocols.
It works through xdg-desktop-portal and its wlroots backend. You'll need to install the runtime pieces
and make sure the user services are running:
sudo pacman -S xdg-desktop-portal xdg-desktop-portal-wlr pipewire wireplumber
fenriz sets XDG_CURRENT_DESKTOP=fenriz:wlroots and installs
fenriz-portals.conf, which routes ScreenCast/RemoteDesktop to the wlr backend automatically.
fenriz exposes a Unix socket (FENRIZ_SOCKET) that streams workspace/window/output state
as newline-delimited JSON and accepts one-line commands — for status bars and shells. See
docs/IPC.md.
src/
main.cpp entry + event loop
server.* backend, renderer, allocator, xdg-shell, seat, protocols; owns the window list
output.* outputs: frame handler, hotplug, enable/disable, clamshell policy
output_policy.cpp pure workspace-assignment rules (evacuate/restore); no wlroots, unit-tested
view.* xdg_toplevel wrapper: geometry, focus, floating/fullscreen, scene nodes
tiling.* dwindle BSP layout
cursor.* pointer focus + interactive move/resize
keyboard.* xkb + keybind dispatch
layer.* wlr-layer-shell (bars/panels/wallpapers) + idle-notify
decoration.* force server-side decoration (xdg-decoration); fenriz draws the border
lock.* session lock (ext-session-lock)
ipc.* FENRIZ_SOCKET control socket (see docs/IPC.md)
config.* Hyprland-style config parser
xwayland.* XWayland support (X11 apps)