Yesterday dove into one of the older animation jank bugs in niri: quickly resizing a window back and forth would cause adjacent windows to jump. This problem is hard to trigger unless you're specifically trying to (then it's easy), but it was causing "downstream" problems for more complex actions.

The fix was simple enough, but I imagined enough "interesting" cases around it and decided to write a whole bulk of tests. Check this out, all thanks to our layout and clock code!

#niri

Merged the "window positions and sizes in IPC" PR. Please test and report if anything's broken or missing, we have time to fix it until the next release.

https://yalter.github.io/niri/niri_ipc/struct.Window.html#structfield.layout

Here's a quick quickshell test I threw together that draws floating windows as rectangles.

Thanks yrkv for getting the PR mostly complete!

https://github.com/YaLTeR/niri/pull/1265

#niri

With massive thanks to cutenice, we have a new wiki site!!! With good search!  

https://yalter.github.io/niri/

Make sure not to miss the new Since: annotations 

The site uses Material for mkdocs, and we retained full compatibility with GitHub Wiki, meaning all existing links keep working.

Also thanks everyone for several suggestions and test wikis in the GitHub discussion!

#niri

Rearranged and expanded quite a bit the design principles page on the wiki: https://yalter.github.io/niri/Development%3A-Design-Principles.html

Give it a read if you're curious about my thinking process about various niri behaviors and such

#niri

Design Principles - niri

Implemented basic AccessKit integration for niri based on @DataTriny's proof-of-concept. I have little experience with screen readers, and also had several questions, so I would appreciate more eyes and testing on the PR:

https://github.com/YaLTeR/niri/pull/2273

#niri #a11y

Implement basic screen reader announcements via AccessKit by YaLTeR · Pull Request #2273 · YaLTeR/niri

Supersedes #2042. Implemented screen reader support for: exit confirmation dialog screenshot UI, overview (it'll just say when these are focused) config parse error announcement workspace swit...

GitHub

niri v25.08 is now released with a logo, xwayland-satellite integration, basic screen reader support, NVIDIA screencast flickering fix, window positions and sizes in IPC, and many other improvements! 

Read the notes here: https://github.com/YaLTeR/niri/releases/tag/v25.08

now i need at least a month off from any release notes preparation 😴

#niri #smithay #wayland #rust

Screen reader announcement demo bc apparently you can't attach video and image at once

#niri

Fullscreen refactor pt. 1: track pending vs. current fullscreen state for columns, avoid vertical jump when waiting for window to commit a new buffer.

#niri

Fullscreen refactor pt. 2: added un/fullscreen animations. This one involved quite a lot of moving parts actually, so looking for testing.

https://github.com/YaLTeR/niri/pull/2333

#niri

Fullscreen refactor pt. 3 turned out to be a refactor of a good chunk of core Smithay xdg-shell/layer-shell/session-lock logic, making it more correct. The fullscreen PR in niri now includes that Smithay refactor, and needs testing even more than before  

https://github.com/YaLTeR/niri/pull/2333#issuecomment-3263990200

Specifically, the refactor makes Smithay correctly track the last acked configure for each commit, also enforces the "must ack before committing first buffer" protocol rule.

#niri

Refactor layout fullscreen handling, add un/fullscreen animations by YaLTeR · Pull Request #2333 · YaLTeR/niri

The first part of the PR splits Column is_fullscreen into is_pending_fullscreen and is_fullscreen() like Tiles always were, and changes the relevant places to use the correct one of the two. This f...

GitHub

With the fullscreen refactors in place, I got started on the thing that I wanted to do all along: maximize.

Niri didn't support normal Wayland maximize because it's very similar (yet slightly different) to our full-width columns—and can't be bound to our full-width state either. However, after plenty of requests, and thinking about it, I reconsidered. Henceforth, the maximize buttons and double-clicking on the titlebars will do the expected thing.

Details in PR: https://github.com/YaLTeR/niri/pull/2376

#niri

My Smithay refactors were merged: the big one mentioned above, plus a fix for popup stacking order (e.g. open popup, then open tooltip also from the toplevel itself), plus a fix for root popup grabs from Qt layer-shell surfaces. All of this along with fullscreen refactors and animations is now merged to niri main. (maximize is still wip)

#niri

There's been a long-standing request to add config includes to niri. They're useful for config organization, but also for custom desktop shells to be able to change colors without having to edit the main user's config.

Today I finished the first step towards this: a many-days-long refactor that makes the main config part, layout, mergeable, i.e., able to be combined from multiple parts. And building on this, per-output/workspace overrides.

https://github.com/YaLTeR/niri/pull/2449

Testing wanted here!

#niri

Per-output and per-workspace layout by YaLTeR · Pull Request #2449 · YaLTeR/niri

Alright, this is a big one, though most merge conflicts should be trivially resolvable. The code should be more or less complete but I haven't edited the wiki yet. In this PR we makes the layou...

GitHub

Our config system is declarative, rather than command-like, which means that we parse the config into a tree of data types instead of reading lines and applying them one-by-one. This design requires a lot of work to properly support includes, but in turn we get atomic and selective reloading (if output part of the config didn't change, we don't override your transient output adjustments), better error messages and no problems with things like "spawn-at-startup" that should only work once.

#niri

After several more days of work, I fully finished config includes. All config sections merge together, live-reloading watches all included files (even if they fail to parse), error messages work across files, documentation is written.

https://github.com/YaLTeR/niri/pull/2482

Once again, this needs testing! There must be NO breakage to existing configs, so if something breaks, I want to know about it to fix it.

#niri

Config includes by YaLTeR · Pull Request #2482 · YaLTeR/niri

Based on #2449 (will merge together), supersedes #2340. Adds support for including other config files. Included files have the same structure as the main config file. Settings from included files w...

GitHub

I merged config includes, along with per-output and per-workspace layout config overrides. Play around with them at your nearest niri-git package.

- https://yalter.github.io/niri/Configuration%3A-Include.html
- https://yalter.github.io/niri/Configuration%3A-Outputs.html#layout-config-overrides
- https://yalter.github.io/niri/Configuration%3A-Named-Workspaces.html#layout-config-overrides

Also merged ignore-drm-device which should let you passthrough a GPU to VMs: https://yalter.github.io/niri/Configuration%3A-Debug-Options.html#ignore-drm-device

#niri

Include - niri

After a detour to config includes and, again, several days/weeks of work implementing all edge cases and expected behaviors, true window maximize is ready and merged to main. Tricky cases like: windows requesting fullscreen and maximize after opening; windows failing to match the full maximized size; transparent windows with the niri border behind them.

https://yalter.github.io/niri/Fullscreen-and-Maximize.html

Give it a try! Ngl I mostly switched to maximize just because I'm too lazy to reach the keyboard for Mod+F.

#niri

Fullscreen and Maximize - niri

One cool thing I noticed about true maximize is that apps like GIMP or Inkscape or Blender, that really want all available space, maximize themselves at startup, so you don't have to window-rule them manually in your config

#niri

microsoft niri

#niri

Small change on niri-git for people using the foot terminal with CSD, or other apps that constrain their sizes to a grid: niri will now match the default column width to a preset width when a window opens. So opening foot sized "proportion 0.5" and then pressing Mod+R will switch you to the next preset width, even if foot actually opened slightly smaller to match its terminal grid. Before the change, the first Mod+R would pick the same "proportion 0.5" in this case and "do nothing".

#niri

Also, experimenting with this interaction tweak on a branch: what if dragging tiled windows horizontally scrolled the view instead of dragging them "out"? This makes it possible to scroll the view mouse-only without going through the Overview (the zooming gets quite tiring when it's frequent), and makes it possible to scroll the view touch-only. To drag the window out of the layout, you can still drag it downward.

#niri

Added a small "Quick Start" to the niri docs that gets you going with niri + DMS in three commands:

https://yalter.github.io/niri/Getting-Started.html#quick-start

Tested the Fedora ones on a fresh VM, worked out nicely, getting me into a session with a very functional desktop shell.

#niri

Getting Started - niri

Currently in the middle of finishing up the Alt-Tab PR for niri: https://github.com/YaLTeR/niri/pull/1704

Got most things working as I'd like, though still plenty of fixes and clean-ups left. Fully live window previews with block-out-from support and fading title labels.

There's some interesting design differences compared to other desktops: on niri I expect it's common to have multiple terminals open, so Alt-Tab must go by windows (not by apps) and must show previews big enough to pick the right one.

#niri

We've hit 15k stars on the niri repo!!   

#niri

Just merged Alt-Tab to main, shortly arriving at your nearest niri-git. Comes with plenty of ways to tweak it if you want [1], and a focus timestamp in the IPC [2] that lets shell devs make their own recent windows switchers.

[1]: https://yalter.github.io/niri/Configuration%3A-Recent-Windows.html
[2]: https://yalter.github.io/niri/niri_ipc/struct.Window.html#structfield.focus_timestamp

#niri

Did some work on the TTY backend in niri over the past few days. Merged PR for DisplayLink dock support, added "panel orientation" property read, and, based on cosmic-comp code, implemented the necessary logic to avoid screen blanking. Finally, both at niri startup and when switching TTYs, your screen won't flicker, as long as resolution/refresh rate stay the same.

Even when the screen does blank, it'll go faster, as there's now just one modeset instead of two (clear then draw frame).

#niri

Took some fighting but I think I've managed to teach the new Alt-Tab to speak to the screen reader

#niri

I finished and merged the horizontal drag interaction tweak from a previous post. It's very handy but can also be annoying when you want to move windows across monitors, so on mouse I restricted it to headerbar dragging (so, not Mod+LMB and not in the overview).

On touch however, it works for both headerbar dragging, and for Mod+Touch, so you can now easily scroll the view around.

I also added the thing where you can touch with another finger to switch between floating and tiling.

#niri

DankMaterialShell folks set up builds for Debian, Ubuntu and OpenSUSE, so now it's super easy to try niri & DMS on those systems.

I added Ubuntu commands to the niri quick start guide: https://yalter.github.io/niri/Getting-Started.html

Debian and OpenSUSE here: https://build.opensuse.org/project/show/home:AvengeMedia:danklinux

#niri

Today I'm releasing niri v25.11 with long-awaited config includes, Alt-Tab, true maximize, custom modes, and a bunch of other improvements!    Enjoy the release notes :)

https://github.com/YaLTeR/niri/releases/tag/v25.11

#niri #smithay #wayland #rust

Congrats sternenseemann on the nixpkgs niri any% WR at 3 h 20 min

https://github.com/NixOS/nixpkgs/pull/466213

#niri

funny how while working on alt-tab i discovered that mouse scrolling on top of the DMS bar switches workspaces, which completely replaced any need i had for alt-tab, so i ended up never using it

this DMS bar scrolling feature also removed one of my main usecases for the overview

and then the new horizontal window drag gesture removed my other main usecase for the overview, so now i'm opening the overview quite rarely too

(both have their uses; just curious to watch my own habits shift)

#niri

I've had one of those sessions today where I worked with a ton of random windows on a long workspace, while preparing slides for a uni scientific presentation. All kinds of various PDFs, file managers, InkScape, GIMP and so on.

Horizontal mouse headerbar drag to scroll the view was a lifesaver. Definitely a good choice adding this. Along with scrolling the view on DnD near the screen edge. Going through the overview, or always through the keyboard, would be very annoying.

#niri

yuxqiu just improved the default GPU detection logic in Smithay, so niri-git now works out of the box on Asahi and Pinephone devices, without having to manually configure render-drm-device!

#niri

i added the pointer warping thing from blender to when you drag the view around in niri with the mouse

hf with this new way to pass time during boring meetings

(on a more serious note this helps when you need to scroll further than the edge of your monitor allows)

also unrelated: merged optional config includes earlier today

#niri

on niri-git, the nautilus rename popup now works properly with IMEs running

(and generally popups with text fields should work now)

#niri

Experimenting with a restructure of the niri rendering code to uncurse it somewhat by getting rid of all complex impl Iterator chains and lifetimes, which also lets me remove some intermediate small Vecs. In essence, going from pull to push iteration.

I'm surprised that the result is consistently 2-3x faster than before. Wonder if it's the Vecs, or if inverting (massive) codegen'd iterators into a normal call stack passing a closure arg, providing the main benefit

#niri

Finished the push-based rendering refactor, made a write-up here for the curious: https://github.com/YaLTeR/niri/pull/3113

It even ended up with a negative delta (+762 -780) which is always a W.

Btw I ran the comparison on my Eee PC and there the difference is even more extreme, like 8x faster rendering list construction (which is once again only a part of the total rendering time, and notably doesn't include actual rendering, but still nice).

#niri

Refactor rendering to push-based instead of pull-based by YaLTeR · Pull Request #3113 · YaLTeR/niri

Our current rendering code constructs and returns complex -> impl Iterator<Item = SomeRenderElement> types that are collected into a vector at the top level Niri::render(). This causes som...

GitHub

biblically accurate window management

#niri

i'm reviving the PR integrating Tracy GPU profiling into Smithay. Here are two test captures from niri: one for normal + screencast rendering, one for iGPU + dGPU monitor rendering

#niri

Looking for ideas on how to go about translating niri (the binary, and the wiki). If you have experience doing this with other FOSS projects, please share:

https://github.com/YaLTeR/niri/discussions/3135

#niri

Translation process for niri and the wiki · YaLTeR niri · Discussion #3135

Discussion to gather ideas on how we should go about translations, both for the niri binary, and for the wiki. I know there are some community translation projects already like the Chinese niri wik...

GitHub

Is there any good way of moving a process into a systemd StartTransientScope together with its children?

In niri we put spawned processes into scopes, so oomd and other stuff can work properly. Usually you do it by putting yourself into a scope, then exec-ing the target program. But that's a 7 ms toll on startup time, so in niri we spawn the program right away, and then put it into a scope. However, if the program forks fast enough, that child doesn't go into the scope..

#niri #linux #systemd

Turns out GNOME Shell has the same problem: https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/6565

I also wrote it down in a more detailed form on the niri issues for future reference: https://github.com/YaLTeR/niri/issues/3201

gnome-shell moves applications between cgroups while they are running (#6565) · Issues · GNOME / gnome-shell · GitLab

While testing the Ubuntu 23.04 development releases we've noticed intermittent failures to launch snap applications from gnome-shell, as documented in LP bug...

GitLab

niri can now include the mouse pointer on window screenshots, a feature that had several more edge cases than I thought before starting to work on it (and it's likely not the ones you think, those ones were easy)

#niri

Merged another long time overdue niri PR: mouse cursor via metadata in PipeWire screencasts (lets you toggle Show Cursor on/off in OBS), and full mouse cursor support in window casts.

The cursor is visible only when the window is receiving mouse events—if you're moving the mouse on top of something else covering the target window, the cursor won't be (unintentionally) painted.

Thanks @abmantis for driving this, including debugging a memory bug in PW!

#niri

Working on a screencast IPC for niri. The idea is to give info to desktop bars to be able to add a screencast indicator whenever something is recording the screen.

Got it hooked up for both PipeWire (obviously) and wlr-screencopy. For the latter there's no good way to tell if something is a screencast so I went with some heuristics.

Here's the icon working on the DMS bar, as well as a popup with the full available info I made for debugging.  

#niri

Oh right, for PipeWire I can send the node ID, which DMS can then use to fetch the consumer application name!

#niri

Cast in niri_ipc - Rust

A screencast.

It's now in niri-git + dms-git, and it just helped me realize I had a bunch of extra screen capture sources in my laptop's OBS lol

Also added niri msg action stop-cast to force-stop a PipeWire screencast

#niri

working on my new visual style

#niri

So yeah, I'm working on blur for niri. I'm doing "xray blur" first where the idea is that you only include background surfaces, so you pretty much never have to redo the blur—next to zero perf impact unless you have a video wallpaper or smth.

Turns out that it's quite tricky to do well, especially with our Overview. I'm like on my third refactor attempt now but I think I've got a good approach.

During this video there's no reblurring whatsoever, all just drawing cached static textures.

#niri

Added non-xray blur, based on @drakulix's Smithay/COSMIC implementation.

Keep in mind this blur work is still extremely WIP and with many issues (some visible on the video). It's also still not entirely clear to me how to best structure the code around it in niri. We'll see

#niri

Alright, getting somewhere! I think I've figured out a good code structure for the xray blur. It now correctly works even inside offscreens (opening animation, and when you drag a window targeting the tiling layout), and it should also work properly with the upcoming screen magnifier (that we have in pull requests).

Still not a single blur re-render in this entire video!

#niri

you know it's serious when you have to pull out a notebook to figure out the coordinate transforms

#niri

Today, got xray working on the closing window animations. The reason this needs special treatment is that when a window closes, niri renders a snapshot of its last visible contents to use for the animation. This happens outside the normal rendering path so I needed to thread through the xray background rendering logic as well as the correct window coordinates (since the xray background needs to know where the window is to draw the correct thing).

#niri

Today: implemented (a limited but useful subset of) both ext-background-effect and org-kde-kwin-blur protocols. Clients use these to request blur on their surfaces without having to configure anything in the compositor. These protocols also allow clients to blur only parts of their surfaces, for example here excluding client-side decoration bars and shadows.

Here are three terminals all with their org-kde-kwin-blur setting enabled.

#niri

Seems that Ghostty sets KDE blur on its entire surface without a region, even with CSD. This means that blur is drawn under the opaque bar and shadows and ignores rounded corners. On the screenshot it's fine because I have a manual niri config override for the Ghostty window corner radius, but it looks broken by default. Would be nice to get that fixed.

@YaLTeR if you open a discussion on GitHub, then it can be triaged into an issue.

- maintainer

@YaLTeR This makes me very happy 😊
@YaLTeR this is so sick, looks like the next release is going to be a big one! Thank you for all your hard work on such an excellent WM, it's really revolutionized how I work on smaller screens
@YaLTeR Everyone does that right?
@YaLTeR i think i never sympathized so much as now (literally did the same thing working on the same problem in the same project)
@YaLTeR impressive! 👍
@YaLTeR @drakulix can you visualize what gets damaged with the fishbowl icons flying under and out of the blurred area?
@bugaevc currently the entire "framebuffer effect" region (blurred contents) gets damaged if anything below is damaged
@YaLTeR @bugaevc With how dual kawase works (which makes it difficult to predict the exact radius, but it does scale linearly) and a blit being a relatively cheap operation, I don’t think that is an issue though compared to what you would assume happens with a more naive blur implementation.
@YaLTeR holy hell, looks great
@YaLTeR looking very good 😊
@YaLTeR this is looking good
@YaLTeR This post is the flick that a lot of us were waiting for to ditch #hyprland and its exhausting breakages!
go go go #niri!!

@YaLTeR awesome! Is there already a branch where we can try it out?

Also I'm not sure if any of it is applicable/compatible with how Niri is built but COSMIC also uses Smithay (afaik) and is also working on a blur implementation, maybe that could serve as inspiration in the future?

@darius there's a branch but it's very wip. And I will be using the thing @drakulix added for cosmic (it's for non-xray blur)
@YaLTeR that looks kinda trippy
@YaLTeR for a stacking wm "xray" blur would be disappointing but for niri it makes total sense! nice
@YaLTeR can you share your Niri/Shell config ?

@ke1su https://github.com/YaLTeR/dotfiles

I don't have dms config backed up, but it shouldn't be hard to configure

GitHub - YaLTeR/dotfiles

Contribute to YaLTeR/dotfiles development by creating an account on GitHub.

GitHub
@YaLTeR I don't mean to sound rude, but how long till this hits stable?
@YaLTeR if you liked Liquid Glass, you'll love Adwaita: Migraine Simulator Edition

@YaLTeR

Looks cool❤️
Does niri implemented blur already? 🤔
or just transparency only at this point?

@vivekanandanks rumor has it there's a branch
@YaLTeR oh wow, I hope it's fluid simulation :D
@YaLTeR i am not sure if distance alone will safe you from @tbernard's wrath
@YaLTeR does this mean blur... or long running shaders.. :p i know phisch will be happy
@YaLTeR It's Niri community meme that's being murdered!
@YaLTeR so OBS doesn't realize the screencast is over?

@bugaevc maybe? But also maybe not; preserving the last frame is one of the valid behaviors, arguably it makes some sense for OBS.

Also I think it's kind of involved to see if your pipewire stream has been disconnected from the other end (vs. just paused for renegotiation or something)

@YaLTeR seriously? knowing that your stream has definitively ended (vs paused) that sounds like a very basic thing
@YaLTeR Nice! Depending on how you implemented that, it might be a good chance to also consider a camera indicator - at least for Pipewire cameras (v4l2 is still tricky).
@rmader that's something for DMS itself to do since niri isn't involved in cameras—the niri side only exposes whenever it's doing a PW screencast. Actually I think DMS already has something like that for PW cameras, but maybe unfinished
@YaLTeR
Noctalia has for cameras i think, it is usually close to DMS.
@rmader
@rmader btw do you know if it's reasonably possible to get pid or some other credentials for the pipewire screencast consumer? Especially if it's going through the portal
@YaLTeR Oh that's really cool. Compositor-independent implementations of the screencopy indicator always worked unreliably for me. It's good to have a built-in option for that. I will definitely implement this in my shel when it comes out!
@YaLTeR @abmantis Goddamn that looks like a pain in the ass! Nice!

@YaLTeR there's only a key binding for window screenshots, right?

How can you toggle between showing and hiding the pointer then?

@ju flag on the key binding:

screenshot-window show-pointer=true;

and the same flag on the CLI/IPC

@YaLTeR ah makes sense!

I wondered the other day, would it be possible to make window screenshots by right-clicking on the headerbar like it works on GNOME?

Or allow window selection in the screenshot UI?

@ju yes to both, i'm leaning toward the first one since it's simpler, but it's blocked on the fact that we don't have any right click menu yet
@YaLTeR This feature is timely for me!