Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/akvadrako/sommelier

A fork of Chromium's wayland proxy to allow HiDPI X11 clients in swaywm
https://github.com/akvadrako/sommelier

Last synced: 16 days ago
JSON representation

A fork of Chromium's wayland proxy to allow HiDPI X11 clients in swaywm

Awesome Lists containing this project

README

        

# Notes for this Fork

This runs a nested Wayland compositor that presents unscaled pixels to a new XWayland instance. Programs run under this X session look sharp. You can use it to achive per-app scaling with both X11 and native wayland clients.

## To build

sudo apt install -y pkg-config git make xwayland libwayland-dev libgbm-dev gcc libx11-xcb-dev \
libsystemd-dev libxcb-composite0-dev libxkbcommon-dev libxrender-dev libxtst-dev libpixman-1-dev libdrm-dev

meson out
cd out
ninja
meson install

## Usage Examples

per-app scaling with GTK:

GDK_BACKEND=x11 GDK_SCALE=2 sommelier -X --scale=2 gedit -s --gdk-debug=misc

shared X server:

sommelier -X --scale=2 --x-display=2 --no-exit-with-child true
export DISPLAY=:2

intellij-idea-ultimate

## Issues

vs-code:

GDK_SCALE=2 sommelier -X --scale=2 code -w

error: zxdg_surface_v6@35: error 3: xdg_surface has never been configured

## References

- [virtwl.h source](https://chromium.googlesource.com/chromiumos/overlays/chromiumos-overlay/+/refs/heads/master/sys-kernel/linux-headers/files/0010-virtwl-add-virtwl-driver.patch)
- [upstream source](https://chromium.googlesource.com/chromiumos/platform2/+/master/vm_tools/sommelier/)

Original readme follows:

# 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
program. As a service, it spawns new processes as needed to service clients.
The parent process is called the master sommelier.

## Sommeliers

### Master Sommelier

The master sommelier instance will create a wayland socket in XDG_RUNTIME_DIR
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.

### Noop

The `noop` shared memory driver simply forwards buffers to the host without
any special processing. This requires that the client inside the container is
using memory that can be shared with the host compositor.

### 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.

### DMABuf

The `dmabuf` driver is similar to the `virtwl-dmabuf` driver. It creates a set
of intermediate buffers for each surface and copies minimal damaged areas from
the client’s standard shared memory buffer into the DMABuf buffer. However,
the buffer is allocated using a DRM device and a prime FD is used to access
buffer memory inside the container. Intermediate buffers are shared with the
host compositor using the linux_dmabuf protocol.

## 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.

### Noop

The `noop` driver simply forwards socket pair FDs to the host without any
special processing. This requires that the client inside the container is
using socket pairs that can be shared with the host compositor.

### 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
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
sommelier should use can be specified with `--dpi=[DPI[,DPI...]]`. Where,
`--dpi=””` will result in sommelier exposing the exact DPI value to clients
(this is the default behaviour).

### 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
[here](https://chromium.googlesource.com/chromium/src/+/master/ash/accelerators/accelerator_table.h#22).

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.

Sommelier provides the `--accelerator=ACCELERATORS` flag for this purpose.
`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. ``) 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.

Consistent with other flags, `SOMMELIER_ACCELERATORS` environment variable can
be used as an alternative to the command line flag.

## Examples

Start master sommelier and use wayland-1 as name of socket to listen on:

```
sommelier --master --socket=wayland-1
```

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="Bracketright,Bracketleft" gedit
```