1<?xml version="1.0" encoding="UTF-8"?>
2<protocol name="neferwl_image_capture_v1">
3 <copyright>
4 neferwl private protocol. No stability promise beyond the version of the
5 interface.
6 </copyright>
7
8 <description summary="neferwl additions to ext-image-copy-capture">
9 Optional additions to ext-image-capture-source-v1, ext-workspace-v1 and
10 ext-image-copy-capture-v1 for what those protocols do not cover:
11 workspace and output-region capture sources, the frame of a workspace,
12 and leaving a client's own surfaces (a recording HUD) out of its
13 captures.
14
15 Capture always goes through ext-image-copy-capture. The compositor applies
16 the same rules to every capture, whatever its source: it may refuse a
17 client (ext_image_copy_capture_session_v1.stopped), and it draws its own
18 capture indicator on screen, never in a captured image, which no client
19 can turn off.
20 </description>
21
22 <interface name="neferwl_image_capture_source_manager_v1" version="1">
23 <description summary="workspace and output-region capture sources">
24 Global. Sources created here are ext_image_capture_source_v1 objects,
25 used with ext_image_copy_capture_manager_v1.create_session like any
26 other source.
27 </description>
28
29 <enum name="error">
30 <entry name="invalid_region" value="0" summary="width or height is not positive"/>
31 </enum>
32
33 <request name="destroy" type="destructor">
34 <description summary="destroy the manager">
35 Sources created through it stay valid.
36 </description>
37 </request>
38
39 <request name="create_workspace_source">
40 <description summary="capture a workspace">
41 The source is the workspace frame, without bars, whether or not the
42 workspace is on screen: a workspace that is not on screen is rendered
43 for capture only. Its buffer size follows the workspace frame. A
44 session on it is stopped when the workspace is removed. A handle
45 already removed gives a source whose sessions stop at once.
46 </description>
47 <arg name="source" type="new_id" interface="ext_image_capture_source_v1"/>
48 <arg name="workspace" type="object" interface="ext_workspace_handle_v1"/>
49 </request>
50
51 <request name="create_output_region_source">
52 <description summary="capture a rectangle of an output">
53 The rectangle is in output-local logical pixels and is clipped to the
54 output. The buffer covers only that rectangle, in physical pixels. A
55 session on it is stopped when the output goes away or when nothing of
56 the rectangle is left on the output.
57 </description>
58 <arg name="source" type="new_id" interface="ext_image_capture_source_v1"/>
59 <arg name="output" type="object" interface="wl_output"/>
60 <arg name="x" type="int"/>
61 <arg name="y" type="int"/>
62 <arg name="width" type="int"/>
63 <arg name="height" type="int"/>
64 </request>
65
66 <request name="get_workspace_frame">
67 <description summary="learn the frame of a workspace">
68 ext-workspace-v1 carries no geometry. The frame object reports the
69 rectangle that a workspace source of the same handle captures. For a
70 handle already removed, the object never sends frame. It needs no
71 capture authorization: the frame is layout information, not pixels.
72 </description>
73 <arg name="id" type="new_id" interface="neferwl_workspace_frame_v1"/>
74 <arg name="workspace" type="object" interface="ext_workspace_handle_v1"/>
75 </request>
76 </interface>
77
78 <interface name="neferwl_workspace_frame_v1" version="1">
79 <description summary="the frame of one workspace">
80 The frame is the area of its output that the workspace draws in,
81 without bars: the whole output, or the smaller size set for the
82 workspace.
83 </description>
84
85 <request name="destroy" type="destructor">
86 <description summary="destroy the frame object"/>
87 </request>
88
89 <event name="frame">
90 <description summary="the workspace frame">
91 The frame in output-local logical pixels. Sent when the object is
92 created and again whenever the frame changes. Not sent once the
93 workspace is removed. Not sent while the session is locked; the
94 current frame is sent after unlock if it changed.
95 </description>
96 <arg name="x" type="int"/>
97 <arg name="y" type="int"/>
98 <arg name="width" type="int"/>
99 <arg name="height" type="int"/>
100 </event>
101 </interface>
102
103 <interface name="neferwl_capture_exclusion_manager_v1" version="1">
104 <description summary="leave a client's own surfaces out of its captures">
105 Global. A recorder asks for an exclusion on its capture session and
106 gets a token; its HUD, usually on another connection of the same user,
107 attaches layer surfaces with that token. Frames of that session leave
108 the attached surfaces out. Every other capture shows them.
109 </description>
110
111 <enum name="error">
112 <entry name="surface_role" value="0" summary="the surface is not a wlr-layer-shell surface"/>
113 <entry name="invalid_layer" value="1" summary="the layer is neither top nor overlay"/>
114 <entry name="exclusive_keyboard" value="2" summary="the layer takes the keyboard exclusively"/>
115 <entry name="invalid_surface" value="3" summary="the surface is already mapped"/>
116 <entry name="already_excluded" value="4" summary="the capture session already has an exclusion"/>
117 </enum>
118
119 <request name="destroy" type="destructor">
120 <description summary="destroy the manager">
121 Exclusions and attachments created through it stay alive.
122 </description>
123 </request>
124
125 <request name="get_exclusion">
126 <description summary="create the exclusion of a capture session">
127 The exclusion answers with exactly one of token or failed. It ends
128 with the capture session.
129 </description>
130 <arg name="id" type="new_id" interface="neferwl_capture_exclusion_v1"/>
131 <arg name="session" type="object" interface="ext_image_copy_capture_session_v1"/>
132 </request>
133
134 <request name="attach_surface">
135 <description summary="attach a layer surface to an exclusion by token">
136 Marks a layer surface of this client as excluded from the frames of
137 the session that owns the token. The client must have the same user
138 ID as the compositor and must also be allowed to capture: its
139 executable is on the capture allowlist (or the allowlist is off), it
140 is not sandboxed, and the session is not locked. The surface must already have the
141 wlr-layer-shell role, on the top or overlay layer, must not have
142 mapped yet and must not ask for exclusive keyboard interactivity. At
143 most 4 layers per exclusion. An attached layer never gets keyboard
144 interactivity; if it moves to another layer the compositor closes it
145 and sends detached.
146
147 The attachment answers with exactly one of attached or failed. The
148 surface is excluded from this request on, before it can map; the
149 client must not show it before attached.
150 </description>
151 <arg name="id" type="new_id" interface="neferwl_capture_layer_v1"/>
152 <arg name="token" type="string"/>
153 <arg name="surface" type="object" interface="wl_surface"/>
154 </request>
155 </interface>
156
157 <interface name="neferwl_capture_exclusion_v1" version="1">
158 <description summary="the exclusion of one capture session">
159 Destroying it detaches every attached layer.
160 </description>
161
162 <enum name="failure">
163 <entry name="busy" value="0" summary="another exclusion is live in the compositor"/>
164 <entry name="session_stopped" value="1" summary="the capture session is stopped"/>
165 </enum>
166
167 <request name="destroy" type="destructor">
168 <description summary="destroy the exclusion"/>
169 </request>
170
171 <event name="token">
172 <description summary="the attachment token">
173 64 lowercase hexadecimal characters (32 random bytes). A secret for
174 the owner and its HUD, never logged, valid until the exclusion ends.
175 </description>
176 <arg name="token" type="string"/>
177 </event>
178
179 <event name="failed">
180 <description summary="no exclusion">
181 Final. Destroy the object.
182 </description>
183 <arg name="reason" type="uint" enum="failure"/>
184 </event>
185 </interface>
186
187 <interface name="neferwl_capture_layer_v1" version="1">
188 <description summary="a layer surface attached to an exclusion">
189 Created by attach_surface. Exactly one of attached or failed comes
190 first; detached comes at most once, after attached.
191 </description>
192
193 <enum name="failure">
194 <entry name="unknown_token" value="0" summary="no live exclusion has this token"/>
195 <entry name="unauthorized" value="1" summary="peer credentials differ from the compositor user's or are unreadable, or the client may not capture (not on the allowlist, sandboxed, or session locked)"/>
196 <entry name="too_many_layers" value="2" summary="the exclusion already has 4 attached layers"/>
197 <entry name="already_attached" value="3" summary="the surface is already attached"/>
198 <entry name="exclusion_ended" value="4" summary="the exclusion ended before the compositor confirmed the layer"/>
199 <entry name="layer_destroyed" value="5" summary="the layer role was destroyed before the compositor confirmed it"/>
200 </enum>
201
202 <enum name="detach_reason">
203 <entry name="exclusion_ended" value="0" summary="the exclusion ended; the compositor closed the layer surface"/>
204 <entry name="layer_destroyed" value="1" summary="the layer role was destroyed"/>
205 </enum>
206
207 <request name="destroy" type="destructor">
208 <description summary="destroy the attachment object">
209 The surface stays excluded until its layer role is destroyed or the
210 exclusion ends.
211 </description>
212 </request>
213
214 <event name="attached">
215 <description summary="the layer is excluded">
216 The compositor confirmed the attachment. Safe to show.
217 </description>
218 </event>
219
220 <event name="failed">
221 <description summary="the attachment was refused"/>
222 <arg name="reason" type="uint" enum="failure"/>
223 </event>
224
225 <event name="detached">
226 <description summary="the layer left the exclusion">
227 Sent once after attached. When the exclusion ended, the compositor
228 also closed the layer surface (zwlr_layer_surface_v1.closed).
229 </description>
230 <arg name="reason" type="uint" enum="detach_reason"/>
231 </event>
232 </interface>
233</protocol>