` focuses a specific window by index.
The tab indicator can be customized in several ways and moved to top/bottom/right of the column. See [the wiki page](https://github.com/YaLTeR/niri/wiki/Configuration:-Layout#tab-indicator) for more details.

You can also make windows open as tabbed columns by default [globally](https://github.com/YaLTeR/niri/wiki/Configuration:-Layout#default-column-display) or with a [window rule](https://github.com/YaLTeR/niri/wiki/Configuration:-Window-Rules#default-column-display). This goes well with the `hide-when-single-tab` setting for the tab indicator.
##### Shadows
Niri can now draw shadows behind windows. Apart from being a nice aesthetic effect, shadows help to delineate floating and otherwise overlapping windows. They are especially useful when you [disable](https://github.com/YaLTeR/niri/wiki/Configuration:-Miscellaneous#prefer-no-csd) or [clip away](https://github.com/YaLTeR/niri/wiki/Configuration:-Window-Rules#clip-to-geometry) client-side decorations (which commonly include shadows of their own).

Niri shadows are not enabled by default to not clash with the shadows coming from client-side decorations. Turning them on is simple enough:
```kdl
// Enable shadows.
layout {
shadow {
on
}
}
// Also ask windows to omit client-side decorations, so that
// they don't draw their own window shadows.
prefer-no-csd
```
You can customize properties like softness (blur radius), spread, offset, and color, both [globally](https://github.com/YaLTeR/niri/wiki/Configuration:-Layout#shadow) and [for individual windows](https://github.com/YaLTeR/niri/wiki/Configuration:-Window-Rules#shadow). Like borders and focus rings, shadows will follow the window corner radius that you set via [`geometry-corner-radius`](https://github.com/YaLTeR/niri/wiki/Configuration:-Window-Rules#geometry-corner-radius).

Shadows also work on layer-shell surfaces. Due to the higher
_[Truncated at 4000 characters — full notes: https://github.com/niri-wm/niri/releases/tag/v25.02]_
### v25.01
- Date: 2025-01-11
- Version: v25.01
- Original notes: https://github.com/niri-wm/niri/releases/tag/v25.01
- Permalink: https://whatsnew.fyi/product/niri/releases/v25.01
- Labels: Platforms: Linux
- **added** — Floating windows support with auto-float for dialogs and fixed-size windows
- **added** — Actions for focusing floating or tiling layout and moving windows between them
- **added** — Window rule matchers and rules for floating windows including is-floating, open-floating, and default-floating-position
- **added** — Mouse right-click dragging to move windows between floating and tiling layouts
- **changed** — Switch to year.month versioning scheme instead of semantic versioning
- **changed** — Minimum required Rust version is now 1.80
- **added** — Environment variables NIRI_BUILD_VERSION_STRING and NIRI_BUILD_COMMIT to override version and commit during builds
- **changed** — Floating windows are positioned relative to monitor size and automatically kept within monitor bounds
- **changed** — Floating windows are restored to their previous size and position when moved back from tiling layout
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... hang on, how come we jumped from v0.1 all the way to v25?
Starting now, niri ~~escapes [ZeroVer](https://0ver.org)~~ is switching to year.month versioning. In **25.01**, the "25" is year 2025, and "01" is month 01 (January). So version 25.01 tells you that this release was tagged in January of 2025.
Hotfix releases will use the third component. For example, the first hotfix for the 25.01 release would be called 25.01.1.
There are a few reasons for this change.
- For niri, semver isn't very useful. Big and small features are added every release, and so far we've managed to avoid any breaking changes to the config file. Calendar versioning at least tells you how old of a version you're running.
- v0.1.x left no place for a hotfix version. I couldn't even put v0.1.10.1 into `Cargo.toml` because it has four components instead of three. The new versioning has just two components, leaving one extra for the hotfix version.
- I feel like niri is now sufficiently featureful to graduate from v0.1. :) I expanded the [Status section](https://github.com/YaLTeR/niri/blob/main/README.md#status) of the README to cover some of the frequently asked "is this thing supported" questions.
Similar versioning is also used in other projects like [Helix](https://github.com/helix-editor/helix), [NixOS](https://nixos.org) and [Ubuntu](https://ubuntu.com/).
With this change, the niri releases remain unscheduled: once every few months, and not bound to any particular cycle. Whenever I feel that it's a good time for a new version.
> [!NOTE]
> Packagers: niri now requires Rust 1.80. Also, there are new environment variables to override the niri version string and commit: `NIRI_BUILD_VERSION_STRING` and `NIRI_BUILD_COMMIT`. The new [Packaging niri](https://github.com/YaLTeR/niri/wiki/Packaging-niri) wiki page shows how to use them, along with everything else important for packaging.
>
> New niri tests need `XDG_RUNTIME_DIR` to be set. You can use `export XDG_RUNTIME_DIR="$(mktemp -d)"`.
>
> If some tests fail with `Err::AlreadyInUse` on a heavily multi-threaded CPU, set `RAYON_NUM_THREADS=1`. This is tracked in #953.
##### Floating windows
Floating windows are here! It took a big refactor and a good month of hard work, but the most *liked* niri feature request is done.

Like other WMs, niri will auto-float dialogs and fixed-size windows. With no extra configuration, this release does away with most of the annoying dialog scrolling.
https://github.com/user-attachments/assets/d560582c-07fd-4fcb-bf86-9ed305df515f
Opening LibreOffice no longer causes the view to shift an ultrawide worth to the right.
Being a scrolling WM, there were several options and design decisions to consider for how floating windows should work. I opted for a setup familiar from other tiling WMs: floating windows are on a separate "layer" that always shows on top of the tiled windows, and the floating layout does not scroll. Each workspace/monitor has its own floating layout, just like each workspace/monitor has its own tiling layout.

Finally, you can properly showcase your scrollable-tiling WM setup.
There's a surprising number of features and small details that go into a good floating experience. Things like correct parent-child stacking, focus-follows-mouse activating but not raising the window, or restoring the floating size and position after moving the window to the tiling layout and back.
https://github.com/user-attachments/assets/376ef176-c546-400e-a977-
_[Truncated at 4000 characters — full notes: https://github.com/niri-wm/niri/releases/tag/v25.01]_
### v0.1.10.1
- Date: 2024-11-13
- Version: v0.1.10.1
- Original notes: https://github.com/niri-wm/niri/releases/tag/v0.1.10.1
- Permalink: https://whatsnew.fyi/product/niri/releases/v0.1.10.1
- Labels: Platforms: Linux
- **fixed** — Scrolling not working when the mouse {} or touchpad {} section is omitted from the config file
- **changed** — Mouse cursor now shows up on scroll which makes scrolling work when the cursor was hidden
- **fixed** — Crash when holding Space in the screenshot UI
- **added** — Touch-dragging with held Mod is now bound to interactive window move
This is a hotfix release for [niri v0.1.10](https://github.com/YaLTeR/niri/releases/tag/v0.1.10).
* Fixed scrolling not working when the `mouse {}` or `touchpad {}` section is omitted from the config file.
* Made the mouse cursor show up on scroll which makes scrolling work when the cursor was hidden (thanks @r-vdp).
* Fixed a crash when holding Space in the screenshot UI.
* Bound touch-dragging with held Mod to interactive window move.
### v0.1.10
- Date: 2024-11-09
- Version: v0.1.10
- Original notes: https://github.com/niri-wm/niri/releases/tag/v0.1.10
- Permalink: https://whatsnew.fyi/product/niri/releases/v0.1.10
- Labels: Platforms: Linux
- **added** — Interactive window moving by dragging windows by title bars or while holding Mod
- **added** — Windows rubber-band before being dragged out to prevent accidental layout changes
- **added** — Interactive moving and resizing on touchscreen
- **added** — Pointer location hint request implementation for locked pointer movement
- **added** — Bindings for laptop lid opening/closing and tablet mode switching
- **added** — Automatic disabling of internal laptop monitor when closing the lid
- **added** — Cursor hiding options including hide when typing and hide after inactivity period
- **added** — Pointer shows up on mouse button press
- **added** — Trackball input config section
- **added** — Scroll-button setting for mice, touchpads, trackpoints, and trackballs
- **added** — Scroll-factor setting for mice and touchpads to adjust scrolling speed
- **added** — Window --id argument to niri msg action consume-or-expel-window-left/right and IPC
- **added** — Explicit power-on-monitors action
- **added** — Support for running niri as a dinit service
- **added** — Disable-monitor-names debug config flag as a workaround for crashes with identical monitor reporting
- **changed** — Tablet input no longer follows monitor rotation
- **changed** — GTK Access portal is now explicitly set in niri-portals.conf
- **changed** — Active workspace is now preserved across monitor disconnects and reconnects
- **changed** — Pointer stays hidden on programmatic and keyboard-triggered movement
- **fixed** — Fixed focus-window-up-or-column-right focusing left instead of right
- **fixed** — Fixed animation jump when expelling a narrower window from a column with uneven window widths
- **fixed** — Fixed logind power key inhibit file descriptor leaking into spawned processes
- **fixed** — Fixed window close view position restoration triggering for unfocused windows
- **fixed** — Fixed crash when an output disappears immediately after connecting
- **fixed** — Fixed used xdg-activation token memory leak
- **fixed** — Fixed lock screen clients hanging when no monitors are enabled
- **fixed** — Fixed memory leak when locking the screen in Smithay
- **fixed** — Fixed occasional visual freezing of GTK and other apps in Smithay
- **fixed** — Fixed regression where increasing output scale in v0.1.9 did not propagate to some clients
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.
##### Interactive window moving
While not full-blown floating window support quite yet, this is an important step towards that. You can now move windows by dragging them by title bars, or anywhere while holding Mod.
https://github.com/user-attachments/assets/b0c36fc3-d4ca-459b-819b-fc7ee223a3d7
To prevent accidental layout changes, the windows rubber-band a little before you drag them out.
https://github.com/user-attachments/assets/7c50c95b-56fe-4d21-b659-ad8cd7f4fad7
Furthermore, I made both interactive moving and resizing work on a touchscreen.
https://github.com/user-attachments/assets/275f27fd-8c26-40a9-82c9-0cd975a96688
Thanks to @Pajn for implementing a fairly complete proof-of-concept of this feature!
##### Locked pointer location hint
@sodiboo implemented the pointer location hint request. Apps like Blender use it to tell the compositor the final location after a locked pointer movement so that the compositor can update its own pointer location to match it.
https://github.com/user-attachments/assets/76e92efb-7c93-4b1f-876e-fbc61912f7ea
##### Laptop lid and tablet mode switch bindings
Thanks to @cmeissl, you can now bind commands to laptop lid opening/closing and tablet mode switching. You can use this to automatically enable an on-screen keyboard when a convertible laptop enters tablet mode. See the [switch events wiki page](https://github.com/YaLTeR/niri/wiki/Configuration:-Switch-Events) for more information and examples.
Additionally, I implemented disabling of the internal laptop monitor when closing the lid. So your workspaces will automatically move to the external screen. If for some reason this breaks for you, set the new `keep-laptop-panel-on-when-lid-is-closed` [debug config](https://github.com/YaLTeR/niri/wiki/Configuration:-Debug-Options) flag.
##### Pointer hiding
@yzy-1 implemented new cursor hiding options: hide when typing (on any key press), and hide after a set inactivity period. See [the wiki page](https://github.com/YaLTeR/niri/wiki/Configuration:-Miscellaneous#hide-when-typing) for more details.
```kdl
cursor {
hide-when-typing
// Or, after a timeout:
// hide-after-inactive-ms 1000
}
```
To complement this, there are a few improvements to the hidden pointer behavior. The pointer will now show up on mouse button press, and on the contrary, it will stay hidden on programmatic and keyboard-triggered movement, like focusing a different monitor, or when using `warp-mouse-to-focus`.
##### Input configuration improvements
Thanks to @tazjin, @chillinbythetree and @elipp for:
- Adding a `trackball` input config section.
- Adding a `scroll-button` setting to mice, touchpads, trackpoints, and trackballs.
- Adding a `scroll-factor` setting to mice and touchpads that you can use to speed up or slow down scrolling.
See the [input config wiki page](https://github.com/YaLTeR/niri/wiki/Configuration:-Input#pointing-devices) for more information.
##### Other improvements in this release
- Tablet input no longer follows the monitor rotation: you need to rotate your graphics tablet together with your monitor. This makes convertible laptops work properly; this is also how input works on other desktop environments. Thanks @cmeissl.
- The GTK Access portal is now explicitly set in `niri-portals.conf`, which makes it work. It is required for applications requesting PipeWire webcam and microphone access, such as the Firefox package on Fedora 41. Thanks @cmeissl.
- The `niri-ipc` crate is now [published to crates.io](https://crates.io/crates/niri-ipc).
- Active workspace is now preserved across monitor disconnects and reconnects.
- Added a window `--id` argument to `niri msg action cons
_[Truncated at 4000 characters — full notes: https://github.com/niri-wm/niri/releases/tag/v0.1.10]_
### v0.1.9
- Date: 2024-09-14
- Version: v0.1.9
- Original notes: https://github.com/niri-wm/niri/releases/tag/v0.1.9
- Permalink: https://whatsnew.fyi/product/niri/releases/v0.1.9
- Labels: Platforms: Linux
- **added** — Implement event stream in IPC that lets you continuously listen to compositor events like workspace or window changes
- **added** — Add unique IDs to IPC windows and workspaces with ability to address specific windows or workspaces by ID
- **added** — Add niri msg windows command to list all windows with their IDs
- **added** — Add --id argument to window commands to target a specific window
- **added** — Add niri msg action focus-window --id action
- **added** — Add niri msg keyboard-layouts command
- **added** — Document programmatic access to the niri IPC socket
- **added** — Set up online rustdoc for the niri-ipc crate
- **added** — Implement preset-window-heights layout option and switch-preset-window-height bind
- **changed** — Make all unit Action enum variants struct variants in JSON, a breaking change to ensure future backward compatibility
- **changed** — Rework window height distribution so columns of two or more windows always try to match monitor height
- **changed** — Make resizing one window resize all other windows in a column proportionally
- **changed** — Change default bind for resetting window height to Mod+Ctrl+R
- **changed** — Use libdisplay-info to display actual monitor names instead of generic identifiers
- **fixed** — Fix windows in a column occasionally snapping to a smaller size when resizing
- **security** — niri now requires libdisplay-info
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.
> [!NOTE]
> Packagers: niri now requires libdisplay-info.
##### New IPC functionality
In this release, I designed and implemented an [event stream](https://github.com/YaLTeR/niri/wiki/IPC#event-stream) in niri's IPC which lets you continuously listen to compositor events like workspace or window changes. The event stream enables taskbar applications to make correct and efficient widgets for niri.
I implemented the [niri modules](https://github.com/Alexays/Waybar/wiki/Module:-Niri) for workspaces, focused window, and keyboard layout in Waybar, available in its fresh [0.11.0 release](https://github.com/Alexays/Waybar/releases/tag/0.11.0). Pull requests are open for [yambar](https://codeberg.org/dnkl/yambar/pulls/405) and [ironbar](https://github.com/JakeStanger/ironbar/pull/726) thanks to their contributors.
https://github.com/user-attachments/assets/6fe9fc99-9246-45e3-a3b2-48ec79282cdd
IPC windows and workspaces now have unique IDs, and all individual window and workspace actions can address a specific window or workspace by its ID. On the command line, a new `niri msg windows` command lists all windows with their IDs, and window commands accept an `--id ` argument to target a specific window, for example:
```
$ niri msg action fullscreen-window --id 2
```
Also, there's a new `niri msg action focus-window --id ` action and a new `niri msg keyboard-layouts` command.
I wrote some documentation on the [programmatic access](https://github.com/YaLTeR/niri/wiki/IPC#programmatic-access) to the niri IPC socket. I also set up an [online rustdoc](https://yalter.github.io/niri/niri_ipc/) for the niri-ipc crate where I documented every IPC type and request. Please refer there when working with the niri IPC.
Unfortunately, while adding ID arguments to IPC actions, I discovered a backward incompatibility trap in serde-json. The default enum representation—externally tagged—prevents you from changing a unit variant to a struct variant, because the representation gains an extra dictionary. `"FullscreenWindow"` becomes `{"FullscreenWindow":{}}`, and the former does not parse with the new definition.
I decided to make a JSON breaking change, converting all unit `Action` enum variants to struct variants (with or without fields). I doubt anyone used them directly through JSON since these actions could only address the focused window or column. All enum variants that already had fields are unchanged, and the `niri msg` CLI is also unaffected.
With this breaking change out of the way, any further JSON additions should remain backward compatible, so that existing scripts and programs communicating with niri will keep working with new niri versions.
##### Height distribution changes
One common complaint about niri's layout was the ability to make a multi-window column not "add up" to the total height of the monitor. The behavior was also fairly unobvious: with two windows in a column, you resize one, and the other resizes along as expected. Then, you resize the other, but the first window doesn't react. It felt like a bug.
Last time there was a design problem (unwanted scrolling with focus-follows-mouse), we quickly found a solution by brainstorming in a Discussion. So, I made a big write-up about window heights in https://github.com/YaLTeR/niri/discussions/593. While there hasn't been much *discussion*, the act of laying out in writing all considerations and constraints had spawned a potential solution in my mind, which turned out to work quite well.
In this release, I reworked the window height distribution to do the *expected thing* in more cases. A column of two or more windows will always try to match the monitor height, as long as the minimum window sizes allow
_[Truncated at 4000 characters — full notes: https://github.com/niri-wm/niri/releases/tag/v0.1.9]_