Introduction

Mir, among other things, aims to make it easy to develop graphical “desktop environments” for Linux. There’s a lot of features that are common between all designs for desktop environments and, in addition, a lot that is common between the majority of designs. For example, it is common for applications to draw “windows” and for these to be combined onto the screen.

By providing the common features, and for the rest offering both sensible defaults and an easy way to customise them Mir is designed to support a range of possible designs.

This is the first of in a series of articles that illustrate the development of an Example Mir Desktop Environment [egmde].

Wayland

Most current desktop environments for Linux are based on X11. This is the last in a line of protocols for communicating between the applications, and parts of the “desktop environment”. However, the environment in which it works has changed somewhat since the 1980’s. That means many fundamental design decisions needed to be re-evaluated.

The result of this re-evaluation is a new protocol: “Wayland”. This has been implemented for a number of application “toolkits” and desktop environments. Instead of being based on X11 Mir supports the newer Wayland protocol.

For more details on the relationship between Wayland and compositors like Mir, KWin, and Mutter see https://discourse.ubuntu.com/t/ok-so-what-is-this-wayland-thing-anyway/8484

Preparation

The code in this article needs Mir 1.2 (or later).

On Ubuntu 18.04 (and later) this is available 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. And finally, the g++ compiler and cmake.

$ sudo apt-add-repository ppa:mir-team/release $ sudo apt install libmiral-dev mir-graphics-drivers-desktop $ sudo apt install weston qtwayland5 $ sudo apt install g++ cmake git pkgconf

On Fedora

$ sudo dnf install mir-devel $ sudo dnf install weston qt5-qtwayland $ sudo dnf install gcc-c++ cmake

Mir is also available from the Arch AUR and can be built from source for many versions of Linux.

Egmde

This series of articles follow the development of a very simple desktop environment. Because this is an example don’t expect it to be polished to a production level. But it is usable and could be the basis for further work.

Building the example

The full code for this example is available on github:

$ git clone https://github.com/AlanGriffiths/egmde.git $ git checkout Article-1

Naturally, the code is likely to evolve, so you will find other branches, but the Article-1 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

Running the example

After this you can start egmde:

$ ./egmde

You should see a black Mir-on-X window with a cursor. You can launch a terminal window with Ctrl-Alt-T (or, if that conflicts with your desktop, Ctrl-Alt-Shift-T).

You should see the same black screen with a weston-terminal window. From this you can run commands and, in particular, start graphical applications. Perhaps qtcreator to examine the code?

You should find that you can do all the normal things – use the keyboard and mouse to switch between and resize windows. If you have a touchscreen, then that will work too.

Running a full desktop type session is also possible, but first I should mention that it is possible to close egmde using the keyboard combination Ctrl-Alt-BkSp. Now switch to a virtual terminal (Ctrl-Alt-F4 for example) log in and run egmde-desktop.

Installing the example

If you install egmde and it will be added to the greeter menu:

$ sudo make install

Depending upon the greeter used on your system it may be necessary to reboot before egmde appears as a login shell.

The example code

A lot of the functionality (default placement of windows, menus etc.) comes with the MirAL library. This means that there’s very little code needed to get this basic shell running:

$ wc -l *.cpp 75 egmde.cpp

The main program for this article is shown below.

This breaks down into three blocks, the first is:

MirRunner runner{argc, argv}; ExternalClientLauncher external_client_launcher;

These are two objects from the MirAL library. The runner takes care of running Mir, it takes the command line arguments to handle configuration options. The external_client_launcher is used later to launch the terminal window.

The second block is a lambda - keyboard_shortcuts - that does some basic input handling. For Ctrl-Alt-T it starts a terminal using external_client_launcher , for Ctrl-Alt-BkSp it tells runner to stop the server.

The final block is a call to runner.run_with() which takes a list of customizations applies them to the server and runs it. This is the main way of customizing your server (we’ll be looking at other options next time). The customizations used here include the keyboard_shortcuts and external_client_launcher mentioned above. There are also couple more MirAL library objects: Keymap and MinimalWindowManager which respectively manage the keyboard layout and provide some default window management.

Installing the example

To register applications with desktop environments we install a .desktop file in /usr/share/applications and to register Wayland based desktops with the greeter we install a .desktop file in /usr/share/wayland-sessions/ . The content needed for both cases is similar, so for for this example we use the same .desktop file and install it to both places.

Conclusion

This article shows how the Mir library makes it easy to get started with a limited, but working “desktop environment”. From that point it is possible to extend the “desktop” in various ways – for example the MinimalWindowManager can be replaced with one that implements “tiling” (there’s an example in the Mir code that does this).

The next article will continue from this point and add features such as a “wallpaper” background and a “launcher” for selecting applications.

Code listing