v0.3.2 — fix overlay crash on first show

v0.3.1 introduced TouchInterceptor (a FrameLayout wrapping the
ComposeView) so we could intercept touches before the inner MapView
saw ACTION_DOWN. That made the wrapper the window-root view (the
View actually attached to WindowManager) but I left the
ViewTreeLifecycleOwner / ViewTreeSavedStateRegistryOwner tags on
the inner ComposeView.

Compose's WindowRecomposer.create looks up findViewTreeLifecycleOwner
on the window-root, not on the inner ComposeView. With the tag
missing on the wrapper, Compose throws IllegalStateException at
composition startup — service crash on overlay enable.

Fix: move setViewTreeLifecycleOwner + setViewTreeSavedStateRegistryOwner
to the wrapper. v0.3.0 worked because the ComposeView itself was the
window-root then; the same pattern (owners on whatever's attached
directly to WindowManager) holds here.
This commit is contained in:
2026-05-07 23:52:57 -04:00
parent eb26def14b
commit fc67d3d203
2 changed files with 9 additions and 4 deletions
+2 -2
View File
@@ -12,8 +12,8 @@ android {
applicationId = "org.soulstone.overwatch"
minSdk = 26
targetSdk = 35
versionCode = 13
versionName = "0.3.1"
versionCode = 14
versionName = "0.3.2"
}
buildTypes {
@@ -92,12 +92,17 @@ class OverlayManager(
val newOwner = OverlayOwner()
val composeView = ComposeView(context).apply {
setViewTreeLifecycleOwner(newOwner)
setViewTreeSavedStateRegistryOwner(newOwner)
setContent { OverlayBubble() }
}
// Wrap so we can intercept *before* MapView's own touch handling.
// Compose's WindowRecomposer reads findViewTreeLifecycleOwner from
// the *window-root* view (= the wrapper here, since it's what's
// attached to WindowManager). Setting the owner only on the inner
// ComposeView throws IllegalStateException at composition startup —
// that was the v0.3.1 crash.
val wrapper = TouchInterceptor(context).apply {
setViewTreeLifecycleOwner(newOwner)
setViewTreeSavedStateRegistryOwner(newOwner)
addView(
composeView,
FrameLayout.LayoutParams(