lamco-portal
High-level Rust interface to XDG Desktop Portal for Wayland screen capture and input control.
Features
- Screen Capture: Capture monitor or window content through PipeWire streams
- Input Injection: Send keyboard and mouse events to the desktop
- Clipboard Integration: Portal-based clipboard for remote desktop scenarios
- Multi-Monitor: Handle multiple displays simultaneously
- Flexible Configuration: Builder pattern and struct literals
- Typed Errors: Match and handle specific error conditions
Requirements
- Wayland compositor (GNOME, KDE Plasma, Sway, etc.)
xdg-desktop-portalinstalled and running- Portal backend for your compositor:
- GNOME:
xdg-desktop-portal-gnome - KDE:
xdg-desktop-portal-kde - wlroots:
xdg-desktop-portal-wlr
- GNOME:
- PipeWire for video streaming
Quick Start
Add to your Cargo.toml:
[]
= "0.1"
= { = "1", = ["full"] }
Basic usage:
use ;
async
Feature Flags
[]
# Default - basic portal functionality
= "0.1"
# With D-Bus clipboard bridge for GNOME (SelectionOwnerChanged workaround)
= { = "0.1", = ["dbus-clipboard"] }
# With ClipboardSink trait for lamco-clipboard-core integration
= { = "0.1", = ["clipboard-sink"] }
| Feature | Description |
|---|---|
dbus-clipboard |
D-Bus clipboard bridge for GNOME - works around missing SelectionOwnerChanged signals |
clipboard-sink |
ClipboardSink trait implementation for lamco-clipboard-core integration |
Configuration
Customize Portal behavior:
use ;
use CursorMode;
use PersistMode;
let config = builder
.cursor_mode // Embed cursor in video
.persist_mode // Remember permission
.build;
let manager = new.await?;
Error Handling
Handle specific error conditions:
use PortalError;
match manager.create_session.await
Examples
See the examples/ directory for complete examples:
basic.rs- Simple screen capture setupinput.rs- Input injection (keyboard/mouse)clipboard.rs- Clipboard integration
Run examples with:
Platform Support
| Platform | Status | Backend Package |
|---|---|---|
| GNOME (Wayland) | ✅ Supported | xdg-desktop-portal-gnome |
| KDE Plasma (Wayland) | ✅ Supported | xdg-desktop-portal-kde |
| Sway / wlroots | ✅ Supported | xdg-desktop-portal-wlr |
| X11 | ❌ Not Supported | Wayland only |
Security
This library triggers system permission dialogs. Users must explicitly grant:
- Screen capture access (which monitors/windows to share)
- Input injection access (keyboard/mouse control)
- Clipboard access (if using clipboard features)
Permissions can be remembered per-application using PersistMode::Application to skip the dialog on subsequent runs.
Architecture
┌─────────────────┐
│ Your Application│
└────────┬────────┘
│
v
┌─────────────────┐
│ lamco-portal │
│ (this crate) │
└────────┬────────┘
│
v
┌─────────────────┐
│ ashpd │ ← Low-level Portal bindings
└────────┬────────┘
│
v
┌─────────────────┐
│ xdg-desktop- │
│ portal │ ← System Portal service
└────────┬────────┘
│
┌────┴────┬─────────────┐
v v v
┌────────┐┌────────┐ ┌──────────┐
│PipeWire││D-Bus │ │Compositor│
└────────┘└────────┘ └──────────┘
Troubleshooting
"Portal not available" error
Solution: Install xdg-desktop-portal and the appropriate backend:
# Arch Linux
# Ubuntu/Debian
# Fedora
"User denied permission" error
Solution: This is expected behavior when the user clicks "Cancel" in the permission dialog. Handle it gracefully in your application.
No streams available
Causes:
- User denied screen access
- No monitors/windows available to share
- Portal backend not running
Solution: Check that your portal backend is running and try again.
License
Licensed under either of:
- Apache License, Version 2.0 (LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0)
- MIT license (LICENSE-MIT or http://opensource.org/licenses/MIT)
at your option.
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
Related Projects
- ashpd - Low-level Portal bindings
- pipewire-rs - PipeWire bindings
- xdg-desktop-portal - Portal specification