Trying out Wayland
I had been meaning for a long time to try out Wayland, which is designed as a modern replacement for the Linux graphical stack, the X Window System. The main selling point of Wayland for me is that it is better designed in terms of security: processes don't have access to each other's events, unlike X where any process can listen to all events that happen on the server. The lack of security in the design of X is a real problem: no matter which other kind of sandboxing you put in place (e.g., separate users, containers, etc.), you can't prevent a rogue process (e.g., malicious JavaScript using a browser security vulnerability) to access all events and, e.g., log all keystrokes that happen elsewhere in the session.
It is possible to sandbox processes in X by running an X server within the X server, e.g., Xnest, or more commonly Xpra. The way this works is that Xpra acts both as a client for the running X server, and as an X server in which you can run the process that you wish to sandbox: Xpra does not give the running process access to all events of the X server, but only gives it the events that it needs. This is what is done by Subuser, and it is what I did in my old setup to sandbox Skype. However, this is a rather ugly hack, and my experience the performance of the applications running inside Xpra has always been quite bad -- usable for Skype, but not really usable for something like a web browser. (I had tested this long ago by compiling the latest version of Xpra, and I just tested it again with the version packaged by Debian: video playback in a Web browser is not smooth.)
Another solution is what is done by QubesOS, which I haven't tested yet, but seems difficult to separate from the rest of their system (which looks interesting, but I'm not ready to migrate there yet). They are also thinking about using Wayland.
Anyway, Wayland looked like a reasonable solution to the problem, especially as the window manager that I use, i3, has been faithfully adapted to Wayland: sway. So I tried it out, and after some hours it seems to be fairly usable (using the Wayland packaged by Debian testing). This blogpost documents what I did.
Installing sway and its dependencies
Use apt-get
to install all requisite dependencies for
sway, and its
dependency wlroots. The list of the
packages that I installed for this is here. We will also need a recent version of libjson-c, because the one packaged by Debian is too old.
Essentially it should be something like:
mkdir ~/apps
cd apps
git clone 'https://github.com/json-c/json-c'
cd json-c
sh autogen.sh
./configure
make
sudo make install
cd ..
git clone 'https://github.com/swaywm/wlroots'
cd wlroots
meson build
ninja -C build
sudo ninja -C build install
cd ..
git clone 'https://github.com/swaywm/sway'
cd sway
meson build
ninja -C build
sudo ninja -C build install
You can then copy your i3 config to sway:
mkdir -p ~/.config/sway
cp ~/.config/{i3,sway}/config
And then you can try running sway
in a TTY and see what happens. For me,
everything almost worked out of the box: I document here what needs to be
adapted. You can also have a look at my
sway configuration,
with only minimal changes relative to my
i3 configuration,
For some reason the font in window titles and in the sway bar was wrong, but
this was simply fixed by changing the font names in the config file to
"Terminus". I think this is essentially the only change I had to make. When
using sway
there are some very small differences with i3
(e.g., the
formatting of window title bars, or the precise behavior), but honestly the
difference is hardly noticeable and I'm rather impressed at how close the
adaptation is.
Fixing the keyboard layout
I have my custom keyboard which adapts the US Dvorak layout with some key
combinations to write French accented characters. I used to load it with
xkbcomp
, but this no longer works with Wayland.
What works instead is to write a keyboard description like this and put it in ~/.xkb/symbols
. Note that this includes some external files, some of which are in in the systemwide /usr/share/X11/xkb/symbols
folder, and others are applying my customizations (see, e.g., this) and they should also go in ~/.xkb/symbols
. For some reason, trying to load this keyboard description by running setxkbmap a3nm
will not work. However, it works to load the keyboard description in sway
, by running XKB_DEFAULT_LAYOUT=a3nm sway
or editing the sway configuration file to add an input *
block containing the xkb_layout a3nm
directive, i.e.:
input * {
repeat_delay 250
repeat_rate 50
xkb_layout a3nm
}
Note that this is also where I configure the keyboard repeat delay and rate.
Many thanks to ManDay for helping me figure this out on the #sway IRC channel.
Switching to apps with native support for Wayland
Most applications do not yet support Wayland, but there is a compatibility layer to run them on Wayland, called XWayland. The way this works is that, when you run an application with no Wayland support (or where Wayland support is not enabled), it will instead be run in an X server that will display in Wayland. For me this worked fine, with no noticeable lags or performance loss. However, all X applications run in XWayland share the same instance (for now), so in terms of security these applications are not better isolated from one another than with X.
So what matters is that applications manipulating sensitive information (e.g., for me, terminal emulators) should not be run in XWayland. This means switching to a Wayland-compatible terminal emulator. My current terminal emulator, rxvt-unicode, is not. For now I just went back to gnome-terminal, which works. Suggestions of terminals to try out (which I haven't tested yet) include:
- Alacritty
- Germinal
- Kitty, which is packaged for Debian but the packaged version doesn't use Wayland (and I didn't find a way to convince it to do otherwise)
- Termite
Again, thanks for ManDay for suggestions here.
As for other applications I don't care much except for the Web browser.
Experimental support for Wayland just landed in Firefox Nightly, you can
download it here,
uncompress it, and then run it with GDK_BACKEND=wayland ./firefox
. This is
promising, however from my tests it's still not very stable: opening a second
window often made it hang or at least fail to redraw the window that was being
manipulated. I hope that this will improve and eventually be available in the
normal Firefox releases.
Tearing
Not a point to fix, but just a remark: one of the things that interested me in testing Wayland was that it is supposed to help reduce screen tearing. That said, it seems I'm no longer able to reproduce tearing on X either... Testing on some videos I didn't manage to see any noticeable difference between X and Wayland, so I can't really claim this as a benefit.
In terms of video playback: Debian's mpv
in testing is able to use Wayland
natively by running mpv --gpu-context=wayland
. For me it worked fine but I
couldn't see any difference with running it in XWayland. VLC, however, does not
use Wayland (I couldn't figure out if there was a Wayland backend). In terms of
performance (measured by CPU usage on the same file) for mpv
and VLC:
- VLC on Wayland (in XWayland) or in X, and
mpv
with hardware acceleration (--hwdec=auto
) and with the native Wayland backend or in X, are the most efficient (around 8% CPU) - Running
mpv
with hardware acceleration and in XWayland is a bit worse (15% CPU) - Without hardware acceleration,
mpv
is much less efficient at around 45% CPU, both in X and in Wayland (both for XWayland and for the native backend).
Disclaimer: enabling hardware acceleration for mpv
is discouraged.
Taking screenshots
I used to take screenshots with scrot
, but it is an X utility, so it will fail
silently. Instead, you can use grim
, as suggested in the sway wiki.
cd ~/apps
git clone 'https://github.com/emersion/grim'
cd grim
meson build
ninja -C build
You cannot invoke grim
without specifying an output file. I preferred
scrot
's way of automatically generating a filename based on date and time, so
you just have to write a wrapper script, e.g.,
this.
Changing the screen locker
It seems that my previous screen locker (xtrlock
) worked with Wayland, but I
thought it safer to switch to the one supplied with sway, i.e., swaylock
. I
customized it to the way I like, e.g., I like to have the possibility of locking
my session without hiding what's on the screen (e.g., to monitor stuff). The
result is
here.
Sandboxing a process
With sway in place, sandboxing a process is rather easy. Let's say that the
process to sandbox uses X (not Wayland natively), and that it is running as user
sandbox
. In Wayland, you just need to issue xhost +si:localuser:sandbox
(which will set the access controls for the XWayland server), and then run the
process with sudo -u sandbox process
as usual: the process will display while
running in XWayland, and will be indistinguishable from other performances, in
particular I didn't notice any performance problems. (For instance, playing a
video on Youtube in Firefox is hungry in terms of CPU, using around 120-150%,
but that's the same figure as running Firefox under X.) The sandboxed process
will have access to all events in other X applications that use XWayland, but it
is not able to access the events of native Wayland applications, and these
applications cannot access the events of one another.
You can use xinput test
(running in XWayland) to see the events that are
communicated to the XWayland X server. In fact, this is the easiest way I found
to test if a window was running natively in Wayland or in XWayland.
Remaining issues
To me the main issues that remain with the setup are:
- General perceived sluggishness. It's hard to explain why but I get the
impression that some things are less smooth in Wayland, in particular moving
windows around (while in tiling mode), but even displaying text in a terminal
emulator just feels a tiny bit slower. I'm not sure if I'm just imagining
this, or I'll stop noticing this after a while, or if there's a way to improve
performance, or if it will improve over time as the code of
sway
,wlroots
, etc., improves. For now it's just a rather mild annoyance. We'll see whether I stick with Wayland nevertheless or if I get fed up with it and give up. - Having to install programs (
sway
and dependencies) that are not packaged for Debian yet. That said, there has been some interest in packaging sway for Debian, and hopefully it will happen once sway reaches version 1.0, which doesn't seem so far away. - Lack of native apps for Wayland, in particular having to go back to
gnome-terminal
or to try more experimental terminals. - The realization that X applications are not isolated from one another as they are all running with the same XWayland server.
- I did not try using a projector yet. With X you use
xrandr
(see my guide here), but this doesn't work on Wayland. It looks like you should configure it instead withsway
by specifying the coordinates of the various outputs. However, I don't know whether projectors would work fine, given that the list of modes that they support is often pretty erratic, whereas with my laptop's screen, for instance,sway
only shows one available mode. Also, there is no support yet for showing the same content on two monitors, e.g., on the screen and on the projector. - There is no support for the
nm-applet
icon to configure NetworkManager, see this issue.
A more subtle point is that there is no discernible benefit to the user in running Wayland: at best it works just like X. For me the main benefit is security, but this is a pretty hard benefit to notice...
Thanks to linkmauve for proofreading and suggestions.