github YaLTeR/niri v0.1.4

latest release: v0.1.5
22 days ago

Before we begin: downgrade xz to v5.4. Done? Good, let's get to the release.

Niri is a scrollable-tiling Wayland compositor. Windows are arranged in columns on an infinite strip going to the right. Opening a new window never causes existing windows to resize.

Here are the improvements from the last release.

Block out windows from screencasts

You can now instruct niri to block out certain windows from screencasts with a window rule. This can be useful for apps like password managers or messengers that you don't want to accidentally show during meetings or streams.

Screenshot showing a visible Secrets window and an OBS window screencasting the screen where there's a black rectangle instead of the Secrets window.

The compositor (niri in this case) is the perfect place for this functionality since it is solely responsible for the video frames sent to displays and screencast clients like OBS. Plus, the compositor has the entire window tree, and can selectively block out individual windows while retaining correct layered compositing.

This blocking out also seamlessly works with the built-in screenshot UI. You can capture a screenshot with interactive area selection while seeing all windows normally, and on a screencast, this entire process, including the interactive selection UI, will have the windows correctly blocked out.


Unfortunately, this kind of tight integration is not possible with third-party screenshot annotation/preview tools. To avoid accidentally showing windows even when using third-party screenshot tools, niri provides a more aggressive mode that blocks out the window from all screen capture tools, not just xdg-desktop-portal screencasts.

Dynamic window rules

Window rules, introduced in the last release, let you adjust behavior for individual windows. For this release, I did the necessary refactors to support dynamic window rules that apply continuously to open windows.

The main example of course is the rule to block out windows from screencasts (described above), but you can also override whether borders draw with a solid background, change the window size limits and adjust window opacity.

As an example, you can replicate the "inactive windows become semitransparent" effect:

window-rule {
    match is-active=false
    opacity 0.9

Screenshot showing three apps, the middle one focused, and the ones on the side are semitransparent.

Check out the window rules wiki page for a complete list of properties that you can set.

By the way, I also added a little niri msg focused-window IPC command that shows you the title and app ID of the focused window, to aid in writing rule matchers.

Warp mouse to focus & focus follows mouse

Two popular features among tiling WMs, now in niri.

Warp mouse to focus, implemented by @FluxTape (thanks!), will automatically move the mouse into windows as you focus them. Focus follows mouse on the other hand will automatically focus windows under the cursor as you move it around.

These two actually work very well together, give it a try!


Mouse and touchpad scroll bindings

It is now possible to bind mouse wheel and touchpad scrolls to perform actions or spawn commands. Mouse scrolling activates every wheel "tick", whereas touchpad scrolling emulates scroll "ticks" based on finger distance traveled.

Additionally, you can now set a cooldown for binds to avoid triggering them too often with scrolling.

binds {
    Mod+WheelScrollDown cooldown-ms=150 { focus-workspace-down; }
    Mod+WheelScrollUp   cooldown-ms=150 { focus-workspace-up; }

    Mod+TouchpadScrollDown { spawn "wpctl" "set-volume" "@DEFAULT_AUDIO_SINK@" "0.02+"; }
    Mod+TouchpadScrollUp   { spawn "wpctl" "set-volume" "@DEFAULT_AUDIO_SINK@" "0.02-"; }

Check the wiki page for more details.


Niri now implements the wlr-gamma-control protocol that is required for "Night Light" tools like wlsunset and gammastep. Thanks @phuhl for working on this!


As it turns out, setting the gamma is pretty slow, at least on my system. I suggest using wlsunset because it only sets the gamma when it needs to change, rather than, say, every few seconds unconditionally.

xdg-desktop-portal-gnome 46.0

I implemented more of the Mutter D-Bus interface to support xdg-desktop-portal-gnome 46.0 with its new screencast monitor selector with visual positions:

Screenshot of the new monitor selector in xdg-desktop-portal-gnome 46.0.


As you've noticed, I've been linking the wiki pages a lot. The reason for this is that over the past week I went through the entire config and wrote detailed documentation and examples for every single option.

Check out all this documentation here on the wiki:

A major benefit of this is that it allowed me to declutter the default config by removing some of the less important things and instead linking the wiki. This will improve the experience for people trying out niri as they no longer need to sift through the entire window rule and animation examples.

If you find a mistake, feel free to open a pull request against the wiki/ folder of the repository.

Also, shoutouts to great reference-style docs @sodiboo had been writing for the nix flake:

Other improvements in this release

  • When opening and closing a window without switching focus in between (think various dialogs and temporary windows), niri focuses the previous window since that's where you came from. Now, when this happens, niri will also restore the view position, which makes the behavior more natural and less annoying.
  • Fixed wp-viewporter bugs in Smithay (thanks @cmeissl). Particularly, this prevented Chromium and Electron applications from accepting mouse input after resizing.
  • Added more information to niri msg outputs (logical output position, size, scale, transform, and current and preferred mode flags).
  • Added a click-method input setting for touchpads (thanks @uetcis).
  • Added a workspace-auto-back-and-forth setting that causes switching to the same workspace by index twice to switch back to the previous workspace (thanks @FluxTape).
  • Added support for ISO_Level3_Shift / Mod5 modifier (thanks @Trundle).
  • Added a once-per-second fallback timer that sends frame callbacks to off-screen windows, which fixes issues with vsynced games in gamescope.
  • The last folder in the screenshot path is now automatically created if it doesn't exist.
  • Corrected pointer location reported to lock screen surfaces.
  • Fixed niri crashing when a screencast is attempted after failing to initialize PipeWire.
    • If on your system PipeWire is not started automatically, you need to make sure that it is started before niri for niri to have screencast support.
  • Fixed a crash that could happen when stopping the same screencast session twice with the right timing.
  • Relaxed checks for DRM render nodes, which in theory allows niri to run on more devices with split DRM display/render nodes (various ARM boards like Raspberry Pi).
  • Made the EGL wl-display extension optional on the TTY which makes niri work on some NVIDIA GPUs where it didn't before.
  • Niri now tries to reduce the max bits-per-channel output property to 8 which may result in more monitor configurations working.
  • Fixed building on musl.
  • Fixed mouse scrolling inside nested niri window sometimes being too slow.
  • Fixed hardcoding us as the keyboard layout when it is missing from the config (turns out libxkbcommon handles that one for us).

Don't miss a new niri release

NewReleases is sending notifications on new releases.