fix(application): keep window content on the UI applier (#636) [2.6] - #649
Merged
kdroidFilter merged 1 commit intoSep 5, 2026
Merged
Conversation
Port of 4126663 to 2.6, extended to the branch's own window openers. The window and dialog openers had their composition target inferred, so a single non-UI-targeted composable called in the `nucleusApplication` scope (the Compose compiler bakes `@ComposableTarget` onto any unmarked factory forwarding a target-marked content lambda) reclassified the whole scope — nested windows included — and every `@UiComposable` call in it warned, which is fatal under `-Werror`. Declare each opener `@ComposableOpenTarget(-1)` with `@UiComposable` content lambdas, the way Compose Desktop's own `Window`/`Dialog` are open: they are callable from any applier and always compose UI content in the new window's own composition, so neither direction of the applier leak survives. Covers `DecoratedWindow`/`DecoratedDialog`, the `NucleusWindowHost` / `NucleusDialogHost` interfaces with their default implementations, `HostedWindow`/`HostedDialog`, `SatelliteWindow`, `Satellite`, `Tab`, and Tao's equivalents plus `TaoStandalonePopup`. `TabWindows`, the v2 `DecoratedWindow`/`DecoratedDialog` and `DragGhostWindow` already infer the same scheme (`[_[UiComposable]]`), as do the Material/Jewel wrappers. Once a declaration carries an explicit target, inference stops for all of it: every composable lambda parameter needs the annotation, not just `content`. `Satellite`'s `floatingContentWrapper` was the one case where leaving one unmarked kept dragging the caller's applier into the satellite content. `COMPOSE_APPLIER_CALL_MISMATCH` is only a warning, so both test compilations escalate it to an error and a fixture per module compiles the reported shape (non-UI factory in the application scope, UI content in every window).
Draft
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.
Port de #648 (commit
41266637) surnucleus-2.6, étendu aux ouvreurs de fenêtres propres à cette branche.Rappel du bug (#636)
Les ouvreurs de fenêtres/dialogues laissaient le compilateur inférer leur cible de composition (
[0[0]]) : un seul jeton liait l'applier de l'appelant à celui du contenu. Un composable non-UI appelé dans le scopenucleusApplication— le compilateur colle@ComposableTargetsur toute factory non annotée qui transmet un lambda de contenu marqué, cf.rememberMapStatede MapLibre Compose — reclassait tout le scope, fenêtres imbriquées incluses, et chaque appel@UiComposabledéclenchait un warning (fatal avec-Werror).Correctif
Chaque ouvreur est
@ComposableOpenTarget(-1)avec des lambdas de contenu@UiComposable: appelable depuis n'importe quel applier, et contenu toujours composé en UI dans la composition propre de la fenêtre.Couvert :
DecoratedWindow/DecoratedDialog, les interfacesNucleusWindowHost/NucleusDialogHost+ implémentations par défaut,HostedWindow/HostedDialog,SatelliteWindow,Satellite,Tab(nouveaux en 2.6), et les équivalents Tao +TaoStandalonePopup.Déjà corrects par inférence, laissés tels quels (vérifié dans le bytecode) :
TabWindows, lesDecoratedWindow/DecoratedDialogv2,DragGhostWindow, et les wrappers Material 2/3 / Jewel — tous en[_[androidx.compose.ui.UiComposable]].Point non évident
Dès qu'une déclaration porte une cible explicite, l'inférence s'arrête pour toute la déclaration : chaque paramètre lambda composable doit être annoté, pas seulement
content.floatingContentWrapperdeSatelliteétait le cas concret — le laisser nu continuait de faire entrer l'applier de l'appelant dans le contenu du satellite. La fixture passe désormais explicitementfloatingContentWrapper,header,stripetwindowContentWrapperpour couvrir ça.Garde anti-régression
COMPOSE_APPLIER_CALL_MISMATCHn'est qu'un warning :compileTestKotlinl'escalade en erreur (-Xwarning-level) dans les deux modules, et uneComposableTargetIsolationFixturepar module compile la forme rapportée (factory non-UI dans le scope application, contenu UI dans chaque fenêtre).Vérifications
Conflits du cherry-pick (en-têtes de fichier + imports des 3 fichiers de
nucleus-application) résolus à la main.apiCheck,detekt,ktlintCheckettestClassespassent ; aucun changement à l'exécution (annotations de compilation uniquement).🤖 Generated with Claude Code