Introduction

I recently (re)introduced a simple shell based on Mir: egmde. This shell is just the code needed to illustrate these articles and, maybe, inspire others to build on it but it is not intended to be a product.

At the end of the last article we could run egmde as a desktop and run and use Wayland based applications.
Those of us in Europe (or elsewhere outside the USA) will soon notice that the keyboard layout has defaulted to US, so I’ll show how to fix that. And the black background is rather depressing, so I’ll show how to implement a simple wallpaper; and, finally, how to allow the user to customize the wallpaper.

Along the way we’ll discuss the way the MirAL API works with us to make it easy to combine features.

Preparation

The code in this article needs Mir 0.31 or later. This exists in Ubuntu 18.04 and Fedora 28 (both unreleased at the time of writing), or from the mir-team/release PPA.

It is also useful to install the weston package as the example makes use of weston-terminal as a Wayland based terminal application and the Qt toolkit’s Wayland support : qtwayland5.

Or, if using Fedora, use:

Naturally, the code is likely to evolve, so you will find other branches, but this branch goes with this article. Assuming that you’ve MirAL installed as described above you can now build egmde as follows:

$ mkdir egmde/build
$ cd egmde/build
$ cmake ..
$ make

After this you can start a basic egmde based desktop. This will use VT4, so first switch to VT4 (Ctrl-Alt-F4) to sign in and switch back again. Then type:

$ ./egmde-desktop

You should see a simple gradient wallpaper with a weston-terminal session.

You can set the wallpaper colour when starting the desktop by supplying a --wallpaper parameter, and the keyboard layout with --keymap like this:

$ ./egmde --wallpaper 0xff3737 --keymap gb

Alternatively, these options can be specified in a config file:

$ cat ~/.config/egmde.config
keymap=gb
wallpaper=0xff0d0

The example code

The previous code is largely unchanged. Just the egmde.cpp file is changed to add a couple of new headers and update the main program that looked like this:

The Keymap utility class handles setting the keymap, used like this it adds and uses a configuration option. (It can also be used to set a specific keymap on construction, or to change it dynamically while the shell is running.)

The CommandLineOption utility class does a number of things, adds a configuration option and calls it’s first argument with the configured value. To make this work nicely with an instance of egmde::Wallpaper the latter implements the function call operator to accept the wallpaper colour.

The StartupInternalClient utility takes an “internal client” object (the wallpaper), waits for the server to start and then connects the client to the server, notifying the internal client object of both the client-side and server-side connection so that the server “knows” which client this is.

By supplying customizations to the run_with() as a list MirAL makes it easy to ensure the server is initialized before they are used and it gives the user flexibility in setting these objects up. For example, the wallpaper instance is created and referenced in a shutdown hook using add_stop_callback() before being used in the run_with() list. This is achived by declaring run_with() to take an initinalizer list:

Each of the supplied utilities “knows” how to integrate itself into the system using the mir::Server. User code should not need to do this directly (so part of the MirAL “abstraction” is to keep this as an opaque type).

This approach has been proven effective by use in more advanced servers such as Unity8.

Implementing the Wallpaper

The Wallpaper class is what we’ll be implementing here, it uses a simple “Worker” class to pass work off to a separate thread. I’ll only show the header here as the methods are self-explanatory: