Mike’s Place

Learning Wayland: Part 1

This is the first part in a series, the length of which is unknown. Since I have decided to resume working on AllTray again, it’s also become clear that in order to modernize it, I need to learn Wayland. It has also become clear, just in my cursory research and what I already know, that the methods that AllTray uses under X11 simply won’t work with Wayland.

The primary point of these posts is to provide personal reference material, as well as help to solidify what I’m learning. Hopefully it’s also useful to you.

An Overview of X11

X11 is the incumbant reigning champion when it comes to display systems for operating systems other than Microsoft Windows and macOS. While it is possible to run X11 applications on both Microsoft Windows and macOS systems, it is not the primary display system, and the native system APIs on those systems interact with the native display systems.

X11 is a protocol, which is spoken over a reliable stream transport such as a unix(7) or tcp(7) socket. In fact, it is often used over UNIX domain sockets, though remote applications may use TCP (possibly tunnelled through ssh(1)) to be displayed on the user’s local system. A program (which is an X11 client) establishes a connection to the display system (which is the X11 server). After the connection is established, packets are sent between the client and the server, representing commands (from the client) and events (from or via the server).

X11 provides a drawing API that applications may use to render lines, various shapes, images, and text. However, these operations occur server-side, and the server might forget the results of them if the window is obscured. When the window is uncovered, the server will ask the application to repaint its window so that the contents appear once again.

There are two free implementations of the client side X11 protocol: Xlib and XCB. Xlib provides a relatively high-level API, and is considered to be deprecated. XCB, on the other hand, is extremely low-level: it is automatically generated from an XML description of the X11 protocol, and provides an asynchronous API that essentially maps directly to that protocol.

While X11 is itself considered to be deprecated, I personally think that it is quite likely to die an IPv4-style death: long and drawn out. So, while it makes sense to support Wayland, it also makes sense to continue to support X11.

An Overview of Wayland

Wayland is the new kid on the block. Like X11, it is also a protocol. However, unlike X11, Wayland does not include any sort of support for drawing. Instead, an application uses the protocol as a control channel, using it to make arrangements to share buffers with the Wayland server. As the notion of “shared buffer” implies shared memory, Wayland applications are not usually displayed “over the network” as X11 applications commonly are. (Okay, it’s technically possible, by having a Wayland proxy to keep the buffer between the application and the real Wayland server in sync… but that’s beyond of the scope of this post.)

Wayland is, in many ways, an improvement over X11:

There are also disadvantages, mostly stemming from the fact that Wayland isolates applications from each other. Because one application cannot draw in or simulate input into another application’s windows, it becomes impossible to “adopt” another application’s window—which is what AllTray does under X11 in order to be able to manage windows it doesn’t own. The consequence of that? In order to provide its functionality in a Wayland environment, it seems that AllTray must become a subcompositor, and run the dockable application inside that subcompositor. Basically, AllTray needs to be a “Wayland proxy,” albeit for a different reason and purpose than attempting to display things over the network.

The Plan (Loosely)

I am familiar with Wayland at a “30,000 foot overview” level. Enough to know the basics about how it works, but not the specifics.

The first thing I need to do is to confirm what I think I already know, that AllTray needs to become a form of Wayland proxy in order to be implemented. If so, that’s okay, but it also means that AllTray cannot support attaching to a running application under Wayland, which would kinda suck.

After that, I need to learn more about Wayland’s protocols and the like.

Then, it’ll be time to get started actually talking to Wayland, which itself might take several parts to do before it’s anywhere close to ready. I need to write Wayland clients, and possibly even servers (compositor-proxies?).

Alright, then… until next time, where it looks like the topic will be a more in-depth analysis of “how Wayland works.”

Thanks for reading.

If you appreciated this article (or anything else I’ve written), please consider donating to help me out with my expenses—and thanks!