Repository navigation
Releases: timkrest/Underlay
Releases · timkrest/Underlay
Release list
0.4.0
implementation("com.timkrest:underlay:0.4.0")Added
liveSnapshotonblurredUnderlay. The host window is captured again every time it draws, one
capture in flight at a time, so a list scrolling under a popup shows through blurred a couple of
frames behind instead of frozen. Off by default: it costs aPixelCopyand a blur per host frame
for as long as the host keeps drawing.SystemBluris live on its own and ignores it.
Changed
:sampleopens itsPopupwithout taking the touches outside it, so the grid scrolls under an
open popup, and the panel carries a switch for the live snapshot.
0.3.1
implementation("com.timkrest:underlay:0.3.1")Fixed
SystemBlurwas reported from the intent to set the window flag, not from the window taking it.
APopupwhose root view had already left the window manager refused the update, and the overlay
reported a system blur while the host stayed sharp behind it. A refusal now falls through to a
snapshot, the same way a device with cross-window blur switched off does.- On a host window whose width or height is not a multiple of four,
PixelCopycaptured the whole
window into a bitmap that could not hold it at a flat quarter scale, whiledecorView.draw()
scaled by exactly a quarter. Placement assumes the quarter, so on thePixelCopypath the
backdrop was shifted, and the last one to three columns or rows of the window had none at all.
Both paths now cover the largest exact quarter that fits.
Changed
:samplecarries the radius slider inside the overlay card as well as in the panel: aDialog
and aPopupswallow the touches outside them, which left re-blurring an open overlay
unreachable. It also reports whether the device has cross-window blur at all, rather than only
pointing at Battery Saver once an overlay had already reachedSystemBlur.
0.3.0
implementation("com.timkrest:underlay:0.3.0")Added
UnderlayState.source: theUnderlaySourcethe overlay carrying the state draws from, as Compose
state. Null while no overlay carries it, so a badge outside the overlay clears on dismiss without
hosting the value fromonSourceChangeby hand. The callback stays for callers without a state.
Fixed
- The snapshot could spill up to three host pixels past the composable it backs, where its
placement rounds out to whole snapshot pixels. It is now clipped to the composable. - On API 31 and above with cross-window blur switched off, opening an overlay captured the host
window twice: the initial callback of the blur listener repeated the choicestart()had already
made. The source is now chosen only when the system's answer changes. - A detached node kept its
Activity,ConfigurationandWindowManageruntil it was collected.
0.2.0
implementation("com.timkrest:underlay:0.2.0")Added
UnderlayStateandrememberUnderlayState(), passed toModifier.blurredUnderlayasstate.
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
minSdkis 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
RenderEffecton the GPU from API 31, where the CPU box passes used
to run.Snapshotis 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. blurredUnderlayis aModifier.Nodeelement rather than a@Composablefunction, so the
modifier can be hoisted into avaloutside composition. Trailing-lambda call sites keep
compiling; a call that passedonSourceChangeas a fourth positional argument does not, because
that position takesstate. Code built against 0.1.0 needs a rebuild either way.
0.1.0
implementation("com.timkrest:underlay:0.1.0")Added
Modifier.blurredUnderlay(blurRadius, tint, fallback, onSourceChange)— a blurred backdrop for
overlays rendered in their own window, on API 24 and above.- Three-step degradation reported through
UnderlaySource:SystemBlur(FLAG_BLUR_BEHIND, API
31+),Snapshot(PixelCopyof the host window,decorView.draw()below API 26) andFallback
(a solid color). A fourth value,Pending, covers the frames where a capture is in flight: only
the tint is drawn there, so an overlay never flashes an opaque fallback on its way to a snapshot. - Live fall-through from
SystemBlurtoSnapshotwhen the system disables cross-window blur, via
WindowManager.addCrossWindowBlurEnabledListener. - Snapshot re-capture when the host window changes size or configuration. Changing only
blurRadiusre-blurs the pixels already captured rather than reading the window back again. :sampleapplication covering all four window kinds:Dialog,Popup, a translucent activity
and a plain in-window overlay.- Instrumentation coverage of every rung of the ladder, run on API 24, 28, 31 and 34: the software
decorViewdraw,PixelCopy, andFLAG_BLUR_BEHIND. The step each test asserts follows what the
device offers, not the API level, so a device with cross-window blur switched off is covered too.