blob: ba1b77d34317a6a971157365d8ebaaae5861fb74 [file] [log] [blame] [view]
<link rel="stylesheet" href="../style.css" />
[TOC]
# fuchsia.ui.observation.geometry
<div class="fidl-version-div"><span class="fidl-attribute fidl-version">Added: 9</span></div>
## **PROTOCOLS**
## ViewTreeWatcher {#ViewTreeWatcher}
*Defined in [fuchsia.ui.observation.geometry/watcher.fidl](https://cs.opensource.google/fuchsia/fuchsia/+/main:sdk/fidl/fuchsia.ui.observation.geometry/watcher.fidl;l=67)*
<p>A method of obtaining view tree snapshots for a particular view, the &quot;context
view&quot;, and its child views, if any. The returned data is a sequence of
snapshots during the period of observation, which starts at the client's
prior Watch() call's <a class='link' href='#epoch_end'>epoch_end</a> (or zx.time 0), and ending at the
current <a class='link' href='#epoch_end'>epoch_end</a>. The timebase is ZX_CLOCK_MONOTONIC.</p>
<p>Clients typically obtain a <code>ViewTreeWatcher</code> capability from within a test,
and it is not generally possible to obtain outside of a test environment.
For more information see <code>fuchsia.ui.observation.test.Registry</code> and
<code>fuchsia.ui.test.scene.Controller</code>.</p>
<p>Usage note. With this protocol, a client can watch for changes to the view
tree over which it has authority. For example, if a client owns view A, then
A serves as the context view for A's subtree (i.e., a &quot;root view&quot;), where A
is a parent of view B, and B is a parent of view C. The client can then
observe key lifecycle events in all of A, B, and C, such as newly connected
views, changes to view position and size, etc. In doing so, a client can
gate its actions on changes to the view tree, in a reliable and ergonomic
manner. For example, a client can wait for a descendant view C to become
connected before requesting a focus transfer to C.</p>
<p>Configuration: The context view is determined outside of this protocol.</p>
<p>Frequency: A client can receive one or more snapshots per frame. Clients
should not &quot;count snapshots&quot;, as the per-frame snapshot count can be
non-deterministic. Instead, clients should look for specific conditions on
the snapshot state.</p>
<p>Issuance: If the context view is disconnected from a display, no
frames are issued on behalf of the context view, and a Watch() call will
sit quietly.</p>
<p>Lifecycle: The server endpoint is closed when the context view dies.</p>
### Watch {#ViewTreeWatcher.Watch}
<p>A method of obtaining view tree snapshots for a particular view.</p>
<p>This call is formulated as a &quot;hanging get&quot; pattern: the client asks for
a set of recent snapshots, and receives them via the callback. This
pull-based approach ensures that clients consume events at their own
pace; events don't clog up the channel in an unbounded manner.</p>
<p>Error Handling. If Error is unset, the client may assume that the
the response contains updates with complete information over its epoch.</p>
<p>Flow control. The caller is allowed at most one in-flight |Watch| call
at a time; it is a logical error to have concurrent calls to |Watch|.
Non-compliance results in channel closure.</p>
<p>Client pacing. The server will dispatch snapshots to the caller on a
lossless, best-effort basis, but the caller must allocate enough time to
keep up with new snapshots.</p>
#### Request {#ViewTreeWatcher.Watch_Request}
&lt;EMPTY&gt;
#### Response {#ViewTreeWatcher.Watch_Response}
<table>
<tr><th>Name</th><th>Type</th></tr>
<tr>
<td><code>payload</code></td>
<td>
<code><a class='link' href='#WatchResponse'>WatchResponse</a></code>
</td>
</tr>
</table>
## **STRUCTS**
### AlignedExtent {#AlignedExtent data-text="AlignedExtent"}
*Defined in [fuchsia.ui.observation.geometry/watcher.fidl](https://cs.opensource.google/fuchsia/fuchsia/+/main:sdk/fidl/fuchsia.ui.observation.geometry/watcher.fidl;l=139)*
<p>A view's bounding box, described in the view's own coordinate system.
Concretely, |AlignedExtent| describes the minimal and maximal points of a
view's bounding box, which is rectangular and axis-aligned.</p>
<p>Note: For describing a view's bounding box in another view's coordinate
system, see |RotatableExtent|.</p>
<p>The origin is min.
The size is: (abs(max.x - min.x), abs(max.y - min.y)).</p>
<table>
<tr><th>Field</th><th>Type</th><th>Description</th><th>Default</th></tr>
<tr id="AlignedExtent.min">
<td><code>min</code></td>
<td>
<code><a class='link' href='../fuchsia.math/'>fuchsia.math</a>/<a class='link' href='../fuchsia.math/#PointF'>PointF</a></code>
</td>
<td><p>The minimal position of the view's bounding box.</p>
</td>
<td>No default</td>
</tr>
<tr id="AlignedExtent.max">
<td><code>max</code></td>
<td>
<code><a class='link' href='../fuchsia.math/'>fuchsia.math</a>/<a class='link' href='../fuchsia.math/#PointF'>PointF</a></code>
</td>
<td><p>The maximal position of the view's bounding box.</p>
</td>
<td>No default</td>
</tr>
</table>
### Layout {#Layout data-text="Layout"}
*Defined in [fuchsia.ui.observation.geometry/watcher.fidl](https://cs.opensource.google/fuchsia/fuchsia/+/main:sdk/fidl/fuchsia.ui.observation.geometry/watcher.fidl;l=195)*
<p>Geometric data of a view.</p>
<p>Note that these are server-side values, and some graphics APIs do not have
consistency guarantees with UI clients around when these values &quot;take
effect&quot;. I.e., the UI client may need to be directly queried to learn what
values they are currently using. However, UI clients are expected to use
these values &quot;immediately&quot;, within a few frames.</p>
<table>
<tr><th>Field</th><th>Type</th><th>Description</th><th>Default</th></tr>
<tr id="Layout.extent">
<td><code>extent</code></td>
<td>
<code><a class='link' href='#AlignedExtent'>AlignedExtent</a></code>
</td>
<td><p>The minimal and maximal points of a view's bounding box, in the
coordinate system of that view.</p>
</td>
<td>No default</td>
</tr>
<tr id="Layout.pixel_scale">
<td><code>pixel_scale</code></td>
<td>
<code><a class='link' href='#PixelScale'>PixelScale</a></code>
</td>
<td><p>The conversion ratio from physical pixels (of a display) to logical pixels
(of the coordinate system of the view).</p>
</td>
<td>No default</td>
</tr>
<tr id="Layout.inset">
<td><code>inset</code></td>
<td>
<code><a class='link' href='../fuchsia.math/'>fuchsia.math</a>/<a class='link' href='../fuchsia.math/#InsetF'>InsetF</a></code>
</td>
<td><p>The offset data for the view's bounding box, in the coordinate system of
that view.</p>
</td>
<td>No default</td>
</tr>
</table>
### RotatableExtent {#RotatableExtent data-text="RotatableExtent"}
*Defined in [fuchsia.ui.observation.geometry/watcher.fidl](https://cs.opensource.google/fuchsia/fuchsia/+/main:sdk/fidl/fuchsia.ui.observation.geometry/watcher.fidl;l=167)*
<p>A view bounding box, described in another view's coordinate system.
Concretely, |RotatableExtent| describes the origin, size, and rotation angle
about the origin, for a view's bounding box.</p>
<p>Note: For describing a view's bounding box in the view's own coordinate
system, see |AlignedExtent|.</p>
<p>We use &quot;V&quot; to refer to the view being described, and &quot;W&quot; to refer to the
view where V is being described.</p>
<p>Note that while |angle| can be arbitrary, typical usage is axis aligned.
To find the bounding box of V in W in clockwise order, starting with
|origin|, where |angle| is 0, 90, 180, or 270, and using o=origin, w=width,
h=height, a=angle:
a= 0: (o.x, o.y), (o.x + w, o.y), (o.x + w, o.y + h), (o.x, o.y + h)
a= 90: (o.x, o.y), (o.x, o.y - w), (o.x + h, o.y - w), (o.x + h, o.y)
a=180: (o.x, o.y), (o.x - w, o.y), (o.x - w, o.y - h), (o.x, o.y - h)
a=270: (o.x, o.y), (o.x, o.y + w), (o.x - h, o.y + w), (o.x - h, o.y)
A formula based on sin a and cos a is readily obtained, but floating point
computation may give only approximate results.</p>
<table>
<tr><th>Field</th><th>Type</th><th>Description</th><th>Default</th></tr>
<tr id="RotatableExtent.origin">
<td><code>origin</code></td>
<td>
<code><a class='link' href='../fuchsia.math/'>fuchsia.math</a>/<a class='link' href='../fuchsia.math/#PointF'>PointF</a></code>
</td>
<td><p>The origin point of V's bounding box, in W's coordinate system.</p>
</td>
<td>No default</td>
</tr>
<tr id="RotatableExtent.width">
<td><code>width</code></td>
<td>
<code>float32</code>
</td>
<td><p>The width of V's bounding box (along the direction where V's x axis
increases), in W's coordinate system.</p>
</td>
<td>No default</td>
</tr>
<tr id="RotatableExtent.height">
<td><code>height</code></td>
<td>
<code>float32</code>
</td>
<td><p>The height of V's bounding box (along the direction where V's y axis
increases), in W's coordinate system.</p>
</td>
<td>No default</td>
</tr>
<tr id="RotatableExtent.angle_degrees">
<td><code>angle_degrees</code></td>
<td>
<code>float32</code>
</td>
<td><p>The clockwise rotation about the origin, in degrees.</p>
</td>
<td>No default</td>
</tr>
</table>
## **TABLES**
### ViewDescriptor {#ViewDescriptor data-text="ViewDescriptor"}
*Defined in [fuchsia.ui.observation.geometry/watcher.fidl](https://cs.opensource.google/fuchsia/fuchsia/+/main:sdk/fidl/fuchsia.ui.observation.geometry/watcher.fidl;l=210)*
<p>Data for a particular view: identifier, position, and children.</p>
<table>
<tr><th>Ordinal</th><th>Field</th><th>Type</th><th>Description</th></tr>
<tr id="ViewDescriptor.view_ref_koid">
<td><h3 id="ViewDescriptor.view_ref_koid" class="add-link hide-from-toc">1</h3></td>
<td><code>view_ref_koid</code></td>
<td>
<code><a class='link' href='../zx/'>zx</a>/<a class='link' href='../zx/#koid'>koid</a></code>
</td>
<td><p>This view's fuchsia.ui.views.ViewRef koid.</p>
</td>
</tr>
<tr id="ViewDescriptor.layout">
<td><h3 id="ViewDescriptor.layout" class="add-link hide-from-toc">2</h3></td>
<td><code>layout</code></td>
<td>
<code><a class='link' href='#Layout'>Layout</a></code>
</td>
<td><p>This view's origin, logical size, pixel scale, and inset data, in the view's
own coordinate system.</p>
<p>Limitations. Data consistency between server and client depend on the
specific graphics API. Some APIs provide weak consistency, where the
server-side data (this data) and the client-side data (in the view's UI
client) are allowed to diverge for some time.</p>
</td>
</tr>
<tr id="ViewDescriptor.extent_in_context">
<td><h3 id="ViewDescriptor.extent_in_context" class="add-link hide-from-toc">3</h3></td>
<td><code>extent_in_context</code></td>
<td>
<code><a class='link' href='#RotatableExtent'>RotatableExtent</a></code>
</td>
<td><p>This view's extent, in the context view's coordinate system.
It does NOT describe the child view's logical size.</p>
<p>This describes the &quot;ground truth&quot; position of this view within the context
view, regardless of view tree depth, or specific layout state of
intermediate views.</p>
<p>Limitations. It does NOT describe whether the view is &quot;visible&quot; (e.g.,
whether the view has opacity applied, or is not occluded by another view),
and it does NOT describe whether the view is &quot;hittable&quot; (e.g., whether the
view is positioned fully inside of every ancestor view's bounding box).</p>
</td>
</tr>
<tr id="ViewDescriptor.extent_in_parent">
<td><h3 id="ViewDescriptor.extent_in_parent" class="add-link hide-from-toc">4</h3></td>
<td><code>extent_in_parent</code></td>
<td>
<code><a class='link' href='#RotatableExtent'>RotatableExtent</a></code>
</td>
<td><p>The space occupied within the parent view's coordinate system.
It does NOT describe the child view's logical size.</p>
</td>
</tr>
<tr id="ViewDescriptor.children">
<td><h3 id="ViewDescriptor.children" class="add-link hide-from-toc">5</h3></td>
<td><code>children</code></td>
<td>
<code>vector&lt;uint32&gt;[300]</code>
</td>
<td><p>The list of child views, in the order known to the graphics API.</p>
<p>Each integer in this vector refers to the child's position in the
|views| or |incomplete| vector that the parent is in.</p>
<p>The identity, position, and size of each child view. Position and size are
described by the extent of the child view within the parent view's
coordinate system.</p>
<p>The view tree topology is reliable. A child placed here is equivalent to
the parent view receiving a &quot;child view connected&quot; signal.</p>
<p>Limitations. A child's view boundary is described in the parent view's
coordinate system, which is subject to weak consistency (depending on the
graphics API). That is, when a parent view has a change in size or metrics,
the context view may observe a &quot;jump&quot; as the parent view incorporates those
data. In such cases, a new ViewTreeSnapshot is issued to describe the
change in position, relative to the context view.</p>
</td>
</tr>
</table>
### ViewTreeSnapshot {#ViewTreeSnapshot data-text="ViewTreeSnapshot"}
*Defined in [fuchsia.ui.observation.geometry/watcher.fidl](https://cs.opensource.google/fuchsia/fuchsia/+/main:sdk/fidl/fuchsia.ui.observation.geometry/watcher.fidl;l=102)*
<p>A description of the context view and its descendant views, if any.</p>
<table>
<tr><th>Ordinal</th><th>Field</th><th>Type</th><th>Description</th></tr>
<tr id="ViewTreeSnapshot.time">
<td><h3 id="ViewTreeSnapshot.time" class="add-link hide-from-toc">1</h3></td>
<td><code>time</code></td>
<td>
<code><a class='link' href='../zx/'>zx</a>/<a class='link' href='../zx/#time'>time</a></code>
</td>
<td><p>When the snapshot was taken. Timebase is monotonic time.</p>
</td>
</tr>
<tr id="ViewTreeSnapshot.views">
<td><h3 id="ViewTreeSnapshot.views" class="add-link hide-from-toc">2</h3></td>
<td><code>views</code></td>
<td>
<code>vector&lt;<a class='link' href='#ViewDescriptor'>ViewDescriptor</a>&gt;[300]</code>
</td>
<td><p>The context view (at element 0) and a complete list of its descendant views.</p>
<p>If <code>MAX_VIEW_COUNT</code> is exceeded, this field is not set, and an error is reported in
<code>Error</code>.</p>
</td>
</tr>
</table>
### WatchResponse {#WatchResponse data-text="WatchResponse"}
*Defined in [fuchsia.ui.observation.geometry/watcher.fidl](https://cs.opensource.google/fuchsia/fuchsia/+/main:sdk/fidl/fuchsia.ui.observation.geometry/watcher.fidl;l=89)*
<p>Response for fuchsia.ui.observation.geometry.ViewTreeWatcher.Watch.</p>
<table>
<tr><th>Ordinal</th><th>Field</th><th>Type</th><th>Description</th></tr>
<tr id="WatchResponse.epoch_end">
<td><h3 id="WatchResponse.epoch_end" class="add-link hide-from-toc">1</h3></td>
<td><code>epoch_end</code></td>
<td>
<code><a class='link' href='../zx/'>zx</a>/<a class='link' href='../zx/#time'>time</a></code>
</td>
<td><p>When the response is sent. Timebase is monotonic time.</p>
</td>
</tr>
<tr id="WatchResponse.updates">
<td><h3 id="WatchResponse.updates" class="add-link hide-from-toc">2</h3></td>
<td><code>updates</code></td>
<td>
<code>vector&lt;<a class='link' href='#ViewTreeSnapshot'>ViewTreeSnapshot</a>&gt;[200]</code>
</td>
<td><p>A list of most recent updates for a particular view.</p>
</td>
</tr>
<tr id="WatchResponse.error">
<td><h3 id="WatchResponse.error" class="add-link hide-from-toc">3</h3></td>
<td><code>error</code></td>
<td>
<code><a class='link' href='#Error'>Error</a></code>
</td>
<td><p>Only set if an error condition is detected. If unset, the client may assume
that updates has complete information over its epoch.</p>
</td>
</tr>
</table>
## **BITS**
### Error [flexible](/fuchsia-src/reference/fidl/language/language.md#strict-vs-flexible){:.fidl-attribute} {#Error}
Type: <code>uint32</code>
*Defined in [fuchsia.ui.observation.geometry/watcher.fidl](https://cs.opensource.google/fuchsia/fuchsia/+/main:sdk/fidl/fuchsia.ui.observation.geometry/watcher.fidl;l=114)*
<table>
<tr><th>Name</th><th>Value</th><th>Description</th></tr>
<tr id="Error.CHANNEL_OVERFLOW">
<td><h3 id="Error.CHANNEL_OVERFLOW" class="add-link hide-from-toc">CHANNEL_OVERFLOW</h3></td>
<td>1</td>
<td><p>Set to true when appending a <code>ViewTreeSnapshot</code> in <code>WatchResponse.updates</code>
would exceed the limit of the FIDL channel. That snapshot is dropped, along with
older snapshots.</p>
</td>
</tr>
<tr id="Error.BUFFER_OVERFLOW">
<td><h3 id="Error.BUFFER_OVERFLOW" class="add-link hide-from-toc">BUFFER_OVERFLOW</h3></td>
<td>2</td>
<td><p>Set to true when appending a <code>ViewTreeSnapshot</code> in <code>WatchResponse.updates</code>
would exceed <code>BUFFER_SIZE</code>. That snapshot is dropped, along with older snapshots.</p>
</td>
</tr>
<tr id="Error.VIEWS_OVERFLOW">
<td><h3 id="Error.VIEWS_OVERFLOW" class="add-link hide-from-toc">VIEWS_OVERFLOW</h3></td>
<td>4</td>
<td><p>Set to true when the size of <code>views</code> in a <code>ViewTreeSnapshot</code> exceeds
<code>MAX_VIEW_COUNT</code>. We represent this situation in the <code>ViewTreeSnapshot</code> with an
unset <code>views</code> field.</p>
</td>
</tr>
</table>
## **CONSTANTS**
<table>
<tr><th>Name</th><th>Value</th><th>Type</th><th>Description</th></tr>
<tr id="BUFFER_SIZE">
<td><a href="https://cs.opensource.google/fuchsia/fuchsia/+/main:sdk/fidl/fuchsia.ui.observation.geometry/watcher.fidl;l=21">BUFFER_SIZE</a></td>
<td>
<code>200</code>
</td>
<td><code>uint32</code></td>
<td><p>The maximum number of <code>ViewTreeSnapshot</code>s a client can expect in a <code>Watch</code> call's
response. The number of <code>ViewTreeSnapshot</code>s can be less than <code>BUFFER_SIZE</code> when
the size of a <code>Watch</code> call's response exceeds the limit of a FIDL channel.</p>
<p>There is a limit on the number of <code>ViewTreeSnapshot</code>s that can be included in a
<code>Watch</code> call's response due to the size restrictions of a FIDL channel. This limit
was calculated by finding out the maximum number of <code>ViewTreeSnapshot</code>s which can be
included in a <code>Watch</code> call's response when <code>MAX_VIEW_COUNT</code> is 1.</p>
<p>Note: This value would have to adjusted when modifying <code>ViewTreeSnapshot</code> or
<code>ViewDescriptor</code>.</p>
</td>
</tr>
<tr id="MAX_VIEW_COUNT">
<td><a href="https://cs.opensource.google/fuchsia/fuchsia/+/main:sdk/fidl/fuchsia.ui.observation.geometry/watcher.fidl;l=32">MAX_VIEW_COUNT</a></td>
<td>
<code>300</code>
</td>
<td><code>uint32</code></td>
<td><p>The maximum number of <code>ViewDescriptor</code>s a client can expect in a
<code>ViewTreeSnapshot</code>.</p>
<p>There is a limit on the number of <code>ViewDescriptor</code>s that can be included in a
<code>ViewTreeSnapshot</code> due to the size restrictions of a FIDL channel. This limit was
calculated by finding out the maximum number of <code>ViewDescriptor</code>s which can be
included in a <code>ViewTreeSnapshot</code> when the <code>BUFFER_SIZE</code> is 1.</p>
<p>Note: This value would have to adjusted when modifying <code>ViewDescriptor</code>.</p>
</td>
</tr>
</table>
## **ALIASES**
<table>
<tr><th>Name</th><th>Value</th><th>Description</th></tr>
<tr id="PixelScale">
<td><a href="https://cs.opensource.google/fuchsia/fuchsia/+/main:sdk/fidl/fuchsia.ui.observation.geometry/watcher.fidl;l=186">PixelScale</a></td>
<td>
<code>array</code>[<code>2</code>]</td>
<td><p>The ratio from physical pixels (of a display) to logical pixels (of the
coordinate system of a view).</p>
<ul>
<li>The values are placed in (x, y) order.</li>
</ul>
</td>
</tr>
</table>