atrium-portal
The xdg-desktop-portal backend that makes screen sharing work: OBS, browsers, Signal, anything that asks the portal for a screen cast.
App → xdg-desktop-portal → atrium-portal → atrium (IPC: StartCast) → PipeWire stream → App
atrium-portal implements org.freedesktop.impl.portal.ScreenCast. It is D-Bus activated when an app first asks, shows a GTK4 picker for the monitor or window, sends StartCast to the compositor over IPC, waits for the pw_node_id on the event stream, and hands that node back to the main portal. Everything else (file chooser, settings, access) is left to xdg-desktop-portal-gtk. There is no Mutter-compatible D-Bus surface anywhere.
Configuration
~/.config/xdg-desktop-portal/portals.conf:
[preferred]
default=gtk
org.freedesktop.impl.portal.ScreenCast=atrium
The compositor’s make install also installs /usr/share/xdg-desktop-portal/atrium-portals.conf, which applies when XDG_CURRENT_DESKTOP=atrium.
The picker floats by rule (match app-id="atrium-portal", in the default config).
Hybrid GPUs
On an Intel plus NVIDIA laptop, Smithay picks the Intel node as primary renderer, so cast buffers carry Intel modifiers while a consumer running with GBM_BACKEND=nvidia-drm asks for NVIDIA ones, and the PipeWire link fails with no common modifier. Fix: tell the compositor to render on the NVIDIA node.
debug {
render-drm-device "/dev/dri/renderD129"
}
Debugging
- Log:
~/.local/state/atrium/atrium-portal.log. - Capabilities should read 3/7, not 0/0:
gdbus call --session --dest=org.freedesktop.portal.Desktop \
--object-path /org/freedesktop/portal/desktop \
--method org.freedesktop.DBus.Properties.GetAll org.freedesktop.portal.ScreenCast
atrium msg castslists the compositor’s active streams.