chore(tao): migrate decorated-window-tao to Compose 1.12.0-beta02 - #354
Draft
kdroidFilter wants to merge 1 commit into
Draft
chore(tao): migrate decorated-window-tao to Compose 1.12.0-beta02#354kdroidFilter wants to merge 1 commit into
kdroidFilter wants to merge 1 commit into
Conversation
kdroidFilter
force-pushed
the
chore/compose-1.12-beta02-tao
branch
from
July 26, 2026 11:44
f7870fd to
3799541
Compare
Adapt the no-AWT Tao backend to the Compose 1.12 ComposeScene API changes so it is ready for Compose 1.12 stable: - ComposeScene.render(canvas, nanoTime) is gone -> FrameRecomposer.performFrame + ComposeScene.measureAndLayout + ComposeScene.draw - scene factories take a FrameRecomposer + invalidateLayout/invalidateDraw instead of coroutineContext + invalidate; the FrameRecomposer owns the frame clock, so the manual per-host BroadcastFrameClock + sendFrame is removed - ComposeSceneContext.createLayer: compositionContext -> consumePointerInputOutside - ComposeSceneLayer.setContent(parentCompositionContext, content) + new consumePointerInputOutside property The scene create + render + dispose plumbing is centralized in TaoSceneBundle (scene/TaoSceneBundle.kt) so future Compose bumps touch one place. Each host, popup layer and overlay keeps `val scene get() = sceneBundle?.scene`, leaving its ~20 `scene?.…` call sites untouched. Behaviour is kept at parity with the 1.11 path (paced frameNs preserved for standalone popups, invalidations funnelled to the same coalescing scheduler). The offscreen scene test harness moves to the same bundle: its explicit sendFrame + pump is now performed inside recordSceneToPicture. All 78 decorated-window-tao tests pass unchanged, including the animation, popup, render and drift batteries. Compose 1.12 also pulls AndroidX Compose 1.12 into examples:cmp-demo's Android target, which requires AGP >= 9.1 and compileSdk 37: - agp 8.13.2 -> 9.1.1, cmp-demo compileSdk/targetSdk 35 -> 37 - android.builtInKotlin=false / android.newDsl=false: AGP 9 refuses com.android.application next to the KMP plugin and points at the KMP *library* plugin, which cmp-demo (a KMP module that builds a real Android app) cannot use without being split into a separate :androidApp module - plugin-build/plugin jvmTarget 11 -> 17: AGP 9 artifacts are built for 17 and are unresolvable from an 11-targeted consumer. Users now need a Gradle daemon on JVM 17+ (mandatory since Gradle 9 anyway) - drop a stray `org.jetbrains.skia.Surface` import from cmp-demo's commonMain: unused, and unresolvable on Android — that target had never compiled
kdroidFilter
force-pushed
the
chore/compose-1.12-beta02-tao
branch
from
July 26, 2026 12:14
3799541 to
1bcd42f
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
Get ahead of the Compose 1.12 release: the no-AWT
decorated-window-taobackend drives Compose's internal
androidx.compose.ui.scene.*APIs directly,so it's the one module that breaks on a minor Compose bump. This PR does that
migration against
1.12.0-beta02so we're ready to flip to1.12.0stable theday it ships (just move the catalog line).
What changed in the 1.12 ComposeScene API
ComposeScene.render(canvas, nanoTime)removed → three steps:FrameRecomposer.performFrame(nanoTime)+ComposeScene.measureAndLayout()+ComposeScene.draw(canvas).Canvas/PlatformLayersComposeScene) dropcoroutineContextinvalidate; now take aFrameRecomposer(which owns the frame clock) +invalidateLayout/invalidateDraw. The manual per-hostBroadcastFrameClockand
frameClock.sendFrame()calls are gone.ComposeSceneContext.createLayer:compositionContext→consumePointerInputOutside.ComposeSceneLayer.setContent(parentCompositionContext, content)+ new abstractconsumePointerInputOutsideproperty.Approach
Scene create/render/dispose plumbing is centralized in
TaoSceneBundle(
scene/TaoSceneBundle.kt). Each host/popup/overlay stores aTaoSceneBundle?and keeps
val scene get() = sceneBundle?.scene, so the ~20scene?.…callsites per file are untouched — only create/render/close move. Future Compose
bumps touch one file for the shared logic.
Behaviour is kept at parity with the 1.11 path: the paced
frameNsis still fedto the frame clock for standalone popups, and every invalidation
(
invalidateLayout/invalidateDraw+ the recomposer's own) funnels into thesame coalescing frame scheduler that
invalidateused before.The offscreen scene test harness (
TaoSceneTestHarness, added after the firstrevision of this PR) moves onto the same bundle: its explicit
frameClock.sendFrame+ secondpumpUntilIdleis now performed insiderecordSceneToPicture→FrameRecomposer.performFrame, which flushes its owndispatchers around the tick.
Note:
SingleComposeSceneRenderingScopeCompose Desktop's AWT path wraps the three render calls in
SingleComposeSceneRenderingScope.render, but that method is Kotlin-internal(JVM-public, module-private) and invisible to external backends.
TaoSceneBundleinlines
performFrame→measureAndLayout→drawdirectly. The only thinglost vs. upstream is its
isRendering-guarded invalidation de-dup — which theold Tao code didn't have either, and the FrameDispatcher coalescing covers it.
Fallout: AGP 9 / Java 17
Compose 1.12 also pulls AndroidX Compose 1.12 into
examples:cmp-demo's Androidtarget, which requires AGP ≥ 9.1 and compileSdk 37. That cascades:
agp8.13.2 → 9.1.1 (9.2+ needs Gradle ≥ 9.4.1, we're on 9.4.0), cmp-democompileSdk/targetSdk35 → 37.android.builtInKotlin=false+android.newDsl=false: since AGP 9,com.android.applicationis rejected alongside the KMP plugin, which points atcom.android.kotlin.multiplatform.library— a library plugin, unusable forcmp-demo (a KMP module that builds a real Android app) without splitting it into
a separate
:androidAppmodule. These are AGP's documented escape hatches.plugin-build/pluginjvmTarget 11 → 17 — AGP 9 artifacts are built for 17and can't be resolved by an 11-targeted consumer. User-visible: the Nucleus
Gradle plugin now needs a Gradle daemon on JVM 17+ (mandatory since Gradle 9
anyway; Gradle 8 + JVM 11 setups are no longer supported).
org.jetbrains.skia.Surfaceimport from cmp-demo'scommonMain— unused, and unresolvable on Android. That target had nevercompiled; it does now (verified
assembleDebug).Verification
JBR 21,
BUILD SUCCESSFUL, ktlint + detekt + apiCheck clean::decorated-window-tao:check— 78 tests pass, including the animation,pointer, popup, render and battery-drift suites that exercise the new frame
path (
--rerun-tasks).assembleacross the whole project, incl.:examples:cmp-demo:assembleDebug(Android), the jni / jbr / jewel / material2 / material3 backends,
graalvm-runtime,nucleus-application, and the tao examples.plugin-build::plugin:check+:plugin:validatePlugins— 209/210 testspass at jvmTarget 17.
checkset for every module listed in thepreMergetask.Two pre-existing local failures, both reproduced on unmodified
mainandunrelated to this PR (both are environment-specific, not Compose-related):
:fs-watcher:testhangs on the real-filesystem test, andLinuxSignerTestfails at
gpg --gen-key.Not done: native runtime smoke tests on macOS / Windows / Linux (headful
window/popup behaviour).
Before merge
composeline to1.12.0stable (not yet published)