Open Source › Lamco Wayland › Portal
lamco-portal
High-level XDG Desktop Portal bindings for Wayland screen capture and input control
The sanctioned Wayland capture path
Wayland intentionally has no equivalent of XShmGetImage — capturing another surface requires going through the xdg-desktop-portal, which prompts the user for consent and returns a PipeWire file descriptor. lamco-portal is a thin, async-first Rust layer over that flow: you get a PortalManager, request a session, and the user’s compositor handles the permission dialog.
What’s inside
Monitor or window content via PipeWire streams
Keyboard and mouse events into the user’s session
Portal-based clipboard for remote desktop scenarios
Multiple displays handled simultaneously
Builder pattern or struct-literal style
Match and handle specific failure conditions
Quick start
[dependencies]
lamco-portal = "0.4"
tokio = { version = "1", features = ["full"] }
use lamco_portal::{PortalManager, PortalConfig};
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
// Create portal manager with default config
let manager = PortalManager::with_default().await?;
// Create session (triggers permission dialog on the compositor)
let session = manager.create_session("my-session".to_string(), None).await?;
// Access PipeWire FD for video capture
let fd = session.pipewire_fd();
let streams = session.streams();
println!("Capturing {} streams on PipeWire FD {}", streams.len(), fd);
// Inject mouse movement
manager.remote_desktop()
.notify_pointer_motion_absolute(
session.ashpd_session(),
0, // stream index
100.0, // x position
200.0, // y position
)
.await?;
Ok(())
}
Feature flags
| Feature | Description |
|---|---|
| (default) | Basic portal functionality — screencast, remote desktop, clipboard |
| dbus-clipboard | D-Bus clipboard bridge for GNOME (works around missing SelectionOwnerChanged signals) |
| clipboard-sink | ClipboardSink trait implementation for lamco-clipboard-core integration |