Skip to content
Salah Adawi Salah Adawi

Release v26.04 · niri-wm/niri

We believe that this document is fully human-written.

Hacker News Article AI Analysis

Content Label

Human

AI Generated

0%

Human

100%

Window 1 - Human
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.As you may have noticed, niri now lives in a GitHub org rather than my (@YaLTeR) personal account.The primary reason was the ability to give out issue triage permissions: I'd like to give a massive thanks to @Sempyos for triaging all of our issues and pull requests, answering many, many questions, and helping people diagnose their problems with niri.We've also moved a few niri-adjacent projects to the GitHub org, like the awesome-niri list of related projects maintained by @Vortriz and a new artwork repo by @bluelinden and @HumpityDumpityDumber—two of the creators of our project logo. In the artwork repo, you can find a badge and several wallpapers, including two stunning 3D works created by @Duncan-Rose in Blender: pool cut The main niri repo also flew past 20,000 stars in February! 🌟 Thanks everyone for support.NotePackagers: our minimum supported Rust version is now 1.85. niri.service no longer hardcodes /usr/bin/ in the niri binary path (thanks @Axlefublr). @markK24 restructured the dinit service files: 3bfa4a7 Now with introductions out of the way, here are the improvements from the last release.BlurIt's here. The most requested niri feature by far. Our highest upvoted issue on GitHub. After tireless fork maintenance by @visualglitch91 and @Naxdy, blur is in mainline niri for everyone to use!Windows and layer-shell components can request blur through the ext-background-effect Wayland protocol with no extra niri configuration.
Window 2 - Human
Many already do: Dank Material Shell v1.5: enable background blur in settings Noctalia shell: enable in settings and see docs Vicinae launcher foot terminal v1.26: set blur=true in colors config kitty terminal v0.46.2: set background_blur 1 Ghostty terminal: will have support in v1.4 Toolkits: Quickshell: will have support in v0.3 winit: will have support in v0.31 For apps that don't support ext-background-effect yet, you can enable blur through the niri config:// Enable blur behind the Alacritty terminal. window-rule { match app-id="^Alacritty$" background-effect { blur true } } // Enable blur behind the fuzzel launcher. layer-rule { match namespace="^launcher$" background-effect { blur true } }Keep in mind that niri-configured blur needs the right geometry-corner-radius, and it won't work with complex surface shapes. See the Window Effects wiki page for details. Have I seen this screenshot before?..We have both normal blur and xray blur that always shows the wallpaper. Xray blur is the default because it's much more efficient: niri computes the blurred wallpaper once, and then reuses it as a static image, which is extremely cheap. Only if the wallpaper changes, the blur is recomputed (so an animated background will shrink the efficiency gains).If you prefer non-xray (normal) blur, you can enable it with a window/layer rule. For example, you can set it on top and overlay layers (that usually overlap other content), via the new layer matcher:// Make top and overlay layers use the regular blur (if enabled), // while bottom and background layers keep using the efficient xray blur. layer-rule { match layer="top" match layer="overlay" background-effect { xray false } }So, if blur is so good, where's blur 2? Err, I mean, why did it take so long to add?In short, background blur turned out to be a massive undertaking.
Window 3 - Human
Not because of the blur algorithm itself (by the way, if you want to learn about different blurs, including the widely used Dual Kawase, I highly recommend this blog post), but because window background effects in general required a lot of thinking and additions to the code, especially to make them as efficient as possible. This is one of the most complex niri features thus far.Xray and non-xray effects are also pretty much two entirely separate and very different beasts, code-wise. Non-xray reads back the just-rendered pixels in the middle of a frame, blurs them, then continues drawing the frame. This required extensive refactors of Smithay's rendering architecture (big thanks to @Drakulix!). Xray on the other hand requires threading the window positions all throughout the rendering code to draw the right cut-out of the background.But it gets worse: we have our Overview. It was quite a challenge figuring out how to support xray blur in the overview, while maintaining the property that it is never re-rendered. niri-xray-blur-offscreens.mp4 I also had to get both of them working with all other niri features, like blocking out from screencasts. When the window itself is blocked out that's easy, but what if something in the background layer, inside the blur, is blocked out? An unusual case for sure, but hardly a good exclude if your sensitive data gets accidentally leaked. niri-xray-blur-blocked-out.mp4 By the way, I made it so xray can be used on its own, without the blur. As well as the noise and saturation effects (normally for reducing blur color banding and bumping the vividness). For example:window-rule { match app-id="Alacritty" // Xray without the blur! background-effect { xray true } }One more thing you can do starting from this release is to configure niri to apply transparency and background effects to pop-up menus, using the new popups block in window or layer rules.// Blur the background behind pop-up menus in Loupe. window-rule { match app-id="Loupe" popups { // Matches the default libadwaita pop-up corner radius. geometry-corner-radius 15 // Note: it'll look better to set background opacity // through your GTK theme CSS and not here. // This is just an example that makes it look obvious.
Window 4 - Human
opacity 0.5 background-effect { blur true } } }Keep in mind that pop-up rules tend to bump even more into problems with application behavior and surface shapes. For example, web apps or Electron don't use Wayland pop-ups at all; they're entirely emulated inside the client—niri cannot do anything with them.Shape-wise, in GTK 4, pop-ups with has-arrow=true won't look right because they aren't rounded rectangles. Thankfully, clients implementing ext-background-effect can shape their blur in any sort of elaborate pattern.Well, enough about blur, we've got more interesting things to cover!Credit: Houl FloofOptional includesPretty much right after I added config includes last release (before I merged them even), people started requesting optional includes—that can be absent without failing config loading. Some use-cases are being able to change parts of an immutable niri config on NixOS, or having local/private overrides for parts of the config.I pushed back for a time because I think some of those problems should be solved elsewhere, rather than requiring every program with includes to support optional. However, the added code complexity was rather low, so I eventually went ahead and accepted @johnrichardrinehart's implementation.Starting from this release, you can make an include optional by setting optional=true:// Won't fail if this file doesn't exist. include optional=true "optional-config.kdl" // Regular include, will fail if the file doesn't exist. include "required-config.kdl"When an optional include file is missing, niri will emit a warning in the logs on every config reload. This reminds you that the file is missing while still loading the config successfully.The optional file is still watched for changes, so if you create it later, the config will automatically reload and apply the new settings. Finally, optional=true only affects whether a missing file causes an error, so if the file exists but contains invalid syntax or other errors, those errors will still cause a parsing failure.While we're talking about includes: they now expand paths starting with ~ to the home directory, so ~/file.kdl will expand to /home/user/file.kdl. Thanks to @HigherOrderLogic and @BennyDeeDev for prototype implementations of this feature.Pointer warping while scrollingLast release, I made dragging windows horizontally by their titlebars scroll the view left and right.
Window 5 - Human
This made mouse-only navigation much more convenient, but I still felt that something was missing.This release makes the pointer warp from one side of the screen to the other during view scrolling gestures, similarly to Blender. It makes scrolling through several windows natural and convenient, even when you start right next to the monitor edge. niri-pointer-warp.mp4 Screencasting featuresEarlier in the release cycle, I spent some time improving various aspects of our screencasting support. In niri, you can screencast through xdg-desktop-portal-gnome via PipeWire (the recommended approach), or through wlr-screencopy (mainly intended for tools such as wf-recorder). Both of these have seen improvements.Pointer in window screencastsWhen sharing the screen, you generally want to include the cursor in the video stream. In PipeWire, you can either do the simple thing and just draw the cursor directly inside the video frames, or you can attach it as a separate frame metadata. In this mode, the video stream itself doesn't contain the cursor, instead, the compositor sends a separate buffer with the cursor icon and coordinates. The consuming application itself (such as OBS, or your browser in a video meeting) then has to draw the cursor on top.This allows the consuming application to control the cursor visibility. You might have seen this toggle in OBS; it can work thanks to the metadata cursor mode:Ever since I implemented PipeWire screencasting in niri about a month into development, it's been using the embedded cursor mode for simplicity. I rendered the cursor for monitor streams and hid it for window streams, and this mostly did what you wanted (and the cursor toggle in OBS didn't work).Doing it properly has always been in the back of my mind though. I was most missing cursor in window streams because I pretty much always use the window target when screensharing in meetings.Well, in the summer of last year, @abmantis took up the task. The road was quite bumpy though: they hit and managed to debug a memory corruption issue in PipeWire (that other compositors haven't hit due to more eagerly overriding unchanged data every frame). The bug was thankfully promptly fixed by a PipeWire developer.