Nucleus
Concepts

Backends

Deux backends de fenêtre derrière le même DecoratedWindow — AWT (legacy, JBR) ou Tao (la nouvelle valeur par défaut en 2.0, fenêtrage natif Rust).

Chaque fenêtre Nucleus est un @Composable. Ce qui la pilote en dessous — la pompe d'événements OS, la possession du handle de fenêtre, la mise à l'écran de la surface GPU Skia — c'est le backend. La 2.0 en livre deux.

L'essentiel

  • AWT (défaut avant la 2.0) : JetBrains Runtime ou OpenJDK standard. Mature, éprouvé, lié à AWT.
  • Tao (nouveau en 2.0, défaut opt-in) : sans AWT. Fenêtrage natif Rust, Wayland natif, multi-touch, stylet, ~60 Mo de RAM sur un Hello World GraalVM.
  • Même API DecoratedWindow. Un seul paramètre de constructeur pour basculer.

AWT — decorated-window-jbr & decorated-window-jni

Le chemin AWT pilote Compose via ComposeWindow / ComposeDialog. Deux saveurs :

  • decorated-window-jbr — utilise l'API de décorations custom de la JetBrains Runtime sur Windows/Linux, plus un petit bridge Cocoa pour les ajustements NSWindow sur macOS. Par défaut quand on livre JBR.
  • decorated-window-jni — la même API DecoratedWindow pour qui ne peut pas livrer JBR. Des bridges JNI par OS parlent à DWM, aux shims CSD X11/Wayland, et à NSWindow directement.

Les deux dépendent de decorated-window-awt, qui contient le code Compose partagé (TitleBar, hit-testing, boutons, drag handler).

Quand garder AWT :

  • En cas de besoin de toute la surface d'intégration AWT (file dialogs, helpers clipboard, interop Swing).
  • Pour qui livre JBR pour les contrôles de fenêtre soignés et on veut le chemin de moindre résistance.
  • Pour qui cible une stack que les bridges JNI couvrent déjà et on n'a pas besoin de Wayland natif ni de multi-touch.

Tao — decorated-window-tao

Tao est la couche de fenêtrage Rust qui sous-tend Tauri 2. Nucleus 2.0 en fait le défaut pour les nouveaux projets — apportant des primitives desktop modernes que JBR ne peut pas atteindre.

Ce que Tao débloque :

  • Wayland natif. Support Wayland de première classe — pas de fallback XWayland, scaling fractionnel, gestures.
  • Multi-touch & gestures. Pinch, swipe, rotate — chaque PointerEvent Compose porte la pression, l'inclinaison et la source.
  • Stylet. Entrée pression-sensible sur tous les OS — Wacom, Surface Pen, Apple Pencil sidecar.
  • HiDPI par moniteur. Configurations mixed-DPI gérées de façon transparente. Déplace une fenêtre d'un écran à l'autre, elle s'adapte.
  • NativeView. Embarque des widgets SwiftUI, WebView2 ou GTK dans Compose, dans la même fenêtre.
  • ~60 Mo de RAM sur un Hello World GraalVM — Tao remplace AWT, pas seulement les décorations, donc la JVM ne charge jamais le toolkit AWT.

Le compromis : c'est le nouveau chemin. Les APIs sont stables mais évoluent ; certaines fonctionnalités AWT-spécifiques (ex. file dialogs AWT-only) demandent des alternatives — voir la section Tao pour la surface complète.

Choisir le backend

import dev.nucleusframework.nucleusapplication.NucleusBackend
import dev.nucleusframework.nucleusapplication.nucleusApplication

fun main() = nucleusApplication(backend = NucleusBackend.Tao) {
    DecoratedWindow(onCloseRequest = ::exitApplication, title = "MyApp") {
        // l'UI Compose
    }
}

NucleusBackend a trois valeurs :

  • Auto — prend Tao si decorated-window-tao est sur le classpath, sinon AWT. Par défaut.
  • Tao — force le backend Tao.
  • Awt — force le backend AWT (JBR ou JNI selon ce qui est résolu).

Le @Composable DecoratedWindow est identique entre backends. Dedans, nucleusWindow.unsafe.taoWindow / nucleusWindow.unsafe.awtWindow sont les échappatoires pour les appels backend-spécifiques.

Hot Reload + Tao sur macOS

Quand decorated-window-tao est sur le classpath, le plugin Gradle injecte automatiquement -XstartOnFirstThread dans les JavaExec de Hot Reload sur macOS — Tao fait tourner la boucle d'événements OS sur le main thread du process.

Côte à côte

AWT (JBR / JNI)Tao
Propriétaire de la event loopJVM (AWT EventQueue)Rust (Tao)
RAM (Hello World, GraalVM)~110 Mo~60 Mo
WaylandFallback XWaylandNatif
Multi-touchLimitéPointerEvent complets avec pression, inclinaison, source
StyletLimitéPression-sensible complète
Embarquement de vues nativesNativeView (SwiftUI, WebView2, GTK)
ÉcosystèmeLibs AWT-boundCompose uniquement

Et ensuite ?