Miriway - bringing Wayland to your desktop

Disclaimer

This is a post about a “side project” of mine, not something sponsored by Canonical. It is based on, and is an update, to a talk of the same name I gave at the Ubuntu Summit 2023.

Introduction

I am the team lead for Canonical “Mir team”, an Englishman with a hobby of walking up hill, another hobby of developing software and drinker of English beers.

Last year I was on holiday in Yorkshire (known for both hills and beers) and one day the weather was hot and my wife suggested it would be better not to climb any hills. She was right (of course) and I decided to “scratch an itch” and see how far I could get in building a “desktop environment” based on Mir.


(You’ll see there’s beer involved too!)

The result was Miriway, and I was so pleased with the results I’ve been improving it since.

Why Miriway matters to you

If you’re interested in creating or maintaining Linux desktop environments it may be significant to you too.

Wayland as a replacement for X11 has “been coming” for a long time, but it is finally the default on major distros such as Ubuntu and Fedora and X11 is set to be dropped from Fedora.

Major desktop environments, such as GNOME and KDE already have plans for moving to Wayland, but there are a lot of less well resourced desktops out there.

Miriway is designed in a way that facilitates building a desktop environment based on “shell components” from other projects. (I didn’t and don’t have time nor inclination to write launchers, docks, top/bottom bars, wallpaper, screen locks, etc.)

Testing Miriway out

If you are running Ubuntu (or any system where snaps are available) it is very easy to try Miriway out.

You can, of course, run Miriway directly on your computer (just snap install miriway --classic and select “Miriway” at the login screen), but I’m going to describe how to experiment in a virtual machine [VM].

Multipass is a widely used tool for managing virtual machines. It is very easy to try Miriway out in a Multipass VM and test Miriway’s integration with “shell components” from other projects.

If you have a launchpad ID, then you can use a script I have prepared and uses ssh, gvncviewer, multipass and frame-it to set up a VM in which it is safe and easy to experiment with Miriway. So, to install these and download the script:

sudo apt install openssh-client gvncviewer
sudo snap install multipass
sudo snap install frame-it --classic
git clone --depth 1 https://github.com/Miriway/Miriway-dev-scripts.git

You can run the script as follows:

Miriway-dev-scripts/multipass-miriway

The script sets up (or starts up if it has been run before) a VM and installs a minimal test environment with Miriway together with the ubuntu-frame-vnc snap to provide a VNC server. We will then use frame-it.vnc to tunnel the VNC connection over ssh. The setup script is listed at the end of this post if you prefer not to use it from github, or which to create your own varient.

Once the script completes successfully you should see messages like the following:

To start server : ssh 10.99.82.181 miriway.vnc-server
To access server: frame-it.vnc 10.99.82.181

These are the commands to set up and access the test system from your system. Try it!

Trying alternative “shell components”

If you want to experiment with different “shell components” then you need to install them, and reconfigure Miriway to use them. The configuration is done by ssh'ing into the test VM and updating ~/.config/miriway-shell.config. To give you a start on experimentation, there are some example scripts for configuring components from several desktop environments:

ssh 10.99.82.181
...
$ find /snap/miriway/current/example-configs/
/snap/miriway/current/example-configs/
/snap/miriway/current/example-configs/LXQT.bash
/snap/miriway/current/example-configs/MATE.bash
/snap/miriway/current/example-configs/SWAY.bash
/snap/miriway/current/example-configs/XFCE.bash
/snap/miriway/current/example-configs/alan_g.bash

These scripts are based on limited experimentation: I’d be very happy to see improvments offered by those with more knowledge of the components involved.

Running one of scripts will set up Miriway with some of the components from the respective environments. For example:

$ /snap/miriway/current/example-configs/XFCE.bash 
Need to install xfce4-terminal
Need to install xfce4-appfinder
WARNING Overwriting /home/alan/.config/miriway-shell.config
OK to proceed? [y/n] 

If you now run the Miriway.vnc-server and connect via frame-it.vnc ... from your desktop you will see the updated display.

Configuring Miriway for your own desktop environment

As indicated above, when running the script, you’ll see a customised ~/.config/miriway-shell.config. In this case:

$ cat ~/.config/miriway-shell.config 
x11-window-title=Miriway
idle-timeout=600
app-env-amend=XDG_SESSION_TYPE=wayland:GTK_USE_PORTAL=0:XDG_CURRENT_DESKTOP=Miriway:GTK_A11Y=none
shell-component=dbus-update-activation-environment --systemd DISPLAY WAYLAND_DISPLAY XDG_SESSION_TYPE XDG_CURRENT_DESKTOP

shell-component=miriway-unsnap swaybg --mode fill --output '*' --image '/usr/share/backgrounds/warty-final-ubuntu.png'
shell-meta=a:miriway-unsnap xfce4-appfinder --disable-server
ctrl-alt=t:miriway-unsnap xfce4-terminal

meta=Left:@dock-left
meta=Right:@dock-right
meta=Space:@toggle-maximized
meta=Home:@workspace-begin
meta=End:@workspace-end
meta=Page_Up:@workspace-up
meta=Page_Down:@workspace-down
ctrl-alt=BackSpace:@exit

This is a standard <key>=<value> configuration file.

The keys to customise for running different commands are shell-component=, shell-meta=, shell-ctrl-alt=, meta= and ctrl-alt=. Each of them takes a command to run (or an “@” command to the window manager). The keys prefixed with shell- run the command with access to “shell” Wayland extensions, the others with only “app” Wayland extensions.

The commands specified by shell-component= run when Miriway starts, the others specify a key and run the command when the corresponding key combination is pressed.

Wayland extensions for “shell components” and “apps”

Miriway is designed to grant access to additional Wayland extensions for applications identified as being part of the shell.

By default, all applications have access to xdg-shell, text_input_v{1,2,3}, output_v1, wl-shell and xdg_shell_v6 and “shell components” also have access to layer_shell_v1 and foreign_toplevel_v1. These latter allow the placement of docs, toolbars, backgrounds, etc. and the tracking of running apps by launchers.

This is configurable, and it is possible to allow any of the following: session_lock_v1, screencopy_v1, virtual_pointer_v1, idle_inhibit_v1, input_method_v2, input_method_v1, input_panel_v1, pointer_constraints_v1, primary_selection_v1, relative_pointer_v1 or virtual_keyboard_v1. So, for example, to enable a swaylock lockscreen:

shell-add-wayland-extension=ext_session_lock_manager_v1
shell-ctrl-alt=l:miriway-unsnap swaylock -i /usr/share/backgrounds/warty-final-ubuntu.png

Miriway features

Working now

  • “Floating” window management
  • Workspaces
  • Configurable keybindings
    • Launching apps
    • Docking left & right
    • Switching workspace
  • Wayland extensions supported by Mir
    • Some configured as for all apps
    • Some configured for “shell-components” only
  • OSK (e.g. maliit & squeekboard)
  • Remote desktop (e.g. wayvnc)
  • Hybrid graphics (Intel, AMD, Nvidia)

Missing features

  • No animations or transitions: Mir doesn’t (yet) have a good API
  • No integration with assistive technologies
  • No integration with portals

Why use Miriway?

Miriway itself is a small (800 lines of code) Wayland compositor built using Mir. Mir is much bigger (100,000 lines of code), but as it is supported by Canonical as part of commercial offerings such as Ubuntu Frame there are resources committed to maintaining it.

Miriway is being used by the Mir team to showcase, test and “dogfood” Mir. This means we are noticing and fixing bugs in Mir that affect its use in Miriway.

It is possible to use Miriway “as is”, contribute to it (it is GPL3, with no CLA), or fork it. (I would welcome contributions that make it better.) For example, The Mir APIs used by Miriway are intended to make customization of window management easy (there is a “proof of concept” tiling window manager in the Mir “examples” code that could be easily improved on and integrated as an option into Miriway).

While it is convenient to use Miriway as a snap package, it can also be built, installed and run from source. (I am aware there is also Nix packaging.)


Notes

Here’s the multipass-miriway script:

#!/bin/bash -e

if [ $# -gt 0 ]; then
  container_name="miriway-${1/./-}"
else
  container_name=miriway-23-10
fi

if ! multipass start "${container_name}"; then

username=${USER}

echo "* To create a miriway test instance we want to set up ssh, To do this we *"
echo "* use Launchpad to retrieve your public key.                             *"
echo ""
read -p "Please enter your Launchpad ID: " lpname

multipass launch --name "${container_name}" --disk 10G --cloud-init - "${@:-23.10}" <<EOF
packages:
    - fonts-freefont-ttf
    - fonts-font-awesome
    - gnome-console
    - ubuntu-wallpapers
runcmd:
    - sudo snap install --classic miriway
    - sudo snap install ubuntu-frame-vnc && sudo snap connect ubuntu-frame-vnc:wayland
    - sudo apt install kate
users:
    - name: ${username}
      ssh_import_id: [lp:${lpname}]
      sudo:  ALL=(ALL) NOPASSWD:ALL
      shell: /usr/bin/bash
EOF
fi

if ! command -v ssh > /dev/null
then
  echo "WARNING: You need to install ssh: sudo apt install openssh-client"
fi

if ! command -v gvncviewer > /dev/null
then
  echo "WARNING: You need to install gvncviewer: sudo apt install gvncviewer"
fi

if ! command -v frame-it > /dev/null
then
  echo "WARNING: You need to install frame-it: sudo snap install frame-it --classic"
fi

host_ip=$(multipass info "${container_name}" --format csv | awk -F, '/^'"${container_name}"'/ { print $3 }')
echo "To start server : ssh ${host_ip} miriway.vnc-server"
echo "To access server: frame-it.vnc ${host_ip}"
8 Likes

This is very interesting, and I might ship this in Fedora as something for people to play with…

But I have a couple of questions here:

  • Is there a roadmap for Mir’s support of various Wayland protocols? Based on Wayland.app, there appears to be a lot of protocols missing compared to KWin or even wlroots/Sway.
  • There’s a large ecosystem of little utilities that people use as replacements for their X equivalents that require compositor support. Many of them are mentioned in the “Are We Wayland Yet?” site. Is there a roadmap for making sure those work with Mir?

Overall, this is great work, though!

4 Likes

There’s no published roadmap for Wayland protocols. They get implemented when we are convinced there’s a need. (But “PRs welcome” as always.)

Are there any that you have a specific interest in? I’m able to run everything I use in the course of my usual activities.

Thanks for the link, I wasn’t aware of that site.

3 Likes

Offhand?

  • xdg-decoration for server-side decorations
  • presentation-time for AV sync
  • cursor-shape for… well, setting cursors
  • drm-lease for VR stuff
  • fractional-scale for… fractional scaling clients
  • xdg-foreign
  • Various wlr-* protocols to enable little utilities that rely on them
1 Like

I don’t think any Wayland compositor commits to delivering each and every Wayland extension: they each prioritise what matters to their users. Mir isn’t different in this and Canonical’s contribution is clearly influenced by Canonical’s interests. (But there are other contributors and contributions are welcome.)

But thank you for your list, it is interesting as an outside perspective and hasn’t been ignored. It is worth noting however, that there are some unstated dependencies in there. For example: fractional-scale isn’t useful without wp_viewporter, xdg-foreign isn’t useful without xdg_exporter, xdg-decoration doesn’t provide server-side decorations (just a way for the server to say they are available, or not).

1 Like

Additionally, one of the biggest problems with the wlroots ecosystem is the lack of a functional xdg-desktop-portal backend. So desktops have two ugly choices:

  • Build using wlroots and having to build xdg-desktop-portal backend for themselves to make up for the poor coverage of xdg-desktop-portal-wlr
  • Build their own compositor from scratch and integrate it into their desktops

This is something that I think Mir could provide a meaningful alternative. A useful agnostic xdg-desktop-portal-mir project that is not confined to the restrictions that wlroots has (and thus implements things that don’t have Wayland protocols but require compositor integration) would make it very attractive. I’m not saying you have to implement all of the portal backend features yourself, but having a basic project and being open to contributions for more protocols would help a lot.

3 Likes