Releases: YaLTeR/niri
v0.1.10.1
This is a hotfix release for niri v0.1.10.
- Fixed scrolling not working when the
mouse {}
ortouchpad {}
section is omitted from the config file. - Made the mouse cursor show up on scroll which makes scrolling work when the cursor was hidden.
- Fixed a crash when holding Space in the screenshot UI.
- Bound touch-dragging with held Mod to interactive window move.
v0.1.10
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.
niri-interactive-move.mp4
To prevent accidental layout changes, the windows rubber-band a little before you drag them out.
niri-interactive-move-rubberband.mp4
Furthermore, I made both interactive moving and resizing work on a touchscreen.
niri-touch-move-resize.mp4
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.
niri-pointer-position-hint.mp4
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 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 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 for more details.
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 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. - Active workspace is now preserved across monitor disconnects and reconnects.
- Added a window
--id
argument toniri msg action consume-or-expel-window-left/right
and to the IPC. - Added an explicit
power-on-monitors
action that can be useful with certain hardware. Niri still automatically powers on monitors on any input event. - Added support for running niri as a dinit service: files in
resources/dinit/
and corresponding code inniri-session
(thanks @markK24). - Added a
disable-monitor-names
debug config flag as a workaround for niri crashing when plugging in two monitors reporting the exact same make/model/serial. This issue is tracked in #734. - The focused window will now become visually inactive when a layer-shell app in front has keyboard focus.
- Fixed
focus-window-up-or-column-right
focusing left instead of right. - Fixed an animation jump when expelling a narrower window from a column with uneven window widths.
- Fixed the logind power key inhibit file descriptor leaking into processes spawned by niri.
- Fixed window close view position restoration triggering for windows that didn't get focused upon opening.
- Fixed a crash when an output disappears immediately after connecting.
- Fixed used xdg-activation token memory leak.
- Fixed lock screen clients hanging until a monitor is enabled when no monitors are enabled.
- Updated Smithay:
- Fixed memory leak when locking the screen.
- Fixed occasional visual freezing of GTK and other apps.
- Fixed a regression that made it so increasing the output scale in niri v0.1.9 didn't propagate to some clients, keeping them blurry.
v0.1.9
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 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 for workspaces, focused window, and keyboard layout in Waybar, available in its fresh 0.11.0 release. Pull requests are open for yambar and ironbar thanks to their contributors.
niri-waybar-workspaces.mp4
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 <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 <ID>
action and a new niri msg keyboard-layouts
command.
I wrote some documentation on the programmatic access to the niri IPC socket. I also set up an online rustdoc 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 #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 that. Resizing one window will resize all other windows in a column proportionally. The window that you resized last retains its height just like before, which lets you size one window in a column exactly to fit something, unaffected by adding more windows into the column, or moving it across monitors.
Keep in mind that a single-window column can still be resized arbitrarily, including shorter or taller than the monitor. Until floating windows are implemented, this is necessary for some uses that require exact-sized windows.
niri-height-distribution.mp4
Additionally, I found and fixed a small issue where windows in a column would occasionally "snap" to a smaller size when resizing.
Preset window heights
@TheAngusMcFire implemented a preset-window-heights
layout option and a corresponding switch-preset-window-height
bind, which work like the existing column width presets.
By default, it's bound to ModShiftR, which is consistent with Shift making resize binds affect the height rather than the width. The default bind to resetting the window height therefore moved to ModCtrlR. (None of this affects you if you already have a niri config; you'll need to add any new binds manually.)
Output names
You might be familiar with this sight:
$ niri msg focused-output
Output "Unknown Unknown Unknown" (DP-1)
...
Thanks to @cmeissl finishing the libdisplay-info bindings, this sight is no more.
$ niri msg focused-output
Output "Acer Technologies XV320QU LV 420615FCD4200" (DP-1)
...
Following this, all throughout niri I implemented the ability to address outputs by name. This includes config output
, map-to-output
, open-on-output
; niri msg output
; wlr-output-management tools (wdisplays, kanshi); and xdg-desktop-portal-gnome screencasting where the screen selector will now show the monitor model and screencast session restore will remember the output name rather than the connector.
The recommended way to configure everything output-related is now by name (as shown in niri msg outputs
). This way, configuration does not depend on the connector name that can be non-deterministic with multiple GPUs or when using thunderbolt docks.
// Previously: output "DP-1" {
output "Dell Inc. Dell S2716DG #ASOwvAqQj0Dd" {
mode "2560x1440@143.998"
// ...
}
I was also finally able to change the monitor sorting order to use the output name rather than the connector name, once again making it more deterministic. Note that this may swap your monitor positions if you were using multiple monitors and haven't manually configured them.
Transactional updates
One of Wayland's premises is that "every frame is perfect" except the first one. The compositor is in full control of the display, and window state changes are atomic and correlate to specific compositor requests.
This allows the compositor to synchronize updates for multiple windows: render the old state until all windows update, then switch to the new state all at once, with no broken frame in between.
However, possible doesn't mean easy, and different kinds of transactional updates need different approaches in the code. For this release, I implemented two relatively common cases.
Resizing
Thanks to the scrollable tiling nature, niri doesn't need to synchronize resizes among all windows on a workspace. However, windows in one column must still resize in unison: they must have the same width, and their heights must add up exactly to the monitor height.
niri-synchronized-resizing.mp4
Closing
Closing a window resizes all other windows in the column to take up the freed space. Normally, resize and close animations hide this, but if you disable animations, the flicker becomes very noticeable. The closing transaction fixes this: niri waits until other windows have resized before hiding the closed window.
niri-close-transactions.mp4
On-demand VRR
Thanks to @my4ng, we now have on-demand variable refresh rate as a window rule.
Some monitors flicker at the lowest VRR refresh rate, some drivers have VRR bugs, and some clients don't handle VRR too well. Now, niri can enable VRR only when a specific window is on screen (for example, a video player, or a game), thereby avoiding most of those issues.
Configure your output with on-demand=true
:
output "Acer Technologies XV320QU LV 420615FCD4200" {
// ...
// This will keep VRR off unless enabled by a window rule.
variable-refresh-rate on-demand=true
}
Then, add variable-refresh-rate true
window rules as necessary:
// Enable VRR when mpv is on screen.
window-rule {
match app-id="^mpv$"
variable-refresh-rate true
}
NVIDIA flickering fix
There was a problem with NVIDIA flickering on niri, which the user could fix by enabling the wait-for-frame-completion-before-queueing
debug flag. Turns out, this was only necessary because ages ago I forgot to add a check in the code. 🤦
Starting from this release, you should no longer need to set that debug flag, and NVIDIA GPUs should no longer flicker on niri out of the box (fingers crossed).
Small UX improvements
The horizontal touchpad swipe gesture will no longer go past the first or last column on the workspace.
niri-horizontal-gesture-snap-limit.mp4
And focus-follows-mouse will no longer "catch" windows on workspaces as you're switching away from them, which is especially important when using the...
v0.1.8
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.
Today is a special day. Niri is one year old! 🥳
┌ (main) ~/s/r/niri
└─ git show --format='commit %H%nCommitDate: %cd%n%n %s' --no-patch ad3c3f8
commit ad3c3f8cefd38d2bf26b466d8e34eccde3bca443
CommitDate: Thu Aug 10 14:49:38 2023 +0400
Init from smallvil
We've come a long way since then! I am very happy with how niri is shaping up. I am especially grateful to 45 (!) contributors who have volunteered their time to improve something in the compositor over the year.
We also managed to amass more than 3000 stars, and almost 400 people in our comfy Matrix room!
Nevertheless, there's plenty to be done. Without further ado, here are the improvements from the last release.
Note
Packagers: niri now requires pango >= 1.44 and rust >= 1.77.
Gradient border color spaces
A big thanks to @CaliOn2 for overhauling gradient rendering in niri, adding support for interpolation color spaces! You can now set gradient borders to draw not just in srgb
, but also in srgb-linear
, oklab
and oklch
, the latter with support for {shorter,longer,increasing,decreasing} hue
.
Which means that you can now have beautiful rainbow gradient borders:
layout {
border {
active-gradient from="red" to="orange" angle=45 in="oklch longer hue"
}
}
As usual, niri gradients are rendered the same way as CSS linear-gradient()
, so you can use any browser tool to configure them.
Additionally, @my4ng debugged and fixed gradients rendering with a sharp edge on NVIDIA, and I fixed gradient rendering being reversed at angle=90
.
Screenshot UI pointer toggle
You can now toggle mouse pointer visibility in the screenshot UI by pressing P. I added a new help panel to remind you of this, and to explain how to capture the screenshot.
niri-screenshot-ui-panel.mp4
Also, the screenshot UI now fades in. (As usual, you can disable this animation if you don't like it.) Finally, I fixed some minor regressions with area selection that were introduced in the fractional scaling refactor.
Key repeat for binds
Thanks to @salman-farooq-sh, niri now has key repeat for all binds. This is especially useful for binds that control volume and brightness. Or for having some fun by spawning a ton of windows.
niri-key-repeat.mp4
You can disable key repeat for specific binds using the new repeat=false
property:
binds {
// Disable key repeat for this bind.
Mod+T repeat=false { spawn "alacritty"; }
}
Focus-follows-mouse improvements
Being a scrollable-tiling compositor, niri faces some unique design challenges for otherwise commonplace functionality. One particularly annoying example was unwanted view movement caused by focus-follows-mouse
.
When using niri, you will frequently have windows partially off-screen. With focus-follows-mouse
, moving the cursor over such a window would focus it and scroll it into view. This is especially problematic if you have two monitors side-by-side, and just want to move the mouse to the other monitor.
To figure out the solution, I outlined all problems and possible solutions in a GitHub discussion. Some very productive brainstorming followed, and a solution emerged: a view scroll threshold for focus-follows-mouse
.
In the config, you can now set a property on focus-follows-mouse
:
input {
focus-follows-mouse max-scroll-amount="0%"
}
This number controls how much scrolling is allowed to happen for focus-follows-mouse
to trigger. With 0% (the new suggested default), focus-follows-mouse
will only focus a window if it does not cause any scrolling. You can also set this to bigger values, e.g. 10% will restrict it to when the view scrolls no more than 10% of the screen width.
niri-focus-follows-mouse-threshold.mp4
I've personally been avoiding focus-follows-mouse
in niri in the past precisely because of the undesired scrolling, but max-scroll-amount="0%"
had pretty much solved that problem, so since then I've been using it just fine.
This release has another fix to focus-follows-mouse
: when using the always-centered mode, it will no longer cause rapid window scrolling. The issue was the way the logic interacted with pointer focus update suppression during animations.
wlr-output-management
@gmorer implemented the wlr-output-management protocol, which means that you can now use third-party tools like kanshi or wdisplays to configure the outputs in niri.
Keep in mind that changes applied this way are transient and are not automatically saved into your niri configuration, just like the niri msg output
command.
wlr-screencopy version 3
Niri had supported wlr-screencopy version 1 since v0.1.3. This was enough for screenshot tools like grim, but not for screen recording tools. This was an intentional choice, as the screen recording parts of this protocol are quite complex, and need a very different implementation from the existing PipeWire screencasting.
For this release, @my4ng dived in and implemented it! Now, niri supports wlr-screencopy version 3 and you can use tools like wf-recorder and wl-mirror.
niri-wf-recorder.mp4
As a bonus, I found and fixed a bug in region capture with a fractional scale.
Negative struts
@salman-farooq-sh implemented a small change to allow strut
config values to go negative. It's not obvious at first why this is needed (why would you want windows to peek outside the screen bounds?), but actually, this is an elegant solution for having smaller outer gaps than inner gaps.
In niri, one of the design principles is that opening a new window never causes existing windows to resize. Turns out, this restriction prevents differentiating horizontal inner and outer gaps. Imagine inner gaps = 10 and outer gaps = 0. A single 50%-wide window should then take exactly 50% of the screen. But then, opening a second window introduces an inner gap, so now the first window must occupy (50% minus a half gap), requiring a resize!
Negative struts work around this problem. All gap values remain equal, but you can use left and right strut values equal to negative gap size to "push" the "outer" gaps off-screen. Visually, this looks the same as having no outer gaps, while not causing any unintended window resizes.
layout {
gaps 16
struts {
left -16
right -16
top -16
bottom -16
}
}
PipeWire screencast fixes
I implemented the full DMA-BUF modifier negotiation procedure for PipeWire screencasts (when using xdg-desktop-portal-gnome). As an immediate benefit, it makes screencasting work on NVIDIA. It should also fix GStreamer-based screen recording tools like Kooha, however, I have not been able to get this to work just yet. Perhaps it'll start working with the next PipeWire release? We'll see.
Wiki configuration snippet tests
This is not directly related to running niri, but is very cool nonetheless! @Suyashtnt implemented a test that verifies that every single config example on the wiki successfully parses. Combined with the fact that every single config option has an example code block, we should be very much set to catch any unintentional config parsing regressions.
Nightly COPR
With some help from @my4ng, I set up a COPR with automatic git niri builds: https://copr.fedorainfracloud.org/coprs/yalter/niri-git
Turns out, this is quite easy, and involves adding a special template .spec file into the repository, and setting up a webhook so GitHub can tell COPR to trigger a build when the main branch is updated.
If you run Fedora, you can use this new COPR to stay more up-to-date with niri development.
Other improvements in this release
- Implemented on-demand keyboard focus mode for layer-shell surfaces, which is used by some newer bar applications.
- Added
focus-window-or-monitor-{up,down}
actions (thanks @TheAngusMcFire). - Added
move-column-left-or-to-monitor-left
andmove-column-right-or-to-monitor-right
actions (thanks @brainlessbitch). - Added a
middle-emulation
flag to touchpad, mouse, and trackpoint settings. - Added a
background-color
option to outputs that sets the color of the default niri solid background. You can use this if you don't want to run any third-party background tools. Thanks @anant-357! - Added
Mod3
/ISO_Level5_Shift
modifier support to key bindings (thanks @jpeeler). - Enabled sub-pixel glyph positioning for better kerning in niri panels.
- Added a
profile-with-tracy-ondemand
build feature that produces a build with on-demand Tracy pr...
v0.1.7
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.
Fractional Scaling
The big update this time is fractional scale support. You can set output scale to fractional values like 1.5 and automatic scale factor guessing will now return fractional scale factors.
On the surface this sounds simple, but under the hood, doing it properly required a complete refactor of the layout system to use fractional coordinates and sizes (and then chasing down all of the bugs caused by this).
The result is well worth it though. Borders, gaps and windows are always physical-pixel aligned, and not restricted to integer logical pixel positions. There's no blur or position-dependent +-1 px jank. Fractional-scale-aware clients remain crisp at any scale.
Here's a demo of going through every single currently representable fractional scale factor between 100% and 200% where everything remains crisp, including a 1 px checkerboard in mpv. Watch it in the native 1920×1080 resolution if you want to see the checkerboard correctly.
niri-scale.mp4
As a bonus, you can set the scale to a value below 1, which will make things smaller and give you more space. This could be useful in specific cases like monitors with very big pixel size, but it will lose you some image crispness.
Fractional Layout
As previously mentioned, niri layout now completely operates in floating-point. While fractional scaling benefits the most from this, fractional layout is also useful for integer scales.
Concretely, you can now set border and focus ring width, gaps, struts to fractional values, which will round to physical pixels according to the monitor's scale factor. Which means you can have 1 px wide borders on a 200% monitor for example by setting the border width to 0.5.
The view position is also no longer restricted to integer logical pixels, so when you do a touchpad swipe gesture on a 200% monitor, windows will move in single physical pixel increments.
If you're interested in the technical details of how this works, check this wiki page.
Window Screencasts
You can now select an individual window to screencast through xdg-desktop-portal-gnome. You can resize windows, open pop-ups, use block-out rules, and it will all work correctly.
niri-window-screencast-2.mp4
This involved some refactoring of the PipeWire screencasting code in niri, most notably adding support for changing the video stream size on the fly. As a bonus, monitor screencasts will now also keep running through monitor resolution changes.
I still need to work out some details like frame callback delivery to obscured windows, but the current implementation should already work for a lot of use cases.
xdg-activation
@pcc implemented the xdg-activation-v1 protocol which allows apps to pass focus to other apps. For example, clicking on a link in a GTK 4 app will now automatically focus your browser, switching the workspace if necessary.
niri-xdg-activation.mp4
This protocol is also used by clients to indicate urgency; this part is not implemented yet (but planned).
Workspace Switch Mouse Gesture
Last release I added the horizontal Mod + middle mouse drag gesture to scroll the view. This release I also added the vertical drag gesture to switch workspaces, just like on a touchpad you can swipe both horizontally and vertically.
niri-vertical-mouse-gesture.mp4
Other improvements in this release
- Added four actions
focus-window-{up,down}-or-column-{left,right}
which allow traversing all windows on a workspace in order (thanks @minego). - Added actions
focus-column-right-or-first
,focus-column-left-or-last
which allow the focus to loop around (thanks @sullyj3). - Added actions
focus-column-or-monitor-left
andfocus-column-or-monitor-right
that switch the monitor upon reaching the end of the workspace. - Added
niri msg focused-output
which returns information about the currently focused output (thanks @rustysec). - Added
off
flag to disable input devices (thanks @yuja). - Added
left-handed
flag to touchpad, mouse, tablet input config. - Added
scroll-method
property to touchpad, mouse, trackpoint input config (thanks @yuja). - Added
disabled-on-external-mouse
flag to touchpad input config (thanks @yuja). - Niri now additionally reads the config file path from
$NIRI_CONFIG
, to help with nix wrappers. The--config
flag still takes precedence (thanks @sodiboo). - Changed absolute pointer input to work over a union rectangle across all outputs, rather than picking a single output (thanks @galister).
- Changed tablet input without a specific
map-to-output
to map to a union rectangle across all outputs. This makes Open Tablet Driver work. - Changed foreign-toplevel (i.e. Waybar) window activation to animate the workspace switch.
- Changed output scale setting to no longer require the fractional part, i.e.
scale 2
will work. - Fixed
focus-window-or-workspace-{up,down}
missing the workspace switch animation. - Fixed empty named workspaces disappearing upon output removal.
- Fixed a crash when an (already unfullscreened) window that in a column with other windows requests to be unfullscreened.
- Fixed key repeat not working when the
keyboard
config section is missing. - Fixed some crashes when no outputs are connected. On some devices outputs reconnect themselves upon resuming from sleep, which was triggering these issues.
- Fixed rounded corners rendering blurry on very high scale factors.
- Fixed the automatic draw border with background check to also include the KDE decoration protocol value. This makes it work for some older clients like GTK 3 (thanks @kchibisov).
- Fixed ISO_Level3_Shift modifier not showing up in the Important Hotkeys list.
- Niri now increases the fd limit to the maximum, fixing some fd-heavy clients (e.g. running RustRover in Xwayland).
- Updated Smithay, which fixes running on the NVIDIA 555 driver (explicit sync is still not implemented for now).
v0.1.6
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.
We've now got a small setup showcase thread, be sure to check it out!
And here are the improvements from the last release.
Gestures
In this release, I added mouse gestures for resizing and scrolling the view. I also made a wiki page listing all existing gestures.
Interactive Window Resizing
You can now resize windows interactively with a mouse (yes, finally). Both by edge-dragging windows with client-side decorations, and anywhere on a window by holding Mod together with the right mouse button.
To complement this, there are two new double-click gestures: double-clicking a resize will expand the window to the full monitor width, or reset the window height to take up all available space, depending on the edge that you double-click. Thanks @FreeFull for suggesting these gestures!
Resetting the window height is also available as the new reset-window-height
key binding.
niri-interactive-resize.mp4
Despite the ubiquity, interactive resizing proved quite tricky to implement with plenty of edge cases (tiling makes it harder since multiple things need to coordinate together). The main challenge stems from the fact that when resizing a window by the left edge, its right edge should stay in place, which means that the window itself must move to the left, strictly in sync with changing size. Throw into the mix slow windows (the red rectangle on the video), windows not strictly obeying the given size (e.g. terminals snapping to the cell grid), and multiple windows in a column (which must all resize together), and you've got a wild asynchronous cocktail.
There was even a Chromium bug involved in this one, and a similar Firefox issue is waiting on a recent GTK 3 update.
Mouse View Scrolling
Holding Mod and the middle mouse button (scroll wheel) will now let you scroll the view. This uses the touchpad swipe gesture code with all its decelerated spring animation goodness, but makes sure that the spot that you "grabbed" stays locked to the mouse cursor.
niri-mouse-view-gesture.mp4
Functionality
This release also adds some nice new functionality.
Named Workspaces
You can now declare named workspaces in the config.
workspace "browser"
workspace "chat" {
open-on-output "DP-2"
}
Unlike normal (dynamic) workspaces, named workspaces are persistent (they are not deleted when they have no windows), but otherwise they behave just like normal workspaces: you can reposition them and move to different monitors.
Actions like focus-workspace
or move-column-to-workspace
can refer to workspaces by name in addition to by index. Also, you can use the new open-on-workspace
window rule to make a window open on a specific named workspace:
// Declare a workspace named "chat" that opens on the "DP-2" output.
workspace "chat" {
open-on-output "DP-2"
}
// Open Fractal on the "chat" workspace.
window-rule {
match app-id=r#"^org\.gnome\.Fractal$"#
open-on-workspace "chat"
}
You can find a few more details on the wiki page.
Named workspaces should mostly solve the "shove a bunch of windows on correct monitors at startup" problem while working seamlessly with the dynamic workspace system. Thanks to @algernon for implementing this!
IPC Improvements
The new niri msg output
command lets you apply transient output configuration changes. It uses the same syntax as the config file, e.g. niri msg output eDP-1 scale 2
. These changes will persist until you edit the output settings in the config file (or restart niri).
While adding this, I also made output names case-insensitive, both for niri msg output
and for the config file, which should make things less annoying.
Additionally, @rustysec added a niri msg workspaces
command which will be extra useful now with the introduction of named workspaces:
┌ ~
└─ niri msg workspaces
Output "DP-2":
1 "chat"
2 "browser"
* 3
4
Output "eDP-1":
1 "notes"
* 2
3
Like with other IPC commands, you can use the --json
flag to get the same data in a machine-readable form.
New Window Rules
You can now set focus-ring
and border
properties in window rules to override them for specific windows.
The new is_active_in_column
matcher, added by @TheZoq2, can be used to make a magnifier-like window layout:
window-rule {
match is-active-in-column=false
min-height 100
max-height 100
}
Finally, the new at-startup
matcher will match during the first 60 seconds after niri startup. You can combine it with open-on-output
or open-on-workspace
properties to put windows where they belong when starting the session, but not afterward. I found it quite useful for e.g. browsers where I want new windows to open normally as I go on with my day, rather than keep spawning on the same monitor and workspace.
// Open Firefox maximized on the "browser" workspace, but only at niri startup.
window-rule {
match at-startup=true app-id=r#"^org\.mozilla\.firefox$"#
open-on-workspace "browser"
open-maximized true
}
Debugging Features
There are a few new debugging features:
-
The
debug-toggle-opaque-regions
bind will draw regions marked as opaque in blue and others in red. -
The
debug-toggle-damage
bind will draw the damage computed for the screen. Kind of, mostly. Good enough to tell when something wrong is going on. -
The
disable-direct-scanout
flag disables direct scanout to the primary and the overlay planes.
Eye candy
Of course, there are also new eye candy features!
Rounded Window Corners
Niri can now do corner rounding, a clear must-have feature for any self-respecting Wayland compositor. I've got quite an extensive implementation here, actually. Let's take a look.
You set the radius with the new geometry-corner-radius
window rule.
By itself, it doesn't clip the window but merely informs elements like the border and the focus ring which window radius they should assume. This means that you can keep using client-side-decorated windows with their own rounded corners and shadows, and have the borders drawn with the right radius.
window-rule {
geometry-corner-radius 12
}
This sets the radius of the window geometry—the inner radius of the border. The outer border radius is computed automatically taking the border width into account.
You can even set a separate radius for every corner, for example, to match GTK 3 applications:
window-rule {
match app-id="^gnome-terminal-server$"
geometry-corner-radius 8 8 0 0
}
Next, the new clip-to-geometry
window rule will make niri actually clip windows to their geometry, including the geometry-corner-radius
that you have set.
window-rule {
geometry-corner-radius 12
clip-to-geometry true
}
Combine this with prefer-no-csd
to get the classic rounded corner setup that works on all windows:
prefer-no-csd
layout {
focus-ring {
off
}
border {
width 2
}
}
window-rule {
geometry-corner-radius 12
clip-to-geometry true
}
All of this works correctly with subsurfaces, windows blocked out from screencasts, transparency, resize and other animations. And whenever possible, there's no overhead: opaque regions are preserved (except for the corners themselves), and even overlay plane unredirection still works for subsurfaces completely inside the clipped geometry!
Tricky Cases | Opaque Regions | Unredirection |
---|---|---|
Screen Transition
I added a do-screen-transition
action which lets you switch between light and dark, or between different themes, smoothly like in GNOME Shell.
niri-screen-transition.mp4
The key is to make sure the applications themselves switch their theme without animation and as fast as possible, then niri's own screen transition will make it look nice and synchronized.
If your apps take just a...
v0.1.5
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.
This time I decided to update the demo video in the README. Here's the new video if you're curious:
demo.mp4
Now let's go over the improvements from the last release.
More animations
A big focus in this release was on animations. I've animated many more actions: window movement, resizing, and closing. Each of these was challenging to implement in its own way, but I'm quite happy with the end result.
niri-new-anims.mp4
Naturally, all animations work well with windows blocked out from screencasts.
As usual, you can disable or configure individual animations if you prefer. Find instructions on the wiki page.
While working on these animations, I fixed a few minor issues with view positioning. So niri now works better even with animations disabled.
Spring animation improvements
Spring animations are now more robust: values and durations are clamped more aggressively where it makes sense. For example, a bouncy window opening animation will become fully opaque upon reaching the full window size, and won't become transparent again during the following bounces.
niri-open-anim-clamp.mp4
Also, when using slowdown
, the touchpad gesture velocity is now scaled by the slowdown factor, making the animation smoother.
Variable refresh rate
Niri now has basic variable refresh rate (VRR) support. You can enable it by setting a variable-refresh-rate
flag in the output config. Check the wiki for an example and caveats.
Additionally, niri msg outputs
now shows whether VRR is supported and enabled.
IPC improvements
niri msg
received a few quality-of-life improvements thanks to @sodiboo:
- Added
niri msg version
that shows the running niri compositor version and the niri CLI version. They are the same binary, so their versions should match, but they can briefly go out of sync after a niri update. - When
niri msg
receives an error from the compositor, it will now check if the compositor and the CLI versions match, and if not, print a message reminding you that you may need to restart niri. - Added
niri msg request-error
that will always result in an error from the compositor. This can aid in script development to check that your error handling works right.
Other improvements in this release
- Added an
allow-when-locked=true
flag for spawn key bindings that makes them work when the session is locked. Check the wiki for an example. - Previous view position is now restored upon unfullscreening a window.
- The
SIGPIPE
handler is now set to default inniri msg
to prevent panic backtraces from showing up when stdout is closed. - The mouse cursor is now hidden upon touchscreen interaction.
- Corrected some DRM leasing behavior to fix crashes when DRM leasing is unavailable and better handle hotplugging.
- Added an
ease-out-quad
easing curve. - Fixed
warp-mouse-to-focus
not triggering when a window is closed by unmapping its buffer. - Fixed the horizontal touchpad gesture redrawing continuously rather than only on touchpad events.
- Fixed overdamped spring instability being able to crash the compositor.
- Added a microphone mute example bind to the default config.
v0.1.4
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.
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.
block-out-from.mp4
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
}
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!
niri-warp-mouse-focus-follows.mp4
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.
wlr-gamma-control
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!
Note
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:
Documentation
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: https://github.com/YaLTeR/niri/wiki/Configuration:-Overview
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: https://github.com/sodiboo/niri-flake/blob/main/docs.md#programsnirisettings
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).
v0.1.3
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: if you're not using systemd and the niri-session
script, you may need to change your niri startup command to niri --session
. Please read below on the changes for environments without systemd.
Also, please consider including the wp-viewporter revert: 40cec34 to fix a mouse input bug with Chromium and Electron apps.
Touchpad gestures
I grew annoyed enough with the lack of a horizontal touchpad gesture in niri, so I spent several days working on the gestures. I tried three different horizontal gesture behaviors, and the one I landed on does a fairly good job of moving the windows where you intended.
I also made many overall improvements to both the vertical and the horizontal gestures to make them feel very good. They are now inertial, meaning that a short flick is enough to take you to the next workspace, as the gesture will account for the speed of your fingers. Vertical gesture has rubberbanding at the edges, indicating that you can't go any further. Finally, both gestures use spring animations when releasing fingers, which feel natural as they also take the finger speed into account. If you swipe with enough force, you'll even get a small bounce at the edge!
touchpad-gestures.mp4
Thanks goes to the maintainers of libadwaita since that's where I copied lots of the code and numeric values from.
Spring animations
As part of the gesture work, niri now supports spring animations. These are physics-based animations that are especially well suited for gestures, but feel good on their own too. Based on the spring configuration, they can optionally give small bounces and oscillations.
I made three of the four default animations to use springs. If you had custom animation settings in your config, comment them out to give springs a try! Also, check the default config for a more detailed explanation and examples on how to set up spring animations.
config-error-bounce.mp4
Touch support
@cmeissl added basic touchscreen support to niri. Thanks!
Gradient borders
Focus ring and borders can now use a linear gradient instead of a solid color!
This is how you can set it up:
layout {
border {
active-gradient from="#f38ba8" to="#f9e2af" angle=45 relative-to="workspace-view"
inactive-gradient from="#585b70" to="#7f849c" angle=45 relative-to="workspace-view"
}
}
Colors can use several CSS-like notations, and the gradient itself is rendered like CSS linear-gradient(angle, from, to)
. You can use some CSS gradient generator, like this one, to get a gradient you like, then copy the values into the niri config.
Also, gradients can be relative to windows individually (the default), or to the whole view of the workspace. It's easier to explain visually:
Default | relative-to="workspace-view" |
---|---|
By the way, regular colors can also now be written with CSS-like notations. The old four-number way is now deprecated.
// catppuccin-mocha Sapphire
active-color "#74c7ec"
// catppuccin-mocha Surface2
inactive-color "#585b70"
wlr-screencopy
While niri supports xdg-desktop-portal screencasting and has a built-in screenshot UI, these are not very well suited for taking programmatic screenshots (and the current screenshot portal API isn't very good either). So, in this release, niri implements wlr-screencopy version 1 (not 3). Now you can take screenshots with grim.
Screen recording tools based on wlr-screencopy will need version 3, so they won't work for now. (The screencast portal is better for this anyway; for example, it leaves frame pacing entirely to the compositor, where it belongs.) Version 1 should be sufficient for any screenshot tool; if a screenshot tool complains that it needs version 3 then it likely needs a simple patch to avoid requesting version 3 if unavailable.
Like other security-sensitive protocols, wlr-screencopy is not available to sandboxed clients with a security context (such as Flatpaks).
Finally, all three of my outputs on a single screenshot.
|
Thanks to @sodiboo for implementing wlr-screencopy support!
Frame timing fixes
I fixed several issues in the presentation time handling and frame callback tracking logic.
- Frame callbacks were sometimes sent ~1 frame later than they should've been, meaning that clients had much less time to render.
- With specific timing it was possible for frame callbacks to stop getting sent to certain surfaces, causing a window to stop redrawing until something else updates the screen.
- Zero presentation time from DRM (which can happen on some drivers) sometimes resulted in a panic.
Stricter config validation
Due to the ease of use in knuffel, the KDL parsing library we use in niri, some nodes technically accepted multiple children, despite only expecting one. Specifically, default-column-width {}
and binds. Also, you could write multiple binds to the same key combination, which is similarly not supported.
This has been fixed to cause a config validation error. While technically a config-breaking change, it's more of a bug fix, since before all these extra nodes that you could write were ignored. Therefore I considered it fine to include in a minor niri version bump.
Thanks @sodiboo for implementing this validation!
Refactored window creation flow
I reworked the window creation flow and tracking of unmapped windows in niri to make it more robust and less "all over the place". As part of this:
- With borders enabled,
default-column-width {}
(unset, the app picks its own) caused the app to shrink a bit right after it appeared. This wasn't really noticeable, but it resulted in a smaller window size than what the app wanted. It is now fixed. - Corrected
default-column-width { fixed N; }
similarly not taking borders into account, resulting in a smaller window than the specified N. - Added support for apps requesting a specific fullscreen monitor before they first appear (
mpv --fs-screen=N
will now work). - Added
open-maximized true
window rule. - Added
open-fullscreen true/false
window rule. Setting it totrue
will fullscreen the window upon opening, and setting it tofalse
will deny the window from fullscreening upon opening.- Some windows can request fullscreen after they are initially configured, but before they are first shown on screen. In this case
open-fullscreen false
will not work, because these window rules apply at the initial configure. So far I only sawmpv --fs
do this, so it's not a big problem (you can just remove the mpv flag).
- Some windows can request fullscreen after they are initially configured, but before they are first shown on screen. In this case
Systemd scopes
When niri runs applications it will now put them into transient systemd scopes. One concrete benefit is that when an application uses too much RAM and systemd-oomd kills it, niri won't go down alongside the app, so the rest of your session will stay intact.
Many other tools (like Flatpak, tmux, or systemd itself) already do this for the commands they spawn, so niri joins this established practice.
┌ ~
└─ systemctl --user status
● sparklingbrook
State: running
Units: 444 loaded (incl. loaded aliases)
Jobs: 0 queued
Failed: 0 units
Since: Mon 2024-03-04 10:25:20 +04; 4 days ago
systemd: 254.9-1.fc39
CGroup: /user.slice/user-1000.slice/user@1000.service
├─app.slice
│ ├─app-niri-alacritty-1672431.scope
│ │ ├─1672431 alacritty
│ │ ├─1672446 /usr/bin/fish
│ │ └─1672578 systemctl --user status --no-pager
│ ├─app-niri-fuzzel-1672466.scope
│ │ └─1672468 /var/home/yalter/stuff/blender-4.0.2-linux-x64/blender
<...>
├─session.slice
│ ├─niri.service
│ │ └─1663138 /usr/bin/niri --session
<...>
Also, since the niri.service
scope now only contains niri itself, I have moved it into session.slice
, a slice for important services such as the compositor.
Running without systemd
I've made it easier to run niri in environments without systemd.
- Added a new, enabled by default, feature
systemd
which gates calls to the systemd D-Bus API. Currently, this includes starting transient scopes andsystemctl import-environment
. - Niri now sets
XDG_CURRENT_DESKTOP
andXDG_SESSION_TYPE
in the main binary, rather than in theniri-session
script. - Added a
niri --session
flag for running niri as the main session instance, which means that it will import environment variables globally into systemd and D-Bus, and start D-Bus services. This flag replaces auto-detection based on the presence of theNOTIFY_SOCKET
...
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.