Building sway from source on Ubuntu derivates
Not for the faint of heart
Sadly, the official sway build instructions are a bit minimalistic and do not take into account that some system packages may be too old. I'm currently running Pop!OS (though once I find the time I'll replace that with Archbtw) and it was a bit of an adventure, as its most recent release is 24.04-LTS.
Even with other distros though, you will be in for a few surprises if you want to have a full-featured build with all optional items enabled…
Since I didn't expect things to get so involved I didn't keep a proper track record from the beginning, so I'm using my shell history and educated guesses. Expect things to be out of order and incomplete - feedback welcome.
Rough reconstruction of steps taken
System packages that still can be used
sudo apt build-dep sway
# aaaand some additional packages required by the deps we are going to build.
# Can probably be trimmed, and some things may be missing that I already had installed, e.g. m4
sudo apt install bison libxcb-xkb-dev libxcb-util1 libxcb-util-dev xcb-proto lua5.4 liblua5.4-dev hwdata liblcms2-dev \
glslang-tools libcairo2-dev libcap-dev libdbus-1-dev libdisplay-info-dev libevdev-dev libgdk-pixbuf2.0-dev libjson-c-dev \
libpam0g-dev libpango1.0-dev libpcre2-dev libpixman-1-dev libseat-dev libsystemd-dev libvulkan-dev libwayland-egl1 libxcb-ewmh-dev scdocBuild dependencies from source
Most dependencies can be built with a simple meson setup build/ --prefix=/usr/local, followed by ninja -C build/ install. Neither require running as root, ninja will ask for privileges when installing. sweet. For wayland we're skipping docs, as this cuts down on further dependencies.
When possible, clones are done with --depth=1 to speed things up (this only fetches HEAD and not the entire history).
Notable exceptions:
wlrootsrequires an older version oflibliftofffor some reasonlibdisplay-infohas subprojects that must be downloadedlibxkbcommonHEAD requires a more recentmesonthan the distro provides, and I really didn't feel like going down that path, so I randomly picked an older release- Xorg
macros: uses autoconf (argh) libxcb-errorsuses autoconf (argh) and won't find dependent macros installed to/usr/local. Fortunately this is easily fixed by settingACLOCAL_PATH. It also requires manual submodule (argh) init
# wayland
git clone --depth=1 https://gitlab.freedesktop.org/wayland/wayland.git
cd wayland
meson setup build/ --prefix=/usr/local -Ddocumentation=false
ninja -C build/ install
cd ..
# wayland-protocols
git clone --depth=1 https://gitlab.freedesktop.org/wayland/wayland-protocols.git
cd wayland-protocols
meson setup build/ --prefix=/usr/local
ninja -C build/ install
# drm
git clone --depth=1 https://gitlab.freedesktop.org/mesa/drm
cd drm
meson setup build/ --prefix=/usr/local
ninja -C build/ install
cd ..
# libxkbcommon
git clone --depth=1 https://github.com/xkbcommon/libxkbcommon.git
cd libxkbcommon
git checkout xkbcommon-1.11.0
meson setup build/ --prefix=/usr/local
ninja -C build/ install
cd ..
# Xorg macros
git clone https://gitlab.freedesktop.org/xorg/util/macros
cd macros
./autogen.sh
./configure --prefix=/usr/local
make
sudo make install
export ACLOCAL_PATH=/usr/local/share/aclocal
cd ..
# libxcb-errors
git clone --depth=1 https://gitlab.freedesktop.org/xorg/lib/libxcb-errors
cd libxcb-errors
git submodule update --init
./autogen.sh
./configure --prefix=/usr/local
make
sudo make install
cd ..
# pixman
git clone --depth=1 https://gitlab.freedesktop.org/pixman/pixman.git
cd pixman
meson setup build/ --prefix=/usr/local
ninja -C build/ install
cd ..
# libinput
git clone --depth=1 https://gitlab.freedesktop.org/libinput/libinput
meson setup build/ --prefix=/usr/local
ninja -C build/ install
cd ..
# libdisplay-info
git clone --depth=1 https://gitlab.freedesktop.org/emersion/libdisplay-info.git
cd libdisplay-info
meson subprojects download
meson setup build/ --prefix=/usr/local
ninja -C build/ install
cd ..
# libliftoff
git clone https://gitlab.freedesktop.org/emersion/libliftoff.git
cd libliftoff
git checkout v0.4
meson setup build/ --prefix=/usr/local
ninja -C build/ install
cd ..Build sway
git clone --depth=1 https://github.com/swaywm/sway.git
meson subprojects download
meson setup build/ --prefix=/usr/local
ninja -C build/ install
Finally. After meson setup you should hopefully see this:
wlroots 0.21.0-dev
drm-backend : YES
x11-backend : YES
libinput-backend : YES
xwayland : YES
gles2-renderer : YES
vulkan-renderer : YES
gbm-allocator : YES
udmabuf-allocator: YES
session : YES
color-management : YES
xcb-errors : YES
egl : YES
libliftoff : YES
sway 1.13-dev
gdk-pixbuf: YES
tray : YES
man-pages : YES
Subprojects
wlroots : YESRunning it
$ /usr/local/bin/sway
/usr/local/bin/sway: error while loading shared libraries: libwlroots-0.21.so: cannot open shared object file: No such file or directory
Oh no, our shiny new dependency libraries cannot be found! Well then.
LD_LIBRARY_PATH=/usr/local/lib/x86_64-linux-gnu:/usr/local/lib /usr/local/bin/sway
Hurray, almost there!
WHAT DO YOU MEAN, ALMOST THERE?!
Welp, one of the reasons to run a modern sway is that it supports screen sharing of application windows since version 0.12 (released in May 2026). But that's not enough - we also need a wlroots desktop portal that understands this.
OKAY, BACK TO THE DRAWING BOARD
- remove the system package, it will get in the way
- build and install
xdg-desktop-por- no wait, install its dependencies first 🙄 - add a systemd unit for our custom build
here's my ~/.config/systemd/user/xdg-desktop-portal-wlr.service:
[Unit]
Description=Portal service (wlroots implementation)
PartOf=graphical-session.target
After=graphical-session.target
ConditionEnvironment=WAYLAND_DISPLAY
[Service]
Type=dbus
BusName=org.freedesktop.impl.portal.desktop.wlr
Environment=LD_LIBRARY_PATH=/usr/local/lib/x86_64-linux-gnu:/usr/local/lib
ExecStart=/usr/local/libexec/xdg-desktop-portal-wlr
Restart=on-failure
once that's in place, install the portal:
systemctl --user stop xdg-desktop-portal-wlr.service
sudo apt remove xdg-desktop-portal-wlr
git clone --depth=1 https://github.com/benhoyt/inih.git
cd inih
meson setup build/ --prefix=/usr/local
ninja -C build/ install
cd ..
git clone --depth=1 https://github.com/emersion/xdg-desktop-portal-wlr.git
cd xdg-desktop-portal-wlr
meson setup build/ --prefix=/usr/local
systemctl daemon-reload
for completeness' sake: this portal needs to be explicitly set as preferred, like so (~/.config/xdg-desktop-portal/sway-portals.conf):
[preferred]
# use xdg-desktop-portal-gtk for every portal interface
default=gtk
# except for the xdg-desktop-portal-wlr supplied interfaces
org.freedesktop.impl.portal.Screencast=wlr
org.freedesktop.impl.portal.Screenshot=wlr