Skip to content

Developing niri

Ivan Molodetskikh edited this page Feb 9, 2024 · 6 revisions

Running a Local Build

The main way of testing niri during development is running it as a nested window. The second step is usually switching to a different TTY and running niri there.

Once a feature or fix is reasonably complete, you generally want to run a local build as your main compositor for proper testing. The easiest way to do that is to install niri normally (from a distro package for example), then overwrite the binary with sudo cp ./target/release/niri /usr/bin/niri. Do make sure that you know how to revert to a working version in case everything breaks though.

If you use an RPM-based distro, you can generate an RPM package for a local build with cargo generate-rpm.

Tests

We have some unit tests, most prominently for the layout code and for config parsing.

When adding new operations to the layout, add them to the Op enum at the bottom of src/layout/mod.rs (this will automatically include it in the randomized tests), and if applicable to the every_op arrays below.

When adding new config options, include them in the config parsing test.

Running Tests

Make sure to run cargo test --all to run tests from sub-crates too.

Some tests are a bit too slow to run normally, like the randomized tests of the layout code, so they are normally skipped. Set the RUN_SLOW_TESTS variable to run them:

env RUN_SLOW_TESTS=1 cargo test --all

It also usually helps to run the randomized tests for a longer period, so that they can explore more inputs. You can control this with environment variables. This is how I usually run tests before pushing:

env RUN_SLOW_TESTS=1 PROPTEST_CASES=200000 PROPTEST_MAX_GLOBAL_REJECTS=200000 RUST_BACKTRACE=1 cargo test --release --all

Visual Tests

The niri-visual-tests sub-crate is a GTK application that runs hard-coded test cases so that you can visually check that they look right. It uses mock windows with the real layout and rendering code. It is especially helpful when working on animations.

Profiling

We have integration with the Tracy profiler which you can enable by building niri with a feature flag:

cargo build --release --features=profile-with-tracy

Then you can open Tracy (you will need the latest stable release) and attach to a running niri instance to collect profiling data. This is not currently "on-demand" (until the next Tracy release), so niri will always collect profiling data when compiled this way, and you can't run a build like this as your main compositor.

To make a niri function show up in Tracy, instrument it like this:

pub fn some_function() {
    let _span = tracy_client::span!("some_function");

    // Code of the function.
}