wlx_monitors
A Rust library for detecting and managing display outputs on Wayland using the wlr-output-management protocol.
What is this?
wlx_monitors provides a safe, idiomatic Rust interface to:
- Detect connected monitors and their properties (resolution, refresh rate, position, scale)
- Monitor for display hotplug events (monitor connected/disconnected)
- Control display outputs (enable/disable, change resolution/refresh rate, scale, and transform/rotation)
Works with wlroots-based Wayland compositors (Sway, Hyprland, River, dwl, etc.) that implement the zwlr_output_manager_v1 protocol.
Quick Start
Add to your Cargo.toml:
[]
= "0.1.8"
Basic usage:
use ;
use mpsc;
Run the included example:
Architecture
This library uses a channel-based event loop pattern:
Events (Wayland → Your App)
The library sends events through an MPSC channel:
WlMonitorEvent::InitialState(Vec<WlMonitor>)- Sent once with all currently connected monitorsWlMonitorEvent::Changed(Box<WlMonitor>)- Sent when a monitor's properties changeWlMonitorEvent::Removed { id, name }- Sent when a monitor is disconnectedWlMonitorEvent::ActionFailed { action, reason }- Sent when an action fails (e.g., invalid mode)
Actions (Your App → Wayland)
Send control actions through another MPSC channel:
WlMonitorAction::Toggle { name, mode, Position }- Enable/disable a monitor by name. Themode: Option<(i32, i32, i32)>lets users optionally specify a custom(width, height, refresh_rate)when toggling a monitor back on. IfNone, the smart mode resolution kicks in (last mode > preferred > first available). Theposition: Option<(i32, i32)>let's you specify a custom position(pos_x, pos_y)for your monitor when turning it on, IfNoneit will by default to (0,0).WlMonitorAction::SwitchMode { name, width, height, refresh_rate }- Change a monitor's modeWlMonitorAction::SetScale { name, scale }- Set a monitor's scale factor (must be > 0, e.g., 1.0, 1.5, 2.0)WlMonitorAction::SetTransform { name, transform }- Set a monitor's rotation/orientation (Normal, Rotate90, Rotate180, Rotate270, Flipped, etc.)WlMonitorAction::SetPosition { name, x, y }- Set a monitor's position in the global coordinate space
Threading Model
┌─────────────────┐ events ┌──────────────────┐
│ Wayland Server │ ───────────────>│ Your App │
│ (Compositor) │ │ (Main Thread) │
└─────────────────┘ └──────────────────┘
^ │
│ │
│ actions │
└────────────────────────────────────┘
┌─────────────────┐
│ Event Loop │
│ (Separate │
│ Thread) │
└─────────────────┘
API Overview
Core Types
WlMonitorManager- Main entry point. Manages the Wayland connection and event loop.WlMonitor- Represents a connected display with properties (name, resolution, modes, etc.)WlMonitorMode- A display mode (resolution + refresh rate)WlResolution/WlPosition- Basic geometry types
Events
Actions
Monitor Properties
Each WlMonitor provides:
| Property | Type | Description |
|---|---|---|
name |
String |
Output name (e.g., "DP-1", "HDMI-A-1") |
description |
String |
Human-readable description |
make |
String |
Manufacturer |
model |
String |
Model name |
serial_number |
String |
Serial number |
enabled |
bool |
Currently enabled? |
resolution |
WlResolution |
Current resolution (width, height) |
position |
WlPosition |
Position in global coordinate space |
scale |
f64 |
Scale factor (1.0, 1.5, 2.0, etc.) |
modes |
Vec<WlMonitorMode> |
Available display modes |
transform |
WlTransform |
Orientation (normal, rotated, flipped) |
Requirements
-
Wayland compositor with
zwlr_output_manager_v1support:- ✓ wlroots-based compositors (Sway, Hyprland, River, dwl, Wayfire, etc.)
- ✓ Some other compositors may support this protocol
- ✗ GNOME (uses different protocol)
- ✗ KDE Plasma (uses different protocol)
-
Rust 1.85+ (for Edition 2024)
Building
# Clone the repository
# Build
# Run example
Example: Controlling Monitors
use ;
use mpsc;
use thread;
Troubleshooting
"Failed to connect to Wayland"
Make sure you're running on a Wayland session:
# Should output something like "wayland-1"
"Compositor rejected the configuration"
The compositor may not support the requested mode or the monitor doesn't support the requested resolution/refresh rate.
Protocol References
License
This project is licensed under the MIT License - see the LICENSE file for details.
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.