Skip to main content

Module placed_semantics

Module placed_semantics 

Source
Expand description

What a screen reader is told, and where each of those things actually is.

build_semantics_tree_from_applier answers the first half and carries no geometry at all; a LayoutBox carries the geometry and knows nothing about semantics. Every question of the form “is this control big enough / on the display / where the label says it is” needs both halves joined, and the join existed in exactly one place: inside the desktop robot, behind an AppShell, a window and an event loop. A unit test that wants to audit a widget tree’s touch targets could not reach it.

This is that join, headless. One composition, one measure pass, and a tree of PlacedSemanticsNode carrying two boxes per node, because they are two different questions and a Wear scaling list is precisely where they diverge:

  • PlacedSemanticsNode::layout_bounds is the box the measure pass gave the node — what the widget asked for and what an unscaled row occupies. This is the box the desktop robot reports, and the one to assert a widget’s own declared minimum against.
  • PlacedSemanticsNode::touch_bounds is the axis-aligned box the renderer draws and the hit test inverts, ancestor graphics layers included. A row that a scaling ramp shrinks to 0.73 is only tappable where it is drawn (cranpose-render-common’s a_shrunken_row_is_only_tappable_where_it_is_drawn settles that), so this is the box a finger has to find. It is None for a node the hit graph carries no region for — a label, a header, anything that is described but not dispatchable.

§Every walk here reads the RETAINED tree, deliberately

compute_layout returns a [LayoutTree] built from the Placements a MeasurePolicy returned. The scene the renderer is handed is not: build_graph_from_applier walks the retained node state and drops any node whose is_placed is false, and is_placed is set by placeable.place(x, y)not by pushing a Placement into a vec. The two disagreed once and a whole widget set laid out correctly in every assertion while reaching the device as an empty screen.

So the layout boxes here come from build_layout_tree_from_applier and not from the tree compute_layout hands back. All three walks — layout, semantics, scene — then apply the same is_placed filter, and a node that one of them loses is lost by all of them. A caller cannot be handed bounds for a control the renderer never drew.

Structs§

PlacedSemanticsNode
One semantics node, with the geometry it was placed and drawn at.

Functions§

placed_semantics_from_applier
Lay root out at size and read back its semantics with geometry.