Mutter is a meson project and can be build the usual way:
meson setup builddir && meson compile -C builddirThere are quite a few dependencies which have to be satisfied. The easiest and risk-free way to obtain the dependencies is through the distribution repository in a Toolbx pet-container.
$ # on the host system:
$ toolbox create --distro fedora mutter
$ toolbox enter mutter
⬢ # inside the mutter Toolbx container:
⬢ sudo dnf builddep -y gnome-shell mutterMost dependencies from the main branch will be satisfied like this but sometimes the main branch requires new or more up-to-date dependencies which must be installed manually. Those dependencies are usually also meson projects and can be installed into the /usr prefix of the mutter Toolbx container:
⬢ # for example, if we the need the latest gnome-desktop:
⬢ git clone https://gitlab.gnome.org/GNOME/gnome-desktop.git
⬢ cd gnome-desktop
⬢ meson setup builddir --prefix=/usr
⬢ meson compile -C builddir
⬢ sudo meson install -CNote: the above should not be run outside the Toolbx container, it may make your system unusable.
When build in a Toolbx container, we can safely install Mutter into the /usr prefix as well:
⬢ meson configure builddir --prefix=/usr
⬢ meson compile -C builddir && sudo meson install -CLike any meson project, the available build options are in the meson_options.txt file. The defaults are usually fine but when developing for the native backend, it's a good idea to turn on additional tests:
⬢ meson configure builddir -Dtty_tests=trueThe KVM tests are usually not necessary to run on your own machine and are meant mainly for CI where it's not possible to run the tty tests due to VKMS not being available.
To run them, a specific version of virtme-ng is required
⬢ sudo dnf install python3-pip qemu
⬢ sudo pip3 install --prefix=/usr --verbose -r requirements.txt .Most of the test suit can be run via the usual meson test command:
⬢ meson test -C builddir --print-errorlogsTo run the tty tests, the VKMS kernel module must be loaded, and the session from which the test are invoked must be a session master. This usually means switching to another tty using ctrl+alt+f3, logging in, possibly entering the Toolbx container, and then invoking meson test with the mutter/tty suite to only run the relevant tests:
$ sudo modprobe vkms
$ toolbox enter mutter
⬢ meson test -C builddir --print-errorlogs --suite mutter/ttyRef-tests compare image captures of Mutter against a reference image. Sometimes a change of the rendering result is expected with some code changes. In those cases it's required to update the reference images. This can be done by running the tests with:
MESA_LOADER_DRIVER_OVERRIDE=swrast MUTTER_REF_TEST_UPDATE='/path/to/test/case'This makes sure a software renderer is being used and the reference image of the test case /path/to/test/case is updated. More information is available in src/tests/meta-ref-test.c.
While the test suite helps to catch mistakes, there are a lot of cases where we actually need to run and interact with Mutter. The least invasive method is running a nested instance using Devkit.
⬢ dbus-run-session mutter --wayland --devkitThis starts a nested Mutter instance in a new dbus session with the default plugin, displayed via a dedicated GTK Devkit application. Often we want to run Mutter with a real plugin, such as gnome-shell:
⬢ dbus-run-session gnome-shell --wayland --devkitBut sometimes running Mutter with the default plugin is preferred but there is nothing to interact with by default. We can either start something, like a terminal directly when invoking Mutter
⬢ dbus-run-session mutter --wayland --devkit -- vte-2.91or via the Launchers menu in the Devkit application menu, or by opening apps on the nested compositor by setting WAYLAND_DISPLAY to the display of the nested session. This is usually just wayland-1 but Mutter should print this to the terminal:
libmutter-Message: 21:01:37.323: Using Wayland display name 'wayland-1'
$ WAYLAND_DISPLAY=wayland-1 vte-2.91In the examples above we use dbus-run-session to create a nested D-Bus user session to avoid messing up the system's running D-Bus user session.
It's sometimes required to run two applications in the same nested D-Bus session. In that case, the dbus-session.sh script helps:
#!/bin/bash
set -euo pipefail
LIGHT_GRAY="\[\033[1m\]"
NO_COLOR="\[\033[0m\]"
export PS1="[$LIGHT_GRAY D-Bus \$(echo \$DBUS_SESSION_BUS_ADDRESS | sed -e 's/.*guid=\([a-z0-9]\{4\}\).*$/\1/') $NO_COLOR][\u@\h \W]$ "
ENV_FILE="$XDG_RUNTIME_DIR/nested-dbus-session.txt"
ACTION=${1:-}
if [[ "$ACTION" = "attach" ]]; then
export DBUS_SESSION_BUS_ADDRESS=$(cat $ENV_FILE)
bash -i
elif [[ "$ACTION" = "new" ]]; then
cat > /tmp/dbussessionbashrc << __EOF__
. ~/.bashrc
echo \$DBUS_SESSION_BUS_ADDRESS > $ENV_FILE
__EOF__
dbus-run-session -- bash --init-file /tmp/dbussessionbashrc -i
else
echo "Usage: $0 [attach|new]"
echo " new .. start a new dbus session"
echo " attach .. to attach to a previously started dbus session"
exit 1
fiWe can create a nested D-Bus user session by running
⬢ dbus-session.sh newThis will create a D-Bus session, and attach to it. To attach to the same session from another terminal, run
⬢ dbus-session.sh attachThere are limitations to the nested instance, such as keyboard shortcuts usually not getting to the nested compositor. The remote-desktop feature can help working around this.
First create a nested D-Bus session. In this, run gnome-shell in headless mode. E.g.
⬢ dbus-session.sh new
⬢ gnome-shell --headlessBuild gnome-remote-desktop and run:
⬢ dbus-session.sh attach
⬢ ./build/src/grdctl rdp set-credentials test test
⬢ ./build/src/grdctl rdp enable
⬢ ./build/src/gnome-remote-desktop-daemon --headless --rdp-port 12345Warning: This turns on rdp access for the entire system with weak credentials! For quick testing, GNOME_REMOTE_DESKTOP_TEST_RDP_USERNAME and GNOME_REMOTE_DESKTOP_TEST_RDP_PASSWORD might be useful.
Finally, connect to localhost:12345 with username and password test using an RDP client, like xfreerdp or Remmina.
Sometimes it's necessary to run the "native backend", on real display hardware. The easiest way is to switch to a tty and run (in your Toolbx container if this is where it was installed):
⬢ dbus-run-session mutter --waylandOne can also run gnome-shell this way, and use the dbus-session.sh script.
When running gnome-shell on the native backend, it's possible to exit gnome-shell by opening the "Run a Command" prompt and executing debugexit.
Unfortunately sometimes none of that is enough and we need to run an entire session with our own Mutter. Some developers found success with some of the following techniques:
- Using an immutable operating system such as Fedora Silverblue and installing to
/usr. It is possible to temporarily make the system mutable and then rollback when something goes wrong. - Installing to
/usr/local - Adding a GNOME session in GDM that uses the built project through environment variables.