pub struct SemanticsRequester { /* private fields */ }Expand description
A handle an app holds to say that what its semantics recorder would report has changed.
A .semantics() recorder is re-run on every collection, so it always reports
the app’s current answer. It cannot say when that answer changed, and a
tree is only re-collected when some node marks its semantics dirty — which
until now meant attaching a node, rebuilding its modifier chain, or a layout
pass. A screen that is one Canvas does none of those: its layout never
changes and its frame loop draws rather than recomposes, so the tree it
published at boot was the tree a screen reader kept reading.
This is the way out, and it is Jetpack Compose’s:
SemanticsModifierNode.invalidateSemantics(). Remember one requester, hang
it on the same node as the recorder, and call invalidate when the content
changes — no recomposition, no layout pass.
let semantics = remember(SemanticsRequester::new).with(Clone::clone);
// ... in the composition:
Modifier::empty()
.semantics_requester(&semantics)
.semantics(move |config| { /* reads live app state */ })
// ... and in the frame loop, guarded by a revision so an unchanged tree is
// not republished every frame:
if revision != last_revision {
last_revision = revision;
semantics.invalidate();
}Implementations§
Source§impl SemanticsRequester
impl SemanticsRequester
pub fn new() -> Self
Sourcepub fn invalidate(&self)
pub fn invalidate(&self)
Marks the attached node’s semantics for re-collection on the next frame.
Idempotent within a frame and cheap: the node joins a set the shell drains once per frame. Before the node attaches, and after it detaches, this does nothing — there is no tree to mark.
Trait Implementations§
Source§impl Clone for SemanticsRequester
impl Clone for SemanticsRequester
Source§impl Debug for SemanticsRequester
impl Debug for SemanticsRequester
Auto Trait Implementations§
impl !RefUnwindSafe for SemanticsRequester
impl !Send for SemanticsRequester
impl !Sync for SemanticsRequester
impl !UnwindSafe for SemanticsRequester
impl Freeze for SemanticsRequester
impl Unpin for SemanticsRequester
impl UnsafeUnpin for SemanticsRequester
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> ErasedDestructor for Twhere
T: 'static,
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more