Using Mir to build a desktop environment

A Desktop Environment comprises much more than a compositor. A Desktop Environment has launchers, panels, integration with the system greeter and other services, and more.

Mir can help you build a compositor, but these other elements need to come from elsewhere. And they need to be integrated with your compositor:

  • Most of the integration with visible elements of the Desktop Environment will be done using Wayland extension protocols, and that is covered in the next section.

  • XDG desktop portals will also integrate based off of Wayland extensions combined with some “magic” to incorporate a portal implementation into your Desktop Environment. (See: How to enable screencasting for an example)

  • For your Desktop Environment to show up in the greeter at login it needs to be listed in a .desktop file under /usr/share/wayland-sessions/.

In the following, example implementations are taken from downstream projects:

Project

Description

miracle-wm

a Wayland compositor based on Mir. It features a tiling window manager at its core, very much in the style of i3 and sway

Ubuntu Frame

A simple fullscreen shell used for kiosks, industrial displays, digital signage, smart mirrors, etc.

Miriway

Miriway is a generic compositor using Mir that can be customised to serve the needs of a range of desktop environments

Wayland extensions

The communication between the compositor and other programs is substantially through Wayland extension protocols. Each extension protocol addresses a specific interaction: drawing a window, cut-and-paste, panel placement, and so on.

If, for example, you have a panel that docks to one edge of the screen, then it should use the zwlr_layer_shell_v1 Wayland extension. But you also need to ensure that your compositor allows the panel client to use that extension.

Adding additional Wayland extensions

It may be necessary to implement Wayland extensions that are not directly supported by Mir. These could be extensions that are specific to your Desktop Environment, or ones that cannot be integrated directly into Mir. (See: How to integrate a custom Wayland protocol)

Privileged Wayland extensions

Mir does not automatically make all Wayland extensions available to all Wayland clients. Some protocol extensions are “privileged” and only intended for clients that meet some trust criteria.

In your compositor you can enable access to the privileged Wayland extensions using the miral::WaylandExtensions APIs:

miral::WaylandExtensions extensions;

// Enable an extension for all clients
extensions.enable(WaylandExtensions::zwlr_layer_shell_v1);
// Enable an extension conditionally
extensions.conditionally_enable(WaylandExtensions::zwlr_virtual_pointer_manager_v1,
    [](miral::WaylandExtensions::EnableInfo const& info)
    {
        return !info.creds().from_application_sandbox();
    });

/// ...
runner.run_with({
    /// ...
    extensions,
});

Most of the extensions that are not enabled by default provide access that could compromise the security of the desktop or allow one application to interfere with the operation of another. For example:

  • The zwp_virtual_keyboard_manager_v1 and zwlr_virtual_pointer_manager_v1 extensions allow a client to inject input events that can be used to control other applications. However they are capabilities that e.g. a remote desktop server or input method might need.

  • The ext_image_copy_capture_manager_v1 and zwlr_screencopy_manager_v1 protocols give access to the window contents of other clients. This should again be restricted to remote desktop servers or the xdg-desktop-portal-wlr portal backend.

  • The ext_foreign_toplevel_list_v1 protocol provides information about windows presented by other clients of the compositor. The zwlr_foreign_toplevel_manager_v1 goes further in offering some level of control. These are useful for building a shell component like a task list or switcher, but you may want to avoid providing this information to sandboxed applications.

  • The zwlr_layer_shell_v1 protocol allows an app to position itself and make exclusive use of part of a portion of the screen. This is useful for shell components, but could be misused by a badly behaved client.

  • The ext_data_control_manager_v1 protocol provides features needed for a clipboard manager to operate. But it may bypass regular protections of the clipboard contents.

For these reasons, they should usually only be enabled using conditionally_enable.

Identifying clients to “qualify” them to use privileged extensions

It is up to you how you identify the clients with access to Privileged Wayland extensions. To help with this, Mir provides some reliable client credentials via the EnableInfo::creds method. The returned ApplicationCredentials object provides the following information:

  • The client’s process ID, user ID, and group ID, valid at the time of connection.

  • The client’s AppArmor label (or an error if AppArmor is not available or acquiring the label fails in some way).

  • If the client is snap sandboxed, the snap name.

  • If the client is flatpak sandboxed, the flatpak application ID.

  • A generic from_application_sandbox check that will return true for both snap and flatpak sandboxes.

Compositor authors are encouraged to use the information collected in the ApplicationCredentials object rather than trying to detect the information themselves. There are some subtle details

In Ubuntu Frame

Ubuntu Frame enables access to certain Wayland extensions to clients belonging to a few known snap packages (an on screen keyboard, VNC service, and some internal clients).

The details can be found in Ubuntu Frame’s AuthModel class in src/frame_authorization.cpp.

In Miriway

In Miriway, trusted “shell components” have to be fork()/exec()d by Miriway, and are identified by PID. This is handled by miriway::ChildControl in miriway_child_control.cpp.

In addition, there’s a shell-component configuration option to allow these programs to be specified by a Desktop Environment using Miriway.