Canonical Voices

Posts tagged with 'miral'

Alan Griffiths

The end of a dream?

We read in the press that Canonical has pulled out of the dream of “convergence”. With that the current support for a whole family of related projects dies.

That doesn’t mean that the dream has to die, but it does mean changes.

I hope the dream doesn’t die, because Canonical has done a lot of the “heavy lifting” – the foundations are laid, the walls are up, we have windows, plumbing and power. But we’re lacking the paintwork and there’s no buyer.

My expertise is developing working software and I’m going to donate some of that to the dream.

Stable Intermediate Forms is an important principle – keep things working while making changes. If you throw away a large chunk intending to replace it you’ll find re-integration really, really hard. Do things gradually!

So, don’t simply fork Unity8 and plan to get it working on Wayland. You’ll end up with a single wall that falls over before you’ve replaced the rest of the building. (Sorry, I went back to “metaphor”.)

Take the whole infrastructure etc. and keep it in place until any replacements are demonstrably ready.

The Elephant in the room

Many have issues with the way Mir has been presented to the community, but in the opinion of the developers it is a good piece of software and not inherently incompatible with Wayland. (Just look at what the developers have written about it especially the early posts that addressed this directly.)

There are two plausible evolutions of the dream that reconcile Mir with Wayland.

Plan 1: (my recommendation) Add support to libmirserver for Wayland clients in parallel to the existing protocol. Once this is working this either junk libmirclient or rework its interaction with libmirserver.

Plan 2: Implement an analog of QtMir/MirAL on your choice of Wayland server. Then transition Unity8 to these and junk Mir.

I can’t guarantee that my recommendation of “plan 1” isn’t biased by my history with the Mir project, clearly I know its potential better than that of competing projects and I would find developing these easier than someone new to the code. In then end, the choice will depend on who takes on the work and what they can achieve most effectively.

Read more
Alan Griffiths

MirAL 1.3.2

There’s a bugfix MirAL release (1.3.2) available in ‘Zesty Zapus’ (Ubuntu 17.04) and the so-called “stable phone overlay” ppa for ‘Xenial Xerus’ (Ubuntu 16.04LTS). MirAL is a project aimed at simplifying the development of Mir servers and particularly providing a stable ABI and sensible default behaviors.

The bugfixes in 1.3.2 are:

In libmiral a couple of “fails to build from source” fixes:

Fix FTBFS against Mir < 0.26 (Xenial, Yakkety)

Update to fix FTBFS against lp:mir (and clang)

In the miral-shell example, a crash fixed:

With latest zesty’s libstdc++-6-dev miral-shell will crash when trying to draw its background text. (LP: #1677550)

Some of the launch scripts have been updated to reflect a change to the way GDK chooses the graphics backend:

change the server and client launch scripts to avoid using the default Mir socket (LP: #1675794)

Update miral-xrun to match GDK changes (LP: #1675115)

In addition a misspelling of “management” has been corrected:

miral/set_window_management_policy.h

Read more
Alan Griffiths

miral gets cut & paste

For some time now I’ve been intending to investigate the cut & paste mechanisms in the Unity8/Mir stack with the intention of ensuring they are supported in MirAL.

I’ve never had the time to do this, so I was surprised to discover that cut & paste is now working! (At least on Zesty.)

I assume that this is piggy-backing off the support being added to enable the “experimental” Unity8 desktop session, so I hope that this “magic” continues to work.

Read more
Alan Griffiths

MirAL 1.3.1

There’s a bugfix MirAL release (1.3.1) available in ‘Zesty Zapus’ (Ubuntu 17.04) and the so-called “stable phone overlay” ppa for ‘Xenial Xerus’ (Ubuntu 16.04LTS). MirAL is a project aimed at simplifying the development of Mir servers and particularly providing a stable ABI and sensible default behaviors.

Unsurprisingly, given the project’s original goal, the ABI is unchanged.

The bugfixes in 1.3.1 are:

In libmiral a focus management fix:

When a dialog is hidden ensure that the active window focus goes to the parent. (LP: #1671072)

In the miral-shell example, two crashes fixed:

If a surface is deleted before its decoration is painted miral-shell can crash, or hang on exit (LP: #1673038)

If the specified “titlebar” font doesn’t exist the server crashes (LP: #1671028)

In addition a misspelling of “management” has been corrected:

SetWindowManagmentPolicy => SetWindowManagementPolicy

Read more
Alan Griffiths

MirAL 1.3

There’s a new MirAL release (1.3.0) available in ‘Zesty Zapus’ (Ubuntu 17.04) and the so-called “stable phone overlay” ppa for ‘Xenial Xerus’ (Ubuntu 16.04LTS). MirAL is a project aimed at simplifying the development of Mir servers and particularly providing a stable ABI and sensible default behaviors.

Unsurprisingly, given the project’s original goal, the ABI is unchanged.

The changes in 1.3.0 fall are:

Support for “workspaces”

This is part of the enabling “workspaces” for Unity8 desktop. MirAL doesn’t provide fancy transitions and spreads, but you can see some basic workspace switching in the miral-shell example program:

$ apt install miral-examples
$ miral-app

There are four workspaces (corresponding to F1-F4) and you can switch using Meta-Alt-[F1|F2|F3|F4], or switch taking the active application to the new workspace using Meta-Ctrl-[F1|F2|F3|F4].

Support for “previous window in application”

You can now use Alt-Shift-` to switch to the previous in an application.

miral-shell adds a background

miral-shell now uses its background for a handy guide to the available keyboard shortcuts.

Bug fixes

Two bug fixes related to shutdown problems: one deals with a possible race in libmiral code, the other works around a bug in Mir.

  • [libmiral] Join internal client threads before server shutdown (LP: #1668651)
  • [miral-shell] Workaround for crash on exit (LP: #1667645)

Read more
Alan Griffiths

miral-workspaces

“Workspaces” have arrived on MirAL trunk (lp:miral).

We won’t be releasing 1.3 with this feature just yet (as we want some experience with this internally first). But if you build from source there’s an example to play with (bin/miral-app).

As always, bug reports and other suggestions are welcome.

Note that the miral-shell doesn’t have transitions and other effects like fully featured desktop environments.

Read more
Alan Griffiths

MirAL 1.0

There’s a new MirAL release (1.0.0) available in ‘Zesty Zapus’ (Ubuntu 17.04) and the so-called “stable phone overlay” ppa for ‘Xenial Xerus’ (Ubuntu 16.04LTS). MirAL is a project aimed at simplifying the development of Mir servers and particularly providing a stable ABI and sensible default behaviors.

Surprisingly, given the project’s original goal, the ABI is changed. This allowed us to address a couple of minor issues and the timing seemed good as downstreams are faced with Mir-0.25 moving some necessary APIs from libmircommon to the more ABI stable libmircore.

The changes in 1.0.0 are:

  1. The default movement of child windows can be overridden by the window management policy;
  2. A new “miral-app” script that runs the miral example servers as an application on an existing desktop;
  3. Bug fix LP: #1646431 “Examples fail to start under Unity8”;
  4. Bug fix LP: #1646735 “[miral-shell –window-manager tiling] windows are not correctly constrained to tiles”; and
  5. A couple of deprecated APIs have been removed.

Read more
Alan Griffiths

Mircade

Mircade

I’ve been playing with the “kiosk” concept implemented by miral-kiosk. Kevin Gunn and Alberto Aguirre have been using it to demonstrate Mir snaps (kg’s blog) so I decided to join the fun.

Mircade is a very basic kiosk-launcher for whatever games are installed on a system. It tries to work out whether the game will run natively on Mir and, if not, will try running them on Xmir (if installed).

To play, you need the latest miral-examples and libmiral-dev installed. You can “apt install miral-examples” from Zesty archive/Xenial “stable phone overlay” PPA, or build it from source on Xenial or later.

$ sudo apt install miral-examples libmiral-dev mir-graphics-drivers-desktop xmir

Once you have that sorted, Mircade is available from github. It has a few dependencies (I’ve tried to list them, but have probably missed one).

$ git clone https://github.com/AlanGriffiths/mircade.git
$ sudo apt install libfreetype6-dev libboost-filesystem-dev libboost-system-dev cmake
$ cd mircade/
$ cmake .
$ make
$ miral-desktop -kiosk -launcher ./mircade

Navigation is by arrow keys (left/right) and selection by Space or Enter. When your game exits you return to the mircade launcher.

Not all games work perfectly on Mir (yet):

  • Most of the GTK based games (like gnome-chess) run, but sometimes fail to “fullscreen”;
  • SDL2 based games (like 7kaa) have a tendency to segfault on exit; and,
  • X11 based games using Xmir may or may not work.

Have fun!

Read more
Alan Griffiths

MirAL 0.5

There’s a new MirAL release (0.5.0) available in ‘Zesty Zapus’ (Ubuntu 17.04) and the so-called “stable phone overlay” ppa for ‘Xenial Xerus’. MirAL is a project aimed at simplifying the development of Mir servers and particularly providing a stable ABI and sensible default behaviors.

Unsurprisingly, given the project’s original goal, the ABI is unchanged. The changes in 0.5.0 fall are:

  1. Some utility scripts to for common tasks;
  2. Improved “–window-manager tiling” mode of miral-shell;
  3. More configuration options for miral-kiosk;
  4. miral::DebugExtension; and,
  5. Some minor bug fixes.

Some utility scripts to for common tasks

There are two of these: miral-desktop and miral-screencast.

miral-desktop creates a pseudo-desktop session:

miral-desktop - Handy launch script for a miral "desktop session"
Usage: miral-desktop [options] [shell options]
Options are:
    -kiosk               use miral-kiosk instead of miral-shell
    -launcher <launcher> use <launcher> instead of 'gnome-terminal --app-id com.canonical.miral.Terminal'
    -vt       <termid>   set the virtual terminal [4]
    -socket   <socket>   set the mir socket [/run/user/1000/mir_socket]
    -bindir   <bindir>   path to the miral executable

For example, I use this to test the “tiling” window management with a UK keyboard layout:

$ miral-desktop -launcher qterminal --window-manager tiling --keymap gb

miral-screencast captures the Mir display (until you press enter) and then encodes it as an mp4:

miral-screencast - screencast capture script for use with Mir servers
Usage: /usr/bin/miral-screencast [options]
Options are:
    --width   set the capture width   [1920]
    --height  set the capture height  [1080]
    --output  set the output filename [screencast.mp4]
    --socket  set the mir socket      [/run/user/1000/mir_socket]

Improved “–window-manager tiling” mode of miral-shell

This has been updated to keep the focused window on the left half of the display (unless there’s only one window) and divide the right side vertically between the remaining windows. There’s also been a general refresh of the code that fixed a lot of minor issues.

More configuration options for miral-kiosk

The miral-kiosk now supports a few more options:

  • –keymap allows for non-US keyboard layout;
  • –kiosk-maximize-root-window kiosk has a new default behavior of maximizing root window, but this can be changed;
  • –kiosk-startup-apps-only prevents new connections after startup

miral::DebugExtension

This allows shells to enable (or disable) the client API “debug” extensions dynamically (AFAICS only useful for automated testing).

Some minor bug fixes

There was a race condition handling fullscreen surfaces when reconfiguring the display for hardware changes, the gmock version in zesty caused a FTBFS, and the clang version in zesty picked up some template instantiation issues.

Read more
Alan Griffiths

Testing for Mir

Need a Mir server?

A couple of times in the last week I’ve been asked about a Mir server for testing. These requests have been from folks wanting to test their client-side work against Mir.

Most application developers will be using a toolkit or other graphics development library and not care if they are running on X11, Mir or even Windows. But the developers of those libraries will want to test with Mir.

For this purpose, the simplest Mir server to use is miral-shell. If you’re on Ubuntu Zesty Zapus then this is readily available:

$ sudo apt install miral-examples mir-graphics-drivers-desktop qtubuntu-desktop

If you’re on an earlier version of Ubuntu then you either need a ppa (such as the “stable phone overlay”) or, less risky to your system, just build and install it yourself. (If you’re not on Ubuntu this is still possible: there are some pointers here.)

What does miral-server provide?

Currently miral-server is the only Mir server to offer libmiral’s “basic window management”. That unique status is due to change real soon as this implementation is being merged into Unity8.

The simplest way way to run miral-shell is using Mir’s “Mir on X” support. From a terminal window just type:

$ miral-shell

Then you can connect your application from another terminal:

$ miral-run <application>

You should see your application appear in the “Mir on X” window.

A lot of the current work is focused on the placement of windows (menues, popup, etc.) and to help with this there’s a facility to trace the window management calls. Start miral-shell like this:

$ miral-shell --window-management-trace

And all the window management events and decisions are logged.

Another interesting option is to use a “tiling” window manager:

$ miral-shell --window-manager tiling

Which has a completely different approach to laying out the application windows.

For a full list of the option:

$ miral-shell --help

Documentation of the Mir “toolkit”API

A related question I’ve been asked is for documentation of the libmirclient API. You can find the documentation like this:

$ sudo apt install mir-doc
$ xdg-open /usr/share/doc/mir-doc/html/group__mir__toolkit.htm

This will open the default browser on the relevant page.

Read more
Alan Griffiths

MirAL 0.4

There’s a new MirAL release (0.4.0) available in ‘Zesty Zapus’ (Ubuntu 17.04) and the so-called “stable phone overlay” ppa for ‘Xenial Xerus’. MirAL is a project aimed at simplifying the development of Mir servers and particularly providing a stable ABI and sensible default behaviors.

Unsurprisingly, given the project’s original goal, the ABI is unchanged. The changes in 0.4.0 fall into two categories:

  1. Displaying titles in titlebars of the miral-shell example; and,
  2. additional features for shell developers to use.

Displaying Titles in Titlebars of the miral-shell Example

Titlebars now contain the window title. The font can be changed by using the –shell-titlebar-font command line option.

Additional Features For Shell Developers To Use

A new class miral::CommandLineOption that allows the developer to add and process command line options. (These can also be supplied via environment variables or config files in the same way as other options.)

A bunch of functions for managing Applications:

void apply_lifecycle_state_to(Application const& application, MirLifecycleState state);
auto name_of(Application const& application) -> std::string;
auto pid_of(Application const& application) -> pid_t;

Add miral::WindowManagerTools::force_close(Window const& window) to forcefully close a window (i.e. without a close request to the client)

Read more
Alan Griffiths

Miral on Dragonboard

Miral on Dragonboard

Having seen Kevin Gunn’s post on the mir-kiosk I thought I’d give it a try.  This is what I found.

Preliminaries

First, I dug out the Dragonboard I’d been testing Mir on a few months ago from a drawer and borrowed the Logitech k400r keyboard I use in my “den”. (This is convenient there because it provides both keyboard and mouse input from one device I can use from my lap.)

There was still a micro SD card in the board, so I extracted that and inserted it via a micro SD adapter into my desktop. Then I downloaded the dragonboard image from the link in Kevin’s article, verified the checksum and discovered that “Disk Image Writer” was the default app for opening the file. That sounded promising, so I opened the file with it, selected the SD card and started writing the image.

While that was going on I found an HDMI/VGA adapter and an old monitor to connect to the Dragonboard and started checking how to install from the SD. The main thing was to get the boot switches on the back of the board into 0110 positions (which means it will boot from the micro SD card).

With all that ready I went to brew tea while “Disk Image Writer” continued reporting progress.

It boots!

Returning with my tea I found that the image was written, so I disconnected the card and put it into the Dragonboard and connected the power.

I was greeted by a blank screen.

After a bit of experimentation I found that I need to connect to a real HDMI monitor during boot, but can switch to the adapter+VGA monitor after that. Annoying, but it works. (As I’m not yet sure where the fault lies I won’t mention the brands.)

Setup is a few simple questions, the only annoyance I had was that the keyboard layout defaults to US which makes typing my network password “interesting” on a UK keyboard.

One thing that could be a trap is that it asked for my email address to connect to the snap store. I’ve never been there before but I took a punt and used my canonical email address. That seemed to work and pick up the credentials on Launchpad.

That meant I could ssh into the Dragonboard from my desktop.

Installing miral-kiosk

Installing the mir libraries and the miral kiosk looks really easy using the commands Kevin provides (in the ssh session):

$ sudo snap install mir-libs --channel=edge --devmode
error: cannot perform the following tasks:
- Download snap "mir-libs" (3) from channel "edge" (unexpected EOF)

Actually, before that message was shown I got one estimating the download time at over an hour! Try again…

$ sudo snap install mir-libs --channel=edge --devmode
mir-libs (edge) 0.1 from 'albaguirre' installed

That’s better! (And only took a few seconds.)

$ sudo snap install mir-kiosk --channel=edge --devmode
mir-kiosk (edge) 0.1 from 'albaguirre' installed

Wow, I see the orange miral-kiosk startup “splash” and a mouse pointer! miral-kiosk is running on the Dragonboard.

A Client Application

To get a client application kg’s blog continues with the instructions:

“Download the appropriate architecture of the mir-client snap and then copy that over to your running ubuntu-core image. “

In this case we’re arm64, so I followed the link and picked out mir-client_0.24.1_arm64.snap. And then copied it to the dragonboard (back to a desktop terminal session):

$ scp Downloads/mir-client_0.24.1_arm64.snap alan-griffiths@192.168.1.159:~
mir-client_0.24.1_arm64.snap 100% 103MB 173.7KB/s 10:05

That took an unexpectedly long time. Back to ssh session:

$ sudo snap install mir-client_0.24.1_arm64.snap --channel=edge --devmode 
mir-client 0.24.1 installed

And there it is – kg’s sample client application running on miral-kiosk.

Read more
Alan Griffiths

MirAL-0.2

There’s a new MirAL release (0.2.0) available in Yakkety. MirAL is a project aimed at simplifying the development of Mir servers and particularly providing a stable ABI and sensible default behaviors.

Unsurprisingly, given the project’s original goal, the ABI is unchanged. The changes in 0.2.0 fall into four categories:

  1. additional features for shell developers to use;
  2. enabling features available in newer Mir versions,
  3. improvements to the example server; and,
  4. bugfixes.

Additional Features for Shell Developers to use

There is a new “–window-management-trace” option for debugging window management. This provides detailed logging of the calls to and from the window management policy.

There is a new miral::CursorTheme class to load cursor themes.

Features available in newer Mir versions

Pointer confinement is now available (where underlying Mir version >= 0.24)
Enhanced “surface placement” handling and the results of “surface placement” requests are notified to clients (where supported by underlying Mir version >= 0.25).

Improvements to the Example Server

Improved resizing of size-constrained windows in miral-shell example.

Bugfixes

#1621917 tests fail when built against lp:mir

#1626659 Dialogs with parents should be modal i.e. they receive focus when the parent is clicked

#1628482 Deadlock in default window manager when Ctrl+Alt+Backspace with a client connected

#1590099 Need to support pointer confinement in Mir and toolkits using Mir

#1616818 User can drag menus (and other inappropriate) surfaces

#1628033 Starting qtcreator on miral-shell gives an orphan “titlebar”

#1628594 advise_focus_lost() isn’t called when the active window is minimised/hidden

#1628630 miral should not change surface geometry because it got maximized

#1628981 TitlebarWindowManager: sometime the initial display of titlebars doesn’t happen

#1625853 Mouse cursor disappears (or just never changes) when entering the windows of Qt apps

Read more
Alan Griffiths

–window-management-trace

A feature added to the lp:miral trunk yesterday is making life a lot easier for developers working on MirAL based servers, and the toolkit extensions that support Mir. The feature is:

miral-shell --window-management-trace

Actually, the –window-management-trace switch will work with any MirAL base server (so miral-kiosk and egmde support it too).

What this does is cause the server to log every interaction with the window management policy – all the notifications it receives and all the calls it makes to the tools as a result.

This means that it is easy to find out that, for example, a “modal” gtk based dialog window is being created without specifying a parent. (Which is why the behaviour isn’t quite as expected – Mir servers will treat it as non-modal.)

To use this feature before the next MirAL release you do need build it yourself, but this only takes a minute (depending on your kit).It really is the easiest way to see exactly what is going on and why.

Read more
Alan Griffiths

MirAL hits the Yakkety archives

Just a quick note: thanks to the efforts of my colleague Larry Price, libmiral is now available from the yakkety archive.

This means that if you’re running Ubuntu 16.10 you can install MirAL using apt and don’t need to build it yourself. Here’s what’s available:

  • libmiral-dev Developer files for the Mir ABI-stable abstraction layer
  • libmiral1 Display server for Ubuntu – ABI preserving abstraction layer
  • miral-doc API documentation for MirAL
  • miral-examples Display server for Ubuntu – demonstration programs

For example, before building egmde you just need to do this:

$ sudo apt install libmiral-dev

You can also install and run the miral-shell program with:

$ sudo apt install miral-examples
$ miral-shell

If you want to run X11 applications under miral-shell on X11 then you can do that too:

$ sudo apt install xmir
$ miral-shell&
$ Xmir -rootless :1&
$ DISPLAY=:1 gedit

Read more
Alan Griffiths

An Example Mir Desktop Environment

The world of Mir

Mir is a set of libraries supporting the development of display servers, desktop environments, shells and implementing toolkit support for applications running on them.

As part of their “convergence” of computing devices Canonical are committed to providing Mir on a range of platforms including desktops, phones, tablets and “the internet of thing”. You can read about the work to provide it as a “snap” in the “internet of things” on Kevin Gunn’s blog [kg’s blog].

Toolkits and other “client” platforms that have support for Mir include GTK, Qt and SDL – which mean that applications using these can work on Mir. There’s a separate Xmir project to support X11 applications on Mir.

On the driver side of things Mir works with Mesa on desktop-like systems and, using libhybris, on an android based stack on a number of devices. The Mesa support is a work in progress and Ubuntu carries a set of patches to enable it. There are some notes about how to incorporate these on other platforms here: [Enabling Mir EGL]. Work is in progress to upstream Mir support.

The “Mir Abstraction Layer” (MirAL) packages the server-side functionality in a way that makes it easy to use. My previous post[MirAL] introduced MirAL in more detail.

Before we begin

If you want to experiment with this code I suggest using Ubuntu 16.04 or later on desktop for the reasons mentioned above. On an Ubuntu phone you can use the current stable version with this code, but doing development on a phone is a whole other article. On other distributions you likely need to patch Mesa and rebuild toolkits with Mir support enabled.

Having got an Ubuntu desktop you also need to install MirAL, at present this is not available from the Ubuntu archives, so you have to build and install it yourself:

$ sudo apt-get install devscripts equivs bzr
$ bzr branch lp:miral
$ sudo mk-build-deps -i --build-dep miral/debian/control
$ mkdir miral/build
$ cd miral/build
$ cmake ..
$ make
$ sudo make install

egmde [Example Mir Desktop Environment]

To illustrate MirAL I’m going to show what is involved in writing a (very simple) window manager. It runs on desktops, tablets and phones and supports keyboard, mouse and touch input. It will support applications using the GTK and Qt toolkits, SDL applications and (using Xmir) X11 applications.

The full code for this example is available on github:

$ git clone https://github.com/AlanGriffiths/egmde.git

Naturally, the code is likely to evolve, especially if I write a follow-up article but the version presented here is tagged v1.0. Assuming that you’ve MirAL installed as described above you can build it as follows:

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

The example code

A lot of the functionality (default placement of windows, menus etc.) comes with the MirAL library. For this exercise we’ll implement one class and write a main function that injects it into MirAL. The main program looks like this:

int main(int argc, char const* argv[])
{
    miral::MirRunner runner{argc, argv};

    return runner.run_with(
        {
            set_window_managment_policy<ExampleWindowManagerPolicy>()
        });
}

Yes, you’ve guessed it: the class we’ll be implementing is ExampleWindowManagerPolicy. It looks like this:

class ExampleWindowManagerPolicy : public CanonicalWindowManagerPolicy
{
public:
    using CanonicalWindowManagerPolicy::CanonicalWindowManagerPolicy;

    // Switch apps  : Alt+Tab
    // Switch window: Alt+`
    // Close window : Alt-F4
    bool handle_keyboard_event(MirKeyboardEvent const* event) override;

    // Switch apps  : click on the corresponding window
    // Switch window: click on the corresponding window
    // Move window  : Alt-leftmousebutton drag
    // Resize window: Alt-middle_button drag
    bool handle_pointer_event(MirPointerEvent const* event) override;

    // Switch apps  : tap on the corresponding window
    // Switch window: tap on the corresponding window
    // Move window  : three finger drag
    // Resize window: three finger pinch
    bool handle_touch_event(MirTouchEvent const* event) override;

private:
    void pointer_resize(Window const& window, Point cursor, Point old_cursor);
    void resize(WindowInfo& window_info, Point new_pos, Size new_size);

    // State held for move/resize by pointer
    Point old_cursor{};
    bool resizing = false;
    bool is_left_resize = false;
    bool is_top_resize = false;

    // State held for move/resize by touch
    int old_touch_pinch_top = 0;
    int old_touch_pinch_left = 0;
    int old_touch_pinch_width = 0;
    int old_touch_pinch_height = 0;
};

For this simple example the only functionality we’ll be providing is the handling of input events to allow the user to switch between applications and windows and to resize and move windows.

We only need to provide three handle_XXX_event() functions as we’re relying on the default behaviour for everything else. The first of these functions is the simplest:

bool ExampleWindowManagerPolicy::handle_keyboard_event(MirKeyboardEvent const* event)
{
    auto const action = mir_keyboard_event_action(event);
    auto const shift_state = mir_keyboard_event_modifiers(event) & shift_states;

    if (action == mir_keyboard_action_down &&
        shift_state == mir_input_event_modifier_alt)
    {
        switch (mir_keyboard_event_scan_code(event))
        {
        case KEY_F4:
            tools.ask_client_to_close(tools.active_window());
            return true;

        case KEY_TAB:
            tools.focus_next_application();
            return true;

        case KEY_GRAVE:
            tools.focus_next_within_application();
            return true;

        }
    }

    return false;
}

I don’t think this needs a lot of explanation: we select key presses while only the Alt button is pressed and act according to the button pressed.

The other two functions are a bit longer as they need to remember some state in order to interpret mouse or touchpad gestures. There’s in them nothing I consider worth pointing out here and the full code is available on github. There’s not much:

$ wc *
15 28 446 CMakeLists.txt
357 957 10528 egmde.cpp
372 985 10974 total

I have much to compare it with, bit I don’t think 372 lines is bad for a functional window manager.

Running egmde

Once egdme has been built you can run it in two modes: the simplest is the “Mir-on-X” mode:

$ ./egmde

This will produce a rather boring black “Mir-on-X” window. You can attach Mir clients to this:

$ miral-run gnome-system-monitor
$ miral-run gnome-terminal

These will run in the window and make it less boring. You can also have egmde launch them when it starts as follows:

$ ./egmde --startup gnome-terminal:gnome-system-monitor

If you don’t want to run in a window under X11 you can also give egmde access to your hardware directly by running it as root and specifying a “virtual terminal”. But I think it is probably better to use mir_demo_server in “system-compositor” mode to handle the hardware and launch egdme a normal user.

$ sudo apt install mir-demos
$ sudo mir_demo_server --vt 3 --window-manager system-compositor

You’ll find this switches you to vt3, switch back with Ctrl-Alt-F7 and, from another terminal, you can connect egdme to this. (We need the VT switch here as the host mir_demo_server is paused while X11 is in control.)

$ sudo chvt 3&&./egmde --host /tmp/mir_socket --startup gnome-terminal

You don’t have to start the gnome-terminal, but it is convenient as you can launch other applications. For example:

$ mir_demo_client_eglplasma

Conclusion

I hope that the egmde example is enough to spark someone’s interest in MirAL and to provide a starting point for developing something more ambitious.

Much of what has been discussed is a work-in-progress, especially MirAL which I hope to get added to the Ubuntu archives soon. I am optimistic this will happen as it is in the interests of both Canonical and the wider community to have a stable server ABI against which to write desktop environments (including Unity8). Indeed I’ve been working with the main developer of the QtMir abstraction layer to migrate it to MirAL.

Similarly, a significant portion of the work needed on Mesa to support Mir is similar to the work to support Wayland/Weston and everyone would benefit from cleaning this up (and, for example, removing hard dependencies on X11).

Read more
Alan Griffiths

MirAL: Mir is not all about Unity8

Introducing The Mir Abstraction Layer

The principle Open Source project I’ve been working on for the last few years is Mir. Mir is a library for writing Linux display servers and shells that are independent of the underlying graphics stack. It fits into a similar role as an X server or Weston (a Wayland server) but was initially motivated by Canonical’s vision of “convergent” computing.

The Mir project has had some success in meeting Canonical’s immediate needs – it is running in the Ubuntu Touch phones and tablets, and as an experimental option for running the Unity8 shell on the desktop. But because of the concentration of effort on delivering the features needed for this internal use it hasn’t really addressed the needs of potential users outside of Canonical.

Mir provides two APIs for users: the “client” API is for applications that run on Mir and that is largely used by toolkits. There is support for Mir in the GTK and Qt toolkits, and in SDL. This works pretty well and the Mir client API has remained backwards compatible for a couple of years and can do so for the foreseeable future.

The problem is that the server-side ABI compatibility is broken by almost every release of Mir. This isn’t a big problem for Canonical, as the API is fairly stable and both Mir and Unity8 are in rapid development: rebuilding Unity8 every time Mir is released is a small overhead. But for independent developers the lack of a stable ABI is problematic as they cannot easily synchronize their releases to updates of Mir.

My answer to this is to provide a stable “abstraction layer” written over the top of the current Mir server API that will provide a stable ABI. There are a number of other goals that can be addressed at the same time:

  • The API can be considerably narrowed as a lot of things can be customized that are of no interest to shell development;
  • A more declarative design style can be followed than the implementation focused approach that the Mir server API follows; and,
  • Common facilities can be provided that don’t belong in the Mir libraries.

At the time of writing the Mir Abstraction Layer (miral) is a proof-of-concept, but work is in progress to package an initial version that can support the functionality needed by some examples, and by qtmir (the Qt support used by Unity8).

Building and using MirAL

These instructions assume that you’re using Ubuntu 16.04LTS or later, I’ve not tested earlier Ubuntu versions or other distributions.

You’ll need a few development and utility packages installed, along with the Mir development packages:

$ sudo apt-get install cmake g++ make bzr python-pil uuid-dev libglib2.0-dev
$ sudo apt-get install libmirserver-dev libmirclient-dev mirtest-dev
$ sudo apt-get install mir-graphics-drivers-desktop libgles2-mesa-dev

(If you’re working on a phone or tablet use mir-graphics-drivers-android in place of mir-graphics-drivers-desktop.)

With these installed you can checkout and build miral:

$ bzr branch lp:miral
$ mkdir miral/build
$ cd  miral/build
$ cmake ..
$ make

This creates libmiral.so in the lib directory and an example shell (miral-shell) in the bin directory. This can be run directly:

 $ bin/miral-shell

With the default options this runs in a window on X (which is convenient for development).

The miral-shell example is simple, don’t expect to see a sophisticated launcher by default. You can start mir apps from the command-line. For example:

 $ bin/miral-run gnome-terminal

That’s right, a lot of standard GTK+ applications will “just work” (the GDK toolkit has a Mir backend). Any that assume the existence of an X11 and bypass the toolkit by making X11 protocol calls will have problems though.

To exit from miral-shell press Ctrl-Alt-BkSp.

To run independently of X11 you need to grant access to the graphics hardware (by running as root) and specify a VT to run in. For example:

$ sudo bin/miral-shell --vt 4 --arw-file --file $XDG_RUNTIME_DIR/mir_socket

For convenient testing there’s a “testrun” script that wraps this command to start the server (as root) and then launches the gnome-terminal (as the current user):

$ ../scripts/testrun

Running applications on MirAL

If you have a terminal session running in the MirAL desktop (as described above) you can start programs from it. GTK, Qt and SDL applications will “just work” provided that they don’t bypass the toolkit and attempt to make X11 protocol calls that are not available.

$ gedit
$ 7kaa

From outside the MirAL session the “miral-run” script sets a few environment variables to configure the Mir support in the various toolkits. (There’s some special treatment for gnome-terminal as starting that can conflict with the desktop default.)


$ bin/miral-run gnome-calculator
$ bin/miral-run 7kaa

There are also some examples of native Mir client applications in the mir-demos package. These are typically basic graphics demos:

$ sudo apt-get install mir-demos
$ mir_demo_client_egltriangle

Support for X11 applications

If you want to run X11 applications that do not have native Mir support in the toolkit they use then the answer is Xmir: an X11 server that runs on Mir. First you need Xmir installed:

$ sudo apt install xmir

Then you can use the testrun script to start miral-shell with Xmir:

$ ../scripts/testrun -Xmir

This starts an X11 server on DISPLAY=:1. This is set in the terminal the script starts so that applications launched from it will automatically connect to miral through Xmir.

Running Qt applications

To run Qt applications under Mir you may need to install qtubuntu-desktop:

$ sudo apt-get install qtubuntu-desktop

Read more