[PATCH wayland-protocols v4 7/7] xdg-shell: Introduce xdg_positioner

Quentin Glidic sardemff7+wayland at sardemff7.net
Wed Jul 20 08:57:44 UTC 2016


On 24/06/2016 08:47, Jonas Ådahl wrote:
> xdg_positioner is a method for declarative positioning of child surfaces
> (currently only xdg_popup surfaces). A client creates a description of a
> positioning logic using the xdg_positioner interface. The xdg_positioner
> object is then used when creating a xdg_popup for describing how the
> child surface should be positioned in relation to the parent surface.
>
> Signed-off-by: Jonas Ådahl <jadahl at gmail.com>
> Signed-off-by: Mike Blumenkrantz <zmike at samsung.com>
> Acked-by: Yong Bakos <ybakos at humanoriented.com>
> ---

I like the idea. I would love to test it for real, but Weston will be 
hard to port to v6. ;-)

Acked-by: Quentin Glidic <sardemff7+git at sardemff7.net>

Cheers,


>
> Changes since v3:
>
>  - Allow combining slide_x/y and flip_x/y enums, while explaining the order of
>    adjustments.
>  - Reworded the non-immediate effect of the configure event (the same as
>    xdg-surface generic split update)
>
>
>  unstable/xdg-shell/xdg-shell-unstable-v6.xml | 266 ++++++++++++++++++++++++++-
>  1 file changed, 263 insertions(+), 3 deletions(-)
>
> diff --git a/unstable/xdg-shell/xdg-shell-unstable-v6.xml b/unstable/xdg-shell/xdg-shell-unstable-v6.xml
> index 4c5dab4..7fab656 100644
> --- a/unstable/xdg-shell/xdg-shell-unstable-v6.xml
> +++ b/unstable/xdg-shell/xdg-shell-unstable-v6.xml
> @@ -45,6 +45,8 @@
>  	     summary="the client specified an invalid popup parent surface"/>
>        <entry name="invalid_surface_state" value="4"
>  	     summary="the client provided an invalid surface state"/>
> +      <entry name="invalid_positioner" value="5"
> +	     summary="the client provided an invalid positioner"/>
>      </enum>
>
>      <request name="destroy" type="destructor">
> @@ -57,6 +59,15 @@
>        </description>
>      </request>
>
> +    <request name="create_positioner">
> +      <description summary="create a positioner object">
> +	Create a positioner object. A positioner object is used to position
> +	surfaces relative to some parent surface. See the interface description
> +	and xdg_surface.get_popup for details.
> +      </description>
> +      <arg name="id" type="new_id" interface="zxdg_positioner_v6"/>
> +    </request>
> +
>      <request name="get_xdg_surface">
>        <description summary="create a shell surface from a surface">
>  	This creates an xdg_surface for the given surface. While xdg_surface
> @@ -101,6 +112,240 @@
>      </event>
>    </interface>
>
> +  <interface name="zxdg_positioner_v6" version="1">
> +    <description summary="child surface positioner">
> +      The xdg_positioner provides an interface for constructing positioning
> +      rules used for positioning a child surface relative to a parent surface
> +      in a certain way. It allows methods for defining a rule that will make
> +      the child surface stay within the border of the visible area of the
> +      screen, with different ways in which the child surface should change
> +      its position, including sliding along an axis, or flipping around a
> +      rectangle.
> +
> +      See the various requests for details about possible rules.
> +
> +      Semantically, an xdg_positioner is a collection of positioning rules. When
> +      used for positioning a surface, for example when passed as an argument to
> +      xdg_surface.get_popup, the compositor copies the rules that were set up at
> +      the time of the request. Making any changes or destroying the object after
> +      it was used has no effect on previous usages.
> +
> +      For an xdg_positioner object to be considered complete, it must have a
> +      non-zero size set by set_size, and a non-zero anchor rectangle set by
> +      set_anchor_rect. Passing an incomplete xdg_positioner object when
> +      positioning a surface raises an error.
> +    </description>
> +
> +    <enum name="error">
> +      <entry name="invalid_input" value="0" summary="invalid input provided"/>
> +    </enum>
> +
> +    <request name="destroy" type="destructor">
> +      <description summary="destroy the xdg_positioner object">
> +	Notify the compositor that the xdg_positioner will no longer be used.
> +      </description>
> +    </request>
> +
> +    <request name="set_size">
> +      <description summary="set the size of the to-be positioned rectangle">
> +	Set the size of the surface that is to be positioned with the positioner
> +	object. The size is in surface-local coordinates and corresponds to the
> +	window geometry. See xdg_surface.set_window_geometry.
> +
> +	If a zero or negative size is set the invalid_input error is raised.
> +      </description>
> +      <arg name="width" type="int" summary="width of positioned rectangle"/>
> +      <arg name="height" type="int" summary="height of positioned rectangle"/>
> +    </request>
> +
> +    <request name="set_anchor_rect">
> +      <description summary="set the anchor rectangle within the parent surface">
> +	Specify the anchor rectangle within the parent surface that the child
> +	surface will be placed relative to. The rectangle is relative to the
> +	window geometry as defined by xdg_surface.set_window_geometry of the
> +	parent surface. The rectangle must be at least 1x1 large.
> +
> +	When the xdg_positioner object is used to position a child surface, the
> +	anchor rectangle may not extend outside the window geometry of the
> +	positioned child's parent surface.
> +
> +	If a zero or negative size is set the invalid_input error is raised.
> +      </description>
> +      <arg name="x" type="int" summary="x position of anchor rectangle"/>
> +      <arg name="y" type="int" summary="y position of anchor rectangle"/>
> +      <arg name="width" type="int" summary="width of anchor rectangle"/>
> +      <arg name="height" type="int" summary="height of anchor rectangle"/>
> +    </request>
> +
> +    <enum name="anchor" bitfield="true">
> +      <entry name="none" value="0"
> +	     summary="the center of the anchor rectangle"/>
> +      <entry name="top" value="1"
> +	     summary="the top edge of the anchor rectangle"/>
> +      <entry name="bottom" value="2"
> +	     summary="the bottom edge of the anchor rectangle"/>
> +      <entry name="left" value="4"
> +	     summary="the left edge of the anchor rectangle"/>
> +      <entry name="right" value="8"
> +	     summary="the right edge of the anchor rectangle"/>
> +    </enum>
> +
> +    <request name="set_anchor">
> +      <description summary="set anchor rectangle anchor edges">
> +	Set the anchor edges of the anchor rectangle. The anchor edges define
> +	where on the anchor rectangle the child surface should be positioned
> +	relative to. An anchor is a bit mask of up to two values of the anchor
> +	enum.
> +
> +	If two values on the same axis (for example left and right) are set the
> +	invalid_input error is raised.
> +
> +	If no anchor is set on any axis, the anchor position will be positioned
> +	at the center of the anchor rectangle on the unset axis. The default
> +	value is "none".
> +      </description>
> +      <arg name="anchor" type="uint" enum="anchor"
> +	   summary="bit mask of anchor edges"/>
> +    </request>
> +
> +    <enum name="gravity" bitfield="true">
> +      <entry name="none" value="0"
> +	     summary="center over the anchor edge"/>
> +      <entry name="top" value="1"
> +	     summary="position above the anchor edge"/>
> +      <entry name="bottom" value="2"
> +	     summary="position below the anchor edge"/>
> +      <entry name="left" value="4"
> +	     summary="position to the left of the anchor edge"/>
> +      <entry name="right" value="8"
> +	     summary="position to the right of the anchor edge"/>
> +    </enum>
> +
> +    <request name="set_gravity">
> +      <description summary="set child surface gravity">
> +	The gravity defines in what direction a surface would be positioned,
> +	relative to the anchor edges on the parent surface. A gravity is a
> +	bit mask of up to two values of the gravity enum.
> +
> +	If two values on the same axis (for example left and right) are set the
> +	invalid_input error is raised.
> +
> +	If no gravity is set on an axis, the gravity for that axis will be
> +	equivalent to setting "none" for that axis, resulting in the child being
> +	centered over the anchor edges on that axis.
> +      </description>
> +      <arg name="gravity" type="uint" enum="gravity"
> +	   summary="bit mask of gravity directions"/>
> +    </request>
> +
> +    <enum name="constrain_adjustment" bitfield="true">
> +      <entry name="none" value="0">
> +	<description summary="don't move the child surface when constrained">
> +	  Don't alter the surface position even if it is constrained on some
> +	  axis, for example partially outside the edge of a monitor.
> +	</description>
> +      </entry>
> +      <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.
> +
> +	  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.
> +
> +	  If 'slide_x' is combined with 'flip_x', 'flip_x' takes precedence.
> +	</description>
> +      </entry>
> +      <entry name="slide_y" value="2">
> +	<description summary="move along the y axis until unconstrained">
> +	  Slide the surface along the y axis until it is no longer constrained.
> +
> +	  First try to slide towards the direction of the gravity on the y 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
> +	  y 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.
> +
> +	  If 'slide_y' is combined with 'flip_y', 'flip_y' takes precedence.
> +	</description>
> +      </entry>
> +      <entry name="flip_x" value="4">
> +	<description summary="invert the anchor and gravity on the x axis">
> +	  Invert the anchor and gravity on the x axis if the surface is
> +	  constrained on the x axis. For example, if the left edge of the
> +	  surface is constrained, the gravity is 'left' and the anchor is
> +	  'left', change the gravity to 'right' and the anchor to 'right'.
> +
> +	  If the adjusted position also ends up being constrained, the resulting
> +	  position will be the one before the adjustment. If the resulting
> +	  position is still constrained, and 'flip_x' is combined with
> +	  'slide_x', the position is adjusted according to 'slide_x'.
> +	</description>
> +      </entry>
> +      <entry name="flip_y" value="8">
> +	<description summary="invert the anchor and gravity on the y axis">
> +	  Invert the anchor and gravity on the y axis if the surface is
> +	  constrained on the y axis. For example, if the bottom edge of the
> +	  surface is constrained, the gravity is 'bottom' and the anchor is
> +	  'bottom', change the gravity to 'top' and the anchor to 'top'.
> +
> +	  If the adjusted position also ends up being constrained, the resulting
> +	  position will be the one before the adjustment. If the resulting
> +	  position is still constrained, and 'flip_y' is combined with
> +	  'slide_y', the position is adjusted according to 'slide_y'.
> +	</description>
> +      </entry>
> +    </enum>
> +
> +    <request name="set_constrain_adjustment">
> +      <description summary="set the adjustment to be done when constrained">
> +	Specify how the window should be positioned if the originally intended
> +	position caused the surface to be constrained, meaning at least
> +	partially outside positioning boundaries set by the compositor. The
> +	adjustment is set by constructing a bitmask describing the adjustment to
> +	be made when the surface is constrained on that axis.
> +
> +	If no bit for one axis is set, the compositor will assume that the child
> +	surface should not change its position on that axis when constrained.
> +
> +	If more than one bit for one axis is set, the order of how adjustments
> +	are applied is specified in the corresponding adjustment descriptions.
> +
> +	The default adjustment is none.
> +      </description>
> +      <arg name="constrain_adjustment" type="uint"
> +	   summary="bit mask of constrain adjustments"/>
> +    </request>
> +
> +    <request name="set_offset">
> +      <description summary="set surface position offset">
> +	Specify the surface position offset relative to the position of the
> +	anchor on the anchor rectangle and the anchor on the surface. For
> +	example if the anchor of the anchor rectangle is at (x, y), the surface
> +	has the gravity bottom|right, and the offset is (ox, oy), the calculated
> +	surface position will be (x + ox, y + oy). The offset position of the
> +	surface is the one used for constraint testing. See
> +	set_constrain_adjustment.
> +
> +	An example use case is placing a popup menu on top of a user interface
> +	element, while aligning the user interface element of the parent surface
> +	with some user interface element placed somewhere in the popup surface.
> +      </description>
> +      <arg name="x" type="int" summary="surface position x offset"/>
> +      <arg name="y" type="int" summary="surface position y offset"/>
> +    </request>
> +  </interface>
> +
>    <interface name="zxdg_surface_v6" version="1">
>      <description summary="desktop user interface surface base interface">
>        An interface that may be implemented by a wl_surface, for
> @@ -169,8 +414,7 @@
>        </description>
>        <arg name="id" type="new_id" interface="zxdg_popup_v6"/>
>        <arg name="parent" type="object" interface="zxdg_surface_v6"/>
> -      <arg name="x" type="int"/>
> -      <arg name="y" type="int"/>
> +      <arg name="positioner" type="object" interface="zxdg_positioner_v6"/>
>      </request>
>
>      <request name="set_window_geometry">
> @@ -729,7 +973,7 @@
>  	button press, key press, or touch down event. The serial number of the
>  	event should be passed as 'serial'.
>
> -	The parent of a grabbing popup must either be a xdg_toplevel surface or
> +	The parent of a grabbing popup must either be an xdg_toplevel surface or
>  	another xdg_popup with an explicit grab. If the parent is another
>  	xdg_popup it means that the popups are nested, with this popup now being
>  	the topmost popup.
> @@ -764,6 +1008,22 @@
>        <arg name="serial" type="uint" summary="the serial of the user event"/>
>      </request>
>
> +    <event name="configure">
> +      <description summary="configure the popup surface">
> +	This event asks the popup surface to configure itself given the
> +	configuration. The configured state should not be applied immediately.
> +	See xdg_surface.configure for details.
> +
> +	The x and y arguments represent the position the popup was placed at
> +	given the xdg_positioner rule, relative to the upper left corner of the
> +	window geometry of the parent surface.
> +      </description>
> +      <arg name="x" type="int"
> +	   summary="x position relative to parent surface window geometry"/>
> +      <arg name="y" type="int"
> +	   summary="y position relative to parent surface window geometry"/>
> +    </event>
> +
>      <event name="popup_done">
>        <description summary="popup interaction is done">
>  	The popup_done event is sent out when a popup is dismissed by the
>


-- 

Quentin “Sardem FF7” Glidic


More information about the wayland-devel mailing list