wayland: Add support for layer_surface_v1.set_exclusive_edge

This can be used to disambiguate the exclusive edge when the anchors are
on a corner (so there would be 2 candidates)

it's quite quick and dirty mostly to understand if we do want to push for
something along the lines (it should at least do a protocol error when
the requested edge is not within the anchors)
wilder/Plasma/6.2
Marco Martin 2 years ago committed by Vlad Zahorodnii
parent 2d2ee710c8
commit fe8fe42ea9
  1. 40
      src/wayland/layershell_v1.cpp
  2. 21
      src/wayland/protocols/wlr-layer-shell-unstable-v1.xml

@ -18,7 +18,7 @@
namespace KWin
{
static const int s_version = 3;
static const int s_version = 5;
class LayerShellV1InterfacePrivate : public QtWaylandServer::zwlr_layer_shell_v1
{
@ -45,6 +45,7 @@ struct LayerSurfaceV1Commit
std::optional<QMargins> margins;
std::optional<QSize> desiredSize;
std::optional<int> exclusiveZone;
std::optional<Qt::Edge> exclusiveEdge;
std::optional<quint32> acknowledgedConfigure;
std::optional<bool> acceptsFocus;
};
@ -57,6 +58,7 @@ struct LayerSurfaceV1State
QMargins margins;
QSize desiredSize = QSize(0, 0);
int exclusiveZone = 0;
Qt::Edge exclusiveEdge = Qt::Edge();
bool acceptsFocus = false;
bool configured = false;
bool closed = false;
@ -82,6 +84,7 @@ protected:
void zwlr_layer_surface_v1_destroy_resource(Resource *resource) override;
void zwlr_layer_surface_v1_set_size(Resource *resource, uint32_t width, uint32_t height) override;
void zwlr_layer_surface_v1_set_anchor(Resource *resource, uint32_t anchor) override;
void zwlr_layer_surface_v1_set_exclusive_edge(Resource *resource, uint32_t edge) override;
void zwlr_layer_surface_v1_set_exclusive_zone(Resource *resource, int32_t zone) override;
void zwlr_layer_surface_v1_set_margin(Resource *resource, int32_t top, int32_t right, int32_t bottom, int32_t left) override;
void zwlr_layer_surface_v1_set_keyboard_interactivity(Resource *resource, uint32_t keyboard_interactivity) override;
@ -203,6 +206,23 @@ void LayerSurfaceV1InterfacePrivate::zwlr_layer_surface_v1_set_anchor(Resource *
}
}
void LayerSurfaceV1InterfacePrivate::zwlr_layer_surface_v1_set_exclusive_edge(Resource *resource, uint32_t edge)
{
if (!edge) {
pending.exclusiveEdge = Qt::Edge();
} else if (edge == anchor_top) {
pending.exclusiveEdge = Qt::TopEdge;
} else if (edge == anchor_right) {
pending.exclusiveEdge = Qt::RightEdge;
} else if (edge == anchor_bottom) {
pending.exclusiveEdge = Qt::BottomEdge;
} else if (edge == anchor_left) {
pending.exclusiveEdge = Qt::LeftEdge;
} else {
wl_resource_post_error(resource->handle, error_invalid_exclusive_edge, "Invalid exclusive edge: %d", edge);
}
}
void LayerSurfaceV1InterfacePrivate::zwlr_layer_surface_v1_set_exclusive_zone(Resource *, int32_t zone)
{
pending.exclusiveZone = zone;
@ -302,6 +322,15 @@ void LayerSurfaceV1InterfacePrivate::apply(LayerSurfaceV1Commit *commit)
}
}
if (commit->exclusiveEdge.has_value() || commit->anchor.has_value()) {
const quint32 exclusiveEdge = commit->exclusiveEdge.value_or(state.exclusiveEdge);
const quint32 anchor = commit->anchor.value_or(state.anchor);
if (exclusiveEdge && !(exclusiveEdge & anchor)) {
wl_resource_post_error(resource()->handle, error_invalid_exclusive_edge, "Exclusive edge is not of the anchors");
return;
}
}
// detect reset
if (!surface->isMapped() && state.firstBufferAttached) {
state = LayerSurfaceV1State();
@ -333,6 +362,10 @@ void LayerSurfaceV1InterfacePrivate::apply(LayerSurfaceV1Commit *commit)
if (commit->exclusiveZone.has_value()) {
state.exclusiveZone = commit->exclusiveZone.value();
}
if (commit->exclusiveEdge.has_value()) {
state.exclusiveEdge = commit->exclusiveEdge.value();
}
if (commit->acceptsFocus.has_value()) {
state.acceptsFocus = commit->acceptsFocus.value();
}
@ -449,6 +482,11 @@ Qt::Edge LayerSurfaceV1Interface::exclusiveEdge() const
if (exclusiveZone() <= 0) {
return Qt::Edge();
}
if (d->state.exclusiveEdge) {
return d->state.exclusiveEdge;
}
if (anchor() == (Qt::LeftEdge | Qt::TopEdge | Qt::RightEdge) || anchor() == Qt::TopEdge) {
return Qt::TopEdge;
}

@ -25,7 +25,7 @@
THIS SOFTWARE.
</copyright>
<interface name="zwlr_layer_shell_v1" version="3">
<interface name="zwlr_layer_shell_v1" version="5">
<description summary="create surfaces that are layers of the desktop">
Clients can use this interface to assign the surface_layer role to
wl_surfaces. Such surfaces are assigned to a "layer" of the output and
@ -100,7 +100,7 @@
</request>
</interface>
<interface name="zwlr_layer_surface_v1" version="3">
<interface name="zwlr_layer_surface_v1" version="5">
<description summary="layer metadata interface">
An interface that may be implemented by a wl_surface, for surfaces that
are designed to be rendered as a layer of a stacked desktop-like
@ -302,6 +302,7 @@
<entry name="invalid_surface_state" value="0" summary="provided surface state is invalid"/>
<entry name="invalid_size" value="1" summary="size is invalid"/>
<entry name="invalid_anchor" value="2" summary="anchor bitfield is invalid"/>
<entry name="invalid_exclusive_edge" value="4" summary="exclusive edge is invalid given the surface anchors"/>
</enum>
<enum name="anchor" bitfield="true">
@ -321,5 +322,21 @@
</description>
<arg name="layer" type="uint" enum="zwlr_layer_shell_v1.layer" summary="layer to move this surface to"/>
</request>
<!-- Version 5 additions -->
<request name="set_exclusive_edge" since="5">
<description summary="set the edge the exclusive zone will be applied to">
Requests an edge for the exclusive zone to apply. The exclusive
edge will be automatically deduced from anchor points when possible,
but when the surface is anchored to a corner, it will be necessary
to set it explicitly to disambiguate, as it is not possible to deduce
which one of the two corner edges should be used.
The edge must be one the surface is anchored to, otherwise the
invalid_exclusive_edge protocol error will be raised.
</description>
<arg name="edge" type="uint"/>
</request>
</interface>
</protocol>

Loading…
Cancel
Save