Releases: YaLTeR/niri
v0.1.2
Thanks everyone for 1000 stars! π₯³
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 libinput >= 1.21.
The new niri-visual-tests subcrate is development-only and should not be packaged. If you do cargo test --workspace
, make sure to exclude it: cargo test --workspace --exclude niri-visual-tests
, as it brings extra native dependencies.
Window opening animations
Windows now appear with an animation! Existing windows to the right move away, and the new window fades in, avoiding sudden visual jumps. All happening quickly enough to hopefully not be distracting.
niri-open-anims-release.mp4
More animations are coming, but they need time and work to implement right.
Animation settings
If you prefer reduced motion, or on the contrary if you want more animation, you can now set this up in a new animations
config section. There's a flag to turn off, and a setting to adjust speed for all animations at once, as well as settings for every individual animation should you need it.
These settings replace the now-removed animation-slowdown
debug flag.
Idle protocols
Niri now implements the ext-idle-notify and idle-inhibit pair of Wayland protocols. This allows tools like swayidle
to work, and clients like mpv
to pause them from working while you're watching videos.
As a bonus, I also implemented the org.freedesktop.ScreenSaver
D-Bus interface for idle inhibiting, used by xdg-desktop-portal-gtk. This was necessary to make Flatpak Firefox correctly inhibit the idle state, and in general covers more applications.
Invoke actions via IPC
As the first expansion to the niri msg
command, you can now invoke any bindable action with niri msg action do-something
. That is, if you can bind something like Mod+F { maximize-column; }
, then you can also call it programmatically with niri msg action maximize-column
.
Turns out, one thing IPC actions are pretty convenient for is scripting video demos, like the one above!
Also, niri now has a way to report errors back to the IPC client, instead of leaving it in the dark for requests that don't otherwise need a response.
Window rules (the beginnings thereof)
You can now set some (at the moment, two) settings on a per-window basis. You can match or exclude windows from a rule with regular expressions on app-id and window title, similarly to other compositors. See the default config for a detailed explanation.
The settings you can currently set are default-column-width
and open-on-output
. Most notably, this lets you work around WezTerm's initial configure bug:
window-rule {
// This regexp is intentionally made as specific as possible.
// You can get away with app-id="wezterm" if you want.
match app-id=r#"^org\.wezfurlong\.wezterm$"#
default-column-width {}
}
More rules, including dynamically updating ones, are coming, after some refactors.
Better focus stealing prevention
To minimize your distraction, niri prevents new windows from taking focus while you're in a fullscreen application (I've had enough games ruined by a sudden Steam chat message). In this release, niri will additionally track when a newly opened window is a dialog from a particular existing window, and put that dialog to the immediate right from its parent window. The dialog will get focus only if the parent window was focused.
This change both prevents some random client from a different monitor/workspace from taking focus with a sudden dialog (looking at you, syncthing-gtk), and lets dialogs originating from fullscreen windows take focus as expected, bypassing the normal fullscreen focus stealing prevention.
Improved filtering in the hotkey overlay
The hotkey overlay shows a hardcoded set of binds that I deemed "most important". Included are the spawn
actions, because binds like "spawn terminal" and "spawn application launcher" are definitely up there in the importance list.
However, not all commands you might want to spawn
are that important, and with a lot of binds, the list could get polluted with many entries like XF86AudioRaiseVolume. Filtering based on program name doesn't sound very robust, so, instead, now the hotkey overlay will only show spawn
binds with Mod
or Super
in the hotkey.
Additionally, out of multiple spawn
binds to the same command, only the first one will show up in the hotkey overlay, which is consistent with all other hotkeys.
Before | After |
---|---|
Other improvements
- Fixed a crash with some monitors with weird EDID data, and fixed inability to light up some monitors by filtering out interlaced modes.
- Implemented DRM leasing. This lets you use VR applications and headsets with niri. Thanks @Supreeeme for working on this!
- Added
consume-or-expel-window-{left,right}
actions that either expel the focused window into its own column, or consume a singular focused window into a column. These act as an alternative to the existing consume and expel commands, and are not bound to any keys by default. Thanks @exoticorn for implementing them! - Added a
dwtp
flag to touchpad settings for disable-when-trackpointing. - Added
trackpoint
input settings. Thanks @okvik for implementing them! - Added a way to bind / IPC-invoke
quit
while skipping the "Are you sure you want to exit niri?" dialog:Mod+Shift+E { quit skip-confirmation=true; }
. - You can no longer spawn multiple lockscreen clients at once (more relevant now with swayidle).
- Fixed binds like
Super+Q
not working (you had to spell it out asMod+Super+Q
). - Changed the default
swaylock
bind fromMod+Alt+L
toSuper+Alt+L
to fix a collision with theMod+L
bind when running niri as a window (not sure how I missed this in testing). You don't usually want to "lock the screen" of a nested niri anyway. - Monitors powered off with DPMS will now light up upon switching the TTY back to niri.
- The
NIRI_SOCKET
environment variable is now exported into the systemd and D-Bus session, which lets systemd units runniri msg
. For example, this allows you to runswayidle
as a systemd service. - Fixed a Smithay bug which mistakenly sent primary-selection to wlr-data-control v1 clients, causing them to crash (thanks @kchibisov).
- Fixed
border
using focus ring's default values instead of its own. - Fixed omitting the
layout
config section resulting ingaps 0
instead of the defaultgaps 16
. - Fixed target monitor not getting focus when pressing
move-column-to-monitor-*
on an empty source monitor.
v0.1.1
Better fresh install workflow
Niri will now create a config file if it's not present, filling it with the default config contents. It will notify about this with a new message.
wlr-foreign-toplevel-management
I've implemented the wlr-foreign-toplevel-management protocol used by taskbars like the wlr/taskbar
Waybar module or sfwbar, and by some other clients like fcitx5.
Output rotation
You can now rotate and flip outputs with a new setting:
output "eDP-1" {
// The rotations are counter-clockwise:
transform "90"
}
Thanks @axtloss for implementing this and to @cmeissl for fixing various Smithay issues that had come up with transforms!
Other improvements in this release
- Keyboard LEDs (Num Lock, Caps Lock, Scroll Lock) will now light up. Thanks @cmeissl!
- Added
move-workspace-to-monitor-{left,right,up,down}
actions that move the entire workspace to a different monitor. They are not bound to any key by default (yet?). Thanks @Trundle for implementing this! - Fixed semitransparent border and focus ring colors.
- Fixed
natural-scroll
not being respected for the touchpad workspace switch gesture. - Fixed windows being unable to open in fullscreen mode right away.
- Monitor screencasts will now stop on monitor size changes. In the future it may be possible to resize the stream on the go but we don't do that yet, so just stop them to avoid wrong video frames.
- Fixed building on Rust 1.72.0.
- Made backend initialization errors more detailed.
- Fixed a panic when closing niri running as a nested window during a screen redraw.
v0.1.0
Here it is. The first real release, after five months of work. Let's do a recap for the occasion.
This is niri, a scrollable-tiling Wayland compositor inspired by PaperWM. Windows are tiled on an infinite horizontal strip that scrolls left and right. They don't "overflow" onto adjacent monitors. Opening a new window never resizes existing ones.
Despite this being the first release with plenty of things left to do, niri already packs a good number of features.
-
All the basics. It's a Wayland compositor, it shows windows, runs on a TTY, works with multiple monitors and mixed-GPU systems, supports HiDPI.
-
Dynamic workspaces like in GNOME, but per-monitor. Workspaces also remember which monitor they were on across monitor disconnects and reconnects.
-
Some of the important desktop component protocols like wlr-layer-shell and ext-session-lock.
-
A built-in screenshot UI. Press PrtSc, select a rectangle on a frozen screen, and press Space to copy the image to the clipboard and save to a file. Or screenshot one window with AltPrtSc.
-
Screencasting support through xdg-desktop-portal-gnome. Works with OBS, browsers, and others.
-
Fully live-reloading config.
-
Configurable layout: things like gaps, borders, struts, window sizes.
If you want to see niri in action, here's a video demo from the README.
niri.mp4
It's also worth mentioning that:
- NVIDIA GPU systems might have rendering issues.
- Xwayland in rootless mode is not supported. However, you can use its excellent rootful mode with niri. Games and X11 apps work just fine for the most part.
If you'd like to give niri a try, check the README for building and running instructions. There are also a few community-maintained packages:
- A COPR for Fedora users (ok, that one's made by myself).
- A Flake for NixOS.
- An AUR package.
- A port for FreeBSD and a pack of other BSDs, if GitHub code search is to be believed.
Finally, we have a Matrix room. Feel free to drop by with a message.
Changes since v0.1.0-beta.1
- Fixed config live-reload on NixOS configurations which change the config file symlink but leave the mtime constant (thanks @sodiboo).
- Fixed most cases of niri failing to light up monitors after a TTY switch (thanks @cmeissl).
- Fixed xdg-desktop-portal-gnome not updating the screencast monitor list upon monitor disconnection / reconnection (niri wasn't notifying it about changes).
- Fixed large windows with large CSD shadows getting cut on screenshots and screencasts.
- Fixed output config changes being ignored if done when on a different TTY.
- Fixed popups not showing up when an IME is active (for now as a workaround by disabling popup grabs when an IME is active).
- Slightly improved cursor rendering performance by avoiding CPU->GPU->CPU transfers (thanks @cmeissl).
- Slightly increased the precision of the default column widths in the default config. This should get one pixel back for the β column width on most monitors.
- xdg-desktop-portal screencasts will now receive the optional logical monitor size which some apps require.
- xdg-desktop-portal screenshots will now get an error instead of a broken screenshot for multi-monitor configurations (it needs to be implemented, see #117). This does not affect the screenshot UI.
- Fixed screenshot UI not showing up if the cursor ended up outside all monitors.
v0.1.0-beta.1
I've made a ton of improvements since the last alpha tag. I am now happy enough with the feature set to make the first proper release. So, this is a beta tag, and 0.1.0 should follow several days later.
Note
Packagers: niri now depends on pangocairo.
IPC, output list
I've implemented the beginnings of IPC, and a new niri msg outputs
subcommand that will list all connected monitors and their available modes. Finally, you no longer need to dig in niri's debug output to find this information.
β ~
ββ niri msg outputs
Output "eDP-1" (Unknown - Unknown - eDP-1)
Current mode: 2560x1600 @ 165.004 Hz
Physical size: 340x210 mm
Available modes:
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
Output settings improvements
All output settings (scale, position, mode, on/off) are now live-reloaded without having to replug the monitors.
Additionally, monitors are now always repositioned from scratch on every change, with preference given to monitors with explicitly-configured positions. Practically this means that your monitor positions will be consistent regardless of the order they are connected in (especially relevant at startup where the order is random).
More libinput settings, live-reload
- Added touchpad
accel-profile
,dwt
,tap-button-map
settings. - Added mouse
natural-scroll
,accel-speed
,accel-profile
settings. - Added live-reload for all libinput settings.
This should cover most of the important libinput settings. These are relatively straightforward to add, so feel free to open a PR if you need some libinput setting that is still missing.
Hotkey help overlay
I've added Pango for text rendering, which unlocks a ton of useful features. One of them is the new Important Hotkeys list that shows up at startup and helps you learn your way around niri.
The list of actions to show is hardcoded, but the actual hotkeys come from the current config, so you will see the keys that you had configured. The bind to display this overlay is show-hotkey-overlay
.
More overlays
I've added two more overlays using text rendering. One shows up when there's an error in your config:
And the second one prompts for a confirmation when pressing the exit bind:
Wayland popup grabs
Niri now correctly implements popup grabs. Practically, this means that:
- You can now dismiss popups by clicking anywhere on screen, including layer-shell popups like the ones from sfwbar.
- You can now navigate the layer-shell popups with the keyboard.
- Popups with grabs will be dismissed when focusing a different window (or in the case of layer-shell, a different monitor), and unfocused windows will be denied popup grabs.
Client-side decoration fixes
By default (without the prefer-no-csd
setting), niri wants clients to use client-side decorations. Turns out that SDL2 has a bug (already fixed but not released) in its xdg-decoration protocol implementation that prevents windows from showing up when the compositor insists on CSD.
To make all apps work properly, niri will now hide the xdg-decoration protocol from the clients when it wants client-side decorations, and only show it when prefer-no-csd
is set.
Improved security
Niri now implements the security-context Wayland protocol which lets it hide a number of sensitive protocols from sandboxed clients. This protocol is used by Flatpak, so now Flatpak apps can no longer steal your clipboard through wlr-data-control, as an example.
β ~
ββ wl-copy 'My secret clipboard contents!'
β ~
ββ flatpak run --command=bash --filesystem=home org.gnome.Adwaita1.Demo
[π¦ org.gnome.Adwaita1.Demo ~]$ wl-paste
Error: A required Wayland protocol (zwlr_data_control_manager_v1 version 1) is not supported by the compositor
[π¦ org.gnome.Adwaita1.Demo ~]$
exit
β ~ 1
ββ wl-paste
My secret clipboard contents!
More improvements in this release
- Added
move-column-to-workspace*
andmove-column-to-monitor*
binds that operate on columns, as opposed to the existingmove-window-to-*
binds. I believe this behavior makes more sense, so I changed the default binds to the new column ones. - Added a
center-focused-column
layout setting that can be set tonever
(the default),always
(always center the focused column) andon-overflow
, which will center the focused column when it doesn't fit together with the previously focused column. Thanks @tversteeg for working on this feature. - Layer-shell surfaces are now properly notified of output removal, which for example fixes mako breaking when disconnecting a monitor that it was displaying a notification on.
- Fixed mouse clicks on layer-shell surfaces activating the windows below them.
- Fixed screencast session restore picking the wrong monitor. This is especially relevant in Chromium where session restore is part of the normal screencast workflow.
- Fixed screencast taking a while to startup if there are no new frames rendered by the compositor.
- Laptop displays will now show up as "Built-in display" in the xdp-gnome monitor selection dialog.
- Fixed niri not redrawing the screen upon changing focus. Usually this isn't a problem because windows redraw in response to changing focus, but it became more visible with popup grabs.
- Niri will now watch the config file path even if the config did not exist, or failed to parse at startup. This is especially relevant for new niri users which don't have a config yet. You can create a config after running niri for the first time, and it will now live-load it without having to restart.
- Added a
niri panic
subcommand that triggers a panic, which you can use to check that you have built / packaged niri with enough debuginfo to produce useful crash backtraces. - Documented the debug settings in the default config file.
- Fixed windows receiving events that look like they left all outputs when consuming them into a column.
- Fixed windows receiving events that look like they left all outputs when replugging monitors.
- Fixed a crash that could happen when a window is closed during a workspace switch transition.
- Fixed a crash that could happen if workspaces are transferred back to their original monitor that was connected during a workspace switch transition.
- Updated Smithay, the Wayland compositor building library that underlies niri, which brought some fixes:
- The cursor plane will now work in more cases. If you needed the
disable-cursor-plane
setting, you might no longer need it. - Fixes to graphical glitches on nouveau and possibly other configurations.
- Fixes to a deadlock when using an IME with certain clients.
- The cursor plane will now work in more cases. If you needed the
Caution
This is an beta tag. There may be breaking changes leading to the release.
Please check the README for building and installation instructions. Also, if you're on Fedora, I've got a COPR. NixOS users, check out https://github.com/sodiboo/niri-flake.
v0.1.0-alpha.3
Config breaking change
Settings for focus-ring
, preset-column-widths
, default-column-width
, gaps
, struts
moved into a new layout { }
node.
layout {
focus-ring { /* ... */ }
preset-column-widths { /* ... */ }
default-column-width { /* ... */ }
gaps 8
struts { /* ... */ }
}
Multi-GPU support
Monitors plugged into secondary GPUs will now light up and work. This is particularly important for hybrid laptops with an integrated and a discrete GPU, where for example a monitor may "plug into" the dGPU while the primary device is the iGPU.
Additionally, direct scan-out will now work in more cases across GPUs (i.e. a dGPU client on an iGPU monitor).
Niri uses the default GPU for rendering, the same as any other GL client. You can force niri to use a different GPU with a new debug setting which works similarly to the WLR_RENDER_DRM_DEVICE
environment variable from wlroots:
debug {
render-drm-device "/dev/dri/renderD129"
}
Borders
You can now add borders to windows with a new setting:
layout {
border {
// The settings are the same as for the focus ring.
// If you enable the border, you probably want to disable the focus ring.
// off
width 4
active-color 255 200 127 255
inactive-color 80 80 80 255
}
}
In contrast to the focus ring, borders are always visible, even on unfocused windows.
Fullscreen backdrop
Fullscreen windows smaller than the monitor now have a monitor-sized black backdrop, as expected by xdg-shell. This makes all fullscreen windows consistent in how they look, while keeping the PaperWM-like property that they mostly behave like a regular column that you can scroll out of view if you want.
More improvements in this release
- Added a
focus-column-{first,last}
actions that focus the leftmost/rightmost column on the workspace, bound to ModHome/End by default. - Added a
move-column-to-{first,last}
actions that move the focused column to the leftmost/rightmost position on the workspace, bound to ModCtrlHome/End by default. - Added an
input { disable-power-key-handling }
config flag to prevent niri from taking over the power button handling (which makes it sleep instead of power off). You can use this flag if you configure the power button elsewhere, i.e. inlogind.conf
. - Windows on unfocused monitors now always display as unfocused.
- When
prefer-no-csd
is unset (the default), niri is now more insistent on client-side decorations. This makes the alacritty 0.13 use CSD in this case for example. - Added a
debug { disable-cursor-plane }
config flag if you're having cursor rendering issues. - Enabled EGL support for clients in the winit backend (when running niri as a nested window). On Fedora with recent Mesa this makes it so you can run GL clients inside nested niri again.
- The
toggle-debug-tint
action, bound to ModCtrlShiftT by default, will now redraw the screen immediately.
Caution
This is an alpha tag. There are known bugs and missing features. Don't be surprised if there's a breaking config change in the future.
Please check the README for building and installation instructions. Also, if you're on Fedora, I've got a COPR. NixOS users, check out https://github.com/sodiboo/niri-flake.
v0.1.0-alpha.2
Several important additions have landed since alpha.1.
Implemented the relative-pointer and pointer-constraints protocols
These protocols allow apps to lock or confine the mouse pointer within their window. In particular, Xwayland makes use of these protocols to make 3D games with mouse look "just work"!
mouse-look.mp4
Other examples include Blender and virtual machines.
blender-warp.mp4
Implemented popup unconstraining
Popups will no longer open partially off-screen. Niri will also try to position popups within the application's window horizontally so that if a window is fully on-screen, the popup will also be fully visible.
Added a struts
option
This one allows you to add a kind of "outer gaps" if you like those layouts. Also, left and right struts will make windows to the sides always partially visible, which can help with mouse-only navigation.
More improvements in this release
- New windows can no longer steal focus from a fullscreen window. All it took was a Syncthing dialog interrupting my Hollow Knight boss battle.
- Tablets will now match their target monitor's aspect ratio (works the same way as in GNOME Shell).
- Tablets can no longer move the cursor outside of their target monitor's bounds.
- Tablets will no longer send wl_pointer events (as they shouldn't), which makes them work correctly with GTK 4 apps.
- Added a
niri validate
subcommand that will check if your config parses successfully. - Added a way to disable an output with an
off
config flag. - Added
focus-window-or-workspace-up
/down
andmove-window-up-or-to-workspace-up
/down
bind commands that do a workspace switch when the focus is at the end of a window column (not bound to anything by default). This way you can avoid an extra set of workspace switch binds. Thanks @rabidpug for adding this. - Keyboard config is now live-reloaded, including the XKB options.
- Fixed screen not immediately redrawing in some cases, most notably when a layer-shell surface shows a popup.
- Allegedly, high-resolution scroll wheel mice should now work after a Smithay update, but I don't have one so I don't know for sure.
This is an alpha tag. There are known bugs and missing features. Don't be surprised if there's a breaking config change in the future.
Please check the README for building and installation instructions. Also, if you're on Fedora, I've got a COPR.
v0.1.0-alpha.1
A good chunk of functionality is implemented. I've been daily driving niri for at least two months now. I feel like it's a good point to make the first tag.
Make no mistake, this is an alpha tag. There are known bugs and missing features. Don't be surprised if there's a breaking config change in the future. But, depending on your needs and preferences, it may already be good enough for daily use.
Please check the README for building and installation instructions. Also, if you're on Fedora, I've got a COPR.
For people following along, I recommend sticking to the main branch rather than freezing on this release.