DecoratedWindow sur Tao
Ouvrez une fenêtre Compose Desktop sur le backend Tao avec un slot de barre de titre personnalisé et des contrôles de fenêtre natifs, sans AWT.
DecoratedWindow est le même Composable sur chaque backend Nucleus. Sur Tao, il ouvre une
fenêtre OS native, monte une surface de rendu Skiko et vous donne un slot TitleBar que vous
remplissez avec du contenu Compose — y compris des dispositions de boutons de contrôle propres
à chaque OS. Cette page décrit le comportement spécifique à Tao de DecoratedWindow et les
membres exposés dans son lambda de contenu.
Ajouter la dépendance
plugins {
id("dev.nucleusframework")
}
dependencies {
implementation("dev.nucleusframework:nucleus.nucleus-application:2.3.0")
implementation("dev.nucleusframework:nucleus.decorated-window-tao:2.3.0")
}nucleus-application fournit le point d'entrée unifié ; decorated-window-tao fournit le
backend Tao. Avec les deux sur le classpath, NucleusBackend.Tao devient disponible.
Ouvrir une fenêtre
Démarrez le runtime avec nucleusApplication, puis appelez DecoratedWindow et ajoutez une
TitleBar :
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.material3.Text
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.DpSize
import androidx.compose.ui.unit.dp
import androidx.compose.ui.window.rememberWindowState
import dev.nucleusframework.application.DecoratedWindow
import dev.nucleusframework.application.NucleusBackend
import dev.nucleusframework.application.nucleusApplication
import dev.nucleusframework.window.NucleusDecoratedWindowTheme
import dev.nucleusframework.window.TitleBar
import dev.nucleusframework.window.macOSLargeCornerRadius
import dev.nucleusframework.window.styling.TitleBarColors
import dev.nucleusframework.window.styling.TitleBarMetrics
import dev.nucleusframework.window.styling.TitleBarStyle
fun main() = nucleusApplication(backend = NucleusBackend.Tao) {
val titleBarStyle = TitleBarStyle(
colors = TitleBarColors(
background = Color(0xFF1A1D24),
inactiveBackground = Color(0xFF15181D),
content = Color(0xFFE6E6E6),
border = Color.Transparent,
),
metrics = TitleBarMetrics(height = 36.dp),
)
NucleusDecoratedWindowTheme(isDark = true, titleBarStyle = titleBarStyle) {
DecoratedWindow(
onCloseRequest = ::exitApplication,
state = rememberWindowState(size = DpSize(1024.dp, 720.dp)),
title = "Tao Demo",
minimumSize = DpSize(640.dp, 480.dp),
) {
TitleBar(modifier = Modifier.macOSLargeCornerRadius()) { state ->
Text("Tao Demo", Modifier.align(Alignment.CenterHorizontally))
}
Box(Modifier.fillMaxSize()) { /* contenu de l'app */ }
}
}
}Le slot TitleBar gère en interne l'appui-glisser sur la barre de titre : la fenêtre se
déplace quand vous glissez une zone vide de la barre. Vous n'avez pas de modifier de drag à
brancher vous-même.
Pour les mises en page plein fenêtre, le chrome d'un design system, les sidebars en verre macOS
ou le Mica/Acrylic Windows 11, utilisez WindowScaffold à la place
(ou autour) du TitleBar stock. Les sites d'appel TitleBar existants restent valides.
Comment ça marche
nucleusApplication { } résout le backend et expose DecoratedWindow sur
NucleusApplicationScope. Sur Tao, cette surcharge délègue à
dev.nucleusframework.window.tao.ApplicationScope.DecoratedWindow, qui ouvre un
TaoWindow et monte une ComposeScene sur la surface native.
Dans le lambda de contenu, vous obtenez un NucleusDecoratedWindowScope. Sa propriété
nucleusWindow renvoie le handle NucleusWindow agnostique au backend : état de focus,
flows minimized / maximized / fullscreen, icône et taille minimale. Récupérez le TaoWindow
brut via nucleusWindow.unsafe.taoWindow quand vous avez besoin d'un comportement propre à Tao.
Le style de la barre de titre est partagé avec les backends AWT. TitleBarStyle,
TitleBarColors et TitleBarMetrics vivent dans decorated-window-core, et
NucleusDecoratedWindowTheme les fournit via des composition locals. Le même thème
fonctionne que la dépendance soit -tao, -jbr ou -jni.
Référence de l'API
Paramètres de DecoratedWindow
| Paramètre | Type | Notes |
|---|---|---|
onCloseRequest | () -> Unit | Émis par l'affordance de fermeture de l'OS. |
state | WindowState | Position, taille, placement. |
visible | Boolean | Défaut true. |
title | String | Titre OS de la fenêtre. |
icon | Painter? | Icône barre des tâches / dock. |
resizable | Boolean | Défaut true. |
enabled / focusable / alwaysOnTop | Boolean | Flags de fenêtre standard. |
undecorated | Boolean | Fenêtre sans cadre ni contrôles. Pris en compte par Tao ; ignoré par AWT. |
popupFor | NucleusWindow? | Linux/Tao uniquement : attache la fenêtre comme popup superposée à une autre. |
nativePopupLayers | Boolean | Défaut false. Matérialise les couches Compose Popup en fenêtres natives transparentes (NSPanel / WS_POPUP HWND). Tao uniquement. |
hiddenFromDock | Boolean | Défaut false. Masque la fenêtre de la barre des tâches / du Dock de l'OS. Pris en compte par Tao ; ignoré par AWT. |
minimumSize | DpSize? | Appliqué après la première passe de layout. |
onPreviewKeyEvent / onKeyEvent | (KeyEvent) -> Boolean | Renvoie true pour consommer l'événement. |
content | @Composable NucleusDecoratedWindowScope.() -> Unit | Slot barre de titre plus votre UI. |
Le DecoratedWindow natif Tao (via taoApplication ou la surcharge de scope Tao) accepte aussi
transparent: Boolean = false pour la transparence plein fenêtre. En 2.2.0, l'umbrella
NucleusApplicationScope.DecoratedWindow ne retransmet pas ce flag — voir
overlays transparents.
Masquer de la barre des tâches / du Dock
hiddenFromDock garde la fenêtre visible et focusable tout en la retirant de la liste des
fenêtres au niveau OS — utile pour les HUD, les overlays et les fenêtres utilitaires en
arrière-plan qui ne doivent pas encombrer la barre des tâches ou le sélecteur d'apps :
DecoratedWindow(
onCloseRequest = ::exitApplication,
hiddenFromDock = true,
) {
// ...
}Le mécanisme diffère selon la plateforme :
- macOS — bascule la
NSApplicationpartagée vers la politique d'activation accessoire (pas d'icône dans le Dock, pas de barre de menu). C'est à l'échelle de l'app, pas par fenêtre : la dernière fenêtre qui applique le flag l'emporte. - Windows — positionne
WS_EX_TOOLWINDOWsur la fenêtre, ce qui supprime son bouton dans la barre des tâches et son entrée dans Alt+Tab. Par fenêtre. - Linux — positionne les hints GTK skip-taskbar/skip-pager (
_NET_WM_STATE_SKIP_TASKBAR). Par fenêtre, et effectif uniquement sous X11 ou XWayland.
Sous Wayland natif, hiddenFromDock n'a aucun effet — Wayland n'a pas de protocole
client-side pour skip-taskbar (xdg-shell, gtk_shell1 et les extensions layer-shell en staging
n'en ont pas, et Mutter rejette wlr-layer-shell). Nucleus journalise un avertissement plutôt que
d'échouer silencieusement. Forcez XWayland avec NUCLEUS_TAO_LINUX_RENDERER=x11 si vous avez besoin que
la fenêtre soit réellement masquée sur une session Wayland — voir
Wayland natif.
Membres de scope
interface NucleusDecoratedWindowScope : DecoratedWindowScope {
val nucleusWindow: NucleusWindow
}
interface NucleusWindow {
val isFocused: Boolean
val isMinimized: Boolean
val isMaximized: Boolean
val isFullscreen: Boolean
val focusFlow: StateFlow<Boolean>
fun setMaximized(maximized: Boolean)
fun setFullscreen(fullscreen: Boolean)
fun setMinimumSize(size: DpSize?)
fun setIcon(painter: Painter?)
fun close()
val unsafe: NucleusWindowUnsafe // .taoWindow, .taoHandle
}Modifiers de barre de titre
Modifier.macOSLargeCornerRadius()— active les coins arrondis de macOS 26+.Modifier.newFullscreenControls()— réagence les boutons de la barre de titre en plein écran.
Scaffold et chrome (2.2+)
Préférez ceux-ci quand le layout du TitleBar stock est trop rigide :
WindowScaffold/TitleBarPlacement— mises en page plein fenêtre et chrome en overlay.Modifier.windowDragArea/noWindowDrag— déclarer (ou exclure) les zones de move natives.WindowControls— min/max/fermer système hors deTitleBar.WindowBackground/WindowAppearance— couleur de clear et clair/sombre natif depuis l'arbre.Modifier.windowGlassRegion(macOS) /WindowsBackdrop(Windows 11) — matériaux de plateforme.
Référence complète : Scaffold de fenêtre et chrome.
TitleBar est une seule extension sur DecoratedWindowScope. Le scope de
nucleusApplication (NucleusDecoratedWindowScope) et le scope Tao natif de
taoApplication (TaoDecoratedWindowScope) l'implémentent tous les deux : le même appel à
TitleBar fonctionne quel que soit le point d'entrée d'où vous partez. Idem pour
WindowScaffold et les primitives de chrome.
Notes
- macOS exige
-XstartOnFirstThread. Le plugin Gradle Nucleus l'ajoute pour vous. - Pour les apps multi-fenêtres, appelez
DecoratedWindowplusieurs fois depuis le même blocnucleusApplication. Chaque fenêtre obtient son propreNucleusWindow. - Les fenêtres CSD Linux dessinent une ombre portée GTK native (motif hidden-titlebar) qui suit la fenêtre pendant les déplacements interactifs.
NucleusApplicationScopeimplémente l'ApplicationScopede Compose, si bien que les bibliothèques scopées au receiver Compose plain (par exemple les composables system-tray) se résolvent dansnucleusApplication { }.
Et ensuite
- Scaffold de fenêtre et chrome — mises en page plein fenêtre et matériaux.
- Le backend Tao — ce que couvre le backend sans AWT.
- DecoratedWindow sur tous les backends — l'API de fenêtre partagée.
- Multi-touch et gestes du trackpad — lire les événements d'entrée Tao.
- Backends — comment Nucleus choisit Tao ou AWT.
Le backend Tao
Tao est un backend de fenêtre natif en Rust qui exécute Compose Desktop sans AWT et ajoute Wayland natif, le multi-touch et le stylet.
Scaffold de fenêtre et chrome
Construisez des mises en page plein fenêtre et des barres de titre personnalisées sur Tao avec WindowScaffold, les zones de drag, WindowControls et les matériaux de plateforme.