xdg-shell: clarify unconstraining by sliding without gravity on the axis
xdg_positioner::constraint_adjustment::slide_x
description states:
Slide the surface along the x axis until it is no longer constrained.
First try to slide towards the direction of the gravity on the x axis
until either the edge in the opposite direction of the gravity is
unconstrained or the edge in the direction of the gravity is
constrained.
Then try to slide towards the opposite direction of the gravity on the
x axis until either the edge in the direction of the gravity is
unconstrained or the edge in the opposite direction of the gravity is
constrained.
The way I read this, sliding can only be done in either the direction of the gravity or the opposite direction of it. That means trying to apply constraint_adjustment
being slide_x | flip_y
with gravity
being bottom
should be no-op. However, that's what GTK seems to set for its tooltips, expecting the compositor to offset them when necessary:
shimarin $ ~ WAYLAND_DEBUG=1 waybar 2>&1 | grep xdg_positioner
[4094418.599] -> xdg_wm_base@36.create_positioner(new id xdg_positioner@42)
[4094418.609] -> xdg_positioner@42.set_size(176, 169)
[4094418.615] -> xdg_positioner@42.set_anchor_rect(1832, -4, 92, 38)
[4094418.625] -> xdg_positioner@42.set_offset(0, 0)
[4094418.634] -> xdg_positioner@42.set_anchor(2)
[4094418.640] -> xdg_positioner@42.set_gravity(2) # bottom
[4094418.648] -> xdg_positioner@42.set_constraint_adjustment(9) # slide_x | flip_y
(Waybar uses gtk-layer-shell, but pure GTK programs like Inkscape set the same positioning rules.)
The motivation for adding gravity-based logic¹:
> + <entry name="slide_x" value="1">
> + <description summary="move along the X-axis until unconstrained">
> + Slide the surface along the X-axis until it is no longer constrained.
> + If the left side of the surface is constrained, slide towards the
> + right; if the right side of the surface is constrained, slide towards
> + the left. If both sides are ends up being constrained, the behaviour is
I think the directionality here should be based on the gravity, eg. if LEFT
gravity is used then it tries to move left if possible, moving right
afterward only if a leftward movement is impossible or does not solve the
positioning. This handles the case of both sides being constrained since
the compositor is then unable to perform any positioning corrections.
> + undefined.
> + </description>
> + </entry>
Note that it doesn't provide a defined behavior for cases where there is no gravity on the chosen axis.
GTK, on which logic xdg_positioner
was apparently based, ignores gravity (surface_anchor
) completely when using X11, sliding to the right in case of both sides being constrained²:
if (anchor_hints & GDK_ANCHOR_SLIDE_X)
{
if (final_rect.x + final_rect.width > bounds->x + bounds->width)
final_rect.x = bounds->x + bounds->width - final_rect.width;
if (final_rect.x < bounds->x)
final_rect.x = bounds->x;
}
What is the expected behavior there? Slide if only one side is constrained, and check gravity only if both sides are constrained? How should no-gravity-on-the-axis case be handled then?
¹https://lists.freedesktop.org/archives/wayland-devel/2016-April/028247.html
²https://gitlab.gnome.org/GNOME/gtk/-/blob/main/gdk/gdksurface.c#L350
As advised, cc @jadahl.