Screen Mirroring
Aqueous can mirror one output to another on the same backend/device. The source keeps its resolution, scale, workspace, and refresh rate. The destination fits the complete source image into its own resolution with black bars where needed, including windows, panels, popups, effects, and the cursor.
Configure a mirror
Section titled “Configure a mirror”Find connector names and advertised modes with aqueousctl outputs --json.
Add the relationship to ~/.config/aqueous/outputs.toml:
[[output]]name = "DP-1"enabled = truemode = "2560x1440@240"transform = "normal"hdr = falsemirror_of = ""
[[output]]name = "HDMI-A-1"enabled = truemode = "1920x1080@60"mirror_of = "DP-1"adaptive_sync = falsehdr = falsetransform = "normal"Both displays must use SDR and normal orientation. The source can keep adaptive sync; the destination uses fixed refresh and disallows tearing. Refresh rates do not need to be integer multiples. Aqueous copies frames at destination demand, skips intermediate source updates, and retains the latest complete image when the source is idle.
The settings plugin also offers Extended desktop and Mirror of … choices. Select compatible modes, SDR, and normal orientation before applying the relationship. Mirrors remain in the display selector but are omitted from the arrangement canvas. Position and scale are retained for a later return to extended mode.
Return to an extended desktop
Section titled “Return to an extended desktop”Explicitly clear the relationship in the file that sets it:
[[output]]name = "HDMI-A-1"mirror_of = ""position = [2560, 0]Adjust the position for your source’s logical size after scaling. An omitted
mirror_of inherits policy; an empty string clears it. A value in
outputs.toml takes precedence over wm.toml. Named output profiles accept
the same field.
Status and runtime changes
Section titled “Status and runtime changes”aqueousctl outputs --jsonWith the embedded output service available, each output can report
mirror_of, mirror_status, and mirror_error. Status is starting,
active, waiting_for_source, suspended, error, or extended.
The existing output service accepts
mirror_of in a set request to $XDG_RUNTIME_DIR/aqueous/outputd.sock:
{ "op": "set", "changes": [ { "name": "HDMI-A-1", "mirror_of": "DP-1", "adaptive_sync": false } ]}Use compatible SDR and orientation settings first. Apply responses describe staged changes; the compositor’s output transaction performs the backend commit. Inspect the resulting status to confirm the mirror is active.
Workspace and lock behavior
Section titled “Workspace and lock behavior”A mirror has no independent workspace or pointer area. Existing windows migrate using output-removal policy. Returning to extended mode recreates its workspace space without automatically moving those windows back. Mirrors cannot be layer-shell or input-device mapping targets.
A disconnected or powered-off source leaves the mirror black until a usable source returns. The mirror is also black during session locking and while locked. Cached desktop images are discarded on locking, source changes, and resizing; unlocking waits for fresh source content.
Supported configurations
Section titled “Supported configurations”The first version supports one pair, SDR, normal transforms, and a shared backend/device. Self references, chains, extra pairs, and incompatible settings are rejected. Vulkan requires timeline synchronization support; the diagnostic Pixman build is also supported. HDR mirroring, rotation, cross-device transfer, delay, audio, and wireless transport are outside this version.
