fix(kwin): drive display topology over kde_output_management_v2, not kscreen-doctor

A KDE host on Nobara stopped disabling its physical screens and creating the
virtual output the moment it updated: streaming still came up, but bring-up took
~26 s and the streamed output never became the desktop (`also_disabled=[]`).

Root cause is not our topology logic — it's that every `kscreen-doctor` call on
the reporter's session wedges. kscreen-doctor drives libkscreen, which (per
setup) waits on the kscreen KDED module over D-Bus; when that layer is stuck it
blocks in its own connect and never returns, so all five topology queries hit
their 5 s budget and got killed (host log). Reproduced live on a Nobara / KWin
6.6.4 box: `kscreen-doctor -j` there times out at 8 s, every time.

But the compositor's OWN Wayland is fully responsive on that same session — the
host just created a virtual output over it via zkde_screencast. So drive the
topology (resolve our output, take primary, disable the physical/bootstrap
outputs, capture their modes, re-enable on teardown, position) directly over
`kde_output_management_v2` + `kde_output_device_v2` instead of shelling out.
On that same Nobara box the in-process path binds management (v19) and
enumerates the outputs in 2.4 ms — ~3400x faster than the 8 s hang, and immune
to whatever wedges the standalone tool.

- vendor kde-output-management-v2 / kde-output-device-v2 (KWin advertises mgmt
  v19, device v20); generate client bindings inline (the interdependent-protocol
  module split from the wayland-protocols crate; needs the `bitflags` dep for the
  device protocol's bitfield enums).
- new `kwin_output_mgmt`: bounded enumerate-then-apply over one Wayland
  connection; every wait is time-bounded so a genuinely wedged compositor
  degrades to `handled = false` and the old kscreen-doctor path still runs.
- `kwin::create` topology + `apply_position` prefer the in-process path (address
  our output by its stable device UUID, supersede-robust) with kscreen-doctor as
  the fallback. The 60 Hz path now makes ZERO kscreen-doctor calls; only the
  >60 Hz custom-mode install still shells out (its in-process port is a follow-up).

Verified on Linux: cargo test -p pf-vdisplay (73 pass), clippy --all-targets
-D warnings clean, fmt clean, punktfunk-host checks clean. In-process enumeration
proven live against KWin 6.6.4 (the reporter's env); the disable/apply path is
not yet on-glass.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-07-24 12:47:33 +02:00
co-authored by Claude Opus 4.8
parent a3e21d9227
commit 86d5d66660
7 changed files with 1955 additions and 32 deletions
@@ -0,0 +1,653 @@
<?xml version="1.0" encoding="UTF-8"?>
<protocol name="kde_output_device_v2">
<copyright><![CDATA[
SPDX-FileCopyrightText: 2008-2011 Kristian Høgsberg
SPDX-FileCopyrightText: 2010-2011 Intel Corporation
SPDX-FileCopyrightText: 2012-2013 Collabora, Ltd.
SPDX-FileCopyrightText: 2015 Sebastian Kügler <sebas@kde.org>
SPDX-FileCopyrightText: 2021 Méven Car <meven.car@enioka.com>
SPDX-License-Identifier: MIT-CMU
]]></copyright>
<interface name="kde_output_device_registry_v2" version="24">
<description summary="output devices">
This interface can be used to list output devices.
If this global is bound with a version less than 21, the unsupported_version
protocol error will be posted.
</description>
<enum name="error">
<description summary="kde_output_device_registry_v2 error values">
These errors can be emitted in response to some requests.
</description>
<entry name="unsupported_version" value="0"
summary="the registry was bound with an unsupported version"/>
</enum>
<event name="finished" type="destructor" since="21">
<description summary="no new output announcements">
This event is sent in response to the stop request. The compositor will
immediately destroy the object after sending this event.
</description>
</event>
<request name="stop" since="21">
<description summary="stop receiving updates">
This request indicates that the client no longer wants to receive new
output announcements. The compositor will send the
kde_output_device_registry_v2.finished event in response to this request.
The compositor may still send new output announcements after calling this
request until the kde_output_device_registry_v2.finished event is sent.
</description>
</request>
<event name="output" since="21">
<description summary="new available output">
This event is sent when a new output is connected or after binding this
global to list all available outputs.
</description>
<arg name="output" type="new_id" interface="kde_output_device_v2"/>
</event>
</interface>
<interface name="kde_output_device_v2" version="24">
<description summary="output configuration representation">
An output device describes a display device available to the compositor.
output_device is similar to wl_output, but focuses on output
configuration management.
A client can query all global output_device objects to enlist all
available display devices, even those that may currently not be
represented by the compositor as a wl_output.
The client sends configuration changes to the server through the
outputconfiguration interface, and the server applies the configuration
changes to the hardware and signals changes to the output devices
accordingly.
This object is published as global during start up for every available
display devices, or when one later becomes available, for example by
being hotplugged via a physical connector.
Warning! The protocol described in this file is a desktop environment
implementation detail. Regular clients must not use this protocol.
Backward incompatible changes may be added without bumping the major
version of the extension.
</description>
<enum name="subpixel">
<description summary="subpixel geometry information">
This enumeration describes how the physical pixels on an output are
laid out.
</description>
<entry name="unknown" value="0"/>
<entry name="none" value="1"/>
<entry name="horizontal_rgb" value="2"/>
<entry name="horizontal_bgr" value="3"/>
<entry name="vertical_rgb" value="4"/>
<entry name="vertical_bgr" value="5"/>
</enum>
<enum name="transform">
<description summary="transform from framebuffer to output">
This describes the transform, that a compositor will apply to a
surface to compensate for the rotation or mirroring of an
output device.
The flipped values correspond to an initial flip around a
vertical axis followed by rotation.
The purpose is mainly to allow clients to render accordingly and
tell the compositor, so that for fullscreen surfaces, the
compositor is still able to scan out directly client surfaces.
</description>
<entry name="normal" value="0"/>
<entry name="90" value="1"/>
<entry name="180" value="2"/>
<entry name="270" value="3"/>
<entry name="flipped" value="4"/>
<entry name="flipped_90" value="5"/>
<entry name="flipped_180" value="6"/>
<entry name="flipped_270" value="7"/>
</enum>
<event name="geometry">
<description summary="geometric properties of the output">
The geometry event describes geometric properties of the output.
The event is sent when binding to the output object and whenever
any of the properties change.
</description>
<arg name="x" type="int"
summary="x position within the global compositor space"/>
<arg name="y" type="int"
summary="y position within the global compositor space"/>
<arg name="physical_width" type="int"
summary="width in millimeters of the output"/>
<arg name="physical_height" type="int"
summary="height in millimeters of the output"/>
<arg name="subpixel" type="int"
summary="subpixel orientation of the output"/>
<arg name="make" type="string"
summary="textual description of the manufacturer"/>
<arg name="model" type="string"
summary="textual description of the model"/>
<arg name="transform" type="int"
summary="transform that maps framebuffer to output"/>
</event>
<event name="current_mode">
<description summary="current mode">
This event describes the mode currently in use for this head. It is only
sent if the output is enabled.
</description>
<arg name="mode" type="object" interface="kde_output_device_mode_v2"/>
</event>
<event name="mode">
<description summary="advertise available output modes and current one">
The mode event describes an available mode for the output.
When the client binds to the output_device object, the server sends this
event once for every available mode the output_device can be operated by.
There will always be at least one event sent out on initial binding,
which represents the current mode.
Later if an output changes, its mode event is sent again for the
eventual added modes and lastly the current mode. In other words, the
current mode is always represented by the latest event sent with the current
flag set.
The size of a mode is given in physical hardware units of the output device.
This is not necessarily the same as the output size in the global compositor
space. For instance, the output may be scaled, as described in
kde_output_device_v2.scale, or transformed, as described in
kde_output_device_v2.transform.
</description>
<arg name="mode" type="new_id" interface="kde_output_device_mode_v2"/>
</event>
<event name="done">
<description summary="sent all information about output">
This event is sent after all other properties have been
sent on binding to the output object as well as after any
other output property change have been applied later on.
This allows to see changes to the output properties as atomic,
even if multiple events successively announce them.
</description>
</event>
<event name="scale">
<description summary="output scaling properties">
This event contains scaling geometry information
that is not in the geometry event. It may be sent after
binding the output object or if the output scale changes
later. If it is not sent, the client should assume a
scale of 1.
A scale larger than 1 means that the compositor will
automatically scale surface buffers by this amount
when rendering. This is used for high resolution
displays where applications rendering at the native
resolution would be too small to be legible.
It is intended that scaling aware clients track the
current output of a surface, and if it is on a scaled
output it should use wl_surface.set_buffer_scale with
the scale of the output. That way the compositor can
avoid scaling the surface, and the client can supply
a higher detail image.
</description>
<arg name="factor" type="fixed" summary="scaling factor of output"/>
</event>
<event name="edid">
<description summary="advertise EDID data for the output">
The edid event encapsulates the EDID data for the outputdevice.
The event is sent when binding to the output object. The EDID
data may be empty, in which case this event is sent anyway.
If the EDID information is empty, you can fall back to the name
et al. properties of the outputdevice.
</description>
<arg name="raw" type="string" summary="base64-encoded EDID string"/>
</event>
<event name="enabled">
<description summary="output is enabled or disabled">
The enabled event notifies whether this output is currently
enabled and used for displaying content by the server.
The event is sent when binding to the output object and
whenever later on an output changes its state by becoming
enabled or disabled.
</description>
<arg name="enabled" type="int" summary="output enabled state"/>
</event>
<event name="uuid">
<description summary="A unique id for this outputdevice">
The uuid can be used to identify the output. It's controlled by
the server entirely. The server should make sure the uuid is
persistent across restarts. An empty uuid is considered invalid.
</description>
<arg name="uuid" type="string" summary="output devices ID"/>
</event>
<event name="serial_number">
<description summary="Serial Number">
Serial ID of the monitor, sent on startup before the first done event.
</description>
<arg name="serialNumber" type="string"
summary="textual representation of serial number"/>
</event>
<event name="eisa_id">
<description summary="EISA ID">
EISA ID of the monitor, sent on startup before the first done event.
</description>
<arg name="eisaId" type="string"
summary="textual representation of EISA identifier"/>
</event>
<enum name="capability" bitfield="true">
<description summary="describes capabilities of the outputdevice">
Describes what capabilities this device has.
</description>
<entry name="overscan" value="0x1"
summary="if this output_device can use overscan"/>
<entry name="vrr" value="0x2"
summary="if this outputdevice supports variable refresh rate"/>
<entry name="rgb_range" value="0x4"
summary="if setting the rgb range is possible"/>
<entry name="high_dynamic_range" value="0x8" since="3"
summary="if this outputdevice supports high dynamic range"/>
<entry name="wide_color_gamut" value="0x10" since="3"
summary="if this outputdevice supports a wide color gamut"/>
<entry name="auto_rotate" value="0x20" since="4"
summary="if this outputdevice supports autorotation"/>
<entry name="icc_profile" value="0x40" since="5"
summary="if this outputdevice supports icc profiles"/>
<entry name="brightness" value="0x80" since="9"
summary="if this outputdevice supports the brightness setting"/>
<entry name="built_in_color" value="0x100" since="12"
summary="if this outputdevice supports the built-in color profile"/>
<entry name="ddc_ci" value="0x200" since="14"
summary="if this outputdevice supports DDC/CI"/>
<entry name="max_bits_per_color" value="0x400" since="15"
summary="if this outputdevice supports setting max bpc"/>
<entry name="edr" value="0x800" since="16"
summary="if this outputdevice supports EDR"/>
<entry name="sharpness" value="0x1000" since="17"
summary="if this outputdevice supports the sharpness setting"/>
<entry name="custom_modes" value="0x2000" since="18"
summary="if this outputdevice supports custom modes"/>
<entry name="auto_brightness" value = "0x4000" since="19"/>
<entry name="hdr_icc_profile" value="0x8000" since="22"
summary="if this outputdevice supports HDR ICC profiles"/>
<entry name="abm_level" value="0x10000" since="23"
summary="if this outputdevice supports the abm level setting"/>
</enum>
<event name="capabilities">
<description summary="capability flags">
What capabilities this device has, sent on startup before the first
done event.
</description>
<arg name="flags" type="uint" enum="capability"/>
</event>
<event name="overscan">
<description summary="overscan">
Overscan value of the monitor in percent, sent on startup before the
first done event.
</description>
<arg name="overscan" type="uint"
summary="amount of overscan of the monitor"/>
</event>
<enum name="vrr_policy">
<description summary="describes vrr policy">
Describes when the compositor may employ variable refresh rate
</description>
<entry name="never" value="0"/>
<entry name="always" value="1"/>
<entry name="automatic" value="2"/>
</enum>
<event name="vrr_policy">
<description summary="Variable Refresh Rate Policy">
What policy the compositor will employ regarding its use of variable
refresh rate.
</description>
<arg name="vrr_policy" type="uint" enum="vrr_policy"/>
</event>
<enum name="rgb_range">
<description summary="describes RGB range policy">
Whether full or limited color range should be used
</description>
<entry name="automatic" value="0"/>
<entry name="full" value="1"/>
<entry name="limited" value="2"/>
</enum>
<event name="rgb_range">
<description summary="RGB range">
What rgb range the compositor is using for this output
</description>
<arg name="rgb_range" type="uint" enum="rgb_range"/>
</event>
<event name="name" since="2">
<description summary="Output's name">
Name of the output, it's useful to cross-reference to an zxdg_output_v1 and ultimately QScreen
</description>
<arg name="name" type="string"/>
</event>
<event name="high_dynamic_range" since="3">
<description summary="if HDR is enabled">
Whether or not high dynamic range is enabled for this output
</description>
<arg name="hdr_enabled" type="uint" summary="1 if enabled, 0 if disabled"/>
</event>
<event name="sdr_brightness" since="3">
<description summary="the brightness of sdr if hdr is enabled">
If high dynamic range is used, this value defines the brightness in nits for content
that's in standard dynamic range format. Note that while the value is in nits, that
doesn't necessarily translate to the same brightness on the screen.
</description>
<arg name="sdr_brightness" type="uint"/>
</event>
<event name="wide_color_gamut" since="3">
<description summary="if WCG is enabled">
Whether or not the use of a wide color gamut is enabled for this output
</description>
<arg name="wcg_enabled" type="uint" summary="1 if enabled, 0 if disabled"/>
</event>
<enum name="auto_rotate_policy">
<description summary="describes when auto rotate should be used"/>
<entry name="never" value="0"/>
<entry name="in_tablet_mode" value="1"/>
<entry name="always" value="2"/>
</enum>
<event name="auto_rotate_policy" since="4">
<description summary="describes when auto rotate is used"/>
<arg name="policy" type="uint" enum="auto_rotate_policy"/>
</event>
<event name="icc_profile_path" since="5">
<description summary="describes the path to the ICC profile used in SDR mode"/>
<arg name="profile_path" type="string"/>
</event>
<event name="brightness_metadata" since="6">
<description summary="metadata about the screen's brightness limits"/>
<arg name="max_peak_brightness" type="uint" summary="in nits"/>
<arg name="max_frame_average_brightness" type="uint" summary="in nits"/>
<arg name="min_brightness" type="uint" summary="in 0.0001 nits"/>
</event>
<event name="brightness_overrides" since="6">
<description summary="overrides for the screen's brightness limits"/>
<arg name="max_peak_brightness" type="int" summary="-1 for no override, positive values are the brightness in nits"/>
<arg name="max_average_brightness" type="int" summary="-1 for no override, positive values are the brightness in nits"/>
<arg name="min_brightness" type="int" summary="-1 for no override, positive values are the brightness in 0.0001 nits"/>
</event>
<event name="sdr_gamut_wideness" since="6">
<description summary="describes which gamut is assumed for sRGB applications">
This can be used to provide the colors users assume sRGB applications should have based on the
default experience on many modern sRGB screens.
</description>
<arg name="gamut_wideness" type="uint" summary="0 means rec.709 primaries, 10000 means native primaries"/>
</event>
<enum name="color_profile_source" since="7">
<description summary="which source the compositor should use for the color profile on an output"/>
<entry name="sRGB" value="0"/>
<entry name="ICC" value="1"/>
<entry name="EDID" value="2"/>
</enum>
<event name="color_profile_source" since="7">
<description summary="describes which source the compositor uses for the color profile on an output in SDR mode"/>
<arg name="source" type="uint" enum="color_profile_source"/>
</event>
<event name="brightness" since="8">
<description summary="brightness multiplier">
This is the brightness modifier of the output. It doesn't specify
any absolute values, but is merely a multiplier on top of other
brightness values, like sdr_brightness and brightness_metadata.
0 is the minimum brightness (not completely dark) and 10000 is
the maximum brightness.
This is currently only supported / meaningful while HDR is active.
</description>
<arg name="brightness" type="uint" summary="brightness in 0-10000"/>
</event>
<enum name="color_power_tradeoff">
<description summary="tradeoff between power and accuracy">
The compositor can do a lot of things that trade between
performance, power and color accuracy. This setting describes
a high level preference from the user about in which direction
that tradeoff should be made.
</description>
<entry name="efficiency" value="0" summary="prefer efficiency and performance"/>
<entry name="accuracy" value="1" summary="prefer accuracy"/>
</enum>
<event name="color_power_tradeoff" since="10">
<description summary="the preferred color/power tradeoff"/>
<arg name="preference" type="uint" enum="color_power_tradeoff"/>
</event>
<event name="dimming" since="11">
<description summary="dimming multiplier">
This is the dimming multiplier of the output. This is similar to
the brightness setting, except it's meant to be a temporary setting
only, not persistent and may be implemented differently depending
on the display.
0 is the minimum dimming factor (not completely dark) and 10000
means the output is not dimmed.
</description>
<arg name="multiplier" type="uint" summary="multiplier in 0-10000"/>
</event>
<event name="replication_source" since="13">
<description summary="source output for mirroring"/>
<arg name="source" type="string" summary="uuid of the source output"/>
</event>
<event name="ddc_ci_allowed" since="14">
<description summary="if DDC/CI should be used to control brightness etc.">
If the ddc_ci capability is present, this determines if settings
such as brightness, contrast or others should be set using DDC/CI.
</description>
<arg name="allowed" type="uint" summary="1 if allowed, 0 if disabled"/>
</event>
<event name="max_bits_per_color" since="15">
<description summary="override max bpc">
This limits the amount of bits per color that are sent to the display.
</description>
<arg name="max_bpc" type="uint" summary="0 for the default / automatic"/>
</event>
<event name="max_bits_per_color_range" since="15">
<description summary="range of max bits per color value"/>
<arg name="min_value" type="uint" summary="the minimum supported by the driver"/>
<arg name="max_value" type="uint" summary="the maximum supported by the driver"/>
</event>
<event name="automatic_max_bits_per_color_limit" since="15">
<description summary="if and to what value automatic max bpc is limited"/>
<arg name="max_bpc_limit" type="uint"
summary="which value automatic bpc gets limited to. 0 if not limited"/>
</event>
<enum name="edr_policy" since="16">
<description summary="when the compositor may make use of EDR"/>
<entry name="never" value="0"/>
<entry name="always" value="1"/>
</enum>
<event name="edr_policy" since="16">
<description summary="when the compositor may apply EDR">
When EDR is enabled, the compositor may increase the backlight beyond
the user-specified setting, in order to present HDR content on displays
without native HDR support.
This will usually result in better visuals, but also increases battery
usage.
</description>
<arg name="policy" type="uint" enum="edr_policy"/>
</event>
<event name="sharpness" since="17">
<description summary="sharpness strength">
This is the sharpness modifier of the output.
0 is sharpness disabled and 10000 is the maximum sharpness
</description>
<arg name="sharpness" type="uint" summary="sharpness in 0-10000"/>
</event>
<event name="priority" since="18">
<description summary="output priority">
Describes the position of the output in the output order list,
with lower values being earlier in the list. There's no specific
value the list has to start at, this value is only used in sorting
outputs.
Note that the output order protocol is not sufficient for this,
as an output may not be in the output order if it's disabled or
mirroring another screen.
</description>
<arg name="priority" type="uint" summary="priority"/>
</event>
<event name="auto_brightness" since="20">
<description summary="whether or not automatic brightness is enabled"/>
<arg name="enabled" type="uint" summary="1 for enabled, 0 for disabled"/>
</event>
<request name="release" type="destructor" since="21">
<description summary="destroy the output device">
This notifies the compositor that the client no longer wishes to use
the kde_output_device_v2 object.
</description>
</request>
<event name="removed" since="21">
<description summary="the output has been removed">
This event is sent when the output device is disconnected and no new
updates will be sent. The client should call the kde_output_device_v2.release
request after receiving this event.
</description>
</event>
<event name="hdr_icc_profile_path" since="22">
<description summary="describes the path to the ICC profile used in HDR mode"/>
<arg name="profile_path" type="string"/>
</event>
<event name="hdr_color_profile_source" since="22">
<description summary="describes which source the compositor uses for the color profile on an output in HDR mode"/>
<arg name="source" type="uint" enum="color_profile_source"/>
</event>
<event name="abm_level" since="23">
<description summary="allowed level of adaptive backlight modulation">
Adaptive backlight modulation is a feature that reduces the backlight
and increases contrast of colors on the screen to improve power usage.
</description>
<arg name="level" type="uint" summary="0 is off, 4 is the maximum level"/>
</event>
</interface>
<interface name="kde_output_device_mode_v2" version="24">
<description summary="output mode">
This object describes an output mode.
Some heads don't support output modes, in which case modes won't be
advertised.
Properties sent via this interface are applied atomically via the
kde_output_device.done event. No guarantees are made regarding the order
in which properties are sent.
</description>
<event name="size">
<description summary="mode size">
This event describes the mode size. The size is given in physical
hardware units of the output device. This is not necessarily the same as
the output size in the global compositor space. For instance, the output
may be scaled or transformed.
</description>
<arg name="width" type="int" summary="width of the mode in hardware units"/>
<arg name="height" type="int" summary="height of the mode in hardware units"/>
</event>
<event name="refresh">
<description summary="mode refresh rate">
This event describes the mode's fixed vertical refresh rate. It is only
sent if the mode has a fixed refresh rate.
</description>
<arg name="refresh" type="int" summary="vertical refresh rate in mHz"/>
</event>
<event name="preferred">
<description summary="mode is preferred">
This event advertises this mode as preferred.
</description>
</event>
<event name="removed">
<description summary="the mode has been destroyed">
The compositor will destroy the object immediately after sending this
event, so it will become invalid and the client should release any
resources associated with it.
</description>
</event>
<enum name="flags">
<description summary="mode flags"/>
<entry name="custom" value="0x1"/>
<entry name="reduced_blanking" value="0x2" deprecated-since="24"/>
</enum>
<event name="flags" since="19">
<description summary="mode flags">
This event describes the mode's flags.
</description>
<arg name="flags" type="uint" enum="flags"/>
</event>
<event name="cvt" since="24">
<description summary="cvt timings">
This event describes the CVT timings associated with the mode.
If an output mode has no CVT timings, this event will not be sent.
</description>
<arg name="dot_clock" type="uint" summary="pixel clock in kHz"/>
<arg name="hdisplay" type="uint" summary="horizontal display size"/>
<arg name="hsync_start" type="uint" summary="horizontal sync start"/>
<arg name="hsync_end" type="uint" summary="horizontal sync end"/>
<arg name="htotal" type="uint" summary="horizontal total size"/>
<arg name="hskew" type="uint" summary="horizontal skew"/>
<arg name="vdisplay" type="uint" summary="vertical display size"/>
<arg name="vsync_start" type="uint" summary="vertical sync start"/>
<arg name="vsync_end" type="uint" summary="vertical sync end"/>
<arg name="vtotal" type="uint" summary="vertical total size"/>
<arg name="vscan" type="uint" summary="vertical scan"/>
<arg name="flags" type="uint" summary="flags, see DRM_MODE_FLAG_*"/>
</event>
</interface>
</protocol>
@@ -0,0 +1,539 @@
<?xml version="1.0" encoding="UTF-8"?>
<protocol name="kde_output_management_v2">
<copyright><![CDATA[
SPDX-FileCopyrightText: 2008-2011 Kristian Høgsberg
SPDX-FileCopyrightText: 2010-2011 Intel Corporation
SPDX-FileCopyrightText: 2012-2013 Collabora, Ltd.
SPDX-FileCopyrightText: 2015 Sebastian Kügler <sebas@kde.org>
SPDX-FileCopyrightText: 2021 Méven Car <meven.car@enioka.com>
SPDX-FileCopyrightText: 2023 Xaver Hugl <xaver.hugl@kde.org>
SPDX-License-Identifier: MIT-CMU
]]></copyright>
<interface name="kde_output_management_v2" version="22">
<description summary="configuration of server outputs through clients">
This interface enables clients to set properties of output devices for screen
configuration purposes via the server. To this end output devices are referenced
by global kde_output_device_v2 objects.
outputmanagement (wl_global)
--------------------------
request:
* create_configuration -> outputconfiguration (wl_resource)
outputconfiguration (wl_resource)
--------------------------
requests:
* enable(outputdevice, bool)
* mode(outputdevice, mode)
* transformation(outputdevice, flag)
* position(outputdevice, x, y)
* apply
events:
* applied
* failed
The server registers one outputmanagement object as a global object. In order
to configure outputs a client requests create_configuration, which provides a
resource referencing an outputconfiguration for one-time configuration. That
way the server knows which requests belong together and can group them by that.
On the outputconfiguration object the client calls for each output whether the
output should be enabled, which mode should be set (by referencing the mode from
the list of announced modes) and the output's global position. Once all outputs
are configured that way, the client calls apply.
At that point and not earlier the server should try to apply the configuration.
If this succeeds the server emits the applied signal, otherwise the failed
signal, such that the configuring client is noticed about the success of its
configuration request.
Through this design the interface enables atomic output configuration changes if
internally supported by the server.
Warning! The protocol described in this file is a desktop environment implementation
detail. Regular clients must not use this protocol. Backward incompatible
changes may be added without bumping the major version of the extension.
</description>
<request name="create_configuration">
<description summary="provide outputconfiguration object for configuring outputs">
Request an outputconfiguration object through which the client can configure
output devices.
</description>
<arg name="id" type="new_id" interface="kde_output_configuration_v2"/>
</request>
<request name="create_mode_list">
<description summary="create a list of custom modes">
For details, see the description of kde_mode_list_v2 and
kde_output_configuration_v2.set_custom_modes.
</description>
<arg name="id" type="new_id" interface="kde_mode_list_v2"/>
</request>
</interface>
<interface name="kde_output_configuration_v2" version="22">
<description summary="configure single output devices">
outputconfiguration is a client-specific resource that can be used to ask
the server to apply changes to available output devices.
The client receives a list of output devices from the registry. When it wants
to apply new settings, it creates a configuration object from the
outputmanagement global, writes changes through this object's enable, scale,
transform and mode calls. It then asks the server to apply these settings in
an atomic fashion, for example through Linux' DRM interface.
The server signals back whether the new settings have applied successfully
or failed to apply. outputdevice objects are updated after the changes have been
applied to the hardware and before the server side sends the applied event.
</description>
<enum name="error">
<description summary="kde_output_configuration_v2 error values">
These error can be emitted in response to kde_output_configuration_v2 requests.
</description>
<entry name="already_applied" value="0" summary="the config is already applied"/>
</enum>
<request name="enable">
<description summary="enable or disable an output">
Mark the output as enabled or disabled.
</description>
<arg name="outputdevice" type="object" interface="kde_output_device_v2" summary="outputdevice to be en- or disabled"/>
<arg name="enable" type="int" summary="1 to enable or 0 to disable this output"/>
</request>
<request name="mode">
<description summary="switch output-device to mode">
Sets the mode for a given output.
</description>
<arg name="outputdevice" type="object" interface="kde_output_device_v2" summary="outputdevice this mode change applies to"/>
<arg name="mode" type="object" interface="kde_output_device_mode_v2" summary="the mode to apply"/>
</request>
<request name="transform">
<description summary="transform output-device">
Sets the transformation for a given output.
</description>
<arg name="outputdevice" type="object" interface="kde_output_device_v2" summary="outputdevice this transformation change applies to"/>
<arg name="transform" type="int" summary="transform enum"/>
</request>
<request name="position">
<description summary="position output in global space">
Sets the position for this output device. (x,y) describe the top-left corner
of the output in global space, whereby the origin (0,0) of the global space
has to be aligned with the top-left corner of the most left and in case this
does not define a single one the top output.
There may be no gaps or overlaps between outputs, i.e. the outputs are
stacked horizontally, vertically, or both on each other.
</description>
<arg name="outputdevice" type="object" interface="kde_output_device_v2" summary="outputdevice this position applies to"/>
<arg name="x" type="int" summary="position on the x-axis"/>
<arg name="y" type="int" summary="position on the y-axis"/>
</request>
<request name="scale">
<description summary="set scaling factor of this output">
Sets the scaling factor for this output device.
</description>
<arg name="outputdevice" type="object" interface="kde_output_device_v2" summary="outputdevice this scale change applies to"/>
<arg name="scale" type="fixed" summary="scaling factor"/>
</request>
<request name="apply">
<description summary="apply configuration changes to all output devices">
Asks the server to apply property changes requested through this outputconfiguration
object to all outputs on the server side.
The output configuration can be applied only once. The already_applied protocol error
will be posted if the apply request is called the second time.
</description>
</request>
<event name="applied">
<description summary="configuration changes have been applied">
Sent after the server has successfully applied the changes.
.
</description>
</event>
<event name="failed">
<description summary="configuration changes failed to apply">
Sent if the server rejects the changes or failed to apply them.
</description>
</event>
<request name="destroy" type="destructor">
<description summary="release the outputconfiguration object"/>
</request>
<request name="overscan">
<description summary="set overscan value">
Set the overscan value of this output device with a value in percent.
</description>
<arg name="outputdevice" type="object" interface="kde_output_device_v2" summary="outputdevice overscan applies to"/>
<arg name="overscan" type="uint" summary="overscan value"/>
</request>
<enum name="vrr_policy">
<description summary="describes vrr policy">
Describes when the compositor may employ variable refresh rate
</description>
<entry name="never" value="0"/>
<entry name="always" value="1"/>
<entry name="automatic" value="2"/>
</enum>
<request name="set_vrr_policy">
<description summary="set the VRR policy">
Set what policy the compositor should employ regarding its use of
variable refresh rate.
</description>
<arg name="outputdevice" type="object" interface="kde_output_device_v2" summary="outputdevice this VRR policy applies to"/>
<arg name="policy" type="uint" enum="vrr_policy" summary="the vrr policy to apply"/>
</request>
<enum name="rgb_range">
<description summary="describes RGB range policy">
Whether this output should use full or limited rgb.
</description>
<entry name="automatic" value="0"/>
<entry name="full" value="1"/>
<entry name="limited" value="2"/>
</enum>
<request name="set_rgb_range">
<description summary="RGB range">
Whether full or limited color range should be used
</description>
<arg name="outputdevice" type="object" interface="kde_output_device_v2" summary="outputdevice the rgb range applies to"/>
<arg name="rgb_range" type="uint" enum="rgb_range"/>
</request>
<request name="set_primary_output" since="2">
<description summary="Select which primary output to use" />
<arg name="output" type="object" interface="kde_output_device_v2" allow-null="false"/>
</request>
<request name="set_priority" since="3">
<description summary="Set the order of outputs">
Set the position of the output in the output order list, with lower values
being earlier in the list. There's no specific value the list has to start
at, this value is only used in sorting outputs.
The order of outputs can be used to assign desktop environment components
to a specific screen, see kde_output_order_v1 and kde-output-device-v2 for
details. Note that for consistent behavior, the priority value needs to be
unique among all enabled outputs.
</description>
<arg name="outputdevice" type="object" interface="kde_output_device_v2" summary="outputdevice the index applies to" />
<arg name="priority" type="uint" summary="the priority of the output" />
</request>
<request name="set_high_dynamic_range" since="4">
<description summary="change if HDR should be enabled">
Sets whether or not the output should be set to HDR mode.
</description>
<arg name="outputdevice" type="object" interface="kde_output_device_v2" summary="outputdevice this setting applies to"/>
<arg name="enable_hdr" type="uint" summary="1 to enable, 0 to disable hdr"/>
</request>
<request name="set_sdr_brightness" since="4">
<description summary="set the brightness for sdr content">
Sets the brightness of standard dynamic range content in nits. Only has an effect while the output is in HDR mode.
Note that while the value is in nits, that doesn't necessarily translate to the same brightness on the screen.
</description>
<arg name="outputdevice" type="object" interface="kde_output_device_v2" summary="outputdevice this setting applies to"/>
<arg name="sdr_brightness" type="uint"/>
</request>
<request name="set_wide_color_gamut" since="4">
<description summary="change if a wide color gamut should be used">
Whether or not the output should use a wide color gamut
</description>
<arg name="outputdevice" type="object" interface="kde_output_device_v2" summary="outputdevice this setting applies to"/>
<arg name="enable_wcg" type="uint" summary="1 to enable, 0 to disable wcg"/>
</request>
<enum name="auto_rotate_policy">
<description summary="describes when auto rotate should be used"/>
<entry name="never" value="0"/>
<entry name="in_tablet_mode" value="1"/>
<entry name="always" value="2"/>
</enum>
<request name="set_auto_rotate_policy" since="5">
<description summary="change when auto rotate should be used"/>
<arg name="outputdevice" type="object" interface="kde_output_device_v2" summary="outputdevice this setting applies to"/>
<arg name="policy" type="uint" enum="auto_rotate_policy"/>
</request>
<request name="set_icc_profile_path" since="6">
<description summary="change the used icc profile for SDR mode"/>
<arg name="outputdevice" type="object" interface="kde_output_device_v2" summary="outputdevice this setting applies to"/>
<arg name="profile_path" type="string"/>
</request>
<request name="set_brightness_overrides" since="7">
<description summary="override metadata about the screen's brightness limits"/>
<arg name="outputdevice" type="object" interface="kde_output_device_v2" summary="outputdevice this setting applies to"/>
<arg name="max_peak_brightness" type="int" summary="-1 for not overriding, or positive values in nits"/>
<arg name="max_frame_average_brightness" type="int" summary="-1 for not overriding, or positive values in nits"/>
<arg name="min_brightness" type="int" summary="-1 for not overriding, or positive values in 0.0001 nits"/>
</request>
<request name="set_sdr_gamut_wideness" since="7">
<description summary="describes which gamut is assumed for sRGB applications">
This can be used to provide the colors users assume sRGB applications should have based on the
default experience on many modern sRGB screens.
</description>
<arg name="outputdevice" type="object" interface="kde_output_device_v2" summary="outputdevice this setting applies to"/>
<arg name="gamut_wideness" type="uint" summary="0 means rec.709 primaries, 10000 means native primaries"/>
</request>
<enum name="color_profile_source" since="7">
<description summary="which source the compositor should use for the color profile on an output"/>
<entry name="sRGB" value="0"/>
<entry name="ICC" value="1"/>
<entry name="EDID" value="2"/>
</enum>
<request name="set_color_profile_source" since="8">
<description summary="which source the compositor should use for the color profile on an output in SDR mode"/>
<arg name="outputdevice" type="object" interface="kde_output_device_v2" summary="outputdevice this setting applies to"/>
<arg name="color_profile_source" type="uint" enum="color_profile_source" summary="the color profile source"/>
</request>
<request name="set_brightness" since="9">
<description summary="brightness multiplier">
Set the brightness modifier of the output. It doesn't specify
any absolute values, but is merely a multiplier on top of other
brightness values, like sdr_brightness and brightness_metadata.
0 is the minimum brightness (not completely dark) and 10000 is
the maximum brightness.
This is supported while HDR is active in versions 8 and below,
or when the device supports the "brightness" capability in
versions 9 and above.
</description>
<arg name="outputdevice" type="object" interface="kde_output_device_v2" summary="outputdevice this setting applies to"/>
<arg name="brightness" type="uint" summary="brightness in 0-10000"/>
</request>
<enum name="color_power_tradeoff">
<description summary="tradeoff between power and accuracy">
The compositor can do a lot of things that trade between
performance, power and color accuracy. This setting describes
a high level preference from the user about in which direction
that tradeoff should be made.
</description>
<entry name="efficiency" value="0" summary="prefer efficiency and performance"/>
<entry name="accuracy" value="1" summary="prefer accuracy"/>
</enum>
<request name="set_color_power_tradeoff" since="10">
<description summary="set the preferred color/power tradeoff"/>
<arg name="outputdevice" type="object" interface="kde_output_device_v2" summary="outputdevice this setting applies to"/>
<arg name="preference" type="uint" enum="color_power_tradeoff"/>
</request>
<request name="set_dimming" since="11">
<description summary="dimming multiplier">
Set the dimming multiplier of the output. This is similar to the
brightness setting, except it's meant to be a temporary setting
only, not persistent and may be implemented differently depending
on the display.
0 is the minimum dimming factor (not completely dark) and 10000
means the output is not dimmed.
This is supported only when the "brightness" capability is
also supported.
</description>
<arg name="outputdevice" type="object" interface="kde_output_device_v2" summary="outputdevice this setting applies to"/>
<arg name="multiplier" type="uint" summary="multiplier in 0-10000"/>
</request>
<event name="failure_reason" since="12">
<description summary="reason for failure">
Describes why applying the output configuration failed. Is only
sent before the failure event.
</description>
<arg name="reason" type="string" summary="reason for failure"/>
</event>
<request name="set_replication_source" since="13">
<description summary="source output for mirroring">
Set the source output that the outputdevice should mirror its
viewport from.
</description>
<arg name="outputdevice" type="object" interface="kde_output_device_v2" summary="outputdevice this setting applies to"/>
<arg name="source" type="string" summary="uuid of the source output"/>
</request>
<request name="set_ddc_ci_allowed" since="14">
<description summary="if DDC/CI should be used to control brightness etc."/>
<arg name="outputdevice" type="object" interface="kde_output_device_v2" summary="outputdevice this setting applies to"/>
<arg name="allowed" type="uint" summary="1 if allowed, 0 if disabled"/>
</request>
<request name="set_max_bits_per_color" since="15">
<description summary="override the max bpc">
This limits the amount of bits per color that are sent to the display.
</description>
<arg name="outputdevice" type="object" interface="kde_output_device_v2" summary="outputdevice this setting applies to"/>
<arg name="max_bpc" type="uint" summary="0 for the default / automatic"/>
</request>
<enum name="edr_policy" since="16">
<description summary="when the compositor may make use of EDR"/>
<entry name="never" value="0"/>
<entry name="always" value="1"/>
</enum>
<request name="set_edr_policy" since="16">
<description summary="set when the compositor may apply EDR">
When EDR is enabled, the compositor may increase the backlight beyond
the user-specified setting, in order to present HDR content on displays
without native HDR support.
This will usually result in better visuals, but also increases battery
usage.
</description>
<arg name="outputdevice" type="object" interface="kde_output_device_v2" summary="outputdevice this setting applies to"/>
<arg name="policy" type="uint" enum="edr_policy"/>
</request>
<request name="set_sharpness" since="17">
<description summary="sharpness strength">
This is the sharpness modifier of the output.
0 is sharpness disabled and 10000 is the maximum sharpness
</description>
<arg name="outputdevice" type="object" interface="kde_output_device_v2" summary="outputdevice this setting applies to"/>
<arg name="sharpness" type="uint" summary="sharpness in 0-10000"/>
</request>
<request name="set_custom_modes" since="18">
<description summary="set the custom mode list">
Set the list of custom modes for this output. The compositor
will in response generate the requested modes and add them to
the output (or delete ones no longer in the list).
This can be useful for overclocking displays, or for working
around broken EDIDs.
Note that there is no guarantee for any custom mode to
actually work, or even to leave the display undamaged (in the
case of CRTs). It's entirely the responsibility of the user
to ensure each added mode is the right one for their display.
</description>
<arg name="outputdevice" type="object" interface="kde_output_device_v2" summary="outputdevice this setting applies to"/>
<arg name="modes" type="object" interface="kde_mode_list_v2"/>
</request>
<request name="set_auto_brightness" since="19">
<description summary="whether or not automatic brightness is enabled"/>
<arg name="outputdevice" type="object" interface="kde_output_device_v2" summary="outputdevice this setting applies to"/>
<arg name="enabled" type="uint" summary="1 for enabled, 0 for disabled"/>
</request>
<request name="set_hdr_icc_profile_path" since="20">
<description summary="change the used icc profile for HDR mode"/>
<arg name="outputdevice" type="object" interface="kde_output_device_v2" summary="outputdevice this setting applies to"/>
<arg name="profile_path" type="string"/>
</request>
<request name="set_hdr_color_profile_source" since="20">
<description summary="which source the compositor should use for the color profile on an output in HDR mode"/>
<arg name="outputdevice" type="object" interface="kde_output_device_v2" summary="outputdevice this setting applies to"/>
<arg name="color_profile_source" type="uint" enum="color_profile_source" summary="the color profile source"/>
</request>
<request name="set_abm_level" since="21">
<description summary="set the allowed level of adaptive backlight modulation">
Adaptive backlight modulation is a feature that reduces the backlight
and increases contrast of colors on the screen to improve power usage.
</description>
<arg name="outputdevice" type="object" interface="kde_output_device_v2" summary="outputdevice this setting applies to"/>
<arg name="level" type="uint" summary="0 is off, 4 is the maximum level"/>
</request>
</interface>
<interface name="kde_mode_list_v2" version="22">
<description summary="a list of custom modes">
This list is populated by first setting each relevant property,
and then calling add_mode to add a mode with these properties.
One would for example call
- set_resolution
- set_refresh_rate
- set_reduced_blanking
- add_mode
add_mode does not reset the properties that were previously set,
they are valid until the object is destroyed.
The compositor may additionally have sensible defaults for some
properties like reduced_blanking, but for consistent results,
it's best to always set each known property every time.
One can also specify custom modes with CVT timings, for example
- add_cvt
- add_cvt
The parameters resolution and refresh rate are required, if they
are not set, the missing_parameters error will be emitted.
</description>
<enum name="error">
<description summary="kde_mode_list_v2 error values">
These errors can be emitted in response to add_mode requests.
</description>
<entry name="missing_parameters" value="0" summary="a required parameter wasn't set"/>
</enum>
<request name="destroy" type="destructor">
<description summary="destroy the mode list object"/>
</request>
<request name="add_mode">
<description summary="Add the current mode configuration to the list"/>
</request>
<request name="set_resolution">
<arg name="width" type="uint"/>
<arg name="height" type="uint"/>
</request>
<request name="set_refresh_rate">
<arg name="rate" type="uint" summary="in milliHz"/>
</request>
<request name="set_reduced_blanking">
<description summary="whether or not the mode should have reduced blanking">
Reduced blanking is an optimization that can reduce bandwidth / timing
requirements for a display mode by reducing the time vblank takes.
As not all displays support it, it may be desired to still turn it off
though (like with CRTs, where full blanking is required).
</description>
<arg name="reduced" type="uint"
summary="1 for reduced blanking, 0 for normal vblank duration"/>
</request>
<request name="add_cvt" since="22">
<description summary="new mode with CVT timings">
Adds a new mode with the specified CVT timings.
</description>
<arg name="dot_clock" type="uint" summary="pixel clock in kHz"/>
<arg name="hdisplay" type="uint" summary="horizontal display size"/>
<arg name="hsync_start" type="uint" summary="horizontal sync start"/>
<arg name="hsync_end" type="uint" summary="horizontal sync end"/>
<arg name="htotal" type="uint" summary="horizontal total size"/>
<arg name="hskew" type="uint" summary="horizontal skew"/>
<arg name="vdisplay" type="uint" summary="vertical display size"/>
<arg name="vsync_start" type="uint" summary="vertical sync start"/>
<arg name="vsync_end" type="uint" summary="vertical sync end"/>
<arg name="vtotal" type="uint" summary="vertical total size"/>
<arg name="vscan" type="uint" summary="vertical scan"/>
<arg name="flags" type="uint" summary="flags, see DRM_MODE_FLAG_*"/>
</request>
</interface>
</protocol>