ONLINE SIGNAL STRONG | MAC · LINUX · LIFE --:--:-- UTC
← all transmissions
Linux June 7, 2026 5 min #Linux#Wayland#Fedora

Building a Niri Desktop on Fedora 44

A scrollable-tiling Wayland setup with niri, waybar, fuzzel, and mako — Tokyo Night all the way down.

I switched my Fedora 44 desktop over to niri, a scrollable-tiling Wayland compositor. Instead of cramming windows into a fixed grid, niri lays them out in an infinite horizontal strip — columns scroll off the sides of the screen and you pan along them. It clicks immediately if you’ve ever wished your tiling WM just let windows be their natural size.

Here’s the full stack and how the pieces fit together.

A niri desktop on Fedora 44 — Tokyo Night waybar over a New York City sunset wallpaper

The stack

PieceJob
niriCompositor / window manager
waybarTop bar (workspaces, clock, system stats, audio visualizer)
fuzzelApp launcher + dmenu backend for my scripts
makoNotification daemon
swwwWallpaper daemon (with transitions)
swaylockScreen locker
ghosttyTerminal
yaziFile manager (runs in ghostty)

Everything is themed Tokyo Night, and everything uses JetBrainsMono Nerd Font so the glyphs in the bar and menus render correctly.

The display

I’m on a single Vizio V405-G9 4K panel over HDMI. niri keys output config by connector name, so:

output "HDMI-A-1" {
    mode "3840x2160"
    scale 1.25
    transform "normal"
    position x=0 y=0
}

The 1.25 scale matches what GNOME was doing — crisp 4K without everything being microscopic. niri auto-picks the highest refresh rate for the resolution unless you pin one with @<rate>.

Layout & looks

The layout section is where niri’s personality lives:

layout {
    gaps 20
    center-focused-column "never"
    preset-column-widths {
        proportion 0.33333
        proportion 0.5
        proportion 0.66667
    }
    default-column-width { proportion 0.5; }
}

New windows open at half the screen width, and Mod+R cycles a column through ⅓ → ½ → ⅔.

For chrome I went with a gradient focus ring instead of a hard border, plus soft drop shadows and rounded corners:

focus-ring {
    width 2
    active-color "#7aa2f7"
    active-gradient from="#7aa2f7" to="#bb9af7" angle=45 relative-to="workspace-view"
    inactive-color "#3b4261"
}

shadow {
    on
    softness 30
    spread 5
    offset x=0 y=5
    color "#0007"
}

One gotcha worth calling out — a window rule ties it all together:

window-rule {
    geometry-corner-radius 10
    clip-to-geometry true
    draw-border-with-background false
}

That draw-border-with-background false matters: without it, niri draws the focus ring as a solid rectangle behind the window, and the color bleeds through semitransparent terminals (ghostty especially) and washes them out. Drawing the ring around the window fixes it, and clip-to-geometry makes the rounded corners actually clip content.

Startup

niri spawns the supporting cast at launch:

spawn-at-startup "waybar"
spawn-at-startup "mako"
spawn-at-startup "~/.config/niri/set-wallpaper"

I also nudge toolkits toward native Wayland via the environment block (Qt, Firefox/MOZ_ENABLE_WAYLAND, Electron’s Ozone hint), and drop server-side decorations where I can.

Keybinds

niri’s Mod is Super on a real TTY. The binds I actually use day to day:

BindAction
Mod+TTerminal (ghostty)
Mod+DLauncher (fuzzel)
Mod+EFile manager (yazi in ghostty)
Mod+QClose window
Mod+H/J/K/LFocus left/down/up/right
Mod+Ctrl+H/J/K/LMove window
Mod+RCycle column width
Mod+FMaximize column
Mod+MMaximize to screen edges
Mod+CCenter column
Mod+VToggle floating
Mod+WToggle tabbed column
Mod+OOverview (zoomed-out workspaces)
Mod+1..9Jump to workspace
Mod+Shift+WWallpaper picker
Mod+Shift+EPower menu
Super+Alt+LLock (swaylock)
PrintScreenshot

Media, volume, and brightness keys are wired to wpctl, playerctl, and brightnessctl, all with allow-when-locked=true so they work on the lock screen.

The bar

Waybar is split three ways:

The whole bar is a single rounded, translucent pill — the trick is styling the inner box rather than the window so GTK clips the corners cleanly:

window#waybar { background: transparent; }
window#waybar > box {
    background: #1a1b26;
    border: 1px solid #3b4261;
    border-radius: 10px;
}

The cava visualizer

Fedora’s waybar build doesn’t ship the built-in cava module, so I feed a custom/cava module from a script. It runs cava in raw ASCII mode and maps each 0–7 level to a block glyph (▁▂▃▄▅▆▇█):

chars=("▁" "▂" "▃" "▄" "▅" "▆" "▇" "█")
cava -p "$conf" | while IFS= read -r line; do
    # ...map each value to a glyph, emit a blank line when silent
done

The blank-line-on-silence bit means the bars only appear while audio is actually playing — no idle clutter.

Helper scripts

I leaned on a few small bash scripts in ~/.config/niri/ rather than stuffing logic into config:

set-wallpaper — the single source of truth for the background. It points a stable symlink (~/.config/niri/wallpaper) at the real image and applies it through swww with a grow transition. Run it bare to re-apply, or with a path to switch:

set-wallpaper ~/Pictures/new.jpg

It also handles the annoying details: swww lives in ~/.cargo/bin (not always on the session PATH), it waits for the daemon’s socket before issuing commands, and it kills any leftover swaybg from the old setup.

wallpaper-picker (Mod+Shift+W) — globs images from the usual wallpaper dirs, shows them in fuzzel, and hands the choice to set-wallpaper.

power-menu (Mod+Shift+E + the waybar power button) — a fuzzel dmenu for Lock / Logout / Suspend / Reboot / Shutdown, backed by swaylock and systemctl.

Notifications

Mako rounds it out, matching the same palette — translucent #1a1b26 background, blue border, with red high-urgency notifications that never auto-dismiss:

border-radius=10
background-color=#1a1b26f0
border-color=#7aa2f7

[urgency=high]
border-color=#f7768e
text-color=#f7768e
default-timeout=0

Verifying changes

One handy thing about niri: it validates your config without a restart.

niri validate

It reloads the config live on save, so most tweaks are instant — but niri validate catches syntax errors before they bite.


That’s the whole desktop: a scrollable-tiling compositor, one cohesive Tokyo Night theme, and a handful of small scripts doing the unglamorous work. The config files are about as boring-on-purpose as I could make them, which is exactly what I want from something I stare at all day.

← all transmissions