[wl-proxy][wl-proxy] is a rust crate that supports proxying wayland connections
and intercepting and manipulating wayland messages. A detailed description of
the functionality is available in the [documentation][docs-rs].
The proxy application can install handlers for objects in the wayland
connection, starting at the wl_display. These handlers are invoked whenever a
message is sent on the object, in either direction. The proxy can then forward
the message to the peer (this is the default behavior), change the message
arguments, black-hole the message, or send a different set of messages in its
place.
For example, the following wl_display handler intercepts get_registry requests
and installs a handler for the new wl_registry object. This handler could be
used to change the set of advertised globals or to create more handlers for
globals bound by the client.
```rust
impl WlDisplayHandler for TheProxyDisplayHandler {
fn handle_get_registry(&mut self, slf: &Rc<WlDisplay>, registry:
&Rc<WlRegistry>) {
// install a handler for the wl_registry object
registry.set_handler(TheProxyRegistryHandler);
// forward the message to the compositor
slf.send_get_registry(registry);
}
// sync requests are not handled explicitly and are therefore passed through
// to the compositor
}
impl WlRegistryHandler for TheProxyRegistryHandler {
// ...
}
```
Multiple client connections can be proxied over a single compositor connection,
allowing one client to embed the surfaces of another client. wl-proxy was
inspired by [Godot][godot] using a similar technique to embed games into their
editor.
The repository also contains a number of applications written with wl-proxy.
- [wl-veil][wl-veil]: This application can be used to hide globals from clients
or to downgrade their version. For example, OBS contains a bug where it
sometimes crashes if explicit sync is being used. Starting OBS with
$ wl-veil -f wp_linux_drm_syncobj_manager_v1 obs
hides the global from OBS. Similarly, firefox contains a bug where it always
binds to the highest available wp-color-management-v1 version. If this version
is higher than 1, firefox immediately crashes due to unhandled events.
Starting firefox with
$ wl-veil -f wp_color_manager_v1=1 firefox
downgrades the version advertised to firefox to 1.
Other use cases include testing the behavior of applications if accelerated
rendering is not available or if the compositor does not advertise any
wl_output globals.
- [wl-format-filter][wl-format-filter]: This application can be used to hide
formats and modifiers from applications. For example
$ wl-format-filter --allow xrgb8888 --deny all mpv
--vo=dmabuf-wayland video.mkv
tests the behavior of mpv's dmabuf-wayland vo if no YUV formats are available.
- [window-to-tray][window-to-tray]: This application can be used to turn
arbitrary xdg-shell applications into tray applications. The core idea is that
all xdg-shell requests by the client are intercepted and xdg_toplevel objects
created by the client are instead turned into wl_subsurface objects on the
compositor side. These subsurfaces can then later be displayed in tray popups
when the user interacts with the tray icon.
In the following screenshot you can see pavucontrol-qt running as a tray
application: https://files.catbox.moe/4dx3lb.png
- [wl-paper][wl-paper]: This application can be used to turn arbitrary xdg-shell
applications into wlr-layer-shell-v1 applications. The name indicates that
this allows arbitrary applications to be used as wallpapers.
This application hasn't been tested thoroughly.
Each protocol must be supported explicitly in wl-proxy but all protocol code is
generated automatically. I've tried to cast as wide a net as possible since
applications such as wl-veil are most useful if they support every protocol out
there. However, some protocols had to be excluded:
- The entire treeland protocol suite since the developers make incompatible
changes to protocols which would turn into compile errors for users of
wl-proxy if the protocols were updated.
- The unstable versions of some stabilized wayland-protocols protocols since
they contain duplicate interface names and all interface names must be unique
in wl-proxy.
- The entire plasma wayland protocols suite since the protocols and their
interfaces are not namespaced.
- cosmic_workspace_unstable_v1 since it contains an interface that uses the same
name for a request and an event which is incompatible with how wl-proxy
handles both types of messages in a single interface. This can theoretically
be worked around by renaming one of the two messages in wl-proxy if there is
interest in that.
- cosmic_toplevel_info_unstable_v1 and cosmic_toplevel_management_unstable_v1
because they depend on cosmic_workspace_unstable_v1.
wl_registry globals with unsupported interfaces are automatically filtered by
wl-proxy.
[wl-proxy]: https://github.com/mahkoh/wl-proxy
[docs-rs]: https://docs.rs/wl-proxy
[wl-veil]:
https://github.com/mahkoh/wl-proxy/blob/master/apps/wl-veil/src/veil.rs
[wl-format-filter]:
https://github.com/mahkoh/wl-proxy/blob/master/apps/wl-format-filter
[window-to-tray]:
https://github.com/mahkoh/wl-proxy/tree/master/apps/window-to-tray
[wl-paper]: https://github.com/mahkoh/wl-proxy/tree/master/apps/wl-paper
[godot]: https://github.com/godotengine/godot/pull/107435