Fix system Back ownership for titles and Home #67
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "fm/tv-back-title"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Outcome
Fix native Back ownership so a title returns to Home without removing Wolfskin’s task. From Home content, the next Back focuses navigation; Back from navigation exits. Preserve child menus, request sheets and unsaved-settings priority.
Base:
fm/tv-round2, starting atb51dced5fed48d719d1fb456378cedb2d9ad9ac0. The walked5fb37886has identical Back sources. AI-assisted implementation and PR description for this internal Wolfskin fork.Root causes
readShellKeymapped nativeKEYCODE_BACKto local logical Back. Title/Home Compose previews therefore acted on key-down, before the activity’s system completion. Native tests reproduced premature title pop and premature Home-nav focus on both SDK 34 and 36. Native Back now belongs only to Android’s dispatcher; the existing Escape shortcut remains local.No debounce, timer, ignored Back, row-name special case or fallback through old setup UI. Keep the root Back handler: Navigation 3 does not handle the single-entry root itself. Child callbacks still get first refusal through the activity dispatcher.
Changes
NavDisplay, loadedTitleDestination/person surface and Home. Cover normal and predictive dispatch, raw-key ownership and a second Back before recomposition.java.base/jdk.internal.accessexport. No dependency-version upgrade or production JVM flag.data/tv-spec/spec.mdanddocker/README.md. No layout, visual token, hero-transition, fetch-order or preset change.Verification — touched only
App coverage includes actual title/person normal and predictive callbacks, immediate second Back before exit recomposition, Home/Discover/Movies/Shows/Anime roots, cold/reopened picker, Coming-in dismissal, real Updates parent pops and unsaved Home Settings guards.
The selected app cohort first passed 43 cases; two title raw-key drivers did not synthesize WindowManager’s predictive completion from raw key-up under Robolectric/NavDisplay. Their navigation, focus and no-exit assertions were retained. The final driver injects raw key-down, verifies it did not navigate, then drives the actual activity dispatcher’s predictive start/progress/complete path; both SDK variants pass. There was no production change between that cohort and the final driver rerun. The Home-row hardware case exercises actual Activity key-down/key-up delivery.
Local evidence:
/root/.treehouse/firstmate-7bab20/2/firstmate/data/tv-r2-home/back-title/—before-sdk34/,before-sdk36/,after-app-first/,after-native-completion/,after-design/andnative/.Limits / integration risk
No full suite, APK build, device access, installation or merge. JVM/native callback proof does not replace the integrated emulator re-walk after the candidate is rebuilt. This is not dismissed as emulator-only: the failing ownership cases and repaired root/title paths exercise Android 14 / SDK 34 as well as SDK 36.
Review of the Back fix at head
a268cdd7b8d887157bcf6749a54c0f9ab0ccf4f1(basefm/tv-round2).Code verdict: APPROVE (
review/code-claude= success).Design verdict: PASS (
review/design-claude= success). Nothing visual changes.One owner per Back.
readShellKeyno longer mapsKey.Back, only Escape. I found no otherKey.BackorKEYCODE_BACKin the Wolfskin sources. Hardware Back therefore reaches Wolfskin only through the Activity dispatcher.TitleState.back).shell.key(Back), so their priority order is preserved.goBackon a one-entry stack.API 34 and 36.
onBackPressedand the dispatcher. [INFERENCE: not run on a device]Tests.
TitleEntryBackTestandWolfskinRootExitTestrun on sdk 34 and 36 with a real NavDisplay, the real activity dispatcher and rawKEYCODE_BACK. They cover the second Back before recomposition and the Home-row down/up path.Unrelated screens and merge. No layout, token or logic changes elsewhere. The Robolectric Android 16 runtime and its
--add-exportsare test-worker only. A merge-tree check against currentfm/tv-round2(985ebc53) is clean.Non-blocking notes:
handleWolfskinBackandhandleBackusebackStack.last(), which throws on an empty stack, where the old code usedlastOrNull(). The stack is only cleared and refilled synchronously on the main thread, so this cannot interleave. AlastOrNull() ?: returnwould be a free safety.Full report (review 6):
/root/.treehouse/firstmate-7bab20/2/firstmate/data/round2-review/report.md. Not run: Gradle/make, nothing on the box.