Add xdg-toplevel-layers for persistent toplevel layering

This new protocol allows clients to set a persistent z-order for their
toplevels, permanently keeping some toplevels above others no matter
which one gets activated by the user.

This paradigm is very commonly used by DAW (Digital Audio Workstation)
and CAD (Computer-aided Design) applications, which utilize a lot of
windows and toolboxes and often have plugins running in separate
processes.

Signed-off-by: Matthias Klumpp <matthias@tenstral.net>
This commit is contained in:
Matthias Klumpp 2025-12-12 18:55:20 +01:00
parent a5caef14e7
commit e40bd38bc5
3 changed files with 148 additions and 0 deletions

View file

@ -73,6 +73,7 @@ staging_protocols = {
'xdg-system-bell': ['v1'], 'xdg-system-bell': ['v1'],
'xdg-toplevel-drag': ['v1'], 'xdg-toplevel-drag': ['v1'],
'xdg-toplevel-icon': ['v1'], 'xdg-toplevel-icon': ['v1'],
'xdg-toplevel-layers': ['v1'],
'xdg-toplevel-tag': ['v1'], 'xdg-toplevel-tag': ['v1'],
'xwayland-shell': ['v1'], 'xwayland-shell': ['v1'],
} }

View file

@ -0,0 +1,4 @@
Toplevel Layers protocol
Maintainers:
Matthias Klumpp <matthias@tenstral.net> (@mak)

View file

@ -0,0 +1,143 @@
<?xml version="1.0" encoding="UTF-8"?>
<protocol name="xdg_toplevel_layers_v1">
<copyright>
Copyright © 2024-2025 Matthias Klumpp
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice (including the next
paragraph) shall be included in all copies or substantial portions of the
Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
</copyright>
<description summary="protocol to allow setting a persistent z-order for toplevels">
This protocol provides a way for clients to set a persistent layering order
between their toplevels.
This is useful for clients that want to keep specific toplevels above or below
other toplevels, no matter whether they current have focus or not when using
a stacking window manager.
This document adheres to RFC 2119 when using words like "must",
"should", "may", etc.
Warning! The protocol described in this file is currently in the testing
phase. Backward compatible changes may be added together with the
corresponding interface version bump. Backward incompatible changes can
only be done by creating a new major version of the extension.
</description>
<interface name="xdg_toplevel_layer_manager_v1" version="1">
<description summary="manage layered items">
The 'xdg_toplevel_layer_manager' interface defines base requests for obtaining and
managing layered items for a client.
</description>
<request name="destroy" type="destructor">
<description summary="Destroy this object">
This has no effect other than to destroy the xdg_toplevel_layer_manager object.
</description>
</request>
<request name="get_layer_item">
<description summary="create a layerable item representing a toplevel">
Create a new layer item from an 'xdg_toplevel'.
The resulting wrapper object can then be used to set a z-order
relative to other layerable items.
</description>
<arg name="id" type="new_id" interface="xdg_toplevel_layer_item_v1"/>
<arg name="toplevel" type="object" interface="xdg_toplevel" summary="the toplevel window"/>
</request>
<request name="get_layer_item_from_imported">
<description summary="create a layerable item representing a toplevel">
Create a new layer item from an imported toplevel that was previously
exported by another client using the xdg-foreign protocol.
The resulting wrapper object can then be used to set a z-order
relative to other layerable items.
</description>
<arg name="id" type="new_id" interface="xdg_toplevel_layer_item_v1"/>
<arg name="imported" type="object" interface="zxdg_imported_v2" summary="the toplevel window"/>
</request>
</interface>
<interface name="xdg_toplevel_layer_item_v1" version="1">
<description summary="opaque window object that can be layered over other items">
The layer item object is an opaque descriptor for a positionable
element, such as a toplevel window.
It currently can only be created from an 'xdg_toplevel' or imported
toplevel.
</description>
<request name="destroy" type="destructor">
<description summary="delete this object">
Destroys the layer item. This request may be sent at any time by the
client.
By destroying the object, the respective toplevel represented by this
item must lose any attached state, like its layer index, and behave
like a regular toplevel.
</description>
</request>
<enum name="error">
<entry name="invalid" value="0"
summary="the requested layering was invalid"/>
</enum>
<request name="set_layer">
<description summary="permanently pin an item to a relative z-order">
Request a preferred permanent Z position for this item relative to
another layer item.
This state is double-buffered and is applied on the next
wl_surface.commit of the surface represented by 'item'.
This function associates a "layer index" with the item, with all
item surfaces assumed to be positioned at a layer with index 0 by
default.
Item surfaces that are positioned in a layer with a higher index
permanently float above items with a lower index. Items with a
lower layer index sink below items with a higher index.
When (de)activated, items must stay in their layers and do not
change order like they normally would in a stacking window manager
paradigm.
All indices are relative to the given reference item. For example,
to position an item A two layers above the reference item, the client
would call this function with the reference item and a layer_index
of 2. This keeps the current item permanently above the reference item.
If the client then calls this function on an item B with the same reference
item, but a layer_index of 1, item B will be positioned permanently above
the reference item, but also permanently below item A.
If a negative layer index is given, this item will permanently sink
below the reference icon. Otherwise the same semantics as with positive
indices apply for negative ones.
Items with the same layer index respective to the reference surface
are subject to compositor policy, which usually means they will obe
user interaction and raise above or sink below each other depending on
which surface is currently activated.
If the reference item is the same item as this item (so, using itself as
reference) an 'invalid' error must be raised.
</description>
<arg name="reference" type="object" interface="xdg_toplevel_layer_item_v1" summary="the reference item"/>
<arg name="layer_index" type="int" summary="the layer position relative to the reference item"/>
</request>
</interface>
</protocol>