[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

Reply via email to