2019-09-20 22:57:28 +00:00
|
|
|
|
# Sommelier - Nested Wayland compositor with support for X11 forwarding
|
|
|
|
|
|
|
|
|
|
Sommelier is an implementation of a Wayland compositor that delegates
|
|
|
|
|
compositing to a 'host' compositor. Sommelier includes a set of features that
|
|
|
|
|
allows it to run inside a tight jail or virtual machine.
|
|
|
|
|
|
|
|
|
|
Sommelier can run as service or as a wrapper around the execution of a
|
2023-01-26 20:40:13 +00:00
|
|
|
|
program. As a service, called the parent sommelier, it spawns new processes as
|
|
|
|
|
needed to service clients.
|
2019-09-20 22:57:28 +00:00
|
|
|
|
|
|
|
|
|
## Sommeliers
|
|
|
|
|
|
2023-01-26 20:40:13 +00:00
|
|
|
|
### Parent Sommelier
|
2019-09-20 22:57:28 +00:00
|
|
|
|
|
2023-01-26 20:40:13 +00:00
|
|
|
|
The parent sommelier instance will create a wayland socket in XDG_RUNTIME_DIR
|
2019-09-20 22:57:28 +00:00
|
|
|
|
and accept connections from regular wayland clients. Each connection will be
|
|
|
|
|
serviced by spawning a child sommelier process.
|
|
|
|
|
|
|
|
|
|
### X11 Sommelier
|
|
|
|
|
|
|
|
|
|
An X11 sommelier instance provides X11 forwarding. Xwayland is used to
|
|
|
|
|
accomplish this. A single X11 sommelier instance is typically shared across
|
|
|
|
|
all X11 clients as they often expect that they can use a shared X server for
|
|
|
|
|
communication. If the X11 sommelier instance crashes in this setup, it takes
|
|
|
|
|
all running X11 programs down with it. Multiple X11 sommelier instances
|
|
|
|
|
can be used for improved isolation or when per-client configuration is
|
|
|
|
|
needed, but it will be at the cost of losing the ability for programs to use
|
|
|
|
|
the X server for communication between each other.
|
|
|
|
|
|
|
|
|
|
### Peer Sommelier
|
|
|
|
|
|
|
|
|
|
Each Linux program that support the Wayland protocol can have its own sommelier.
|
|
|
|
|
This provides better use of multiple cores when servicing clients, and it
|
|
|
|
|
prevents errors in one client from causing other clients to crash.
|
|
|
|
|
|
|
|
|
|
## Host Compositor Channel
|
|
|
|
|
|
|
|
|
|
Sommelier needs a channel to the host compositor in order to serve Wayland
|
|
|
|
|
clients inside a container. If the container environment provides a socket
|
|
|
|
|
that can be used to establish a connection to the host compositor, then
|
|
|
|
|
pointing sommelier to this socket using the `--display=DISPLAY` flag is
|
|
|
|
|
sufficient.
|
|
|
|
|
|
|
|
|
|
### VirtWL
|
|
|
|
|
|
|
|
|
|
The VirtWL device can be used to establish a new connection when no socket
|
|
|
|
|
is available (typically when running inside a VM). If a VirtWL device has been
|
|
|
|
|
specified (e.g. `--virtwl-device=/dev/wl0`) then sommelier will use this
|
|
|
|
|
mechanism by default to establish new channels between the host compositor and
|
|
|
|
|
sommelier instances. Data is forwarded between the VirtWL device and the core
|
|
|
|
|
Wayland dispatch mechanism using non-blocking I/O multiplexing.
|
|
|
|
|
|
|
|
|
|
## Shared Memory Drivers
|
|
|
|
|
|
|
|
|
|
Shared memory allocated inside a container cannot always be shared with the
|
|
|
|
|
host compositor. Sommelier provides a shared memory driver option as a
|
|
|
|
|
solution for this. What's the most appropriate option depends on the host
|
|
|
|
|
compositor and device drivers available for allocating buffers.
|
|
|
|
|
|
|
|
|
|
### VirtWL
|
|
|
|
|
|
|
|
|
|
The `virtwl` driver creates a set of intermediate virtwl buffers for each
|
|
|
|
|
surface, and copies minimal damaged areas from the client’s standard shared
|
|
|
|
|
memory buffers into the virtwl buffers that can be shared with the host
|
|
|
|
|
compositor.
|
|
|
|
|
|
|
|
|
|
### VirtWL-DMABuf
|
|
|
|
|
|
|
|
|
|
The `virtwl-dmabuf` works the same way as the `virtwl` driver but allocates
|
|
|
|
|
buffers that can be shared with the host compositor using the linux_dmabuf
|
|
|
|
|
protocol. The benefits of using this driver over the basic `virtwl` driver
|
|
|
|
|
are:
|
|
|
|
|
|
|
|
|
|
* Larger set of supported formats (E.g NV12).
|
|
|
|
|
* Host compositor can avoid expensive texture uploads.
|
|
|
|
|
* HW overlays can be used for presentation if support by the host compositor.
|
|
|
|
|
|
|
|
|
|
## Damage Tracking
|
|
|
|
|
|
|
|
|
|
Shared memory drivers that use intermediate buffers require some form of
|
|
|
|
|
damage tracking in order to update intermediate buffers.
|
|
|
|
|
|
|
|
|
|
### Surface Buffer Queue
|
|
|
|
|
|
|
|
|
|
Each client surface in sommelier is associated with a buffer queue. Each
|
|
|
|
|
buffer in the buffer queue has a region (list of rectangles) that describes
|
|
|
|
|
the part of the buffer that is damaged compared to the last frame submitted
|
|
|
|
|
by the client. This provides high precision damage tracking across multiple
|
|
|
|
|
frames. Each new frame from the client adds damage to existing buffers. When
|
|
|
|
|
submitting a frame to the host compositor, the next available buffer is
|
|
|
|
|
dequeued and updated to not contain any damage. This is done by copying
|
|
|
|
|
contents from the current client buffer into the dequeued buffer.
|
|
|
|
|
|
|
|
|
|
The client's buffer is released as soon as this copy operation described above
|
|
|
|
|
is complete and the client can then reuse the shared memory buffer for another
|
|
|
|
|
frame.
|
|
|
|
|
|
|
|
|
|
Note: It is important to release the buffer immediately as clients don’t
|
|
|
|
|
expect it to be held by the compositor for long when using shared memory.
|
|
|
|
|
|
|
|
|
|
### Back Pressure
|
|
|
|
|
|
|
|
|
|
Sommelier doesn’t provide any back pressure for when the client is producing
|
|
|
|
|
contents faster than the host compositor can consume it. The size of the
|
|
|
|
|
buffer queue can as a result grow large. This is not a problem as Xwayland
|
|
|
|
|
and other clients handle back pressure themselves using Wayland frame
|
|
|
|
|
callbacks or similar mechanism.
|
|
|
|
|
|
|
|
|
|
## Data Drivers
|
|
|
|
|
|
|
|
|
|
Socket pairs created inside a container cannot always be shared with the
|
|
|
|
|
host compositor. Sommelier provides a data driver option as a solution
|
|
|
|
|
for this.
|
|
|
|
|
|
|
|
|
|
### VirtWL
|
|
|
|
|
|
|
|
|
|
The `virtwl` driver creates a special pipe that can be shared with the host
|
|
|
|
|
compositor and forwards all data received over this pipe to the client FD.
|
|
|
|
|
Forwarding is done using non-blocking I/O multiplexing.
|
|
|
|
|
|
|
|
|
|
## Flags and Settings
|
|
|
|
|
|
|
|
|
|
Sommelier has two forms of configuration. Command line flags and environment
|
|
|
|
|
variables. Standard practice is to expose each option both as a command line
|
|
|
|
|
flag and as an environment variable. Command line flags will always override
|
|
|
|
|
the configuration provided by environment variables. This makes it easy to
|
|
|
|
|
run sommelier as a systemd service and allow the system-wide configuration
|
|
|
|
|
to be overridden using a local user provided systemd override file.
|
|
|
|
|
|
|
|
|
|
## Density and Scaling
|
|
|
|
|
|
|
|
|
|
A protocol aware proxy compositor between the client and the host compositor
|
|
|
|
|
makes it easier to support Linux programs that lack good HiDPI support.
|
|
|
|
|
It can also be used to adjust the scale of contents to support the dynamic
|
|
|
|
|
density changes that Chrome OS UI provide, and it gives the user an option
|
|
|
|
|
override any density decisions made by the host compositor. For example,
|
|
|
|
|
HiDPI aware programs can run at native display resolution, while some older
|
|
|
|
|
programs can use half of that resolution.
|
|
|
|
|
|
|
|
|
|
### Contents Scaling
|
|
|
|
|
|
|
|
|
|
Contents scaling can be applied to both native wayland clients and X11
|
|
|
|
|
clients. It can be controlled using the `--scale=SCALE` flag or
|
|
|
|
|
`SOMMELIER_SCALE=SCALE` variable. Where `SCALE` is a display density
|
|
|
|
|
multiplier. For example, if the default density is 200 DPI, then using
|
|
|
|
|
`--scale=0.5` will result in contents produced for 100 DPI.
|
|
|
|
|
|
|
|
|
|
### Scale Factor
|
|
|
|
|
|
|
|
|
|
An optimal scale factor is calculated for Wayland clients based on contents
|
|
|
|
|
scale setting and the current host compositor scaling. This allows Wayland
|
|
|
|
|
clients to produce contents at an optimal resolution for all combinations of
|
|
|
|
|
scaling used by sommelier and the host compositor.
|
|
|
|
|
|
|
|
|
|
### DPI
|
|
|
|
|
|
|
|
|
|
An exact value for DPI is calculated by sommelier. However, many Linux
|
|
|
|
|
programs expect DPI to be one out of a well known set of values. Sommelier
|
|
|
|
|
solves this by adjusting DPI using a set of buckets. For example, given the
|
2023-01-26 20:40:13 +00:00
|
|
|
|
set of buckets (72, 96, 160, 240), Sommelier will use 96 as DPI when the
|
|
|
|
|
exact value is 112, or 160 when exact value is 188. The DPI buckets that
|
2019-09-20 22:57:28 +00:00
|
|
|
|
sommelier should use can be specified with `--dpi=[DPI[,DPI...]]`. Where,
|
2023-01-26 20:40:13 +00:00
|
|
|
|
`--dpi=””` will result in sommelier exposing the exact DPI value to clients
|
|
|
|
|
(this is the default behaviour).
|
2019-09-20 22:57:28 +00:00
|
|
|
|
|
|
|
|
|
### XCursor
|
|
|
|
|
|
|
|
|
|
Sommelier will set `XCURSOR_SIZE` environment variable automatically based on
|
|
|
|
|
the contents scale and preferred host compositor scale factor.
|
|
|
|
|
|
|
|
|
|
## Accelerators
|
|
|
|
|
|
|
|
|
|
If the host compositor support dynamic handling of keyboard events, then
|
|
|
|
|
keyboard shortcuts are forwarded to the Linux program by default. A small set
|
|
|
|
|
of shortcuts are expected to be reserved by the host compositor. A list of
|
|
|
|
|
reserved shortcuts on Chrome OS can be found
|
2023-01-26 20:40:13 +00:00
|
|
|
|
[here](https://chromium.googlesource.com/chromium/src/+/HEAD/ash/accelerators/accelerator_table.h#22).
|
2019-09-20 22:57:28 +00:00
|
|
|
|
|
|
|
|
|
There’s unfortunately no reliable way to detect if a Linux program handled a
|
|
|
|
|
key event or not. This means that all non-reserved shortcuts that the user
|
|
|
|
|
want the host compositor to handle needs to be explicitly listed as an
|
|
|
|
|
accelerator. For example, on Chrome OS, the launcher can be brought up using
|
|
|
|
|
the "launcher" button during normal usage. The "launcher" button event is
|
|
|
|
|
forwarded to Linux programs by default so it won’t work when a Linux program
|
|
|
|
|
has keyboard focus unless this shortcut is explicitly listed as an accelerator.
|
|
|
|
|
|
2023-01-26 20:40:13 +00:00
|
|
|
|
Sommelier provides the `--accelerators=ACCELERATORS` flag for this purpose.
|
2019-09-20 22:57:28 +00:00
|
|
|
|
`ACCELERATORS` is a comma separated list of accelerators that shouldn’t be
|
|
|
|
|
forwarded to the Linux program but instead handled by the host compositor.
|
|
|
|
|
Each accelerator can contain a list of modifiers (e.g. `<Control><Alt>`) and
|
|
|
|
|
must be followed by an XKB keysym. The `xev` utility can be used to determine
|
|
|
|
|
what the XKB keysym is for a specific key. Given the launcher button example
|
|
|
|
|
above (which happens to have XKB keysym `Super_L` on the Chromebook Pixel),
|
|
|
|
|
`--accelerators=Super_L` needs to be passed to sommelier for the this button to
|
|
|
|
|
bring up the application launcher when Linux programs have keyboard focus.
|
|
|
|
|
|
2023-01-26 20:40:13 +00:00
|
|
|
|
There is also the `--windowed-accelerators=WINDOWED_ACCELERATORS` flag for
|
|
|
|
|
accelerators that should be handled by the host compositor when the focused
|
|
|
|
|
window is windowed but not while it is fullscreen.
|
|
|
|
|
|
|
|
|
|
Consistent with other flags, `SOMMELIER_ACCELERATORS` and
|
|
|
|
|
`SOMMELIER_WINDOWED_ACCELERATORS` environment variable can
|
2019-09-20 22:57:28 +00:00
|
|
|
|
be used as an alternative to the command line flag.
|
|
|
|
|
|
|
|
|
|
## Examples
|
|
|
|
|
|
2023-01-26 20:40:13 +00:00
|
|
|
|
Start parent sommelier and use wayland-1 as name of socket to listen on:
|
2019-09-20 22:57:28 +00:00
|
|
|
|
|
|
|
|
|
```
|
2023-01-26 20:40:13 +00:00
|
|
|
|
sommelier --parent --socket=wayland-1
|
2019-09-20 22:57:28 +00:00
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
Start sommelier that runs weston-terminal with density scale multiplier 1.5:
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
sommelier --scale=1.5 weston-terminal
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
Start sommelier that runs inkscape with density scale multiplier 0.75 and 120
|
|
|
|
|
dots per inch (note that -X is specified as inkscape is an X11 client and
|
|
|
|
|
requires X11 forwarding):
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
sommelier -X --scale=0.75 --dpi=120 inkscape
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
Start sommelier that runs gedit with some accelerators reserved to the host
|
|
|
|
|
compositor instead of being sent to gedit:
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
sommelier --accelerators="<Alt>Bracketright,<Alt>Bracketleft" gedit
|
|
|
|
|
```
|