implementation("com.timkrest:underlay:0.2.0")
Added
UnderlayState and rememberUnderlayState(), passed to Modifier.blurredUnderlay as state.
refresh() captures the host window again, for content that moves underneath an open overlay.
The snapshot on screen stays until the new one is ready, so a refresh does not flash.
Changed
minSdk is 23, down from 24 - the floor Compose itself declares. CI runs the instrumentation
suite on API 23, 26, 28, 31 and 34.
- A capture waits for the frame it was asked from to reach the screen.
UnderlayState.refresh()
called right after changing the content underneath now captures that change rather than the
frame before it.
- The CPU blur radius is the one whose three box passes land closest to the requested Gaussian.
The previous SVG approximation rounded some radii down to no blur and undershot the rest by up
to 29%.
- A snapshot that covers only part of the composable is drawn at its capture scale over that part
instead of being stretched across the whole of it.
- The snapshot is blurred with
RenderEffect on the GPU from API 31, where the CPU box passes used
to run. Snapshot is reached when the system switches cross-window blur off, which is usually
battery saver - the moment CPU is least available. Below API 31 the platform ignores
RenderEffect, so the box blur stays.
blurredUnderlay is a Modifier.Node element rather than a @Composable function, so the
modifier can be hoisted into a val outside composition. Trailing-lambda call sites keep
compiling; a call that passed onSourceChange as a fourth positional argument does not, because
that position takes state. Code built against 0.1.0 needs a rebuild either way.