14.3 A Closer Look at Wayland
We’ll start with Wayland because it’s the emerging standard, currently used by default on many distributions. Unfortunately, in part due to its design and young age, there aren’t as many tools for prodding into Wayland as there are for X. We’ll do what we can.
But first, let’s talk about what Wayland is and isn’t. The name Wayland refers to a communications protocol between a compositing window manager and graphical client program. If you go looking for a big Wayland core package, you won’t find one, but you will find the Wayland library that most clients use to speak to the protocol (at least for now).
There’s also a reference compositing window manager called Weston and a few associated clients and utilities. What reference means here is that Weston contains the necessary functionality of a compositor, but it’s not meant for use by the general public because it has a bare-bones interface. The idea is that developers of compositing window managers can look at the Weston source code to see how to implement critical functions correctly.
14.3.1 The Compositing Window Manager
Odd as it might sound, you might not know which Wayland compositing window manager you’re actually running. You might be able to find the name from an information option in the interface, but there’s no set place to look. However, you can nearly always find the running compositor process by tracking down the Unix domain socket that it uses to communicate with clients. The socket is the display name in the WAYLAND_DISPLAY environment variable, which is usually wayland-0 and typically found in /run/user/<uid>, where <uid> is your user ID (if not, check the $XDG_RUNTIME_DIR environment variable). Running as root, you can find the process listening on this socket with the ss command, but the output will look a little crazy:
# ss -xlp | grep wayland-
u_str LISTEN 0 128
/run/user/1000/wayland-0 755881
* 0 users:(("gnome-shell",pid=1522,fd=30),("gnome-
shell",pid=1522,fd=28))
However, you just need to pick through it; you can see here that the compositor process is gnome-shell, PID 1522. Unfortunately, yet another layer of indirection is going on here; the GNOME shell is a plug-in of Mutter, which is the compositing window manager used in the GNOME desktop environment. (Here, calling the GNOME shell a plug-in is just a fancy way of saying that it calls Mutter as a library.)
One of the more unusual aspects of Wayland systems is the mechanism for drawing window decorations, such as title bars. In X, the window manager did it all, but in the initial implementations of Wayland, this was left up to the client applications, which sometimes led to windows having many different kinds of decorations on the same screen. Now there’s a part of the protocol called XDG-Decoration that allows the client to negotiate with the window manager to see if the window manager is willing to draw decorations.
In the context of a Wayland compositor, you can think of the display as the viewable space, represented by the framebuffer. A display can span more than one monitor if more than one is connected to a computer.
Although it’s rare, you can run more than one compositor at once. One way to do this is to run compositors on separate virtual terminals. In this case, the first compositor would normally have the display name set to wayland-0, the second wayland-1, and so on.
You can gain a bit of insight into your compositor with the weston-info command, which shows a few characteristics of the interfaces that the compositor has available. However, you shouldn’t expect very much beyond information on your display and some input devices.
14.3.2 libinput
In order to get the input from devices, such as a keyboard, from the kernel to clients, a Wayland compositor needs to collect that input and direct it to an appropriate client in a standardized form. The libinput library includes the support necessary to collect the input from the various /dev/input kernel devices and massage them. In Wayland, the compositor doesn’t usually just pass an input event as is; it translates the event into the Wayland protocol before sending to a client.
Normally, something like libinput wouldn’t be terribly interesting to talk about, but it comes with a small utility, also called libinput, that allows you to inspect input devices and events as they are presented by the kernel.
Try the following to look at the available input devices (you’ll probably get a lot of output, so be prepared to page through it):
# libinput list-devices
--snip--
Device: Cypress USB Keyboard
Kernel: /dev/input/event3
Group: 6
Seat: seat0, default
Capabilities: keyboard
Tap-to-click: n/a
Tap-and-drag: n/a
Tap drag lock: n/a
Left-handed: n/a
--snip--
In this partial view, you can see the type of device (keyboard) and where the kernel evdev device is (/dev/input/event3). That device shows up when you listen for events like this:
# libinput debug-events --show-keycodes
-event2 DEVICE_ADDED Power Button seat0 default
group1 cap:k
--snip--
-event5 DEVICE_ADDED Logitech T400 seat0 default
group5 cap:kp left scroll-nat scroll-button
-event3 DEVICE_ADDED Cypress USB Keyboard seat0 default
group6 cap:k
--snip--
event3 KEYBOARD_KEY +1.04s KEY_H (35) pressed
event3 KEYBOARD_KEY +1.10s KEY_H (35) released
event3 KEYBOARD_KEY +3.06s KEY_I (23) pressed
event3 KEYBOARD_KEY +3.16s KEY_I (23) released
When you run this command, move the mouse pointer around and press some keys. You’ll get some output describing these events.
Remember that the libinput library is just a system for capturing kernel events. As such, it is used not only under Wayland, but also under the X Window System.
14.3.3 X Compatibility in Wayland
Before discussing the X Window System in general, let’s first explore its compatibility with Wayland. There are countless applications for X, and any effort to move from it to Wayland would be greatly hindered by a lack of X support. There are two simultaneous approaches to bridge the gap.
The first approach is to add Wayland support to the application, creating a native Wayland application. Most graphical applications that run on X already use toolkits such as the ones found in GNOME and KDE. Because the work of adding Wayland support to these toolkits has already been done, it’s not much of a stretch to make an X application into a native Wayland application. In addition to paying attention to support for window decorations and input device configuration, a developer need only deal with the rare stray X library dependencies in an application. For many major applications, this work is already complete.
The alternative is to run an X application through a compatibility layer in Wayland. This is accomplished with an entire X server running as a Wayland client. Called Xwayland, this server is really just another layer jammed underneath X clients, run by default by most compositor startup sequences. The Xwayland server needs to translate input events and maintain its window buffers separately. Introducing another middleman like this always slows things down slightly, but it’s mostly inconsequential.
Going in reverse doesn’t work as well. You can’t run Wayland clients on X in the same way (theoretically, it’s possible to write such a system, but there’s not much point). However, you can run a compositor inside an X window. For example, if you’re running X, you can just run weston on the command line to bring up a compositor. You can open a terminal window and any other Wayland app inside, and you can even run X clients inside the compositor if you’ve started Xwayland properly.
However, if you leave this compositor running and go back to your regular X session, you might find that certain utilities don’t work as you expected, and they might also show up in the compositor window when you expected them to show up as an X window. The reason for this is that many applications on systems such as GNOME and KDE are now built with both X and Wayland support. They will look for a Wayland compositor first, and by default, the code in libwayland that looks for a display defaults to wayland-0 if the WAYLAND_DISPLAY environment variable isn’t set. An application that finds a working compositor will use it if it can.
The best way to avoid this is simply not to run a compositor inside X or at the same time as an X server.